cue/parser: remove support for space-separated labels
Issue #339
Change-Id: Id3bf16f8f344cd9cfbcb51ce5d3a4359b8effafe
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5681
Reviewed-by: roger peppe <rogpeppe@gmail.com>
diff --git a/cmd/cue/cmd/fix_test.go b/cmd/cue/cmd/fix_test.go
index e7b64ba..15093b3 100644
--- a/cmd/cue/cmd/fix_test.go
+++ b/cmd/cue/cmd/fix_test.go
@@ -73,18 +73,6 @@
"\(k)": v
}
`,
- }, {
- name: "templates",
- in: `package foo
-
-a: <Name>: { name: Name }
-b: <X>: { name: string }
-`,
- out: `package foo
-
-a: [Name=_]: {name: Name}
-b: [string]: {name: string}
-`,
// }, {
// name: "slice",
// in: `package foo
diff --git a/cmd/cue/cmd/testdata/script/legacy.txt b/cmd/cue/cmd/testdata/script/legacy.txt
index 1b92cc3..13cd68f 100644
--- a/cmd/cue/cmd/testdata/script/legacy.txt
+++ b/cmd/cue/cmd/testdata/script/legacy.txt
@@ -8,15 +8,12 @@
cmp foo.cue foo-new.cue
-- expect-stderr --
-space-separated labels deprecated as of v0.0.13: try running `cue fmt` on the file to upgrade.:
- ./foo.cue:1:3
old-style comprehensions deprecated as of v0.0.11: try running `cue fmt` on the file to upgrade.:
- ./foo.cue:2:8
+ ./foo.cue:1:8
-- foo.cue --
-a b: 2
"x": 3 for x in a
-- foo-new.cue --
-a: b: 2
+
for x in a {
"x": 3
-}
\ No newline at end of file
+}
diff --git a/cue/ast/astutil/apply_test.go b/cue/ast/astutil/apply_test.go
index f6e412a..a9dc94a 100644
--- a/cue/ast/astutil/apply_test.go
+++ b/cue/ast/astutil/apply_test.go
@@ -136,12 +136,12 @@
name: "templates",
in: `
foo: {
- a: <b>: c: 3
+ a: [string]: c: 3
}
`,
out: `
foo: {
- a: <b>: {
+ a: [string]: {
c: 3
iam: new
}
diff --git a/cue/ast_test.go b/cue/ast_test.go
index dfd8359..3cc17bd 100644
--- a/cue/ast_test.go
+++ b/cue/ast_test.go
@@ -150,7 +150,7 @@
in: `
a: 5 | "a" | true
aa: 5 | *"a" | true
- b c: {
+ b: c: {
cc: { ccc: 3 }
}
d: true
@@ -158,8 +158,8 @@
out: "<0>{a: (5 | \"a\" | true), aa: (5 | *\"a\" | true), b: <1>{c: <2>{cc: <3>{ccc: 3}}}, d: true}",
}, {
in: `
- a a: { b: a } // referencing ancestor nodes is legal.
- a b: a.a // do lookup before merging of nodes
+ a: a: { b: a } // referencing ancestor nodes is legal.
+ a: b: a.a // do lookup before merging of nodes
b: a.a // different node as a.a.b, as first node counts
c: a // same node as b, as first node counts
d: a["a"]
@@ -282,11 +282,11 @@
}, {
in: `
a: {
- <name>: { n: name }
+ [name=_]: { n: name }
k: 1
}
b: {
- <X>: { x: 0, y: 1 }
+ [X=_]: { x: 0, y: 1 }
v: {}
}
`,
@@ -347,7 +347,7 @@
out: "unexpected ')':\n test:2:18\nattribute missing ')':\n test:3:3\n<0>{}",
}, {
in: `
- a d: {
+ a: d: {
base
info :: {
...
@@ -359,7 +359,7 @@
info :: {...}
}
- a <Name>: { info :: {
+ a: [Name=string]: { info :: {
X: "foo"
}}
`,
diff --git a/cue/build_test.go b/cue/build_test.go
index 90b15b7..14f7479 100644
--- a/cue/build_test.go
+++ b/cue/build_test.go
@@ -183,7 +183,7 @@
import bar "pkg1"
import baz "example.com/foo/pkg2:pkg"
- pkg1 Object: 3
+ pkg1: Object: 3
"Hello \(pkg1.Object)!"`),
}),
`imported and not used: "pkg1" as bar (and 1 more errors)`,
diff --git a/cue/builtin_test.go b/cue/builtin_test.go
index 3480268..8d3428a 100644
--- a/cue/builtin_test.go
+++ b/cue/builtin_test.go
@@ -258,7 +258,7 @@
test("list", `list.Sort([], list.Ascending)`),
`[]`,
}, {
- test("list", `list.Sort([2, 3, 1, 4], {x:_, y:_, less: (x<y)})`),
+ test("list", `list.Sort([2, 3, 1, 4], {x:_, y:_, less: x<y})`),
`[1,2,3,4]`,
}, {
test("list", `list.SortStable([{a:2,v:1}, {a:1,v:2}, {a:1,v:3}], {
@@ -404,7 +404,7 @@
testExpr(`len({})`),
`0`,
}, {
- testExpr(`len({a: 1, b: 2, <foo>: int, _c: 3})`),
+ testExpr(`len({a: 1, b: 2, [foo=_]: int, _c: 3})`),
`2`,
}, {
testExpr(`len([1, 2, 3])`),
diff --git a/cue/export_test.go b/cue/export_test.go
index af303e0..6967acb 100644
--- a/cue/export_test.go
+++ b/cue/export_test.go
@@ -281,8 +281,8 @@
idx: a[str]
str: string
}
- b a b: 4
- a b: 3
+ b: a: b: 4
+ a: b: 3
}`,
// reference to a must be redirected to outer a through alias
out: unindent(`
diff --git a/cue/format/testdata/expressions.golden b/cue/format/testdata/expressions.golden
index 5ed1f18..0dbc658 100644
--- a/cue/format/testdata/expressions.golden
+++ b/cue/format/testdata/expressions.golden
@@ -10,7 +10,7 @@
c: b: a: 4
c?: bb?: aaa?: 5
- c: b: <Name>: a: int
+ c: b: [Name=string]: a: int
alias = 3.14
"g\("en")"?: 4
diff --git a/cue/format/testdata/expressions.input b/cue/format/testdata/expressions.input
index 3ea84a8..8b19de6 100644
--- a/cue/format/testdata/expressions.input
+++ b/cue/format/testdata/expressions.input
@@ -8,9 +8,9 @@
b: 3
- c b a: 4
- c? bb? aaa?: 5
- c b <Name> a: int
+ c: b: a: 4
+ c?: bb?: aaa?: 5
+ c: b: [Name=string]: a: int
alias = 3.14
"g\("en")"?: 4
diff --git a/cue/instance_test.go b/cue/instance_test.go
index 0a7ca56..e11cbf6 100644
--- a/cue/instance_test.go
+++ b/cue/instance_test.go
@@ -54,12 +54,12 @@
}, {
desc: "templates",
instances: insts(`
- obj <X>: { a: "A" }
- obj alpha: { b: 2 }
+ obj: [string]: { a: "A" }
+ obj: alpha: { b: 2 }
`,
`
- obj <X>: { a: "B" }
- obj beta: { b: 3 }
+ obj: [string]: { a: "B" }
+ obj: beta: { b: 3 }
`,
),
out: `{obj:{alpha:{a:A,b:2},beta:{a:B,b:3}}}`,
@@ -71,13 +71,13 @@
desc: "shared struct",
instances: insts(`
_shared: { a: "A" }
- obj <X>: _shared & {}
- obj alpha: { b: 2 }
+ obj: [string]: _shared & {}
+ obj: alpha: { b: 2 }
`,
`
_shared: { a: "B" }
- obj <X>: _shared & {}
- obj beta: { b: 3 }
+ obj: [string]: _shared & {}
+ obj: beta: { b: 3 }
`,
),
out: `{obj:{alpha:{a:A,b:2},beta:{a:B,b:3}}}`,
@@ -85,13 +85,13 @@
desc: "top-level comprehensions",
instances: insts(`
t: { for k, x in s {"\(k)": 10} }
- s <Name>: {}
- s foo a: 1
+ s: [string]: {}
+ s: foo: a: 1
`,
`
t: { for k, x in s {"\(k)": 10 } }
- s <Name>: {}
- s bar b: 2
+ s: [string]: {}
+ s: bar: b: 2
`,
),
out: `{t:{foo:10,bar:10},s:{foo:{a:1},bar:{b:2}}}`,
diff --git a/cue/parser/parser.go b/cue/parser/parser.go
index f1adb42..85c1061 100644
--- a/cue/parser/parser.go
+++ b/cue/parser/parser.go
@@ -786,7 +786,6 @@
this := &ast.Field{Label: nil}
m := this
- multipleLabels := false
allowComprehension := true
for i := 0; ; i++ {
@@ -816,18 +815,14 @@
return e
}
- if tok != token.LSS && p.tok == token.OPTION {
+ if p.tok == token.OPTION {
m.Optional = p.pos
p.next()
}
if p.tok == token.COLON || p.tok == token.ISA {
- if p.tok == token.ISA && multipleLabels {
- p.errf(p.pos, "more than one label before '::' (only one allowed)")
- }
break
}
- multipleLabels = true
// TODO: consider disallowing comprehensions with more than one label.
// This can be a bit awkward in some cases, but it would naturally
@@ -836,12 +831,6 @@
// allowComprehension = false
switch p.tok {
- case token.IDENT, token.STRING, token.LSS, token.INTERPOLATION, token.LBRACK:
- p.assertV0(p.pos, 0, 12, "space-separated labels")
- field := &ast.Field{}
- m.Value = &ast.StructLit{Elts: []ast.Decl{field}}
- m = field
-
case token.COMMA:
p.expectComma() // sync parser.
fallthrough
@@ -988,7 +977,7 @@
switch tok {
case token.IDENT, token.STRING, token.INTERPOLATION,
token.NULL, token.TRUE, token.FALSE:
- expr = p.parseExpr(true)
+ expr = p.parseExpr()
switch x := expr.(type) {
case *ast.BasicLit:
@@ -1047,76 +1036,12 @@
p.errf(pos, "expected operand, found '%s'", ident.Name)
expr = &ast.BadExpr{From: pos, To: p.pos}
// Sync expression.
- expr = p.parseBinaryExprTail(false, token.LowestPrec+1, expr)
+ expr = p.parseBinaryExprTail(token.LowestPrec+1, expr)
expr = c.closeExpr(p, expr)
break
}
label = ident
ok = true
-
- case token.LSS:
- p.openList()
- defer p.closeList()
-
- pos := p.pos
- c := p.openComments()
- p.next()
- var ident *ast.Ident
- var gtr token.Pos
- switch {
- case rhs:
- // TODO: remove this code once the <X> notation is out.
- if p.tok != token.IDENT {
- // parse RHS and continue binary Expression
- expr = p.parseUnaryExpr()
- expr = &ast.UnaryExpr{OpPos: pos, Op: token.LSS, X: expr}
- expr = c.closeExpr(p, expr)
- return nil, p.parseBinaryExprTail(false, token.LowestPrec+1, expr), false
- }
-
- ident = p.parseIdent()
- if p.tok != token.GTR {
- expr = p.parsePrimaryExprTail(ident)
- expr = &ast.UnaryExpr{OpPos: pos, Op: token.LSS, X: expr}
- expr = c.closeExpr(p, expr)
- return nil, p.parseBinaryExprTail(false, token.LowestPrec+1, expr), false
- }
- gtr = p.pos
- p.next()
-
- // NOTE: at this point, even if there still a syntactically valid
- // expression, it will always yield bottom, as '>' does not take
- // boolean arguments.
- // This code does not allow for `<X>[string]:` and so on. So a
- // new way to alias labels should be introduced at the time
- // such constructs are introduced. For instance `(X,Y)=[string]:`.
- if p.tok != token.COLON && p.tok != token.ISA {
- expr = &ast.UnaryExpr{OpPos: pos, Op: token.LSS, X: ident}
- expr = c.closeExpr(p, expr)
- c := p.openComments()
- prec := token.GTR.Precedence()
- expr = c.closeExpr(p, &ast.BinaryExpr{
- X: expr,
- OpPos: gtr,
- Op: token.GTR,
- Y: p.checkExpr(p.parseBinaryExpr(false, prec)),
- })
- return nil, expr, false
- }
-
- default:
- ident = p.parseIdent()
- gtr = p.pos
- if p.tok != token.GTR {
- p.expect(token.GTR)
- }
- p.next()
- }
-
- p.assertV0(p.pos, 0, 12, "template labels")
- label = &ast.TemplateLabel{Langle: pos, Ident: ident, Rangle: gtr}
- c.closeNode(p, label)
- ok = true
}
return label, expr, ok
}
@@ -1291,7 +1216,7 @@
c := p.openComments()
defer func() { c.closeNode(p, expr) }()
- expr = p.parseBinaryExprTail(false, token.LowestPrec+1, p.parseUnaryExpr())
+ expr = p.parseBinaryExprTail(token.LowestPrec+1, p.parseUnaryExpr())
expr = p.parseAlias(expr)
// Enforce there is an explicit comma. We could also allow the
@@ -1455,26 +1380,19 @@
}
// If lhs is set and the result is an identifier, it is not resolved.
-func (p *parser) parseBinaryExpr(lhs bool, prec1 int) ast.Expr {
+func (p *parser) parseBinaryExpr(prec1 int) ast.Expr {
if p.trace {
defer un(trace(p, "BinaryExpr"))
}
p.openList()
defer p.closeList()
- return p.parseBinaryExprTail(lhs, prec1, p.parseUnaryExpr())
+ return p.parseBinaryExprTail(prec1, p.parseUnaryExpr())
}
-func (p *parser) parseBinaryExprTail(lhs bool, prec1 int, x ast.Expr) ast.Expr {
+func (p *parser) parseBinaryExprTail(prec1 int, x ast.Expr) ast.Expr {
for {
op, prec := p.tokPrec()
- if lhs && op == token.LSS {
- // Eagerly interpret this as a template label.
- // TODO: remove once <X> is deprecated.
- if _, ok := x.(ast.Label); ok {
- return x
- }
- }
if prec < prec1 {
return x
}
@@ -1486,7 +1404,7 @@
OpPos: pos,
Op: op,
// Treat nested expressions as RHS.
- Y: p.checkExpr(p.parseBinaryExpr(false, prec+1))})
+ Y: p.checkExpr(p.parseBinaryExpr(prec + 1))})
}
}
@@ -1531,7 +1449,7 @@
}
// Callers must check the result (using checkExpr), depending on context.
-func (p *parser) parseExpr(lhs bool) (expr ast.Expr) {
+func (p *parser) parseExpr() (expr ast.Expr) {
if p.trace {
defer un(trace(p, "Expression"))
}
@@ -1539,11 +1457,11 @@
c := p.openComments()
defer func() { c.closeExpr(p, expr) }()
- return p.parseBinaryExpr(lhs, token.LowestPrec+1)
+ return p.parseBinaryExpr(token.LowestPrec + 1)
}
func (p *parser) parseRHS() ast.Expr {
- x := p.checkExpr(p.parseExpr(false))
+ x := p.checkExpr(p.parseExpr())
return x
}
diff --git a/cue/parser/parser_test.go b/cue/parser/parser_test.go
index 46f4a03..45bdbe0 100644
--- a/cue/parser/parser_test.go
+++ b/cue/parser/parser_test.go
@@ -153,14 +153,6 @@
`,
`a: {b :: {c?: {[Name=_]: {d: 1}}}}, "g\("en")"?: 4, job: {"foo": {[_]: {bar: 1}}}`,
}, {
- "collapsed fields", // TODO: remove
- `a: b:: c?: <Name>: d: 1
- "g\("en")"?: 4
- // job foo { bar: 1 } // TODO error after foo
- job "foo" <X>: { bar: 1 }
- `,
- `a: {b :: {c?: {<Name>: {d: 1}}}}, "g\("en")"?: 4, job: {"foo": {<X>: {bar: 1}}}`,
- }, {
"identifiers",
`// $_: 1,
a: {b: {c: d}}
@@ -273,17 +265,17 @@
}, {
"duplicates allowed",
`{
- a b: 3
+ a: b: 3
a: { b: 3 }
}`,
"{a: {b: 3}, a: {b: 3}}",
}, {
"templates", // TODO: remove
`{
- <foo>: { a: int }
+ [foo=_]: { a: int }
a: { a: 1 }
}`,
- "{<foo>: {a: int}, a: {a: 1}}",
+ "{[foo=_]: {a: int}, a: {a: 1}}",
}, {
"foo",
`[
diff --git a/cue/parser/short_test.go b/cue/parser/short_test.go
index bfdb14c..da4e58a 100644
--- a/cue/parser/short_test.go
+++ b/cue/parser/short_test.go
@@ -21,7 +21,7 @@
var valids = []string{
"\n",
`{}`,
- `{ <Name>: foo }`,
+ `{ [Name=_]: foo }`,
`{ a: 3 }`,
}
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index 95f8e29..591b3c5 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -531,7 +531,7 @@
desc: "pick first",
in: `
a: *5 | "a" | true
- b c: *{
+ b: c: *{
a: 2
} | {
a : 3
@@ -565,12 +565,12 @@
func TestResolve(t *testing.T) {
testCases := []testCase{{
desc: "convert _ to top",
- in: `a: { <_>: _ }`,
+ in: `a: { [_]: _ }`,
out: `<0>{a: <1>{...}}`,
}, {
in: `
a: b.c.d
- b c: { d: 3 }
+ b: c: { d: 3 }
c: { c: d.d, }
d: { d: 2 }
`,
@@ -1180,7 +1180,7 @@
Bar :: {
field: int
- <A>: int
+ [A=_]: int
}
bar: Bar
bar: { feild: 2 }
@@ -1205,13 +1205,13 @@
in: `
// Allow combining of structs within a definition
D1 :: {
- env a: "A"
- env b: "B"
+ env: a: "A"
+ env: b: "B"
def :: {a: "A"}
def :: {b: "B"}
}
- d1: D1 & { env c: "C" }
+ d1: D1 & { env: c: "C" }
D2 :: {
a: int
@@ -1221,15 +1221,15 @@
}
D3 :: {
- env a: "A"
+ env: a: "A"
}
D3 :: {
- env b: "B"
+ env: b: "B"
}
D4 :: {
env: DC
- env b: int
+ env: b: int
}
DC :: { a: int }
@@ -1245,13 +1245,13 @@
}, {
desc: "recursive closing starting at non-definition",
in: `
- z a: {
+ z: a: {
B:: {
- c d: 1
- c f: 1
+ c: d: 1
+ c: f: 1
}
}
- A: z & { a: { B :: { c e: 2 } } }
+ A: z & { a: { B :: { c: e: 2 } } }
`,
out: `<0>{z: <1>{a: <2>{B :: <3>C{c: <4>C{d: 1, f: 1}}}}, A: <5>{a: <6>{B :: <7>C{c: _|_(2:field "e" not allowed in closed struct)}}}}`,
}, {
@@ -1317,7 +1317,7 @@
{ a: 1 } |
{ b: 2 }
}
- x c: 3
+ x: c: 3
}
`,
out: `<0>{` +
@@ -1337,9 +1337,9 @@
}
// adding a field to a nested struct that is closed.
- e1 :: S & { a d: 4 }
+ e1 :: S & { a: d: 4 }
// literal struct not closed until after unification.
- v1 :: S & { a c: 4 }
+ v1 :: S & { a: c: 4 }
`,
out: `<0>{` +
`E :: <1>C{a: <2>C{b: int}}, ` +
@@ -1418,8 +1418,8 @@
b: B
}
V: S & {
- c e: int
- b extra: int
+ c: e: int
+ b: extra: int
}
`,
out: `<0>{` +
@@ -1548,12 +1548,12 @@
desc: "references from template to concrete",
in: `
res: [t]
- t <X>: {
+ t: [X=string]: {
a: c + b.str
- b str: string
+ b: str: string
c: "X"
}
- t x: { b str: "DDDD" }
+ t: x: { b: str: "DDDD" }
`,
out: `<0>{res: [<1>{[]: <2>(X: string)-><3>{a: (<3>.c + <3>.b.str), c: "X", b: <4>{str: string}}, x: <5>{a: "XDDDD", c: "X", b: <6>{str: "DDDD"}}}], t: <7>{[]: <2>(X: string)-><3>{a: (<3>.c + <3>.b.str), c: "X", b: <4>{str: string}}, x: <8>{a: "XDDDD", c: "X", b: <9>{str: "DDDD"}}}}`,
}, {
@@ -1644,17 +1644,17 @@
desc: "field templates",
in: `
a: {
- <name>: int
+ [name=_]: int
k: 1
}
b: {
- <X>: { x: 0, y: *1 | int }
+ [X=_]: { x: 0, y: *1 | int }
v: {}
w: { x: 0 }
}
- b: { <y>: {} }
+ b: { [y=_]: {} }
c: {
- <Name>: { name: Name, y: 1 }
+ [Name=_]: { name: Name, y: 1 }
foo: {}
bar: _
}
@@ -1764,11 +1764,11 @@
}, {
desc: "struct comprehensions",
in: `
- obj foo a: "bar"
- obj <Name>: {
+ obj: foo: a: "bar"
+ obj: [Name=string]: {
a: *"dummy" | string
if true {
- sub as: a
+ sub: as: a
}
}
@@ -1810,7 +1810,7 @@
x: y+"?"
y: x+"!"
}
- a x: "hey"
+ a: x: "hey"
`,
out: `<0>{a: <1>{x: _|_(("hey!?" & "hey"):conflicting values "hey!?" and "hey"), y: "hey!"}}`,
}, {
@@ -2032,30 +2032,30 @@
}, {
desc: "resolve all disjunctions",
in: `
- service <Name>: {
+ service: [Name=string]: {
name: string | *Name
port: int | *7080
}
- service foo: _
- service bar: { port: 8000 }
- service baz: { name: "foobar" }
+ service: foo: _
+ service: bar: { port: 8000 }
+ service: baz: { name: "foobar" }
`,
out: `<0>{service: <1>{[]: <2>(Name: string)-><3>{name: (string | *<2>.Name), port: (int | *7080)}, foo: <4>{name: "foo", port: 7080}, bar: <5>{name: "bar", port: 8000}, baz: <6>{name: "foobar", port: 7080}}}`,
}, {
desc: "field templates",
in: `
a: {
- <name>: int
+ [name=_]: int
k: 1
}
b: {
- <X>: { x: 0, y: *1 | int }
+ [X=_]: { x: 0, y: *1 | int }
v: {}
w: { y: 0 }
}
- b: { <y>: {} } // TODO: allow different name
+ b: { [y=_]: {} } // TODO: allow different name
c: {
- <Name>: { name: Name, y: 1 }
+ [Name=_]: { name: Name, y: 1 }
foo: {}
bar: _
}
@@ -2112,9 +2112,9 @@
}, {
desc: "referencing field in field comprehension",
in: `
- a: { b c: 4 }
+ a: { b: c: 4 }
a: {
- b d: 5
+ b: d: 5
for k, v in b {
"\(k)": v
}
@@ -2124,9 +2124,9 @@
}, {
desc: "different labels for templates",
in: `
- a <X>: { name: X }
- a <Name>: { name: Name }
- a foo: {}
+ a: [X=string]: { name: X }
+ a: [Name=string]: { name: Name }
+ a: foo: {}
`,
out: `<0>{a: <1>{[]: <2>(X: string)->(<3>{name: <2>.X} & <4>{name: <2>.X}), foo: <5>{name: "foo"}}}`,
}, {
@@ -2134,13 +2134,13 @@
desc: "nested templates in one field",
in: `
- a <A> b <B>: {
+ a: [A=string]: b: [B=string]: {
name: A
kind: B
}
- a "A" b "B": _
- a "C" b "D": _
- a "EE" b "FF": { c: "bar" }
+ a: "A": b: "B": _
+ a: "C": b: "D": _
+ a: "EE": b: "FF": { c: "bar" }
`,
out: `<0>{a: <1>{[]: <2>(A: string)-><3>{b: <4>{[]: <5>(B: string)-><6>{name: <2>.A, kind: <5>.B}, }}, ` +
`A: <7>{b: <8>{[]: <9>(B: string)-><10>{name: <11>.A, kind: <9>.B}, ` +
@@ -2153,12 +2153,13 @@
desc: "template unification within one struct",
in: `
a: {
- <A>: { name: A }
- <A>: { kind: A }
+ [A=string]: { name: A }
+ // TODO: allow duplicate alias here
+ [X=string]: { kind: X }
}
- a "A": _
- a "C": _
- a "E": { c: "bar" }
+ a: "A": _
+ a: "C": _
+ a: "E": { c: "bar" }
`,
out: `<0>{a: <1>{[]: <2>(A: string)->(<3>{name: <2>.A} & <4>{kind: <2>.A}), ` +
`E: <5>{name: "E", kind: "E", c: "bar"}, ` +
@@ -2172,7 +2173,7 @@
{a: "C", b: "D" },
{a: "E", b: "F" },
] {
- a "\(x.a)" b "\(x.b)": x
+ a: "\(x.a)": b: "\(x.b)": x
}
for x in [
@@ -2180,7 +2181,7 @@
{a: "C", b: "D" },
{a: "E", b: "F" },
] {
- "\(x.a)" "\(x.b)": x
+ "\(x.a)": "\(x.b)": x
}
`,
out: `<0>{E: <1>{F: <2>{a: "E", b: "F"}}, ` +
@@ -2204,13 +2205,13 @@
num: 1
a: {
if num < 5 {
- <A> <B>: {
+ [A=string]: [B=string]: {
name: A
kind: B
}
}
}
- a b c d: "bar"
+ a: b: c: d: "bar"
`,
out: `<0>{num: 1, a: <1>{[]: <2>(A: string)-><3>{[]: <4>(B: string)-><5>{name: <2>.A, kind: <4>.B}, }, ` +
`b: <6>{[]: <7>(B: string)-><8>{name: <9>.A, kind: <7>.B}, ` +
@@ -2264,14 +2265,14 @@
in: `
result: [ v for _, v in service ]
- service <Name>: {
+ service: [Name=string]: {
name: *Name | string
type: "service"
port: *7080 | int
}
- service foo: {}
- service bar: { port: 8000 }
- service baz: { name: "foobar" }
+ service: foo: {}
+ service: bar: { port: 8000 }
+ service: baz: { name: "foobar" }
`,
out: `<0>{result: [` +
`<1>{name: "foo", type: "service", port: 7080},` +
@@ -2338,8 +2339,8 @@
res: [ y & { d: "b" } for x in a for y in x ]
res: [ a.b.c & { d: "b" } ]
- a b <C>: { d: string, s: "a" + d }
- a b c d: string
+ a: b: [C=string]: { d: string, s: "a" + d }
+ a: b: c: d: string
`,
// TODO(perf): unification should catch shared node.
out: `<0>{res: [<1>{d: "b", s: "ab"}], ` +
@@ -2351,21 +2352,21 @@
f1: { y: string, res: a.b.c & { d: y } }
- a b c: { d: string, s: "a" + d }
- a b <C>: { d: string, s: "a" + d }
- a b c d: string
+ a: b: c: { d: string, s: "a" + d }
+ a: b: [C=string]: { d: string, s: "a" + d }
+ a: b: c: d: string
`,
out: `<0>{r1: <1>{y: "c", res: <2>{d: "c", s: "ac"}}, f1: <3>{y: string, res: <4>{d: string, s: (("a" + <5>.d) & ("a" + <5>.d))}}, a: <6>{b: <7>{[]: <8>(C: string)-><9>{d: string, s: ("a" + <9>.d)}, c: <10>{d: string, s: (("a" + <11>.d) & ("a" + <11>.d))}}}}`,
}, {
desc: "references from template to concrete",
in: `
res: [t]
- t <X>: {
+ t: [X=string]: {
a: c + b.str
- b str: string
+ b: str: string
c: "X"
}
- t x: { b str: "DDDD" }
+ t: x: { b: str: "DDDD" }
`,
out: `<0>{res: [<1>{[]: <2>(X: string)-><3>{a: (<3>.c + <3>.b.str), c: "X", b: <4>{str: string}}, x: <5>{a: "XDDDD", c: "X", b: <6>{str: "DDDD"}}}], ` +
`t: <7>{[]: <2>(X: string)-><3>{a: (<3>.c + <3>.b.str), c: "X", b: <4>{str: string}}, x: <8>{a: "XDDDD", c: "X", b: <9>{str: "DDDD"}}}}`,
@@ -2543,7 +2544,7 @@
}, {
desc: "retain references with interleaved embedding",
in: `
- a d: {
+ a: d: {
base
info :: {...}
Y: info.X
@@ -2553,7 +2554,7 @@
info :: {...}
}
- a <Name>: { info :: {
+ a: [Name=string]: { info :: {
X: "foo"
}}
`,
@@ -2580,14 +2581,14 @@
in: `
Workflow :: {
jobs: {
- <jobID>: {
+ [jobID=string]: {
}
}
JobID :: or([ k for k, _ in jobs ])
}
foo: Workflow & {
- jobs foo: {
+ jobs: foo: {
}
}
`,
diff --git a/cue/types_test.go b/cue/types_test.go
index 284f9c2..1c90aec 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -940,32 +940,32 @@
want string
}{{
value: `
- a <Name>: Name
+ a: [Name=string]: Name
`,
path: []string{"a", ""},
want: `"label"`,
}, {
value: `
- <Name>: { a: Name }
+ [Name=string]: { a: Name }
`,
path: []string{"", "a"},
want: `"label"`,
}, {
value: `
- <Name>: { a: Name }
+ [Name=string]: { a: Name }
`,
path: []string{""},
want: `{"a":"label"}`,
}, {
value: `
- a <Foo> <Bar>: { b: Foo+Bar }
+ a: [Foo=string]: [Bar=string]: { b: Foo+Bar }
`,
path: []string{"a", "", ""},
want: `{"b":"labellabel"}`,
}, {
value: `
- a <Foo> b <Bar>: { c: Foo+Bar }
- a foo b <Bar>: { d: Bar }
+ a: [Foo=string]: b: [Bar=string]: { c: Foo+Bar }
+ a: foo: b: [Bar=string]: { d: Bar }
`,
path: []string{"a", "foo", "b", ""},
want: `{"c":"foolabel","d":"label"}`,
@@ -1222,8 +1222,8 @@
}{{
desc: "issue #51",
in: `
- a <Name>: foo
- a b: {}
+ a: [string]: foo
+ a: b: {}
`,
err: true,
}, {
@@ -1231,7 +1231,7 @@
in: `
a: 1
b: { c: 2, d: 3 }
- c d e f: 5
+ c: d: e: f: 5
g?: int
`,
opts: []Option{Concrete(true)},
@@ -1345,7 +1345,7 @@
func TestPath(t *testing.T) {
config := `
- a b c: 5
+ a: b: c: 5
b: {
b1: 3
b2: 4
@@ -1779,10 +1779,10 @@
}
// foos are instances of Foo.
- foos <foo>: Foo
+ foos: [string]: Foo
// My first little foo.
- foos MyFoo: {
+ foos: MyFoo: {
// local field comment.
field1: 0
diff --git a/encoding/protobuf/testdata/gateway.proto.out.cue b/encoding/protobuf/testdata/gateway.proto.out.cue
index 25d80c5..b5e3056 100644
--- a/encoding/protobuf/testdata/gateway.proto.out.cue
+++ b/encoding/protobuf/testdata/gateway.proto.out.cue
@@ -215,7 +215,7 @@
selector?: {
[string]: string
} @protobuf(2,type=map<string,string>)
- selector?: <name>: name
+ selector?: [name=_]: name
}
// `Server` describes the properties of the proxy on a given load balancer
diff --git a/encoding/protobuf/testdata/istio.io/api/networking/v1alpha3/gateway.proto b/encoding/protobuf/testdata/istio.io/api/networking/v1alpha3/gateway.proto
index c69f42a..3f8f96b 100644
--- a/encoding/protobuf/testdata/istio.io/api/networking/v1alpha3/gateway.proto
+++ b/encoding/protobuf/testdata/istio.io/api/networking/v1alpha3/gateway.proto
@@ -220,7 +220,7 @@
// label search is restricted to the configuration namespace in which the
// the resource is present. In other words, the Gateway resource must
// reside in the same namespace as the gateway workload instance.
- map<string, string> selector = 2 [ (cue.val) = "{<name>: name}"];
+ map<string, string> selector = 2 [ (cue.val) = "{[name=_]: name}"];
}
// `Server` describes the properties of the proxy on a given load balancer
diff --git a/encoding/protobuf/testdata/istio.io/api/networking/v1alpha3/gateway_proto_gen.cue b/encoding/protobuf/testdata/istio.io/api/networking/v1alpha3/gateway_proto_gen.cue
index 9a20844..e9136a6 100644
--- a/encoding/protobuf/testdata/istio.io/api/networking/v1alpha3/gateway_proto_gen.cue
+++ b/encoding/protobuf/testdata/istio.io/api/networking/v1alpha3/gateway_proto_gen.cue
@@ -215,7 +215,7 @@
selector?: {
[string]: string
} @protobuf(2,type=map<string,string>)
- selector?: {<name>: name}
+ selector?: {[name=_]: name}
}
// `Server` describes the properties of the proxy on a given load balancer