this repo has no description
0
fork

Configure Feed

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

internal/core/adt: add Expr method on CallContext

This method allows looking up the unevaluated
expression of a CallExpr. To avoid having to create
a slice, it computes the exact position of the
argument depending on whether the call represents
a validation or function call.

As expressions are raw, we now also need to set
the Environment in Validate. For calls the
Environment was already passed correctly.

The usage of these calls will happen in subsequent
CLs. We make these change already to isolate any
problems that may arise from these more
straightforward changes.

Issue #3649

Signed-off-by: Marcel van Lohuizen <mpvl@gmail.com>
Change-Id: I2818a7f0ca8fb00c8746007e64623d0278e31c53
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1208684
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Matthew Sackman <matthew@cue.works>

+31 -10
+21 -5
internal/core/adt/call.go
··· 69 69 return c.args 70 70 } 71 71 72 - // Exprs return the unevaluated argument expressions. This function is only used 73 - // for transitioning and will be removed at some point. Use [CallContext.Expr] 74 - // instead. (TODO) 75 - func (c *CallContext) Exprs() []Expr { 76 - return c.call.Args 72 + // Expr returns the nth argument expression. The value is evaluated and any 73 + // cycle information is accumulated in the context. This allows cycles in 74 + // arguments to be detected. 75 + // 76 + // This method of getting an argument should be used when the argument is used 77 + // as a schema and may contain cycles. 78 + func (c *CallContext) Expr(i int) Expr { 79 + // If the call context represents a validator call, the argument will be 80 + // offset by 1. 81 + if c.isValidator { 82 + if i == 0 { 83 + c.Errf("Expr may not be called for 0th argument of validator") 84 + return nil 85 + } 86 + i-- 87 + } 88 + return c.call.Args[i] 89 + } 90 + 91 + func (c *CallContext) Errf(format string, args ...interface{}) *Bottom { 92 + return c.ctx.NewErrf(format, args...) 77 93 }
+3
internal/core/adt/context.go
··· 461 461 462 462 src := c.src 463 463 ci := c.ci 464 + env := c.e 464 465 c.src = check.Source() 465 466 c.ci = check.CloseInfo 467 + c.e = check.Env 466 468 467 469 err := check.x.(Validator).validate(c, value) 468 470 469 471 c.src = src 470 472 c.ci = ci 473 + c.e = env 471 474 472 475 return err 473 476 }
+2 -2
internal/core/compile/builtin.go
··· 118 118 Result: adt.IntKind, 119 119 RawFunc: func(call *adt.CallContext) adt.Value { 120 120 c := call.OpContext() 121 - args := call.Exprs() 121 + arg := call.Expr(0) 122 122 123 123 // Pass through the cycle information from evaluating the first argument. 124 - v := c.EvaluateKeepState(args[0]) 124 + v := c.EvaluateKeepState(arg) 125 125 list := c.RawElems(v) 126 126 if len(list) == 0 { 127 127 return &adt.Top{}
+4 -3
internal/pkg/builtin.go
··· 132 132 133 133 // call, _ := ctx.Source().(*ast.CallExpr) 134 134 c := &CallCtxt{ 135 - ctx: ctx, 136 - args: args, 137 - builtin: b, 135 + CallContext: call, 136 + ctx: ctx, 137 + args: args, 138 + builtin: b, 138 139 } 139 140 defer func() { 140 141 var errVal interface{} = c.Err
+1
internal/pkg/context.go
··· 28 28 29 29 // CallCtxt is passed to builtin implementations that need to use a cue.Value. This is an internal type. Its interface may change. 30 30 type CallCtxt struct { 31 + *adt.CallContext 31 32 ctx *adt.OpContext 32 33 builtin *Builtin 33 34 Err interface{}