cue: prepare to hoist index type
Change-Id: If27ae95cff0e43de01d1fc03938e487d57fc67eb
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/6507
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/ast.go b/cue/ast.go
index 1f322c7..09d9d36 100644
--- a/cue/ast.go
+++ b/cue/ast.go
@@ -150,7 +150,7 @@
func (v *astVisitor) resolve(n *ast.Ident) value {
ctx := v.ctx()
name := v.ident(n)
- label := v.label(name, true)
+ label := v.Label(name, true)
if r := v.resolveRoot; r != nil {
for _, a := range r.arcs {
if a.feature == label {
@@ -254,7 +254,7 @@
if i != len(n.Elts)-1 {
return v1.walk(x.Type) // Generate an error
}
- f := v.ctx().label("_", true)
+ f := v.ctx().Label("_", true)
sig := ¶ms{}
sig.add(f, &basicType{newNode(x), stringKind})
template := &lambdaExpr{newNode(x), sig, &top{newNode(x)}}
@@ -429,9 +429,9 @@
a, ok := expr.(*ast.Alias)
if ok {
expr = a.Expr
- f = v.label(v.ident(a.Ident), true)
+ f = v.Label(v.ident(a.Ident), true)
} else {
- f = v.label("_", true)
+ f = v.Label("_", true)
}
// Parse the key filter or a bulk-optional field. The special value
@@ -456,7 +456,7 @@
v.errf(x, "map element type cannot be a definition")
}
v.sel = "*"
- f := v.label(v.ident(x.Ident), true)
+ f := v.Label(v.ident(x.Ident), true)
sig := ¶ms{}
sig.add(f, &basicType{newNode(lab), stringKind})
@@ -474,7 +474,7 @@
v.sel = "*"
}
}
- f, ok := v.nodeLabel(x)
+ f, ok := v.NodeLabel(x)
if !ok {
return v.errf(lab, "invalid field name: %v", lab)
}
@@ -587,7 +587,7 @@
break
}
- f := v.label(name, true)
+ f := v.Label(name, true)
if _, ok := n.Node.(*ast.ImportSpec); ok {
n2 := v.mapScope(n.Node)
ref := &nodeRef{baseValue: newExpr(n), node: n2, label: f}
@@ -631,7 +631,7 @@
ret = v.errf(n, "invalid label: %v", err)
case name != "":
- f = v.label(name, true)
+ f = v.Label(name, true)
ret = &selectorExpr{newExpr(n), ret, f}
default:
@@ -704,7 +704,7 @@
ret = &selectorExpr{
newExpr(n),
v.walk(n.X),
- v.label(v.ident(n.Sel), true),
+ v.Label(v.ident(n.Sel), true),
}
v.inSelector--
@@ -822,10 +822,10 @@
if n.Key != nil {
key = v.ident(n.Key)
}
- f := v.label(key, true)
+ f := v.Label(key, true)
fn.add(f, &basicType{newExpr(n.Key), stringKind | intKind})
- f = v.label(v.ident(n.Value), true)
+ f = v.Label(v.ident(n.Value), true)
fn.add(f, &top{})
y = &feed{newExpr(n.Source), v.walk(n.Source), fn}
diff --git a/cue/binop.go b/cue/binop.go
index b7ec258..01d0037 100644
--- a/cue/binop.go
+++ b/cue/binop.go
@@ -570,7 +570,7 @@
return ctx.mkErr(x, "invalid custom validator")
} else if !b.b {
var buf bytes.Buffer
- fmt.Fprintf(&buf, "%s.%s", ctx.labelStr(x.call.pkg), x.call.Name)
+ fmt.Fprintf(&buf, "%s.%s", ctx.LabelStr(x.call.pkg), x.call.Name)
buf.WriteString("(")
for _, a := range x.args {
buf.WriteString(ctx.str(a))
@@ -672,7 +672,7 @@
// TODO: pass position of key, not value. Currently does not have
// a position.
return ctx.mkErr(a.v, a.v, "field %q not allowed in closed struct",
- ctx.labelStr(a.feature))
+ ctx.LabelStr(a.feature))
}
cp := ctx.copy(a.v)
obj.arcs = append(obj.arcs,
@@ -688,7 +688,7 @@
if a.definition != b.definition {
src := binSrc(x.Pos(), op, a.v, b.v)
return ctx.mkErr(src, "field %q declared as definition and regular field",
- ctx.labelStr(a.feature))
+ ctx.LabelStr(a.feature))
}
w := b.v
if x.closeStatus.shouldFinalize() {
@@ -717,7 +717,7 @@
// TODO: pass position of key, not value. Currently does not have a
// position.
return ctx.mkErr(a.v, x, "field %q not allowed in closed struct",
- ctx.labelStr(a.feature))
+ ctx.LabelStr(a.feature))
}
a.setValue(v)
obj.arcs = append(obj.arcs, a)
diff --git a/cue/build.go b/cue/build.go
index 33c24c5..634cdb1 100644
--- a/cue/build.go
+++ b/cue/build.go
@@ -20,6 +20,7 @@
"sync"
"cuelang.org/go/cue/ast"
+ "cuelang.org/go/cue/ast/astutil"
"cuelang.org/go/cue/build"
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/token"
@@ -121,20 +122,11 @@
// may import builtin packages. Use Build to allow importing non-builtin
// packages.
func (r *Runtime) CompileExpr(expr ast.Expr) (*Instance, error) {
- ctx := r.buildContext()
- p := ctx.NewInstance("", dummyLoad)
- switch x := expr.(type) {
- case *ast.StructLit:
- _ = p.AddSyntax(&ast.File{Decls: x.Elts})
- default:
- _ = p.AddSyntax(&ast.File{
- Decls: []ast.Decl{&ast.EmbedDecl{Expr: expr}},
- })
+ f, err := astutil.ToFile(expr)
+ if err != nil {
+ return nil, err
}
- if p.Err != nil {
- return nil, p.Err
- }
- return r.complete(p)
+ return r.CompileFile(f)
}
// Parse parses a CUE source value into a CUE Instance. The source code may
@@ -192,14 +184,9 @@
//
// Deprecated: use CompileExpr
func (r *Runtime) FromExpr(expr ast.Expr) (*Instance, error) {
- i := r.index().newInstance(nil)
- err := i.insertFile(&ast.File{
+ return r.CompileFile(&ast.File{
Decls: []ast.Decl{&ast.EmbedDecl{Expr: expr}},
})
- if err != nil {
- return nil, err
- }
- return i, nil
}
// index maps conversions from label names to internal codes.
@@ -239,7 +226,6 @@
// FileSet idea from the API. Just take the hit of the extra pointers for
// positions in the ast, and then optimize the storage in an abstract
// machine implementation for storing graphs.
- token.NewFile("dummy", sharedOffset, 0)
i := &index{
labelMap: map[string]label{"": 0},
labels: []string{""},
@@ -262,22 +248,32 @@
return i
}
-func (idx *index) strLabel(str string) label {
- return idx.label(str, false)
+func (idx *index) StrLabel(str string) label {
+ return idx.Label(str, false)
}
-func (idx *index) nodeLabel(n ast.Node) (f label, ok bool) {
+func (idx *index) NodeLabel(n ast.Node) (f label, ok bool) {
switch x := n.(type) {
case *ast.BasicLit:
name, _, err := ast.LabelName(x)
- return idx.label(name, false), err == nil
+ return idx.Label(name, false), err == nil
case *ast.Ident:
name, err := ast.ParseIdent(x)
- return idx.label(name, true), err == nil
+ return idx.Label(name, true), err == nil
}
return 0, false
}
+func (idx *index) HasLabel(s string) (ok bool) {
+ for x := idx; x != nil; x = x.parent {
+ _, ok = x.labelMap[s]
+ if ok {
+ break
+ }
+ }
+ return ok
+}
+
func (idx *index) findLabel(s string) (f label, ok bool) {
for x := idx; x != nil; x = x.parent {
f, ok = x.labelMap[s]
@@ -288,7 +284,7 @@
return f, ok
}
-func (idx *index) label(s string, isIdent bool) label {
+func (idx *index) Label(s string, isIdent bool) label {
f, ok := idx.findLabel(s)
if !ok {
f = label(len(idx.labelMap)) + idx.offset
@@ -307,13 +303,18 @@
return f
}
-func (idx *index) labelStr(l label) string {
+func (idx *index) LabelStr(l label) string {
l >>= labelShift
for ; l < idx.offset; idx = idx.parent {
}
return idx.labels[l-idx.offset]
}
+func isBuiltin(s string) bool {
+ _, ok := builtins[s]
+ return ok
+}
+
func (idx *index) loadInstance(p *build.Instance) *Instance {
if inst := idx.loaded[p]; inst != nil {
if !inst.complete {
@@ -324,11 +325,13 @@
return inst
}
files := p.Files
- inst := idx.newInstance(p)
+ inst := newInstance(idx, p)
+ idx.loaded[p] = inst
+
if inst.Err == nil {
// inst.instance.index.state = s
// inst.instance.inst = p
- inst.Err = resolveFiles(idx, p)
+ inst.Err = resolveFiles(idx, p, isBuiltin)
for _, f := range files {
err := inst.insertFile(f)
inst.Err = errors.Append(inst.Err, err)
@@ -344,7 +347,11 @@
return n.Pos().String()
}
-func resolveFiles(idx *index, p *build.Instance) errors.Error {
+func resolveFiles(
+ idx *index,
+ p *build.Instance,
+ isBuiltin func(s string) bool,
+) errors.Error {
// Link top-level declarations. As top-level entries get unified, an entry
// may be linked to any top-level entry of any of the files.
allFields := map[string]ast.Node{}
@@ -358,14 +365,20 @@
}
}
for _, f := range p.Files {
- if err := resolveFile(idx, f, p, allFields); err != nil {
+ if err := resolveFile(idx, f, p, allFields, isBuiltin); err != nil {
return err
}
}
return nil
}
-func resolveFile(idx *index, f *ast.File, p *build.Instance, allFields map[string]ast.Node) errors.Error {
+func resolveFile(
+ idx *index,
+ f *ast.File,
+ p *build.Instance,
+ allFields map[string]ast.Node,
+ isBuiltin func(s string) bool,
+) errors.Error {
unresolved := map[string][]*ast.Ident{}
for _, u := range f.Unresolved {
unresolved[u.Name] = append(unresolved[u.Name], u)
@@ -390,7 +403,7 @@
name := path.Base(id)
if imp := p.LookupImport(id); imp != nil {
name = imp.PkgName
- } else if _, ok := builtins[id]; !ok {
+ } else if !isBuiltin(id) {
errs = errors.Append(errs,
nodeErrorf(spec, "package %q not found", id))
continue
diff --git a/cue/build_test.go b/cue/build_test.go
index 97bf20b..51309a5 100644
--- a/cue/build_test.go
+++ b/cue/build_test.go
@@ -85,7 +85,7 @@
ImportPath: importPath,
PkgName: "foo",
}},
- }, map[string]ast.Node{})
+ }, map[string]ast.Node{}, isBuiltin)
if err != nil {
t.Errorf("exected no error, found %v", err)
diff --git a/cue/builtin.go b/cue/builtin.go
index a13d384..616cf4b 100644
--- a/cue/builtin.go
+++ b/cue/builtin.go
@@ -71,11 +71,11 @@
func mustCompileBuiltins(ctx *context, p *builtinPkg, pkgName string) *structLit {
obj := &structLit{}
- pkgLabel := ctx.label(pkgName, false)
+ pkgLabel := ctx.Label(pkgName, false)
for _, b := range p.native {
b.pkg = pkgLabel
- f := ctx.label(b.Name, false) // never starts with _
+ f := ctx.Label(b.Name, false) // never starts with _
// n := &node{baseValue: newBase(imp.Path)}
var v evaluated = b
if b.Const != "" {
@@ -243,7 +243,7 @@
if x.pkg == 0 {
return x.Name
}
- return fmt.Sprintf("%s.%s", ctx.labelStr(x.pkg), x.Name)
+ return fmt.Sprintf("%s.%s", ctx.LabelStr(x.pkg), x.Name)
}
func (x *builtin) isValidator() bool {
@@ -288,29 +288,7 @@
if err := recover(); err != nil {
errVal = err
}
- const msg = "error in call to %s: %v"
- switch err := errVal.(type) {
- case nil:
- case *callError:
- ret = err.b
- case *json.MarshalerError:
- if err, ok := err.Err.(*marshalError); ok && err.b != nil {
- ret = err.b
- }
- case *marshalError:
- ret = err.b
- ret = ctx.mkErr(src, x, ret, msg, x.name(ctx), err)
- case *valueError:
- ret = err.err
- ret = ctx.mkErr(src, x, ret, msg, x.name(ctx), err)
- default:
- if call.err == internal.ErrIncomplete {
- ret = ctx.mkErr(src, codeIncomplete, "incomplete value")
- } else {
- // TODO: store the underlying error explicitly
- ret = ctx.mkErr(src, x, msg, x.name(ctx), err)
- }
- }
+ ret = processErr(&call, errVal, ret)
}()
x.Func(&call)
switch v := call.ret.(type) {
@@ -322,6 +300,36 @@
return convert(ctx, x, true, call.ret)
}
+func processErr(call *callCtxt, errVal interface{}, ret value) value {
+ ctx := call.ctx
+ x := call.builtin
+ src := call.src
+ const msg = "error in call to %s: %v"
+ switch err := errVal.(type) {
+ case nil:
+ case *callError:
+ ret = err.b
+ case *json.MarshalerError:
+ if err, ok := err.Err.(*marshalError); ok && err.b != nil {
+ ret = err.b
+ }
+ case *marshalError:
+ ret = err.b
+ ret = ctx.mkErr(src, x, ret, msg, x.name(ctx), err)
+ case *valueError:
+ ret = err.err
+ ret = ctx.mkErr(src, x, ret, msg, x.name(ctx), err)
+ default:
+ if call.err == internal.ErrIncomplete {
+ ret = ctx.mkErr(src, codeIncomplete, "incomplete value")
+ } else {
+ // TODO: store the underlying error explicitly
+ ret = ctx.mkErr(src, x, msg, x.name(ctx), err)
+ }
+ }
+ return ret
+}
+
// callCtxt is passed to builtin implementations.
type callCtxt struct {
src source
@@ -384,7 +392,7 @@
if s == nil {
return v
}
- a := s.lookup(ctx, ctx.label(name, false))
+ a := s.lookup(ctx, ctx.Label(name, false))
if a.v == nil {
return v
}
diff --git a/cue/debug.go b/cue/debug.go
index 630b4be..3de2dcf 100644
--- a/cue/debug.go
+++ b/cue/debug.go
@@ -142,7 +142,7 @@
return strconv.Itoa(int(f))
}
- str := p.ctx.labelStr(f)
+ str := p.ctx.LabelStr(f)
if strings.HasPrefix(str, "#") && f&definition == 0 ||
strings.HasPrefix(str, "_") && f&hidden == 0 ||
!ast.IsValidIdent(str) {
diff --git a/cue/eval.go b/cue/eval.go
index e5794c5..9965410 100644
--- a/cue/eval.go
+++ b/cue/eval.go
@@ -126,11 +126,11 @@
}
n := sc.lookup(ctx, x.feature)
if n.optional {
- field := ctx.labelStr(x.feature)
+ field := ctx.LabelStr(x.feature)
return ctx.mkErr(x, codeIncomplete, "field %q is optional", field)
}
if n.val() == nil {
- field := ctx.labelStr(x.feature)
+ field := ctx.LabelStr(x.feature)
if st, ok := sc.(*structLit); ok && !st.isClosed() {
return ctx.mkErr(x, codeIncomplete, "undefined field %q", field)
}
@@ -161,11 +161,11 @@
}
n := sc.lookup(ctx, x.feature)
if n.optional {
- field := ctx.labelStr(x.feature)
+ field := ctx.LabelStr(x.feature)
return ctx.mkErr(x, codeIncomplete, "field %q is optional", field)
}
if n.val() == nil {
- field := ctx.labelStr(x.feature)
+ field := ctx.LabelStr(x.feature)
if st, ok := sc.(*structLit); ok && !st.isClosed() {
return ctx.mkErr(x, codeIncomplete, "undefined field %q", field)
}
@@ -198,7 +198,7 @@
if e.is(index, stringKind, msgIndexType, k) {
s := index.strValue()
// TODO: must lookup
- n := v.lookup(ctx, ctx.strLabel(s))
+ n := v.lookup(ctx, ctx.StrLabel(s))
if n.definition {
return ctx.mkErr(x, index,
"field %q is a definition", s)
@@ -247,7 +247,7 @@
if e.is(index, stringKind, msgIndexType, k) {
s := index.strValue()
// TODO: must lookup
- n := v.lookup(ctx, ctx.strLabel(s))
+ n := v.lookup(ctx, ctx.StrLabel(s))
if n.definition {
return ctx.mkErr(x, index,
"field %q is a definition", s)
@@ -474,7 +474,7 @@
if !k.kind().isAnyOf(stringKind) {
return ctx.mkErr(k, "key must be of type string")
}
- f := ctx.label(k.strValue(), true)
+ f := ctx.Label(k.strValue(), true)
st := &structLit{baseValue: x.baseValue}
st.insertValue(ctx, f, x.opt, x.def, v, x.attrs, x.doc)
return st
diff --git a/cue/export.go b/cue/export.go
index af4e116..ea5e9d0 100644
--- a/cue/export.go
+++ b/cue/export.go
@@ -135,8 +135,8 @@
s = strings.ToUpper(s)
lab := s
for {
- if _, ok := p.ctx.findLabel(lab); !ok {
- p.ctx.label(lab, true)
+ if !p.ctx.HasLabel(lab) {
+ p.ctx.Label(lab, true)
break
}
lab = s + fmt.Sprintf("%0.6x", rand.Intn(1<<24))
@@ -145,7 +145,7 @@
}
func (p *exporter) label(f label) ast.Label {
- str := p.ctx.labelStr(f)
+ str := p.ctx.LabelStr(f)
if strings.HasPrefix(str, "#") && f&definition == 0 ||
strings.HasPrefix(str, "_") && f&hidden == 0 ||
!ast.IsValidIdent(str) {
@@ -155,7 +155,7 @@
}
func (p *exporter) identifier(f label) *ast.Ident {
- str := p.ctx.labelStr(f)
+ str := p.ctx.LabelStr(f)
return &ast.Ident{Name: str}
}
@@ -171,7 +171,7 @@
Source: p.expr(x.source),
}
key := x.fn.params.arcs[0]
- if p.ctx.labelStr(key.feature) != "_" {
+ if p.ctx.LabelStr(key.feature) != "_" {
feed.Key = p.identifier(key.feature)
}
return feed, x.fn.value.(yielder)
@@ -187,22 +187,22 @@
short := info.short
if !ok {
short = inst.PkgName
- if _, ok := p.top[p.ctx.label(short, true)]; ok && preferred != "" {
+ if _, ok := p.top[p.ctx.Label(short, true)]; ok && preferred != "" {
short = preferred
info.name = short
}
for {
- if _, ok := p.top[p.ctx.label(short, true)]; !ok {
+ if _, ok := p.top[p.ctx.Label(short, true)]; !ok {
break
}
short += "x"
info.name = short
}
info.short = short
- p.top[p.ctx.label(short, true)] = true
+ p.top[p.ctx.Label(short, true)] = true
p.imports[pkg] = info
}
- f := p.ctx.label(short, true)
+ f := p.ctx.Label(short, true)
for _, e := range p.stack {
if e.from == f {
if info.alias == "" {
@@ -435,7 +435,7 @@
if x.pkg == 0 {
return ast.NewIdent(x.Name)
}
- pkg := p.ctx.labelStr(x.pkg)
+ pkg := p.ctx.LabelStr(x.pkg)
inst := builtins[pkg]
short := p.shortName(inst, "", pkg)
return ast.NewSel(ast.NewIdent(short), x.Name)
@@ -445,7 +445,7 @@
// NOTE: this nodeRef is used within a selector.
return nil
}
- short := p.ctx.labelStr(x.label)
+ short := p.ctx.LabelStr(x.label)
if inst := p.ctx.getImportFromNode(x.node); inst != nil {
return ast.NewIdent(p.shortName(inst, short, inst.ImportPath))
@@ -457,7 +457,7 @@
case *selectorExpr:
n := p.expr(x.x)
if n != nil {
- return ast.NewSel(n, p.ctx.labelStr(x.feature))
+ return ast.NewSel(n, p.ctx.LabelStr(x.feature))
}
f := x.feature
ident := p.identifier(f)
@@ -486,7 +486,7 @@
if conflict {
ident = e.to
if e.to == nil {
- name := p.unique(p.ctx.labelStr(f))
+ name := p.unique(p.ctx.LabelStr(f))
e.syn.Elts = append(e.syn.Elts, &ast.Alias{
Ident: p.ident(name),
Expr: p.identifier(f),
diff --git a/cue/go.go b/cue/go.go
index 24843ea..20dee9a 100644
--- a/cue/go.go
+++ b/cue/go.go
@@ -70,7 +70,7 @@
}
expr, err := parser.ParseExpr("<field:>", tag)
if err != nil {
- field := ctx.labelStr(field)
+ field := ctx.LabelStr(field)
return ctx.mkErr(baseValue{}, "invalid tag %q for field %q: %v", tag, field, err)
}
v := newVisitor(ctx.index, nil, nil, obj, true)
@@ -389,7 +389,7 @@
if name == "-" {
continue
}
- f := ctx.strLabel(name)
+ f := ctx.StrLabel(name)
obj.arcs = append(obj.arcs, arc{feature: f, v: sub})
}
sort.Sort(obj)
@@ -438,12 +438,12 @@
// Assign label in normalized order.
sort.Strings(sorted)
for _, k := range sorted {
- ctx.strLabel(k)
+ ctx.StrLabel(k)
}
// Now assign the labels to the arcs.
for i, k := range keys {
- obj.arcs[i].feature = ctx.strLabel(k)
+ obj.arcs[i].feature = ctx.StrLabel(k)
}
sort.Sort(obj)
return obj
@@ -597,7 +597,7 @@
if name == "-" {
continue
}
- l := ctx.strLabel(name)
+ l := ctx.StrLabel(name)
obj.arcs = append(obj.arcs, arc{
feature: l,
// The GO JSON decoder always allows a value to be undefined.
@@ -658,7 +658,7 @@
obj := newStruct(baseValue{})
sig := ¶ms{}
- sig.add(ctx.label("_", true), &basicType{k: stringKind})
+ sig.add(ctx.Label("_", true), &basicType{k: stringKind})
v := goTypeToValueRec(ctx, allowNullDefault, t.Elem())
if v == nil {
return ctx.mkErr(baseValue{}, "unsupported Go type (%v)", t.Elem())
diff --git a/cue/instance.go b/cue/instance.go
index b16be57..0ec3dee 100644
--- a/cue/instance.go
+++ b/cue/instance.go
@@ -83,7 +83,7 @@
}
// newInstance creates a new instance. Use Insert to populate the instance.
-func (x *index) newInstance(p *build.Instance) *Instance {
+func newInstance(x *index, p *build.Instance) *Instance {
// TODO: associate root source with structLit.
st := &structLit{baseValue: baseValue{nil}}
i := &Instance{
@@ -237,7 +237,7 @@
idx := inst.index
- i := idx.newInstance(p)
+ i := newInstance(idx, p)
if i.Err != nil {
return i
}
@@ -251,7 +251,7 @@
}
i.scope = v.obj
- if err := resolveFiles(idx, p); err != nil {
+ if err := resolveFiles(idx, p, isBuiltin); err != nil {
i.setError(err)
return i
}
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index 5a394be..e7480da 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -39,10 +39,10 @@
func compileInstance(t *testing.T, body string) (*context, *Instance, error) {
var r Runtime
- inst, err := r.Parse("test", body)
+ inst, err := r.Compile("test", body)
if err != nil {
- x := newIndex(sharedIndex).newInstance(nil)
+ x := newInstance(newIndex(sharedIndex), nil)
ctx := x.newContext()
return ctx, x, err
}
diff --git a/cue/subsume.go b/cue/subsume.go
index 05881cb..e1e58d9 100644
--- a/cue/subsume.go
+++ b/cue/subsume.go
@@ -36,7 +36,7 @@
src := binSrc(token.NoPos, opUnify, s.gt, s.lt)
var ok bool
if s.missing != 0 {
- b = ctx.mkErr(src, "missing field %q", ctx.labelStr(s.missing))
+ b = ctx.mkErr(src, "missing field %q", ctx.LabelStr(s.missing))
} else if b, ok = binOp(ctx, src, opUnify, s.gt, s.lt).(*bottom); !ok {
b = ctx.mkErr(src, "value not an instance")
}
@@ -180,7 +180,7 @@
if b.optional || b.definition {
continue
}
- name := ctx.labelStr(b.feature)
+ name := ctx.LabelStr(b.feature)
arg := &stringLit{x.baseValue, name, nil}
u, _ := x.optionals.constraint(ctx, arg)
if u != nil && !s.subsumes(u, b.v) {
@@ -248,7 +248,7 @@
}
a := x.lookup(ctx, b.feature)
if a.val() == nil {
- name := ctx.labelStr(b.feature)
+ name := ctx.LabelStr(b.feature)
arg := &stringLit{x.baseValue, name, nil}
u, _ := x.optionals.constraint(ctx, arg)
if u == nil { // subsumption already checked
diff --git a/cue/subsume_test.go b/cue/subsume_test.go
index 8925bd5..d41ada7 100644
--- a/cue/subsume_test.go
+++ b/cue/subsume_test.go
@@ -454,9 +454,9 @@
var a, b value
for _, arc := range root.arcs {
switch arc.feature {
- case ctx.strLabel("a"):
+ case ctx.StrLabel("a"):
a = arc.v
- case ctx.strLabel("b"):
+ case ctx.StrLabel("b"):
b = arc.v
}
}
diff --git a/cue/types.go b/cue/types.go
index 5c68c88..e1f2ce2 100644
--- a/cue/types.go
+++ b/cue/types.go
@@ -152,13 +152,13 @@
func (o *structValue) At(i int) (key string, v Value) {
a := o.arcs[i]
v = newChildValue(o, i)
- return o.ctx.labelStr(a.feature), v
+ return o.ctx.LabelStr(a.feature), v
}
// Lookup reports the field for the given key. The returned Value is invalid
// if it does not exist.
func (o *structValue) Lookup(key string) Value {
- f := o.ctx.strLabel(key)
+ f := o.ctx.StrLabel(key)
i := 0
len := o.Len()
for ; i < len; i++ {
@@ -281,7 +281,7 @@
if i.f == 0 {
return ""
}
- return i.ctx.labelStr(i.f)
+ return i.ctx.LabelStr(i.f)
}
// IsHidden reports if a field is hidden from the data model.
@@ -563,7 +563,7 @@
case listKind:
a = append(a, strconv.FormatInt(int64(v.index), 10))
case structKind:
- f := idx.labelStr(v.arc.feature)
+ f := idx.LabelStr(v.arc.feature)
if v.arc.feature&(hidden|definition) == 0 {
if !isIdent(f) && !isNumber(f) {
f = quote(f, '"')
@@ -634,7 +634,7 @@
x := obj.obj
ctx := obj.ctx
if x.optionals != nil {
- name := ctx.labelStr(x.arcs[i].feature)
+ name := ctx.LabelStr(x.arcs[i].feature)
arg := &stringLit{x.baseValue, name, nil}
val, _ := x.optionals.constraint(ctx, arg)
@@ -720,7 +720,7 @@
return nil, nil
}
- a = append(a, ctx.label(s.str, false))
+ a = append(a, ctx.Label(s.str, false))
case *nodeRef:
n = x
@@ -821,7 +821,7 @@
if v.path.feature == 0 {
return "", false
}
- return v.idx.labelStr(v.path.feature), true
+ return v.idx.LabelStr(v.path.feature), true
}
// Kind returns the kind of value. It returns BottomKind for atomic values that
@@ -1430,7 +1430,7 @@
// rewritten.
x := s.s
if x.optionals != nil {
- name := ctx.labelStr(x.arcs[i].feature)
+ name := ctx.LabelStr(x.arcs[i].feature)
arg := &stringLit{x.baseValue, name, nil}
val, _ := x.optionals.constraint(ctx, arg)
@@ -1440,7 +1440,7 @@
}
v := Value{ctx.index, &valueData{s.v.path, uint32(i), a}}
- str := ctx.labelStr(a.feature)
+ str := ctx.LabelStr(a.feature)
return FieldInfo{str, i, v, a.definition, a.optional, a.feature&hidden != 0}
}
@@ -1448,7 +1448,7 @@
// look up a definition or hidden field (starting with `_` or `_#`). Otherwise
// it interprets name as an arbitrary string for a regular field.
func (s *Struct) FieldByName(name string, isIdent bool) (FieldInfo, error) {
- f := s.v.ctx().label(name, isIdent)
+ f := s.v.ctx().Label(name, isIdent)
for i, a := range s.s.arcs {
if a.feature == f {
return s.Field(i), nil
@@ -1515,7 +1515,7 @@
return newErrValue(v, err)
}
- f := v.ctx().label(name, true)
+ f := v.ctx().Label(name, true)
for i, a := range o.arcs {
if a.feature == f {
if f&hidden != 0 || !a.definition || a.optional {
@@ -1751,7 +1751,7 @@
switch sel := v.path.v.(type) {
case *selectorExpr:
x = sel.x
- feature = ctx.labelStr(sel.feature)
+ feature = ctx.LabelStr(sel.feature)
case *indexExpr:
e := sel.index.evalPartial(ctx)
@@ -1772,7 +1772,7 @@
func mkPath(c *context, up *valueData, x value, feature string, d int) (imp *Instance, a []string) {
switch x := x.(type) {
case *selectorExpr:
- imp, a = mkPath(c, up, x.x, c.labelStr(x.feature), d+1)
+ imp, a = mkPath(c, up, x.x, c.LabelStr(x.feature), d+1)
if imp == nil {
return nil, nil
}
@@ -1818,7 +1818,7 @@
}
root, a = mkFromRoot(c, up.parent, d+1)
if up.parent != nil {
- a = append(a, c.labelStr(up.feature))
+ a = append(a, c.LabelStr(up.feature))
} else {
root = up.v
}
@@ -1867,7 +1867,7 @@
}
path := make([]string, len(p.stack))
for i, v := range p.stack {
- path[len(path)-1-i] = ctx.labelStr(v)
+ path[len(path)-1-i] = ctx.LabelStr(v)
}
p.paths = append(p.paths, path)
p.stack = p.stack[:i]
@@ -2291,7 +2291,7 @@
a = append(a, remakeValue(v, x.x))
a = append(a, remakeValue(v, &stringLit{
x.baseValue,
- v.ctx().labelStr(x.feature),
+ v.ctx().LabelStr(x.feature),
nil,
}))
op = SelectorOp
diff --git a/cue/types_test.go b/cue/types_test.go
index b615158..0421920 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -770,7 +770,7 @@
}
}
-func compile(t *testing.T, r *Runtime, s string) *Instance {
+func compileT(t *testing.T, r *Runtime, s string) *Instance {
t.Helper()
inst, err := r.Compile("", s)
if err != nil {
@@ -838,8 +838,8 @@
path = strings.Split(tc.path, ",")
}
- v := compile(t, r, tc.in).Value().Fill(tc.x, path...)
- w := compile(t, r, tc.out).Value()
+ v := compileT(t, r, tc.in).Value().Fill(tc.x, path...)
+ w := compileT(t, r, tc.out).Value()
if !reflect.DeepEqual(goValue(v), goValue(w)) {
t.Errorf("\ngot: %s\nwant: %s", v, w)
@@ -899,7 +899,7 @@
for _, tc := range testCases {
t.Run(tc.def, func(t *testing.T) {
- v := compile(t, r, tc.in).Value()
+ v := compileT(t, r, tc.in).Value()
v = v.LookupDef(tc.def)
got := fmt.Sprint(v)
diff --git a/cue/value.go b/cue/value.go
index 00a958f..fd5ada1 100644
--- a/cue/value.go
+++ b/cue/value.go
@@ -26,6 +26,7 @@
"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/literal"
"cuelang.org/go/cue/token"
+ "cuelang.org/go/internal/core/adt"
)
type value interface {
@@ -805,7 +806,7 @@
return false
}
- str := ctx.labelStr(f)
+ str := ctx.LabelStr(f)
arg := &stringLit{str: str}
found, ok := o.match(ctx, arg)
@@ -1015,7 +1016,7 @@
// TODO: adding more technical debt here. The evaluator should be
// rewritten.
if x.optionals != nil {
- name := ctx.labelStr(x.arcs[i].feature)
+ name := ctx.LabelStr(x.arcs[i].feature)
arg := &stringLit{x.baseValue, name, nil}
val, _ := x.optionals.constraint(ctx, arg)
@@ -1206,7 +1207,7 @@
}
if x.arcs[i].feature&(hidden|definition) == 0 {
- name := ctx.labelStr(x.arcs[i].feature)
+ name := ctx.LabelStr(x.arcs[i].feature)
arg := &stringLit{x.baseValue, name, nil}
var val value
@@ -1223,7 +1224,7 @@
}
// A label is a canonicalized feature name.
-type label uint32
+type label = adt.Feature
const (
hidden label = 0x01 // only set iff identifier starting with _ or #_
@@ -1361,7 +1362,7 @@
src := binSrc(token.NoPos, opUnify, p.v, value)
x.arcs[i].v = ctx.mkErr(src,
"field %q declared as definition and regular field",
- ctx.labelStr(f))
+ ctx.LabelStr(f))
isDef = false
}
x.arcs[i].definition = isDef
@@ -1913,7 +1914,7 @@
for i, a := range src.arcs {
key := &stringLit{
x.baseValue,
- ctx.labelStr(a.feature),
+ ctx.LabelStr(a.feature),
nil,
}
if a.definition || a.optional || a.feature&hidden != 0 {