Skip to content

Commit d9af603

Browse files
committed
cue: add InferBuiltins EncodeOption
This functionality is currently partially internal or deprecated. This adds this functionality to the new API. This also removes a cyclic dependency in package dependencies that needs to be removed for the implementation of structure sharing. This moves resolveExpr to below BuildExpr, as their bodies are almost the same (functionally the same at the moment). This also removes dead code. Expresses the old CompileExpr in terms of the new BuildExpr. This is mostly done as a verification and to allow automatic rewrites in the future. Change-Id: I7d63aa097dd8f652b9b0b0181a2b148c8bb1f2d4 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9571 Reviewed-by: CUE cueckoo <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]> Reviewed-by: Paul Jolly <[email protected]>
1 parent b9e7d90 commit d9af603

File tree

8 files changed

+79
-150
lines changed

8 files changed

+79
-150
lines changed

cmd/cue/cmd/common.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,11 @@ func (i *expressionIter) value() cue.Value {
350350
if len(i.expr) == 0 {
351351
return i.iter.value()
352352
}
353-
// TODO: replace with FillPath.
354-
return value.EvalExpr(i.iter.value(), i.expr[i.i])
353+
v := i.iter.value()
354+
return v.Context().BuildExpr(i.expr[i.i],
355+
cue.Scope(v),
356+
cue.InferBuiltins(true),
357+
)
355358
}
356359

