Skip to content

Commit c365513

Browse files
committed
cue: prepare API implementation for structure sharing
The CUE API relies on the Parent field to reflect the path down which the user descended to obtain the value. With structure sharing, this means this parent field may vary by context. This now adds another field to Value, which keeps track of a differing parent Value chain. The field only needs to be set in the case of actual structure sharing. Change-Id: Ia03de7d249ce72e72104740ce649827e7b07f2ad Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9572 Reviewed-by: CUE cueckoo <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]> Reviewed-by: Paul Jolly <[email protected]>
1 parent d9af603 commit c365513

File tree

6 files changed

+141
-61
lines changed

6 files changed

+141
-61
lines changed

cue/context.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func Scope(scope Value) BuildOption {
7272
if o.Scope != nil {
7373
panic("more than one scope is given")
7474
}
75-
o.Scope = scope.v
75+
o.Scope = valueScope(scope)
7676
}
7777
}
7878

@@ -181,8 +181,8 @@ func (c *Context) BuildExpr(x ast.Expr, options ...BuildOption) Value {
181181
func errFn(pos token.Pos, msg string, args ...interface{}) {}
182182

183183
// 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}
184+
func resolveExpr(ctx *adt.OpContext, v Value, x ast.Expr) adt.Value {
185+
cfg := &compile.Config{Scope: valueScope(v)}
186186

187187
astutil.ResolveExpr(x, errFn)
188188

cue/instance.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ func (inst *hiddenInstance) Build(p *build.Instance) *Instance {
263263

264264
rErr := r.ResolveFiles(p)
265265

266-
cfg := &compile.Config{Scope: inst.root}
266+
cfg := &compile.Config{Scope: valueScope(Value{idx: r, v: inst.root})}
267267
v, err := compile.Files(cfg, r, p.ID(), p.Files...)
268268

269269
v.AddConjunct(adt.MakeRootConjunct(nil, inst.root))

cue/query.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ import (
2323
// getScopePrefix finds the Vertex that exists in v for the longest prefix of p.
2424
//
2525
// It is used to make the parent scopes visible when resolving expressions.
26-
func getScopePrefix(v Value, p Path) *adt.Vertex {
26+
func getScopePrefix(v Value, p Path) Value {
2727
for _, sel := range p.Selectors() {
2828
w := v.LookupPath(MakePath(sel))
2929
if !w.Exists() {
3030
break
3131
}
3232
v = w
3333
}
34-
return v.v
34+
return v
3535
}
3636

3737
// LookupPath reports the value for path p relative to v.
@@ -40,25 +40,28 @@ func (v Value) LookupPath(p Path) Value {
4040
return Value{}
4141
}
4242
n := v.v
43+
parent := v.parent_
4344
ctx := v.ctx()
4445

4546
outer:
4647
for _, sel := range p.path {
4748
f := sel.sel.feature(v.idx)
4849
for _, a := range n.Arcs {
4950
if a.Label == f {
51+
parent = linkParent(parent, n, a)
5052
n = a
5153
continue outer
5254
}
5355
}
5456
if sel.sel.optional() {
5557
x := &adt.Vertex{
56-
Parent: v.v,
58+
Parent: n,
5759
Label: sel.sel.feature(ctx),
5860
}
5961
n.MatchAndInsert(ctx, x)
6062
if len(x.Conjuncts) > 0 {
6163
x.Finalize(ctx)
64+
parent = linkParent(parent, n, x)
6265
n = x
6366
continue
6467
}
@@ -71,8 +74,8 @@ outer:
7174
// TODO: better message.
7275
x = mkErr(v.idx, n, adt.NotExistError, "field %q not found", sel.sel)
7376
}
74-
v := makeValue(v.idx, n)
77+
v := makeValue(v.idx, n, parent)
7578
return newErrValue(v, x)
7679
}
77-
return makeValue(v.idx, n)
80+
return makeValue(v.idx, n, parent)
7881
}

0 commit comments

Comments
 (0)