cue: fix PathCorrection tests
This fixes one bug in Reference, but mostly just
means dealing with a different ordering of fields.
Change-Id: I5a220bdb239ffddae2ba56efed2d591b4c86d78c
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7741
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/types.go b/cue/types.go
index ac9c3a9..fa0d082 100644
--- a/cue/types.go
+++ b/cue/types.go
@@ -1830,6 +1830,13 @@
defer ctx.PopState(ctx.PushState(env, r.Source()))
switch x := r.(type) {
+ // TODO: do we need to handle Vertex as well, in case this is hard-wired?
+ // Probably not, as this results from dynamic content.
+
+ case *adt.NodeLink:
+ // TODO: consider getting rid of NodeLink.
+ inst, path = mkPath(c, nil, x.Node)
+
case *adt.FieldReference:
env := ctx.Env(x.UpCount)
inst, path = mkPath(c, nil, env.Vertex)
diff --git a/cue/types_test.go b/cue/types_test.go
index 66850e2..87df504 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -2482,32 +2482,33 @@
want string
skip bool
}{{
- // // TODO: structural cycle.
- // input: `
- // a: b: {
- // c: d: b
- // }
- // `,
- // lookup: func(i *Instance) Value {
- // _, a := i.Lookup("a", "b", "c", "d").Expr()
- // return a[0].Lookup("b", "c", "d")
- // },
- // want: "a.b",
- // }, {
+ input: `
+ a: b: {
+ c: d: b
+ }
+ `,
+ lookup: func(i *Instance) Value {
+ op, a := i.Lookup("a", "b", "c", "d").Expr()
+ _ = op
+ return a[0] // structural cycle errors.
+ },
+ want: "a",
+ }, {
// TODO: embedding: have field operators.
- // input: `
- // a: {
- // c: 3
- // {x: c}
- // }
- // `,
- // lookup: func(i *Instance) Value {
- // _, a := i.Lookup("a").Expr()
- // return a[1].Lookup("x")
- // },
- // want: "a.c",
- // }, {
+ input: `
+ a: {
+ {x: c}
+ c: 3
+ }
+ `,
+ lookup: func(i *Instance) Value {
+ op, a := i.Lookup("a").Expr()
+ _ = op
+ return a[0].Lookup("x")
+ },
+ want: "a.c",
+ }, {
// TODO: implement proper Elem()
input: `
@@ -2557,46 +2558,45 @@
return a[0]
},
want: "#T",
- // }, {
- // input: `
- // #a: {
- // #T: {b: 3}
- // close({}) | close({c: #T}) | close({d: string})
- // }
- // `,
- // lookup: func(i *Instance) Value {
- // f, _ := i.LookupField("#a")
- // _, a := f.Value.Expr() // &
- // _, a = a[1].Expr() // |
- // return a[1].Lookup("c")
- // },
- // want: "#a.#T",
}, {
- // TODO: iterate over Definitions
- // input: `
- // package foo
+ input: `
+ #a: {
+ close({}) | close({c: #T}) | close({d: string})
+ #T: {b: 3}
+ }
+ `,
+ lookup: func(i *Instance) Value {
+ f, _ := i.LookupField("#a")
+ _, a := f.Value.Expr() // &
+ _, a = a[0].Expr() // |
+ return a[1].Lookup("c")
+ },
+ want: "#a.#T",
+ }, {
+ input: `
+ package foo
- // #Struct: {
- // #T: int
+ #Struct: {
+ #T: int
- // {b?: #T}
- // }`,
- // want: "#Struct.#T",
- // lookup: func(inst *Instance) Value {
- // // Locate Struct
- // i, _ := inst.Value().Fields(Definitions(true))
- // if !i.Next() {
- // t.Fatal("no fields")
- // }
- // // Locate b
- // i, _ = i.Value().Fields(Definitions(true), Optional(true))
- // if !(i.Next() && i.Next()) {
- // t.Fatal("no fields")
- // }
- // v := i.Value()
- // return v
- // },
- // }, {
+ {b?: #T}
+ }`,
+ want: "#Struct.#T",
+ lookup: func(inst *Instance) Value {
+ // Locate Struct
+ i, _ := inst.Value().Fields(Definitions(true))
+ if !i.Next() {
+ t.Fatal("no fields")
+ }
+ // Locate b
+ i, _ = i.Value().Fields(Definitions(true), Optional(true))
+ if !(i.Next() && i.Next()) {
+ t.Fatal("no fields")
+ }
+ v := i.Value()
+ return v
+ },
+ }, {
input: `
package foo
@@ -2617,80 +2617,71 @@
v = v.Lookup("a")
return v
},
- // }, {
+ }, {
// TODO: record additionalItems in list
- // input: `
- // package foo
+ input: `
+ package foo
- // #A: #B: #T
+ #A: #B: #T
- // #T: {
- // a: [...#S]
- // #S: {}
- // }
- // `,
- // want: "#T.#S",
- // lookup: func(inst *Instance) Value {
- // f, _ := inst.Value().LookupField("#A")
- // f, _ = f.Value.LookupField("#B")
- // v := f.Value
- // v = Dereference(v)
- // v, _ = v.Lookup("a").Elem()
- // return v
- // },
- // }, {
+ #T: {
+ a: [...#S]
+ #S: {}
+ }
+ `,
+ want: "#T.#S",
+ lookup: func(inst *Instance) Value {
+ f, _ := inst.Value().LookupField("#A")
+ f, _ = f.Value.LookupField("#B")
+ v := f.Value
+ v = Dereference(v)
+ v, _ = v.Lookup("a").Elem()
+ return v
+ },
+ }, {
+ input: `
+ #A: {
+ b: #T
+ }
- // YAY: works.
- // input: `
- // #A: {
- // b: #T
- // }
+ #T: {
+ a: #S
+ #S: {}
+ }
+ `,
+ want: "#T.#S",
+ lookup: func(inst *Instance) Value {
+ f, _ := inst.Value().LookupField("#A")
+ v := f.Value.Lookup("b")
+ v = Dereference(v)
+ v = v.Lookup("a")
+ return v
+ },
+ }, {
+ input: `
+ #Tracing: {
+ #T: { address?: string }
+ #S: { ip?: string }
- // #T: {
- // a: #S
- // #S: {}
- // }
- // `,
- // want: "#T.#S",
- // lookup: func(inst *Instance) Value {
- // f, _ := inst.Value().LookupField("#A")
- // v := f.Value.Lookup("b")
- // v = Dereference(v)
- // v = v.Lookup("a")
- // return v
- // },
- // }, {
-
- // // TODO(eval): embedded structs are currently represented at the same
- // // level as the enclosing struct. This means that the parent of an
- // // embedded struct skips the struct in which it is embedded. Treat
- // // embedded structs as "anonymous" fields.
- // // This could perhaps be made fixed with dereferencing as well.
- // skip: true,
- // input: `
- // #Tracing: {
- // #T: { address?: string }
- // #S: { ip?: string }
-
- // close({}) | close({
- // t: #T
- // }) | close({
- // s: #S
- // })
- // }
- // #X: {}
- // #X // Disconnect top-level struct from the one visible by close.
- // `,
- // want: "",
- // lookup: func(inst *Instance) Value {
- // f, _ := inst.Value().LookupField("#Tracing")
- // v := f.Value.Eval()
- // _, args := v.Expr()
- // v = args[1].Lookup("t")
- // v = Dereference(v)
- // return v
- // },
+ close({}) | close({
+ t: #T
+ }) | close({
+ s: #S
+ })
+ }
+ #X: {}
+ #X // Disconnect top-level struct from the one visible by close.
+ `,
+ want: "#Tracing.#T",
+ lookup: func(inst *Instance) Value {
+ f, _ := inst.Value().LookupField("#Tracing")
+ v := f.Value.Eval()
+ _, args := v.Expr()
+ v = args[1]
+ v = v.Lookup("t")
+ return v
+ },
}}
for _, tc := range testCases {
if tc.skip {