357360
type config struct {

cue/build.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package cue
1616

1717
import (
1818
"cuelang.org/go/cue/ast"
19+
"cuelang.org/go/cue/ast/astutil"
1920
"cuelang.org/go/cue/build"
2021
"cuelang.org/go/cue/errors"
2122
"cuelang.org/go/internal/core/adt"
@@ -78,11 +79,22 @@ func (r *hiddenRuntime) CompileFile(file *ast.File) (*Instance, error) {
7879
//
7980
// Deprecated: use BuildExpr. The use of Instance is being phased out.
8081
func (r *hiddenRuntime) CompileExpr(expr ast.Expr) (*Instance, error) {
81-
v, p, err := r.runtime().CompileExpr(nil, expr)
82+
f, err := astutil.ToFile(expr)
8283
if err != nil {
8384
return nil, err
8485
}
85-
return r.complete(p, v)
86+
v := (*Context)(r).BuildExpr(expr)
87+
err = v.Err()
88+
inst := &Instance{
89+
index: r.runtime(),
90+
root: v.v,
91+
inst: &build.Instance{
92+
Files: []*ast.File{f},
93+
},
94+
Err: errors.Promote(err, ""),
95+
Incomplete: err != nil,
96+
}
97+
return inst, err
8698
}
8799

88100
// Parse parses a CUE source value into a CUE Instance. The source code may be
@@ -149,7 +161,3 @@ func (r *hiddenRuntime) FromExpr(expr ast.Expr) (*Instance, error) {
149161
Decls: []ast.Decl{&ast.EmbedDecl{Expr: expr}},
150162
})
151163
}
152-
153-
func isBuiltin(s string) bool {
154-
return runtime.SharedRuntime.IsBuiltinPackage(s)
155-
}

cue/context.go

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@ package cue
1616

1717
import (
1818
"cuelang.org/go/cue/ast"
19+
"cuelang.org/go/cue/ast/astutil"
1920
"cuelang.org/go/cue/build"
2021
"cuelang.org/go/cue/errors"
22+
"cuelang.org/go/cue/token"
2123
"cuelang.org/go/internal/core/adt"
24+
"cuelang.org/go/internal/core/compile"
2225
"cuelang.org/go/internal/core/convert"
2326
"cuelang.org/go/internal/core/debug"
2427
"cuelang.org/go/internal/core/eval"
@@ -78,6 +81,23 @@ func Filename(filename string) BuildOption {
7881
return func(o *runtime.Config) { o.Filename = filename }
7982
}
8083

84+
// InferBuiltins allows unresolved references to bind to builtin packages with a
85+
// unique package name.
86+
//
87+
// This option is intended for evaluating expressions in a context where import
88+
// statements cannot be used. It is not recommended to use this for evaluating
89+
// CUE files.
90+
func InferBuiltins(elide bool) BuildOption {
91+
return func(o *runtime.Config) {
92+
o.Imports = func(x *ast.Ident) (pkgPath string) {
93+
if !o.Runtime.IsBuiltinPackage(x.Name) {
94+
return ""
95+
}
96+
return x.Name
97+
}
98+
}
99+
}
100+
81101
func (c *Context) parseOptions(options []BuildOption) (cfg runtime.Config) {
82102
cfg.Runtime = (*runtime.Runtime)(c)
83103
for _, f := range options {
@@ -143,14 +163,39 @@ func (c *Context) compile(v *adt.Vertex, p *build.Instance) Value {
143163
// The returned Value will represent an error, accessible through Err, if any
144164
// error occurred.
145165
func (c *Context) BuildExpr(x ast.Expr, options ...BuildOption) Value {
166+
r := c.runtime()
146167
cfg := c.parseOptions(options)
147-
v, p, err := c.runtime().CompileExpr(&cfg, x)
168+
169+
ctx := c.ctx()
170+
171+
astutil.ResolveExpr(x, errFn)
172+
conjunct, err := compile.Expr(&cfg.Config, r, anonymousPkg, x)
148173
if err != nil {
149-
return c.makeError(p.Err)
174+
return c.makeError(err)
150175
}
176+
v := adt.Resolve(ctx, conjunct)
177+
151178
return c.make(v)
152179
}
153180

181+
func errFn(pos token.Pos, msg string, args ...interface{}) {}
182+
183+
// resolveExpr binds unresolved expressions to values in the expression or v.
184+
func resolveExpr(ctx *adt.OpContext, v *adt.Vertex, x ast.Expr) adt.Value {
185+
cfg := &compile.Config{Scope: v}
186+
187+
astutil.ResolveExpr(x, errFn)
188+
189+
c, err := compile.Expr(cfg, ctx, anonymousPkg, x)
190+
if err != nil {
191+
return &adt.Bottom{Err: err}
192+
}
193+
return adt.Resolve(ctx, c)
194+
}
195+
196+
// anonymousPkg reports a package path that can never resolve to a valid package.
197+
const anonymousPkg = "_"
198+
154199
// CompileString parses and build a Value from the given source string.
155200
//
156201
// The returned Value will represent an error, accessible through Err, if any

cue/instance.go

Lines changed: 5 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -190,66 +190,6 @@ func (inst *Instance) eval(ctx *adt.OpContext) adt.Value {
190190
return v
191191
}
192192

193-
// pkgID reports a package path that can never resolve to a valid package.
194-
func pkgID() string {
195-
return "_"
196-
}
197-
198-
// evalExpr evaluates expr within scope.
199-
func evalExpr(ctx *adt.OpContext, scope *adt.Vertex, expr ast.Expr) adt.Value {
200-
cfg := &compile.Config{
201-
Scope: scope,
202-
Imports: func(x *ast.Ident) (pkgPath string) {
203-
if !isBuiltin(x.Name) {
204-
return ""
205-
}
206-
return x.Name
207-
},
208-
}
209-
210-
c, err := compile.Expr(cfg, ctx, pkgID(), expr)
211-
if err != nil {
212-
return &adt.Bottom{Err: err}
213-
}
214-
return adt.Resolve(ctx, c)
215-
216-
// scope.Finalize(ctx) // TODO: not appropriate here.
217-
// switch s := scope.Value.(type) {
218-
// case *bottom:
219-
// return s
220-
// case *adt.StructMarker:
221-
// default:
222-
// return ctx.mkErr(scope, "instance is not a struct, found %s", scope.Kind())
223-
// }
224-
225-
// c := ctx
226-
227-
// x, err := compile.Expr(&compile.Config{Scope: scope}, c.Runtime, expr)
228-
// if err != nil {
229-
// return c.NewErrf("could not evaluate %s: %v", c.Str(x), err)
230-
// }
231-
232-
// env := &adt.Environment{Vertex: scope}
233-
234-
// switch v := x.(type) {
235-
// case adt.Value:
236-
// return v
237-
// case adt.Resolver:
238-
// r, err := c.Resolve(env, v)
239-
// if err != nil {
240-
// return err
241-
// }
242-
// return r
243-
244-
// case adt.Evaluator:
245-
// e, _ := c.Evaluate(env, x)
246-
// return e
247-
248-
// }
249-
250-
// return c.NewErrf("could not evaluate %s", c.Str(x))
251-
}
252-
253193
// ID returns the package identifier that uniquely qualifies module and
254194
// package name.
255195
func (inst *Instance) ID() string {
@@ -278,12 +218,12 @@ func (inst *Instance) Value() Value {
278218
// Eval evaluates an expression within an existing instance.
279219
//
280220
// Expressions may refer to builtin packages if they can be uniquely identified.
221+
//
222+
// Deprecated: use
223+
// inst.Value().Context().BuildExpr(expr, Scope(inst.Value), InferBuiltins(true))
281224
func (inst *hiddenInstance) Eval(expr ast.Expr) Value {
282-
ctx := newContext(inst.index)
283-
v := inst.root
284-
v.Finalize(ctx)
285-
result := evalExpr(ctx, v, expr)
286-
return newValueRoot(inst.index, ctx, result)
225+
v := inst.Value()
226+
return v.Context().BuildExpr(expr, Scope(v), InferBuiltins(true))
287227
}
288228

289229
// DO NOT USE.

cue/query.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@
1515
package cue
1616

1717
import (
18-
"cuelang.org/go/cue/ast"
19-
"cuelang.org/go/cue/ast/astutil"
20-
"cuelang.org/go/cue/token"
2118
"cuelang.org/go/internal/core/adt"
22-
"cuelang.org/go/internal/core/compile"
2319
)
2420

2521
// This file contains query-related code.
@@ -38,21 +34,6 @@ func getScopePrefix(v Value, p Path) *adt.Vertex {
3834
return v.v
3935
}
4036

41-
func errFn(pos token.Pos, msg string, args ...interface{}) {}
42-
43-
// resolveExpr binds unresolved expressions to values in the expression or v.
44-
func resolveExpr(ctx *adt.OpContext, v *adt.Vertex, x ast.Expr) adt.Value {
45-
cfg := &compile.Config{Scope: v}
46-
47-
astutil.ResolveExpr(x, errFn)
48-
49-
c, err := compile.Expr(cfg, ctx, pkgID(), x)
50-
if err != nil {
51-
return &adt.Bottom{Err: err}
52-
}
53-
return adt.Resolve(ctx, c)
54-
}
55-
5637
// LookupPath reports the value for path p relative to v.
5738
func (v Value) LookupPath(p Path) Value {
5839
if v.v == nil {

internal/core/runtime/build.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,6 @@ func (r *Runtime) CompileFile(cfg *Config, file *ast.File) (*adt.Vertex, *build.
114114
return v, p
115115
}
116116

117-
func (r *Runtime) CompileExpr(cfg *Config, expr ast.Expr) (*adt.Vertex, *build.Instance, error) {
118-
f, err := astutil.ToFile(expr)
119-
if err != nil {
120-
return nil, nil, err
121-
}
122-
v, p := r.CompileFile(cfg, f)
123-
return v, p, p.Err
124-
}
125-
126117
func (x *Runtime) buildSpec(cfg *Config, b *build.Instance, spec *ast.ImportSpec) (errs errors.Error) {
127118
info, err := astutil.ParseImportSpec(spec)
128119
if err != nil {

internal/value/value.go

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@ import (
2020
"strings"
2121

2222
"cuelang.org/go/cue"
23-
"cuelang.org/go/cue/ast"
2423
"cuelang.org/go/cue/errors"
2524
"cuelang.org/go/internal/core/adt"
26-
"cuelang.org/go/internal/core/compile"
2725
"cuelang.org/go/internal/core/convert"
2826
"cuelang.org/go/internal/core/eval"
2927
"cuelang.org/go/internal/core/runtime"
@@ -97,39 +95,3 @@ func FromGoType(r *cue.Context, x interface{}) cue.Value {
9795
n.AddConjunct(adt.MakeRootConjunct(nil, expr))
9896
return r.Encode(n)
9997
}
100-
101-
// EvalExpr evaluates an expression within an existing struct value.
102-
// Identifiers only resolve to values defined within the struct.
103-
//
104-
// Expressions may refer to builtin packages if they can be uniquely identified
105-
func EvalExpr(value cue.Value, expr ast.Expr) cue.Value {
106-
r, scope := ToInternal(value)
107-
ctx := eval.NewContext(r, nil)
108-
109-
cfg := &compile.Config{
110-
Scope: scope,
111-
Imports: func(x *ast.Ident) (pkgPath string) {
112-
if !isBuiltin(x.Name) {
113-
return ""
114-
}
115-
return x.Name
116-
},
117-
}
118-
119-
c, err := compile.Expr(cfg, ctx, pkgID(), expr)
120-
if err != nil {
121-
return MakeError(r, err)
122-
}
123-
v := adt.Resolve(ctx, c)
124-
125-
return (*cue.Context)(r).Encode(v)
126-
}
127-
128-
func isBuiltin(s string) bool {
129-
return runtime.SharedRuntime.IsBuiltinPackage(s)
130-
}
131-
132-
// pkgID reports a package path that can never resolve to a valid package.
133-
func pkgID() string {
134-
return "_"
135-
}

pkg/encoding/yaml/manual.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"cuelang.org/go/internal"
2424
cueyaml "cuelang.org/go/internal/encoding/yaml"
2525
"cuelang.org/go/internal/third_party/yaml"
26-
"cuelang.org/go/internal/value"
2726
)
2827

2928
// Marshal returns the YAML encoding of v.
@@ -84,7 +83,7 @@ func Validate(b []byte, v cue.Value) (bool, error) {
8483
if err != nil {
8584
return false, err
8685
}
87-
r := value.ConvertToRuntime(v.Context())
86+
r := v.Context()
8887
for {
8988
expr, err := d.Decode()
9089
if err != nil {
@@ -94,8 +93,8 @@ func Validate(b []byte, v cue.Value) (bool, error) {
9493
return false, err
9594
}
9695

97-
inst, err := r.CompileExpr(expr)
98-
if err != nil {
96+
x := r.BuildExpr(expr)
97+
if err := x.Err(); err != nil {
9998
return false, err
10099
}
101100

@@ -108,7 +107,7 @@ func Validate(b []byte, v cue.Value) (bool, error) {
108107
// if err := v.Subsume(inst.Value(), cue.Final()); err != nil {
109108
// return false, err
110109
// }
111-
x := v.Unify(inst.Value())
110+
x = v.Unify(x)
112111
if err := x.Err(); err != nil {
113112
return false, err
114113
}
@@ -128,7 +127,7 @@ func ValidatePartial(b []byte, v cue.Value) (bool, error) {
128127
if err != nil {
129128
return false, err
130129
}
131-
r := value.ConvertToRuntime(v.Context())
130+
r := v.Context()
132131
for {
133132
expr, err := d.Decode()
134133
if err != nil {
@@ -138,12 +137,12 @@ func ValidatePartial(b []byte, v cue.Value) (bool, error) {
138137
return false, err
139138
}
140139

141-
inst, err := r.CompileExpr(expr)
142-
if err != nil {
140+
x := r.BuildExpr(expr)
141+
if err := x.Err(); err != nil {
143142
return false, err
144143
}
145144

146-
if x := v.Unify(inst.Value()); x.Err() != nil {
145+
if x := v.Unify(x); x.Err() != nil {
147146
return false, x.Err()
148147
}
149148
}

0 commit comments

Comments
 (0)