this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>

+86 -60
+51 -55
cue/builtin.go
··· 35 35 "cuelang.org/go/internal/core/adt" 36 36 "cuelang.org/go/internal/core/compile" 37 37 "cuelang.org/go/internal/core/convert" 38 - "cuelang.org/go/internal/core/runtime" 39 38 ) 40 39 41 40 // A Builtin is a builtin function or constant. ··· 122 121 Name: b.Name, 123 122 } 124 123 x.Func = func(ctx *adt.OpContext, args []adt.Value) (ret adt.Expr) { 125 - runtime := ctx.Impl().(*runtime.Runtime) 126 - index := runtime.Data.(*index) 127 - 128 124 // call, _ := ctx.Source().(*ast.CallExpr) 129 125 c := &CallCtxt{ 130 126 // src: call, 131 - ctx: index.newContext(), 127 + ctx: ctx, 132 128 args: args, 133 129 builtin: b, 134 130 } ··· 143 139 switch v := c.Ret.(type) { 144 140 case adt.Value: 145 141 return v 146 - case *valueError: 147 - return v.err 142 + case bottomer: 143 + return v.Bottom() 148 144 } 149 145 if c.Err != nil { 150 146 return nil ··· 180 176 return src.Pos() 181 177 } 182 178 183 - func (x *Builtin) name(ctx *context) string { 179 + func (x *Builtin) name(ctx *adt.OpContext) string { 184 180 if x.Pkg == 0 { 185 181 return x.Name 186 182 } 187 - return fmt.Sprintf("%s.%s", ctx.LabelStr(x.Pkg), x.Name) 183 + return fmt.Sprintf("%s.%s", x.Pkg.StringValue(ctx), x.Name) 188 184 } 189 185 190 186 func (x *Builtin) isValidator() bool { ··· 193 189 194 190 func processErr(call *CallCtxt, errVal interface{}, ret adt.Expr) adt.Expr { 195 191 ctx := call.ctx 196 - src := call.src 197 192 switch err := errVal.(type) { 198 193 case nil: 199 194 case *callError: 200 195 ret = err.b 201 196 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 + } 204 201 } 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()) 209 204 case errors.Error: 210 205 ret = wrapCallErr(call, &adt.Bottom{Err: err}) 211 206 case error: 212 207 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 214 211 } else { 215 212 // TODO: store the underlying error explicitly 216 213 ret = wrapCallErr(call, &adt.Bottom{Err: errors.Promote(err, "")}) ··· 278 275 // CallCtxt is passed to builtin implementations that need to use a cue.Value. This is an internal type. It's interface may change. 279 276 type CallCtxt struct { 280 277 src adt.Expr // *adt.CallExpr 281 - ctx *context 278 + ctx *adt.OpContext 282 279 builtin *Builtin 283 280 Err interface{} 284 281 Ret interface{} ··· 287 284 } 288 285 289 286 func (c *CallCtxt) Pos() token.Pos { 290 - return c.ctx.opCtx.Pos() 287 + return c.ctx.Pos() 291 288 } 292 289 293 290 func (c *CallCtxt) Name() string { ··· 349 346 // Do returns whether the call should be done. 350 347 func (c *CallCtxt) Do() bool { 351 348 return c.Err == nil 349 + } 350 + 351 + type bottomer interface { 352 + error 353 + Bottom() *adt.Bottom 352 354 } 353 355 354 356 type callError struct { ··· 360 362 } 361 363 362 364 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 366 368 } 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}} 371 371 } 372 372 373 373 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 379 376 c.Err = &callError{err} 380 377 } 381 378 382 379 func (c *CallCtxt) Value(i int) Value { 383 - v := newValueRoot(c.ctx, c.args[i]) 380 + v := MakeValue(c.ctx, c.args[i]) 384 381 // TODO: remove default 385 382 // v, _ = v.Default() 386 383 if !v.IsConcrete() { ··· 390 387 } 391 388 392 389 func (c *CallCtxt) Struct(i int) *Struct { 393 - v := newValueRoot(c.ctx, c.args[i]) 390 + v := MakeValue(c.ctx, c.args[i]) 394 391 s, err := v.Struct() 395 392 if err != nil { 396 393 c.invalidArgType(c.args[i], i, "struct", err) ··· 400 397 } 401 398 402 399 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() { 404 401 c.Err = ve 405 402 return 406 403 } ··· 410 407 if !ok { 411 408 c.errf(c.src, nil, 412 409 "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) 414 411 } 415 412 if err != nil { 416 413 c.errf(c.src, err, 417 414 "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) 419 416 } else { 420 417 c.errf(c.src, err, 421 418 "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()) 423 420 } 424 421 } 425 422 ··· 432 429 433 430 func (c *CallCtxt) intValue(i, bits int, typ string) int64 { 434 431 arg := c.args[i] 435 - x := newValueRoot(c.ctx, arg) 432 + x := MakeValue(c.ctx, arg) 436 433 n, err := x.Int(nil) 437 434 if err != nil { 438 435 c.invalidArgType(arg, i, typ, err) ··· 454 451 func (c *CallCtxt) Uint64(i int) uint64 { return uint64(c.uintValue(i, 64, "uint64")) } 455 452 456 453 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]) 458 455 n, err := x.Int(nil) 459 456 if err != nil || n.Sign() < 0 { 460 457 c.invalidArgType(c.args[i], i, typ, err) ··· 469 466 } 470 467 471 468 func (c *CallCtxt) Decimal(i int) *apd.Decimal { 472 - x := newValueRoot(c.ctx, c.args[i]) 469 + x := MakeValue(c.ctx, c.args[i]) 473 470 if _, err := x.MantExp(nil); err != nil { 474 471 c.invalidArgType(c.args[i], i, "Decimal", err) 475 472 return nil 476 473 } 477 - return &c.args[i].(*numLit).X 474 + return &c.args[i].(*adt.Num).X 478 475 } 479 476 480 477 func (c *CallCtxt) Float64(i int) float64 { 481 - x := newValueRoot(c.ctx, c.args[i]) 478 + x := MakeValue(c.ctx, c.args[i]) 482 479 res, err := x.Float64() 483 480 if err != nil { 484 481 c.invalidArgType(c.args[i], i, "float64", err) ··· 488 485 } 489 486 490 487 func (c *CallCtxt) BigInt(i int) *big.Int { 491 - x := newValueRoot(c.ctx, c.args[i]) 488 + x := MakeValue(c.ctx, c.args[i]) 492 489 n, err := x.Int(nil) 493 490 if err != nil { 494 491 c.invalidArgType(c.args[i], i, "int", err) ··· 500 497 var ten = big.NewInt(10) 501 498 502 499 func (c *CallCtxt) BigFloat(i int) *big.Float { 503 - x := newValueRoot(c.ctx, c.args[i]) 500 + x := MakeValue(c.ctx, c.args[i]) 504 501 var mant big.Int 505 502 exp, err := x.MantExp(&mant) 506 503 if err != nil { ··· 518 515 } 519 516 520 517 func (c *CallCtxt) String(i int) string { 521 - x := newValueRoot(c.ctx, c.args[i]) 518 + x := MakeValue(c.ctx, c.args[i]) 522 519 v, err := x.String() 523 520 if err != nil { 524 521 c.invalidArgType(c.args[i], i, "string", err) ··· 528 525 } 529 526 530 527 func (c *CallCtxt) Bytes(i int) []byte { 531 - x := newValueRoot(c.ctx, c.args[i]) 528 + x := MakeValue(c.ctx, c.args[i]) 532 529 v, err := x.Bytes() 533 530 if err != nil { 534 531 c.invalidArgType(c.args[i], i, "bytes", err) ··· 538 535 } 539 536 540 537 func (c *CallCtxt) Reader(i int) io.Reader { 541 - x := newValueRoot(c.ctx, c.args[i]) 538 + x := MakeValue(c.ctx, c.args[i]) 542 539 // TODO: optimize for string and bytes cases 543 540 r, err := x.Reader() 544 541 if err != nil { ··· 549 546 } 550 547 551 548 func (c *CallCtxt) Bool(i int) bool { 552 - x := newValueRoot(c.ctx, c.args[i]) 549 + x := MakeValue(c.ctx, c.args[i]) 553 550 b, err := x.Bool() 554 551 if err != nil { 555 552 c.invalidArgType(c.args[i], i, "bool", err) ··· 560 557 561 558 func (c *CallCtxt) List(i int) (a []Value) { 562 559 arg := c.args[i] 563 - x := newValueRoot(c.ctx, arg) 560 + x := MakeValue(c.ctx, arg) 564 561 v, err := x.List() 565 562 if err != nil { 566 563 c.invalidArgType(c.args[i], i, "list", err) ··· 574 571 575 572 func (c *CallCtxt) Iter(i int) (a Iterator) { 576 573 arg := c.args[i] 577 - x := newValueRoot(c.ctx, arg) 574 + x := MakeValue(c.ctx, arg) 578 575 v, err := x.List() 579 576 if err != nil { 580 577 c.invalidArgType(c.args[i], i, "list", err) 581 - return Iterator{ctx: c.ctx} 582 578 } 583 579 return v 584 580 } 585 581 586 582 func (c *CallCtxt) DecimalList(i int) (a []*apd.Decimal) { 587 583 arg := c.args[i] 588 - x := newValueRoot(c.ctx, arg) 584 + x := MakeValue(c.ctx, arg) 589 585 v, err := x.List() 590 586 if err != nil { 591 587 c.invalidArgType(c.args[i], i, "list", err) 592 588 return nil 593 589 } 594 590 for j := 0; v.Next(); j++ { 595 - num, err := v.Value().getNum(numKind) 591 + num, err := v.Value().Decimal() 596 592 if err != nil { 597 593 c.errf(c.src, err, "invalid list element %d in argument %d to %s: %v", 598 594 j, i, c.Name(), err) 599 595 break 600 596 } 601 - a = append(a, &num.X) 597 + a = append(a, num) 602 598 } 603 599 return a 604 600 } 605 601 606 602 func (c *CallCtxt) StringList(i int) (a []string) { 607 603 arg := c.args[i] 608 - x := newValueRoot(c.ctx, arg) 604 + x := MakeValue(c.ctx, arg) 609 605 v, err := x.List() 610 606 if err != nil { 611 607 c.invalidArgType(c.args[i], i, "list", err)
+2
cue/errors.go
··· 41 41 err *bottom 42 42 } 43 43 44 + func (e *valueError) Bottom() *adt.Bottom { return e.err } 45 + 44 46 func (e *valueError) Error() string { 45 47 return errors.String(e) 46 48 }
+2 -1
cue/testdata/fulleval/048_dont_pass_incomplete_values_to_builtins.txtar
··· 18 18 (struct){ 19 19 input: (string){ string } 20 20 foo: (_|_){ 21 - // [incomplete] non-concrete argument 0 21 + // [incomplete] foo: non-concrete argument 0: 22 + // ./in.cue:4:8 22 23 } 23 24 }
+4 -2
cue/testdata/fulleval/051_detectIncompleteYAML.txtar
··· 77 77 use: (string){ string } 78 78 } 79 79 baz: (_|_){ 80 - // [incomplete] non-concrete argument 0 80 + // [incomplete] #Spec.data.baz: non-concrete argument 0: 81 + // ./in.cue:11:11 81 82 } 82 83 foobar: (_|_){ 83 - // [incomplete] incomplete value 84 + // [incomplete] #Spec.data.foobar: incomplete value: 85 + // ./in.cue:12:11 84 86 } 85 87 } 86 88 }
+2 -1
cue/testdata/fulleval/052_detectIncompleteJSON.txtar
··· 69 69 use: (string){ string } 70 70 } 71 71 baz: (_|_){ 72 - // [incomplete] non-concrete argument 0 72 + // [incomplete] #Spec.data.baz: non-concrete argument 0: 73 + // ./in.cue:11:11 73 74 } 74 75 foobar: (_|_){ 75 76 // [incomplete] cannot convert incomplete value "string" to JSON
+2 -1
cue/testdata/fulleval/056_issue314.txtar
··· 96 96 #U: (#struct){ 97 97 s: (string){ string } 98 98 out: (_|_){ 99 - // [incomplete] incomplete value 99 + // [incomplete] #U.out: incomplete value: 100 + // ./in.cue:26:7 100 101 } 101 102 } 102 103 }
+23
cue/types.go
··· 36 36 "cuelang.org/go/internal/core/convert" 37 37 "cuelang.org/go/internal/core/eval" 38 38 "cuelang.org/go/internal/core/export" 39 + "cuelang.org/go/internal/core/runtime" 39 40 "cuelang.org/go/internal/core/subsume" 40 41 "cuelang.org/go/internal/core/validate" 41 42 ) ··· 187 188 return fmt.Sprintf("cue: marshal error: %v", e.err) 188 189 } 189 190 191 + func (e *marshalError) Bottom() *adt.Bottom { return e.b } 190 192 func (e *marshalError) Path() []string { return e.err.Path() } 191 193 func (e *marshalError) Msg() (string, []interface{}) { return e.err.Msg() } 192 194 func (e *marshalError) Position() token.Pos { return e.err.Position() } ··· 328 330 } 329 331 } 330 332 return int(n.X.Exponent), nil 333 + } 334 + 335 + // Decimal is for internal use only. The Decimal type that is returned is 336 + // subject to change. 337 + func (v Value) Decimal() (d *internal.Decimal, err error) { 338 + n, err := v.getNum(numKind) 339 + if err != nil { 340 + return nil, err 341 + } 342 + return &n.X, nil 331 343 } 332 344 333 345 // AppendInt appends the string representation of x in the given base to buf and ··· 607 619 return newErrValue(v, b) 608 620 } 609 621 return makeValue(v.idx, n) 622 + } 623 + 624 + // MakeValue converts an adt.Value and given OpContext to a Value. The context 625 + // must be directly or indirectly obtained from the NewRuntime defined in this 626 + // package and it will panic if this is not the case. This is for internal use 627 + // only. 628 + func MakeValue(ctx *adt.OpContext, v adt.Value) Value { 629 + runtime := ctx.Impl().(*runtime.Runtime) 630 + index := runtime.Data.(*index) 631 + 632 + return newValueRoot(index.newContext(), v) 610 633 } 611 634 612 635 func makeValue(idx *index, v *adt.Vertex) Value {