cue: allow multiple comprehensions in lists
Closes #574
Change-Id: Ic80f605470f0c918f6762d9d878256c63858addd
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7727
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/format/testdata/expressions.golden b/cue/format/testdata/expressions.golden
index b7e4457..725e740 100644
--- a/cue/format/testdata/expressions.golden
+++ b/cue/format/testdata/expressions.golden
@@ -149,8 +149,16 @@
if x > 9 { x } ]
e: [
for x in someObject
- if x > 9 { x }
+ if x > 9 { x // TODO(deprecated): remove!
+ }
]
+
+ e: [
+ if x > 1 {},
+ if x > 1 {},
+ for x in src {},
+ ]
+
for k, v in someObject {
"\(k)": v
}
diff --git a/cue/format/testdata/expressions.input b/cue/format/testdata/expressions.input
index c0898ee..b72299c 100644
--- a/cue/format/testdata/expressions.input
+++ b/cue/format/testdata/expressions.input
@@ -145,10 +145,17 @@
e: [ x
for x in someObject
if x > 9 ]
- e: [ x
+ e: [ x // TODO(deprecated): remove!
for x in someObject
if x > 9
]
+
+ e: [
+ if x > 1 {},
+ if x > 1 {},
+ for x in src {},
+ ]
+
for k, v in someObject {
"\(k)": v
}
diff --git a/cue/parser/parser.go b/cue/parser/parser.go
index dbdf0f3..157b1b5 100644
--- a/cue/parser/parser.go
+++ b/cue/parser/parser.go
@@ -1213,12 +1213,6 @@
}
}
- for _, v := range list {
- if _, ok := v.(*ast.Comprehension); ok && len(list) != 1 {
- p.errf(v.Pos(), "multiple comprehensions per list not yet supported")
- }
- }
-
return
}
diff --git a/cue/testdata/comprehensions/incomplete.txtar b/cue/testdata/comprehensions/incomplete.txtar
new file mode 100644
index 0000000..1d4b4cf
--- /dev/null
+++ b/cue/testdata/comprehensions/incomplete.txtar
@@ -0,0 +1,30 @@
+-- in.cue --
+cond: bool
+src: {}
+a: [ if cond {} ]
+b: [ for x in src.foo {} ]
+-- out/eval --
+(struct){
+ cond: (bool){ bool }
+ src: (struct){
+ }
+ a: (_|_){
+ // [incomplete] a: incomplete bool value 'bool'
+ }
+ b: (_|_){
+ // [incomplete] b: undefined field foo:
+ // ./in.cue:4:19
+ }
+}
+-- out/compile --
+--- in.cue
+{
+ cond: bool
+ src: {}
+ a: [
+ if 〈0;cond〉 {},
+ ]
+ b: [
+ for _, x in 〈0;src〉.foo {},
+ ]
+}
diff --git a/cue/testdata/comprehensions/multi.txtar b/cue/testdata/comprehensions/multi.txtar
new file mode 100644
index 0000000..57b5236
--- /dev/null
+++ b/cue/testdata/comprehensions/multi.txtar
@@ -0,0 +1,101 @@
+-- in.cue --
+list: [2, 3]
+a: [ 3, for x in list { x }, for x in list { x } ]
+b: [ 3, if true { 3 }, for x in list if x > 2 { x } ]
+
+issue574: {
+ greet: true
+ bye: true
+
+ message1: [
+ if greet { "hello" },
+ "how are you doing?",
+ "bye",
+ ]
+
+ message2: [
+ if !greet { "hello" },
+ "how are you doing?",
+ if bye {
+ "bye"
+ },
+ ]
+}
+-- out/eval --
+(struct){
+ list: (#list){
+ 0: (int){ 2 }
+ 1: (int){ 3 }
+ }
+ a: (#list){
+ 0: (int){ 3 }
+ 1: (int){ 2 }
+ 2: (int){ 3 }
+ 3: (int){ 2 }
+ 4: (int){ 3 }
+ }
+ b: (#list){
+ 0: (int){ 3 }
+ 1: (int){ 3 }
+ 2: (int){ 3 }
+ }
+ issue574: (struct){
+ greet: (bool){ true }
+ bye: (bool){ true }
+ message1: (#list){
+ 0: (string){ "hello" }
+ 1: (string){ "how are you doing?" }
+ 2: (string){ "bye" }
+ }
+ message2: (#list){
+ 0: (string){ "how are you doing?" }
+ 1: (string){ "bye" }
+ }
+ }
+}
+-- out/compile --
+--- in.cue
+{
+ list: [
+ 2,
+ 3,
+ ]
+ a: [
+ 3,
+ for _, x in 〈0;list〉 {
+ 〈1;x〉
+ },
+ for _, x in 〈0;list〉 {
+ 〈1;x〉
+ },
+ ]
+ b: [
+ 3,
+ if true {
+ 3
+ },
+ for _, x in 〈0;list〉 if (〈0;x〉 > 2) {
+ 〈1;x〉
+ },
+ ]
+ issue574: {
+ greet: true
+ bye: true
+ message1: [
+ if 〈0;greet〉 {
+ "hello"
+ },
+ "how are you doing?",
+ "bye",
+ ]
+ message2: [
+ if !〈0;greet〉 {
+ "hello"
+ },
+ "how are you doing?",
+ if 〈0;bye〉 {
+ "bye"
+ },
+ ]
+ }
+}
diff --git a/internal/core/eval/eval.go b/internal/core/eval/eval.go
index ed9ccef..885a719 100644
--- a/internal/core/eval/eval.go
+++ b/internal/core/eval/eval.go
@@ -1908,7 +1908,7 @@
n.insertField(label, c)
})
hasComprehension = true
- if err != nil && !err.IsIncomplete() {
+ if err != nil {
n.addBottom(err)
}