Skip to content

Commit

Permalink
cue: some API adjustments for new-style definitions
Browse files Browse the repository at this point in the history
The API is now rather unsuitable for handling definitions.
Add some temporary workarounds until we have a new API.

Also updates some old-style defintions to new style.

Change-Id: Ib5c3210016aca971c45c7eddbc9dcb65f7fdc4e1
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/6000
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
  • Loading branch information
mpvl committed May 13, 2020
1 parent b7083ff commit 0240d4e
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 51 deletions.
4 changes: 2 additions & 2 deletions cmd/cue/cmd/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ cuelang.org/go/pkg/tool/tool.cue.
command: [Name]: Command
Command :: {
Command: {
// Tasks specifies the things to run to complete a command. Tasks are
// typically underspecified and completed by the particular internal
// handler that is running them. Tasks can be a single task, or a full
Expand Down Expand Up @@ -447,7 +447,7 @@ cuelang.org/go/pkg/tool/tool.cue.
}
// Name defines a valid task or command name.
Name :: =~#"^\PL([-](\PL|\PN))*$"#
Name: =~#"^\PL([-](\PL|\PN))*$"#
// A Task defines a step in the execution of a command.
Task: {
Expand Down
6 changes: 3 additions & 3 deletions cue/builtins.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions cue/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,33 +73,33 @@ func ExampleValue_Subsume() {
inst, err := r.Compile("apis", `
// Release notes:
// - You can now specify your age and your hobby!
V1 :: {
#V1: {
age: >=0 & <=100
hobby: string
}
// Release notes:
// - People get to be older than 100, so we relaxed it.
// - It seems not many people have a hobby, so we made it optional.
V2 :: {
#V2: {
age: >=0 & <=150 // people get older now
hobby?: string // some people don't have a hobby
}
// Release notes:
// - Actually no one seems to have a hobby nowadays anymore,
// so we dropped the field.
V3 :: {
#V3: {
age: >=0 & <=150
}`)

if err != nil {
fmt.Println(err)
// handle error
}
v1, err1 := inst.LookupField("V1")
v2, err2 := inst.LookupField("V2")
v3, err3 := inst.LookupField("V3")
v1, err1 := inst.Value().FieldByName("#V1", true)
v2, err2 := inst.Value().FieldByName("#V2", true)
v3, err3 := inst.Value().FieldByName("#V3", true)
if err1 != nil || err2 != nil || err3 != nil {
log.Println(err1, err2, err3)
}
Expand All @@ -113,5 +113,5 @@ func ExampleValue_Subsume() {

// Output:
// V2 is backwards compatible with V1: <nil>
// V3 is backwards compatible with V2: V2: conflicting values <=150 and string (mismatched types number and string)
// V3 is backwards compatible with V2: #V2: conflicting values <=150 and string (mismatched types number and string)
}
4 changes: 2 additions & 2 deletions cue/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ func TestExport(t *testing.T) {
}, {
// Here the failed lookups are permanent failures as the structs are
// closed.
in: `{ a :: { b: 2.0, s: "abc" }, b: a.b, c: a.c, d: a["d"], e: a.t[2:3] }`,
in: `{ #a: { b: 2.0, s: "abc" }, b: #a.b, c: #a.c, d: #a["d"], e: #a.t[2:3] }`,
out: unindent(`
{
a :: {
#a: {
b: 2.0
s: "abc"
}
Expand Down
2 changes: 1 addition & 1 deletion cue/format/testdata/expressions.golden
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ package expressions
aaa: 10
}

someDefinition :: {
#someDefinition: {
embedding

field: 2
Expand Down
2 changes: 1 addition & 1 deletion cue/format/testdata/expressions.input
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ package expressions
aaa: 10
}

someDefinition :: {
#someDefinition: {
embedding

field: 2
Expand Down
11 changes: 6 additions & 5 deletions cue/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
package cue

import (
goast "go/ast"

"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/build"
"cuelang.org/go/cue/errors"
Expand Down Expand Up @@ -299,21 +297,24 @@ func (inst *Instance) LookupDef(path string) Value {
// path is not. The empty path returns v itself.
//
// It cannot look up hidden or unexported fields.
//
// Deprecated: this API does not work with new-style definitions. Use
// FieldByName defined on inst.Value().
func (inst *Instance) LookupField(path ...string) (f FieldInfo, err error) {
idx := inst.index
ctx := idx.newContext()
v := newValueRoot(ctx, inst.rootValue)
for i, k := range path {
for _, k := range path {
s, err := v.Struct()
if err != nil {
return f, err
}

f, err = s.FieldByName(k)
f, err = s.FieldByName(k, true)
if err != nil {
return f, err
}
if f.IsHidden || (i == 0 || f.IsDefinition) && !goast.IsExported(f.Name) {
if f.IsHidden {
return f, errNotFound
}
v = f.Value
Expand Down
38 changes: 29 additions & 9 deletions cue/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"bytes"
"encoding/json"
"fmt"
goast "go/ast"
"io"
"math"
"math/big"
Expand Down Expand Up @@ -565,8 +564,10 @@ func (v *valueData) appendPath(a []string, idx *index) ([]string, kind) {
a = append(a, strconv.FormatInt(int64(v.index), 10))
case structKind:
f := idx.labelStr(v.arc.feature)
if !isIdent(f) && !isNumber(f) {
f = quote(f, '"')
if v.arc.feature&(hidden|definition) == 0 {
if !isIdent(f) && !isNumber(f) {
f = quote(f, '"')
}
}
a = append(a, f)
}
Expand Down Expand Up @@ -648,7 +649,7 @@ func newChildValue(obj *structValue, i int) Value {
return Value{obj.ctx.index, &valueData{obj.path, uint32(i), a}}
}

// Dereference reports to the value v refers to if v is a reference or v itself
// Dereference reports the value v refers to if v is a reference or v itself
// otherwise.
func Dereference(v Value) Value {
if v.path == nil {
Expand Down Expand Up @@ -680,12 +681,15 @@ func Dereference(v Value) Value {
}

cached := p.cache
if cached != nil {
if cached == nil {
cached = p.v.evalPartial(ctx)
}
s := cached.(*structLit)
for _, f := range a {
a := s.lookup(ctx, f)
if a.v == nil {
return Value{}
}
p = &valueData{parent: p, arc: a} // index
s, _ = a.cache.(*structLit)
}
Expand Down Expand Up @@ -1408,8 +1412,11 @@ func (s *Struct) Field(i int) FieldInfo {
return FieldInfo{str, i, v, a.definition, a.optional, a.feature&hidden != 0}
}

func (s *Struct) FieldByName(name string) (FieldInfo, error) {
f := s.v.ctx().strLabel(name)
// FieldByName looks up a field for the given name. If isIdent is true, it will
// 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)
for i, a := range s.s.arcs {
if a.feature == f {
return s.Field(i), nil
Expand Down Expand Up @@ -1491,18 +1498,31 @@ func (v Value) LookupDef(name string) Value {

var errNotFound = errors.Newf(token.NoPos, "field not found")

// FieldByName looks up a field for the given name. If isIdent is true, it will
// look up a definition or hidden field (starting with `_` or `_#`). Otherwise
// it interprets name as an arbitrary string for a regular field.
func (v Value) FieldByName(name string, isIdent bool) (f FieldInfo, err error) {
s, err := v.Struct()
if err != nil {
return f, err
}
return s.FieldByName(name, isIdent)
}

// LookupField reports information about a field of v.
//
// Deprecated: this API does not work with new-style definitions. Use FieldByName.
func (v Value) LookupField(name string) (FieldInfo, error) {
s, err := v.Struct()
if err != nil {
// TODO: return a Value at the same location and a new error?
return FieldInfo{}, err
}
f, err := s.FieldByName(name)
f, err := s.FieldByName(name, true)
if err != nil {
return f, err
}
if f.IsHidden || f.IsDefinition && !goast.IsExported(name) {
if f.IsHidden {
return f, errNotFound
}
return f, err
Expand Down
10 changes: 5 additions & 5 deletions cue/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -704,13 +704,13 @@ func TestAllFields(t *testing.T) {
func TestLookup(t *testing.T) {
var runtime = new(Runtime)
inst, err := runtime.Compile("x.cue", `
V :: {
#V: {
x: int
}
X :: {
#X: {
[string]: int64
} & V
v: X
} & #V
v: #X
`)
if err != nil {
t.Fatalf("compile: %v", err)
Expand Down Expand Up @@ -747,7 +747,7 @@ v: X
if err != nil {
t.Fatal(err)
}
fi, err := s.FieldByName(ref)
fi, err := s.FieldByName(ref, false)
if err != nil {
t.Fatal(err)
}
Expand Down
18 changes: 14 additions & 4 deletions pkg/tool/doc.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions pkg/tool/os/doc.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions pkg/tool/os/os.cue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Copyright 2019 The CUE Authors
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//
// http://www.apache.org/licenses/LICENSE-2.0
//
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand All @@ -16,10 +16,10 @@ package os

// A Value are all possible values allowed in flags.
// A null value unsets an environment variable.
Value :: bool | number | *string | null
Value: bool | number | *string | null

// Name indicates a valid flag name.
Name :: !="" & !~"^[$]"
Name: !="" & !~"^[$]"

// Setenv defines a set of command line flags, the values of which will be set
// at run time. The doc comment of the flag is presented to the user in help.
Expand Down
4 changes: 2 additions & 2 deletions pkg/tool/tool.cue
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ Tasks: Task | {
[name=Name]: Tasks
}

// Name defines a valid task or command name.
Name :: =~#"^\PL([-](\PL|\PN))*$"#
// #Name defines a valid task or command name.
Name: =~#"^\PL([-](\PL|\PN))*$"#

// A Task defines a step in the execution of a command.
Task: {
Expand Down

0 comments on commit 0240d4e

Please sign in to comment.