Skip to content

Commit 9acd624

Browse files
committed
cue: prepare to hoist builtins, step 2
Changed code to allow it to be extracted from the cue package. Add the following functionality (for internal usage only): - Value.Decimal - bottomer: allow access to Bottom method of custom error types - MakeValue create Value from internal types Change-Id: I26076ef2f75b5f39f8f65ecf8814557457db8daf Reviewed-on: https://cue-review.googlesource.com/c/cue/+/6882 Reviewed-by: CUE cueckoo <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent ce28b20 commit 9acd624

File tree

7 files changed

+86
-60
lines changed

7 files changed

+86
-60
lines changed

cue/builtin.go

Lines changed: 51 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import (
3535
"cuelang.org/go/internal/core/adt"
3636
"cuelang.org/go/internal/core/compile"
3737
"cuelang.org/go/internal/core/convert"
38-
"cuelang.org/go/internal/core/runtime"
3938
)
4039

4140
// A Builtin is a builtin function or constant.
@@ -122,13 +121,10 @@ func toBuiltin(ctx *adt.OpContext, b *Builtin) *adt.Builtin {
122121
Name: b.Name,
123122
}
124123
x.Func = func(ctx *adt.OpContext, args []adt.Value) (ret adt.Expr) {
125-
runtime := ctx.Impl().(*runtime.Runtime)
126-
index := runtime.Data.(*index)
127-
128124
// call, _ := ctx.Source().(*ast.CallExpr)
129125
c := &CallCtxt{
130126
// src: call,
131-
ctx: index.newContext(),
127+
ctx: ctx,
132128
args: args,
133129
builtin: b,
134130
}
@@ -143,8 +139,8 @@ func toBuiltin(ctx *adt.OpContext, b *Builtin) *adt.Builtin {
143139
switch v := c.Ret.(type) {
144140
case adt.Value:
145141
return v
146-
case *valueError:
147-
return v.err
142+
case bottomer:
143+
return v.Bottom()
148144
}
149145
if c.Err != nil {
150146
return nil
@@ -180,11 +176,11 @@ func pos(n adt.Node) (p token.Pos) {
180176
return src.Pos()
181177
}
182178

183-
func (x *Builtin) name(ctx *context) string {
179+
func (x *Builtin) name(ctx *adt.OpContext) string {
184180
if x.Pkg == 0 {
185181
return x.Name
186182
}
187-
return fmt.Sprintf("%s.%s", ctx.LabelStr(x.Pkg), x.Name)
183+
return fmt.Sprintf("%s.%s", x.Pkg.StringValue(ctx), x.Name)
188184
}
189185

190186
func (x *Builtin) isValidator() bool {
@@ -193,24 +189,25 @@ func (x *Builtin) isValidator() bool {
193189

194190
func processErr(call *CallCtxt, errVal interface{}, ret adt.Expr) adt.Expr {
195191
ctx := call.ctx
196-
src := call.src
197192
switch err := errVal.(type) {
198193
case nil:
199194
case *callError:
200195
ret = err.b
201196
case *json.MarshalerError:
202-
if err, ok := err.Err.(*marshalError); ok && err.b != nil {
203-
ret = err.b
197+
if err, ok := err.Err.(bottomer); ok {
198+
if b := err.Bottom(); b != nil {
199+
ret = b
200+
}
204201
}
205-
case *marshalError:
206-
ret = wrapCallErr(call, err.b)
207-
case *valueError:
208-
ret = wrapCallErr(call, err.err)
202+
case bottomer:
203+
ret = wrapCallErr(call, err.Bottom())
209204
case errors.Error:
210205
ret = wrapCallErr(call, &adt.Bottom{Err: err})
211206
case error:
212207
if call.Err == internal.ErrIncomplete {
213-
ret = ctx.mkErr(src, codeIncomplete, "incomplete value")
208+
err := ctx.NewErrf("incomplete value")
209+
err.Code = adt.IncompleteError
210+
ret = err
214211
} else {
215212
// TODO: store the underlying error explicitly
216213
ret = wrapCallErr(call, &adt.Bottom{Err: errors.Promote(err, "")})
@@ -278,7 +275,7 @@ func (c *CallCtxt) convertError(x interface{}, name string) *adt.Bottom {
278275
// CallCtxt is passed to builtin implementations that need to use a cue.Value. This is an internal type. It's interface may change.
279276
type CallCtxt struct {
280277
src adt.Expr // *adt.CallExpr
281-
ctx *context
278+
ctx *adt.OpContext
282279
builtin *Builtin
283280
Err interface{}
284281
Ret interface{}
@@ -287,7 +284,7 @@ type CallCtxt struct {
287284
}
288285

289286
func (c *CallCtxt) Pos() token.Pos {
290-
return c.ctx.opCtx.Pos()
287+
return c.ctx.Pos()
291288
}
292289

293290
func (c *CallCtxt) Name() string {
@@ -351,6 +348,11 @@ func (c *CallCtxt) Do() bool {
351348
return c.Err == nil
352349
}
353350

351+
type bottomer interface {
352+
error
353+
Bottom() *adt.Bottom
354+
}
355+
354356
type callError struct {
355357
b *adt.Bottom
356358
}
@@ -360,27 +362,22 @@ func (e *callError) Error() string {
360362
}
361363

362364
func (c *CallCtxt) errf(src adt.Node, underlying error, format string, args ...interface{}) {
363-
a := make([]interface{}, 0, 2+len(args))
364-
if err, ok := underlying.(*valueError); ok {
365-
a = append(a, err.err)
365+
var errs errors.Error
366+
if err, ok := underlying.(bottomer); ok {
367+
errs = err.Bottom().Err
366368
}
367-
a = append(a, format)
368-
a = append(a, args...)
369-
err := c.ctx.mkErr(src, a...)
370-
c.Err = &callError{err}
369+
errs = errors.Wrapf(errs, c.ctx.Pos(), format, args...)
370+
c.Err = &callError{&adt.Bottom{Err: errs}}
371371
}
372372

373373
func (c *CallCtxt) errcf(src adt.Node, code adt.ErrorCode, format string, args ...interface{}) {
374-
a := make([]interface{}, 0, 2+len(args))
375-
a = append(a, code)
376-
a = append(a, format)
377-
a = append(a, args...)
378-
err := c.ctx.mkErr(src, a...)
374+
err := c.ctx.NewErrf(format, args...)
375+
err.Code = code
379376
c.Err = &callError{err}
380377
}
381378

382379
func (c *CallCtxt) Value(i int) Value {
383-
v := newValueRoot(c.ctx, c.args[i])
380+
v := MakeValue(c.ctx, c.args[i])
384381
// TODO: remove default
385382
// v, _ = v.Default()
386383
if !v.IsConcrete() {
@@ -390,7 +387,7 @@ func (c *CallCtxt) Value(i int) Value {
390387
}
391388

392389
func (c *CallCtxt) Struct(i int) *Struct {
393-
v := newValueRoot(c.ctx, c.args[i])
390+
v := MakeValue(c.ctx, c.args[i])
394391
s, err := v.Struct()
395392
if err != nil {
396393
c.invalidArgType(c.args[i], i, "struct", err)
@@ -400,7 +397,7 @@ func (c *CallCtxt) Struct(i int) *Struct {
400397
}
401398

402399
func (c *CallCtxt) invalidArgType(arg adt.Expr, i int, typ string, err error) {
403-
if ve, ok := err.(*valueError); ok && ve.err.IsIncomplete() {
400+
if ve, ok := err.(bottomer); ok && ve.Bottom().IsIncomplete() {
404401
c.Err = ve
405402
return
406403
}
@@ -410,16 +407,16 @@ func (c *CallCtxt) invalidArgType(arg adt.Expr, i int, typ string, err error) {
410407
if !ok {
411408
c.errf(c.src, nil,
412409
"cannot use incomplete value %s as %s in argument %d to %s: %v",
413-
c.ctx.str(arg), typ, i, c.Name(), err)
410+
c.ctx.Str(arg), typ, i, c.Name(), err)
414411
}
415412
if err != nil {
416413
c.errf(c.src, err,
417414
"cannot use %s (type %s) as %s in argument %d to %s: %v",
418-
c.ctx.str(arg), v.Kind(), typ, i, c.Name(), err)
415+
c.ctx.Str(arg), v.Kind(), typ, i, c.Name(), err)
419416
} else {
420417
c.errf(c.src, err,
421418
"cannot use %s (type %s) as %s in argument %d to %s",
422-
c.ctx.str(arg), v.Kind(), typ, i, c.Name())
419+
c.ctx.Str(arg), v.Kind(), typ, i, c.Name())
423420
}
424421
}
425422

@@ -432,7 +429,7 @@ func (c *CallCtxt) Int64(i int) int64 { return int64(c.intValue(i, 64, "int64"))
432429

433430
func (c *CallCtxt) intValue(i, bits int, typ string) int64 {
434431
arg := c.args[i]
435-
x := newValueRoot(c.ctx, arg)
432+
x := MakeValue(c.ctx, arg)
436433
n, err := x.Int(nil)
437434
if err != nil {
438435
c.invalidArgType(arg, i, typ, err)
@@ -454,7 +451,7 @@ func (c *CallCtxt) Uint32(i int) uint32 { return uint32(c.uintValue(i, 32, "uint
454451
func (c *CallCtxt) Uint64(i int) uint64 { return uint64(c.uintValue(i, 64, "uint64")) }
455452

456453
func (c *CallCtxt) uintValue(i, bits int, typ string) uint64 {
457-
x := newValueRoot(c.ctx, c.args[i])
454+
x := MakeValue(c.ctx, c.args[i])
458455
n, err := x.Int(nil)
459456
if err != nil || n.Sign() < 0 {
460457
c.invalidArgType(c.args[i], i, typ, err)
@@ -469,16 +466,16 @@ func (c *CallCtxt) uintValue(i, bits int, typ string) uint64 {
469466
}
470467

471468
func (c *CallCtxt) Decimal(i int) *apd.Decimal {
472-
x := newValueRoot(c.ctx, c.args[i])
469+
x := MakeValue(c.ctx, c.args[i])
473470
if _, err := x.MantExp(nil); err != nil {
474471
c.invalidArgType(c.args[i], i, "Decimal", err)
475472
return nil
476473
}
477-
return &c.args[i].(*numLit).X
474+
return &c.args[i].(*adt.Num).X
478475
}
479476

480477
func (c *CallCtxt) Float64(i int) float64 {
481-
x := newValueRoot(c.ctx, c.args[i])
478+
x := MakeValue(c.ctx, c.args[i])
482479
res, err := x.Float64()
483480
if err != nil {
484481
c.invalidArgType(c.args[i], i, "float64", err)
@@ -488,7 +485,7 @@ func (c *CallCtxt) Float64(i int) float64 {
488485
}
489486

490487
func (c *CallCtxt) BigInt(i int) *big.Int {
491-
x := newValueRoot(c.ctx, c.args[i])
488+
x := MakeValue(c.ctx, c.args[i])
492489
n, err := x.Int(nil)
493490
if err != nil {
494491
c.invalidArgType(c.args[i], i, "int", err)
@@ -500,7 +497,7 @@ func (c *CallCtxt) BigInt(i int) *big.Int {
500497
var ten = big.NewInt(10)
501498

502499
func (c *CallCtxt) BigFloat(i int) *big.Float {
503-
x := newValueRoot(c.ctx, c.args[i])
500+
x := MakeValue(c.ctx, c.args[i])
504501
var mant big.Int
505502
exp, err := x.MantExp(&mant)
506503
if err != nil {
@@ -518,7 +515,7 @@ func (c *CallCtxt) BigFloat(i int) *big.Float {
518515
}
519516

520517
func (c *CallCtxt) String(i int) string {
521-
x := newValueRoot(c.ctx, c.args[i])
518+
x := MakeValue(c.ctx, c.args[i])
522519
v, err := x.String()
523520
if err != nil {
524521
c.invalidArgType(c.args[i], i, "string", err)
@@ -528,7 +525,7 @@ func (c *CallCtxt) String(i int) string {
528525
}
529526

530527
func (c *CallCtxt) Bytes(i int) []byte {
531-
x := newValueRoot(c.ctx, c.args[i])
528+
x := MakeValue(c.ctx, c.args[i])
532529
v, err := x.Bytes()
533530
if err != nil {
534531
c.invalidArgType(c.args[i], i, "bytes", err)
@@ -538,7 +535,7 @@ func (c *CallCtxt) Bytes(i int) []byte {
538535
}
539536

540537
func (c *CallCtxt) Reader(i int) io.Reader {
541-
x := newValueRoot(c.ctx, c.args[i])
538+
x := MakeValue(c.ctx, c.args[i])
542539
// TODO: optimize for string and bytes cases
543540
r, err := x.Reader()
544541
if err != nil {
@@ -549,7 +546,7 @@ func (c *CallCtxt) Reader(i int) io.Reader {
549546
}
550547

551548
func (c *CallCtxt) Bool(i int) bool {
552-
x := newValueRoot(c.ctx, c.args[i])
549+
x := MakeValue(c.ctx, c.args[i])
553550
b, err := x.Bool()
554551
if err != nil {
555552
c.invalidArgType(c.args[i], i, "bool", err)
@@ -560,7 +557,7 @@ func (c *CallCtxt) Bool(i int) bool {
560557

561558
func (c *CallCtxt) List(i int) (a []Value) {
562559
arg := c.args[i]
563-
x := newValueRoot(c.ctx, arg)
560+
x := MakeValue(c.ctx, arg)
564561
v, err := x.List()
565562
if err != nil {
566563
c.invalidArgType(c.args[i], i, "list", err)
@@ -574,38 +571,37 @@ func (c *CallCtxt) List(i int) (a []Value) {
574571

575572
func (c *CallCtxt) Iter(i int) (a Iterator) {
576573
arg := c.args[i]
577-
x := newValueRoot(c.ctx, arg)
574+
x := MakeValue(c.ctx, arg)
578575
v, err := x.List()
579576
if err != nil {
580577
c.invalidArgType(c.args[i], i, "list", err)
581-
return Iterator{ctx: c.ctx}
582578
}
583579
return v
584580
}
585581

586582
func (c *CallCtxt) DecimalList(i int) (a []*apd.Decimal) {
587583
arg := c.args[i]
588-
x := newValueRoot(c.ctx, arg)
584+
x := MakeValue(c.ctx, arg)
589585
v, err := x.List()
590586
if err != nil {
591587
c.invalidArgType(c.args[i], i, "list", err)
592588
return nil
593589
}
594590
for j := 0; v.Next(); j++ {
595-
num, err := v.Value().getNum(numKind)
591+
num, err := v.Value().Decimal()
596592
if err != nil {
597593
c.errf(c.src, err, "invalid list element %d in argument %d to %s: %v",
598594
j, i, c.Name(), err)
599595
break
600596
}
601-
a = append(a, &num.X)
597+
a = append(a, num)
602598
}
603599
return a
604600
}
605601

606602
func (c *CallCtxt) StringList(i int) (a []string) {
607603
arg := c.args[i]
608-
x := newValueRoot(c.ctx, arg)
604+
x := MakeValue(c.ctx, arg)
609605
v, err := x.List()
610606
if err != nil {
611607
c.invalidArgType(c.args[i], i, "list", err)

cue/errors.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ type valueError struct {
4141
err *bottom
4242
}
4343

44+
func (e *valueError) Bottom() *adt.Bottom { return e.err }
45+
4446
func (e *valueError) Error() string {
4547
return errors.String(e)
4648
}

cue/testdata/fulleval/048_dont_pass_incomplete_values_to_builtins.txtar

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ foo: json.Marshal(input)
1818
(struct){
1919
input: (string){ string }
2020
foo: (_|_){
21-
// [incomplete] non-concrete argument 0
21+
// [incomplete] foo: non-concrete argument 0:
22+
// ./in.cue:4:8
2223
}
2324
}

cue/testdata/fulleval/051_detectIncompleteYAML.txtar

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,12 @@ Val:
7777
use: (string){ string }
7878
}
7979
baz: (_|_){
80-
// [incomplete] non-concrete argument 0
80+
// [incomplete] #Spec.data.baz: non-concrete argument 0:
81+
// ./in.cue:11:11
8182
}
8283
foobar: (_|_){
83-
// [incomplete] incomplete value
84+
// [incomplete] #Spec.data.foobar: incomplete value:
85+
// ./in.cue:12:11
8486
}
8587
}
8688
}

cue/testdata/fulleval/052_detectIncompleteJSON.txtar

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ Val:
6969
use: (string){ string }
7070
}
7171
baz: (_|_){
72-
// [incomplete] non-concrete argument 0
72+
// [incomplete] #Spec.data.baz: non-concrete argument 0:
73+
// ./in.cue:11:11
7374
}
7475
foobar: (_|_){
7576
// [incomplete] cannot convert incomplete value "string" to JSON

cue/testdata/fulleval/056_issue314.txtar

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ x:
9696
#U: (#struct){
9797
s: (string){ string }
9898
out: (_|_){
99-
// [incomplete] incomplete value
99+
// [incomplete] #U.out: incomplete value:
100+
// ./in.cue:26:7
100101
}
101102
}
102103
}

0 commit comments

Comments
 (0)