cue/ast: first step to new comprehension format.
Change-Id: Idbeff0071b9bb8d70c13f8600df94e25ce09204f
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2952
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/import.go b/cmd/cue/cmd/import.go
index adb58c2..4a601f8 100644
--- a/cmd/cue/cmd/import.go
+++ b/cmd/cue/cmd/import.go
@@ -666,7 +666,7 @@
ast.Walk(expr, func(n ast.Node) bool {
switch n.(type) {
- case *ast.ComprehensionDecl:
+ case *ast.Comprehension:
return false
}
return true
diff --git a/cmd/cue/cmd/trim.go b/cmd/cue/cmd/trim.go
index 0e13c26..081ac71 100644
--- a/cmd/cue/cmd/trim.go
+++ b/cmd/cue/cmd/trim.go
@@ -218,7 +218,7 @@
t.markAlwaysGen(x.Value, false)
}
- case *ast.ListComprehension, *ast.ComprehensionDecl:
+ case *ast.ListComprehension, *ast.Comprehension:
t.markAlwaysGen(x, true)
}
})
diff --git a/cue/ast.go b/cue/ast.go
index b8163ee..17605d2 100644
--- a/cue/ast.go
+++ b/cue/ast.go
@@ -262,7 +262,7 @@
case *ast.Field, *ast.Alias:
v1.walk(e)
- case *ast.ComprehensionDecl:
+ case *ast.Comprehension:
v1.walk(x)
}
}
@@ -303,17 +303,21 @@
case *ast.Ellipsis:
return v.errf(n, "ellipsis (...) only allowed at end of list or struct")
- case *ast.ComprehensionDecl:
+ case *ast.Comprehension:
+ st, ok := n.Value.(*ast.StructLit)
+ if !ok || len(st.Elts) != 1 {
+ return v.errf(n, "invalid comprehension: %v", n)
+ }
+ field := st.Elts[0].(*ast.Field)
yielder := &yield{
- baseValue: newExpr(n.Field.Value),
- opt: n.Field.Optional != token.NoPos,
- def: n.Field.Token == token.ISA,
+ baseValue: newExpr(n.Value),
+ opt: field.Optional != token.NoPos,
+ def: field.Token == token.ISA,
}
fc := &fieldComprehension{
baseValue: newDecl(n),
clauses: wrapClauses(v, yielder, n.Clauses),
}
- field := n.Field
switch x := field.Label.(type) {
case *ast.Interpolation:
v.sel = "?"
diff --git a/cue/ast/ast.go b/cue/ast/ast.go
index deb5915..e558b79 100644
--- a/cue/ast/ast.go
+++ b/cue/ast/ast.go
@@ -63,7 +63,7 @@
func (*ListLit) exprNode() {}
func (*Ellipsis) exprNode() {}
-// func (*StructComprehension) exprNode() {}
+// func (*Comprehension) exprNode() {}
func (*ListComprehension) exprNode() {}
func (*ParenExpr) exprNode() {}
func (*SelectorExpr) exprNode() {}
@@ -80,13 +80,13 @@
declNode()
}
-func (*Field) declNode() {}
-func (*ComprehensionDecl) declNode() {}
-func (*ImportDecl) declNode() {}
-func (*BadDecl) declNode() {}
-func (*EmbedDecl) declNode() {}
-func (*Alias) declNode() {}
-func (*Ellipsis) declNode() {}
+func (*Field) declNode() {}
+func (*Comprehension) declNode() {}
+func (*ImportDecl) declNode() {}
+func (*BadDecl) declNode() {}
+func (*EmbedDecl) declNode() {}
+func (*Alias) declNode() {}
+func (*Ellipsis) declNode() {}
// Not technically declarations, but appearing at the same level.
func (*Package) declNode() {}
@@ -317,20 +317,16 @@
func (a *Alias) Pos() token.Pos { return a.Ident.Pos() }
func (a *Alias) End() token.Pos { return a.Expr.End() }
-// A ComprehensionDecl node represents a field comprehension.
-type ComprehensionDecl struct {
+// A Comprehension node represents a comprehension declaration.
+type Comprehension struct {
comments
- Field *Field
- Select token.Pos
- Clauses []Clause
+ Clauses []Clause // There must be at least one clause.
+ Value Expr // Must be a struct
}
-func (x *ComprehensionDecl) Pos() token.Pos { return x.Field.Pos() }
-func (x *ComprehensionDecl) End() token.Pos {
- if len(x.Clauses) > 0 {
- return x.Clauses[len(x.Clauses)-1].End()
- }
- return x.Select
+func (x *Comprehension) Pos() token.Pos { return x.Clauses[0].Pos() }
+func (x *Comprehension) End() token.Pos {
+ return x.Value.End()
}
// ----------------------------------------------------------------------------
diff --git a/cue/ast/walk.go b/cue/ast/walk.go
index 8fb1ee9..6e66754 100644
--- a/cue/ast/walk.go
+++ b/cue/ast/walk.go
@@ -169,11 +169,11 @@
walk(v, n.Ident)
walk(v, n.Expr)
- case *ComprehensionDecl:
- walk(v, n.Field)
+ case *Comprehension:
for _, c := range n.Clauses {
walk(v, c)
}
+ walk(v, n.Value)
// Files and packages
case *File:
diff --git a/cue/export.go b/cue/export.go
index 8cd1518..1a72d4c 100644
--- a/cue/export.go
+++ b/cue/export.go
@@ -678,7 +678,12 @@
}
var decl ast.Decl = f
if len(clauses) > 0 {
- decl = &ast.ComprehensionDecl{Field: f, Clauses: clauses}
+ decl = &ast.Comprehension{
+ Clauses: clauses,
+ Value: &ast.StructLit{
+ Elts: []ast.Decl{f},
+ },
+ }
}
obj.Elts = append(obj.Elts, decl)
break
diff --git a/cue/format/node.go b/cue/format/node.go
index e2bf474..70f08fd 100644
--- a/cue/format/node.go
+++ b/cue/format/node.go
@@ -223,11 +223,16 @@
f.print(formfeed)
}
- case *ast.ComprehensionDecl:
- f.decl(n.Field)
+ case *ast.Comprehension:
+ st, ok := n.Value.(*ast.StructLit)
+ if !ok || len(st.Elts) != 1 {
+ f.print(n.Value, "*bad decl*", declcomma)
+ }
+ field := st.Elts[0]
+ f.decl(field)
f.print(blank)
- if n.Select != token.NoPos {
- f.print(n.Select, token.ARROW, blank)
+ if n.Clauses[0].Pos().RelPos() >= token.Newline {
+ f.print(token.ARROW, blank)
}
f.print(indent)
f.walkClauseList(n.Clauses)
diff --git a/cue/parser/parser.go b/cue/parser/parser.go
index 31eb2e5..7a6b9ef 100644
--- a/cue/parser/parser.go
+++ b/cue/parser/parser.go
@@ -767,10 +767,9 @@
p.closeList()
decl = this
- var arrow token.Pos
switch p.tok {
case token.ARROW:
- arrow = p.expect(token.ARROW)
+ p.expect(token.ARROW)
fallthrough
case token.FOR, token.IF:
@@ -778,10 +777,11 @@
p.errf(p.pos, "comprehension not allowed for this field")
}
clauses := p.parseComprehensionClauses()
- return &ast.ComprehensionDecl{
- Field: this,
- Select: arrow,
+ return &ast.Comprehension{
Clauses: clauses,
+ Value: &ast.StructLit{
+ Elts: []ast.Decl{this},
+ },
}
}
diff --git a/cue/parser/parser_test.go b/cue/parser/parser_test.go
index a4fd97f..38f4114 100644
--- a/cue/parser/parser_test.go
+++ b/cue/parser/parser_test.go
@@ -231,7 +231,7 @@
y: { a: 1, b: 2}
a: { "\(k)": v for k, v in y if v > 2 }
}`,
- `{y: {a: 1, b: 2}, a: {"\(k)": v for k: v in y if v>2 }}`,
+ `{y: {a: 1, b: 2}, a: {for k: v in y if v>2 {"\(k)": v}}}`,
}, {
"duplicates allowed",
`{
diff --git a/cue/parser/print.go b/cue/parser/print.go
index 7fd2dda..f72a636 100644
--- a/cue/parser/print.go
+++ b/cue/parser/print.go
@@ -82,10 +82,9 @@
}
return out
- case *ast.ComprehensionDecl:
- out := debugStr(v.Field)
- out += " "
- out += debugStr(v.Clauses)
+ case *ast.Comprehension:
+ out := debugStr(v.Clauses)
+ out += debugStr(v.Value)
return out
case *ast.StructLit:
diff --git a/cue/parser/resolve.go b/cue/parser/resolve.go
index fd17c1e..f164fd0 100644
--- a/cue/parser/resolve.go
+++ b/cue/parser/resolve.go
@@ -115,7 +115,7 @@
case *ast.StructLit:
return newScope(s.file, s, x, x.Elts)
- case *ast.ComprehensionDecl:
+ case *ast.Comprehension:
s = scopeClauses(s, x.Clauses)
case *ast.ListComprehension:
diff --git a/cue/parser/walk.go b/cue/parser/walk.go
index 58b3085..53f68c2 100644
--- a/cue/parser/walk.go
+++ b/cue/parser/walk.go
@@ -164,11 +164,11 @@
walk(v, n.Ident)
walk(v, n.Expr)
- case *ast.ComprehensionDecl:
- walk(v, n.Field)
+ case *ast.Comprehension:
for _, c := range n.Clauses {
walk(v, c)
}
+ walk(v, n.Value)
// Files and packages
case *ast.File: