From f14c9a4d897d59e0dbee6c0a9968271b5ccfdf40 Mon Sep 17 00:00:00 2001 From: Marcel van Lohuizen Date: Mon, 19 Apr 2021 18:03:14 +0200 Subject: [PATCH] cue: add Selector.PkgPath Also fixes bug in Path, which did not convert hidden fields properly. Change-Id: I02d2173b53642b0da1db0576d5d2717fc6cb6541 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9444 Reviewed-by: CUE cueckoo Reviewed-by: Paul Jolly --- cue/path.go | 7 +++++++ cue/path_test.go | 2 +- cue/query_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++++++ cue/types.go | 8 +++++++- 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/cue/path.go b/cue/path.go index 5afaf2a90..b5574c057 100644 --- a/cue/path.go +++ b/cue/path.go @@ -49,6 +49,13 @@ func (sel Selector) IsDefinition() bool { return sel.sel.kind() == adt.DefinitionLabel } +// PkgPath reports the package path associated with a hidden label or "" if +// this is not a hidden label. +func (sel Selector) PkgPath() string { + h, _ := sel.sel.(scopedSelector) + return h.pkg +} + var ( // AnyField can be used to ask for any single label. // diff --git a/cue/path_test.go b/cue/path_test.go index 334bb3950..05de651bc 100644 --- a/cue/path_test.go +++ b/cue/path_test.go @@ -19,7 +19,7 @@ import ( "testing" ) -func Test(t *testing.T) { +func TestPaths(t *testing.T) { var r Runtime inst, _ := r.Compile("", ` #Foo: a: b: 1 diff --git a/cue/query_test.go b/cue/query_test.go index 5f147d60d..6d7503795 100644 --- a/cue/query_test.go +++ b/cue/query_test.go @@ -16,10 +16,14 @@ package cue_test import ( "bytes" + "io/ioutil" "testing" "cuelang.org/go/cue" + "cuelang.org/go/cue/cuecontext" + "cuelang.org/go/internal/cuetxtar" "cuelang.org/go/internal/diff" + "github.com/rogpeppe/go-internal/txtar" ) func TestLookupPath(t *testing.T) { @@ -139,3 +143,51 @@ func compileT(t *testing.T, r *cue.Runtime, s string) cue.Value { } return inst.Value() } + +func TestHidden(t *testing.T) { + in := ` +-- cue.mod/module.cue -- +module: "example.com" + +-- in.cue -- +import "example.com/foo" + +a: foo.C +b: _c +_c: 2 +-- foo/foo.cue -- +package foo + +C: _d +_d: 3 + ` + + a := txtar.Parse([]byte(in)) + dir, _ := ioutil.TempDir("", "*") + instance := cuetxtar.Load(a, dir)[0] + if instance.Err != nil { + t.Fatal(instance.Err) + } + + v := cuecontext.New().BuildInstance(instance) + + testCases := []struct { + path cue.Path + pkg string + }{{ + path: cue.ParsePath("a"), + pkg: "example.com/foo", + }, { + path: cue.ParsePath("b"), + pkg: "_", + }} + for _, tc := range testCases { + t.Run(tc.path.String(), func(t *testing.T) { + v := v.LookupPath(tc.path) + p := cue.Dereference(cue.Dereference(v)).Path().Selectors() + if got := p[len(p)-1].PkgPath(); got != tc.pkg { + t.Errorf("got %v; want %v", got, tc.pkg) + } + }) + } +} diff --git a/cue/types.go b/cue/types.go index e06cef0ec..5edb989b2 100644 --- a/cue/types.go +++ b/cue/types.go @@ -1491,9 +1491,15 @@ func (v Value) Path() Path { case adt.IntLabel: a[i] = Selector{indexSelector(f)} - case adt.DefinitionLabel, adt.HiddenDefinitionLabel, adt.HiddenLabel: + case adt.DefinitionLabel: a[i] = Selector{definitionSelector(f.SelectorString(v.idx))} + case adt.HiddenDefinitionLabel, adt.HiddenLabel: + a[i] = Selector{scopedSelector{ + name: f.IdentString(v.idx), + pkg: f.PkgID(v.idx), + }} + case adt.StringLabel: a[i] = Selector{stringSelector(f.StringValue(v.idx))} }