From dab8a33f0b9581bb6b195cd00918f81dcf04b4b2 Mon Sep 17 00:00:00 2001 From: "William C. Johnson" Date: Thu, 28 Sep 2017 19:07:51 -0400 Subject: [PATCH] =?UTF-8?q?Enhanced=20comprehensions=20use=20`=E2=80=A6`?= =?UTF-8?q?=20syntax?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/comprehension.lsc | 142 +++++++++++------- src/config.lsc | 2 +- .../comprehensions/await/options.json | 2 +- .../assignment-expr/actual.js | 2 +- .../assignment-expr/exec.js | 2 +- .../enhanced-comprehensions/await/actual.js | 2 +- .../await/options.json | 2 +- .../enhanced-comprehensions/basic/actual.js | 2 +- .../closure-nested-deep/actual.js | 6 +- .../closure-nested-semantic.js | 4 - .../closure-nested/actual.js | 2 +- .../closure-nested/exec.js | 4 + .../closure-semantic.js | 4 - .../enhanced-comprehensions/closure/actual.js | 2 +- .../enhanced-comprehensions/closure/exec.js | 4 + .../declared-inner-function-semantic.js | 7 - .../declared-inner-function/actual.js | 2 +- .../declared-inner-function/exec.js | 7 + test/fixtures/enhanced-comprehensions/from.js | 2 +- .../enhanced-comprehensions/if-elif.js | 2 +- .../enhanced-comprehensions/if-else-if.js | 2 +- .../enhanced-comprehensions/if-else.js | 2 +- test/fixtures/enhanced-comprehensions/if.js | 2 +- test/fixtures/enhanced-comprehensions/in.js | 4 +- .../enhanced-comprehensions/multi/actual.js | 6 +- .../enhanced-comprehensions/multiple-for.js | 4 +- .../enhanced-comprehensions/nested/actual.js | 1 + .../{nested.js => nested/exec.js} | 2 +- .../nested/expected.js | 9 ++ .../object-basic/actual.js | 2 +- .../{object.js => object-basic/exec.js} | 2 +- .../object-declared-inner-function/actual.js | 4 +- .../expected.js | 3 +- .../enhanced-comprehensions/object-if.js | 2 +- .../object-malformed-expr-1/actual.js | 2 +- .../object-malformed-expr-1/options.json | 2 +- .../object-malformed-expr-2/actual.js | 2 +- .../object-malformed-expr-2/options.json | 2 +- .../enhanced-comprehensions/object-nested.js | 2 +- test/fixtures/enhanced-comprehensions/of.js | 4 +- .../enhanced-comprehensions/return/actual.js | 2 +- test/fixtures/enhanced-comprehensions/semi.js | 2 +- .../variable-decl/actual.js | 2 +- .../enhanced-comprehensions/yield/actual.js | 2 +- 44 files changed, 159 insertions(+), 110 deletions(-) delete mode 100644 test/fixtures/enhanced-comprehensions/closure-nested-semantic.js create mode 100644 test/fixtures/enhanced-comprehensions/closure-nested/exec.js delete mode 100644 test/fixtures/enhanced-comprehensions/closure-semantic.js create mode 100644 test/fixtures/enhanced-comprehensions/closure/exec.js delete mode 100644 test/fixtures/enhanced-comprehensions/declared-inner-function-semantic.js create mode 100644 test/fixtures/enhanced-comprehensions/declared-inner-function/exec.js create mode 100644 test/fixtures/enhanced-comprehensions/nested/actual.js rename test/fixtures/enhanced-comprehensions/{nested.js => nested/exec.js} (50%) create mode 100644 test/fixtures/enhanced-comprehensions/nested/expected.js rename test/fixtures/enhanced-comprehensions/{object.js => object-basic/exec.js} (51%) diff --git a/src/comprehension.lsc b/src/comprehension.lsc index 81a7fa7..04c6c4d 100644 --- a/src/comprehension.lsc +++ b/src/comprehension.lsc @@ -3,7 +3,7 @@ import { transformTails } from './tails' import { isa } from './is' import { toStatement } from './blocks' -import { getLoc, placeAtLoc as atLoc, placeAtNode as atNode, getSurroundingLoc, span } from 'ast-loc-utils' +import { getLoc, placeAtLoc as atLoc, placeAtNode as atNode, getSurroundingLoc, span, placeTreeAtLocWhenUnplaced as allAtLoc } from 'ast-loc-utils' validateComprehensionBody(path) -> path.traverse({ @@ -14,7 +14,7 @@ validateComprehensionBody(path) -> AwaitExpression(awaitPath) -> throw awaitPath.buildCodeFrameError( "`await` is not allowed within Comprehensions; " + - "instead, await the Comprehension (eg; `y <- [for x of xs: x]`)." + "instead, await the Comprehension." ) YieldExpression(yieldPath) -> @@ -37,32 +37,59 @@ iife(body, id, initializer) -> [] )~atLoc(loc) -retailObject(path, id, transformPathName, returnPathName) -> +isSimpleObject(objExpr) -> + objExpr.properties?.length == 1 and + (not objExpr~isa("ObjectComprehension")) and + objExpr.properties[0].type == "ObjectProperty" and + (not objExpr.properties[0].decorators?.length) + +retailObject(info, path, id, transformPathName, returnPathName) -> transformPath = path.get(transformPathName) validateComprehensionBody(transformPath) transformTails( transformPath true false - (seqExpr, tailPath) -> - if ( - seqExpr.type !== "SequenceExpression" or - seqExpr.expressions.length !== 2 - ): - throw tailPath.buildCodeFrameError("Object comprehensions must end" + - " with a (key, value) pair.") - - [ keyExpr, valExpr ] = seqExpr.expressions - - t.assignmentExpression("=", - t.memberExpression(id, keyExpr, true)~atNode(seqExpr), - valExpr - )~atNode(seqExpr) + (expr, tailPath) -> + if info.isLegacy: + if ( + expr.type !== "SequenceExpression" or + expr.expressions.length !== 2 + ): + throw tailPath.buildCodeFrameError("Object comprehensions must end" + + " with a (key, value) pair.") + + [ keyExpr, valExpr ] = expr.expressions + + return t.assignmentExpression("=", + t.memberExpression(id, keyExpr, true)~atNode(expr), + valExpr + )~atNode(expr) + + if not expr~isa("ObjectExpression"): + throw tailPath.buildCodeFrameError("Object comprehensions must end with an object expression.") + + if expr~isSimpleObject(): + // Simple object case: { [k]: v } --> obj[k] = v + { properties: [prop] } = expr + t.assignmentExpression("=", + t.memberExpression(id, prop.key, prop.computed)~atNode(expr), + prop.value + )~atNode(expr) + else: + // Complex object case: { ... } -> Object.assign(obj, { ... }) + t.callExpression( + t.memberExpression( + t.identifier("Object") + t.identifier("assign") + )~allAtLoc(expr~getLoc()) + [id, expr] + )~atNode(expr) ) path.get(returnPathName).node -retailArray(path, id, transformPathName, returnPathName) -> +retailArray(info, path, id, transformPathName, returnPathName) -> transformPath = path.get(transformPathName) validateComprehensionBody(transformPath) transformTails( @@ -74,23 +101,38 @@ retailArray(path, id, transformPathName, returnPathName) -> t.memberExpression(id, t.identifier("push")~atNode(expr))~atNode(expr) [expr] )~atNode(expr) + + // XXX: below code is for allowing ArrayExpressions in tail position + // if not expr~isa("ArrayExpression"): + // throw tailPath.buildCodeFrameError("Array comprehensions must end with an array expression.") + + // t.callExpression( + // t.memberExpression(id, t.identifier("push")~atNode(expr))~atNode(expr) + // if expr.elements?.length == 1 and (not expr~isa("ArrayComprehension")): + // // Shortcut for simple array exprs: just array.push the single entry. + // [expr.elements[0]] + // else: + // // ES6-spread the tail array onto the base array + // [t.spreadElement(expr)~atNode(expr)] + // )~atNode(expr) ) path.get(returnPathName).node -transformLoop(path, ref, isObject, stmts) -> - if isObject: - stmts.push(retailObject(path, ref, "loop.body", "loop")) +transformLoop(info, path, ref, stmts) -> + if info.isObject: + stmts.push(retailObject(info, path, ref, "loop.body", "loop")) else: - stmts.push(retailArray(path, ref, "loop.body", "loop")) + stmts.push(retailArray(info, path, ref, "loop.body", "loop")) -transformCase(path, ref, isObject, stmts) -> - if isObject: - stmts.push(retailObject(path, ref, "conditional", "conditional")) +transformCase(info, path, ref, stmts) -> + if info.isObject: + stmts.push(retailObject(info, path, ref, "conditional", "conditional")) else: - stmts.push(retailArray(path, ref, "conditional", "conditional")) + stmts.push(retailArray(info, path, ref, "conditional", "conditional")) -pushBundle(stmts, ref, bundle, isObject) -> +pushBundle(info, stmts, ref, bundle) -> + { isObject } = info if isObject: // _ref.k1 = v1; _ref.k2 = v2; ... for elem property in bundle: @@ -111,7 +153,8 @@ pushBundle(stmts, ref, bundle, isObject) -> )~atLoc(loc)~toStatement() ) -export transformComprehension(path, isObject) -> +export transformComprehension(info) -> + { path, isObject } = info { node } = path elements = if isObject: node.properties else: node.elements nodeKey = if isObject: "properties" else: "elements" @@ -119,6 +162,7 @@ export transformComprehension(path, isObject) -> id = path.scope.generateUidIdentifier(isObject ? "obj" : "arr")~t.clone()~atLoc(getLoc(node)~span(1)) let i = 0, len = elements.length, bundle = [], first = true, initializer + while i < len: element = elements[i] if element~isa("Comprehension"): @@ -126,21 +170,22 @@ export transformComprehension(path, isObject) -> now initializer = bundle now first = false else: - if bundle.length > 0: stmts~pushBundle(id, bundle, isObject) + if bundle.length > 0: pushBundle(info, stmts, id, bundle) now bundle = [] match element: | ~isa("LoopComprehension"): - path.get(`${nodeKey}.${i}`)~transformLoop(id, isObject, stmts) + info~transformLoop(path.get(`${nodeKey}.${i}`), id, stmts) | ~isa("CaseComprehension"): - path.get(`${nodeKey}.${i}`)~transformCase(id, isObject, stmts) - | else: throw new Error("Invalid comprehension node (this is an internal error)") + info~transformCase(path.get(`${nodeKey}.${i}`), id, stmts) + | else: + throw new Error("Invalid comprehension node (this is an internal error)") else: bundle.push(element) i++ - if bundle.length > 0: stmts~pushBundle(id, bundle, isObject) + if bundle.length > 0: pushBundle(info, stmts, id, bundle) initializerLoc = if initializer.length == 0: getLoc(node)~span(1) @@ -154,36 +199,31 @@ export transformComprehension(path, isObject) -> path.replaceWith(stmts~iife(id, finalInitializer)) +getComprehensionInfo(path, isObject, isLegacy) -> + { path, isObject, isLegacy } + export transformArrayComprehension(path): void -> - transformComprehension(path, false) + getComprehensionInfo(path, false, false)~transformComprehension() export transformObjectComprehension(path): void -> - transformComprehension(path, true) + getComprehensionInfo(path, true, false)~transformComprehension() -export transformPlainArrayComprehension(path): void -> - // Shim V1 onto V2 +export transformLegacyComprehension(path, isObject): void -> + // Shim legacy comprehensions onto new model { node } = path { loop } = node if loop: delete node.loop // TODO: fix babel patch so there's a builder for this... - node.elements = [ { + node[if isObject: "properties" else: "elements"] = [ { type: "LoopComprehension" loop }~atNode(node) ] path.replaceWith(node) - transformArrayComprehension(path) + getComprehensionInfo(path, isObject, true)~transformComprehension() + +export transformPlainArrayComprehension(path): void -> + transformLegacyComprehension(path, false) export transformPlainObjectComprehension(path): void -> - // Shim V1 onto V2 - { node } = path - { loop } = node - if loop: - delete node.loop - // TODO: fix babel patch so there's a builder for this... - node.properties = [ { - type: "LoopComprehension" - loop - }~atNode(node) ] - path.replaceWith(node) - transformObjectComprehension(path) + transformLegacyComprehension(path, true) diff --git a/src/config.lsc b/src/config.lsc index a624c20..eb1335f 100644 --- a/src/config.lsc +++ b/src/config.lsc @@ -94,7 +94,7 @@ export getParserOpts(pluginOpts, initialParserOpts) -> if pluginOpts?.bangCall != false: plugins.push("bangCall") if not pluginOpts?.noEnforcedSubscriptIndentation: plugins.push("enforceSubscriptIndentation") if pluginOpts?.flippedImports: plugins.push("flippedImports") - if pluginOpts?.enhancedComprehension: plugins.push("enhancedComprehension") + if pluginOpts?.enhancedComprehension: plugins.push("splatComprehension") if pluginOpts?.whiteblock: plugins.push("whiteblockOnly") if pluginOpts?.placeholderArgs: plugins.push("syntacticPlaceholder") if pluginOpts?.placeholder: diff --git a/test/fixtures/comprehensions/await/options.json b/test/fixtures/comprehensions/await/options.json index 9f42101..1a90745 100644 --- a/test/fixtures/comprehensions/await/options.json +++ b/test/fixtures/comprehensions/await/options.json @@ -1,3 +1,3 @@ { - "throws": "`await` is not allowed within Comprehensions; instead, await the Comprehension (eg; `y <- [for x of xs: x]`)." + "throws": "`await` is not allowed within Comprehensions; instead, await the Comprehension." } diff --git a/test/fixtures/enhanced-comprehensions/assignment-expr/actual.js b/test/fixtures/enhanced-comprehensions/assignment-expr/actual.js index 841dda0..ccdcb11 100644 --- a/test/fixtures/enhanced-comprehensions/assignment-expr/actual.js +++ b/test/fixtures/enhanced-comprehensions/assignment-expr/actual.js @@ -1,3 +1,3 @@ -[for idx i in Array(10): +[...for idx i in Array(10): now x = f(i) ] diff --git a/test/fixtures/enhanced-comprehensions/assignment-expr/exec.js b/test/fixtures/enhanced-comprehensions/assignment-expr/exec.js index fd938fa..59d5392 100644 --- a/test/fixtures/enhanced-comprehensions/assignment-expr/exec.js +++ b/test/fixtures/enhanced-comprehensions/assignment-expr/exec.js @@ -1,5 +1,5 @@ let x = 0 -result = [for idx i in Array(10): +result = [...for idx i in Array(10): now x = i ] assert.deepEqual(result, [0,1,2,3,4,5,6,7,8,9]) diff --git a/test/fixtures/enhanced-comprehensions/await/actual.js b/test/fixtures/enhanced-comprehensions/await/actual.js index c26ddd4..870c44a 100644 --- a/test/fixtures/enhanced-comprehensions/await/actual.js +++ b/test/fixtures/enhanced-comprehensions/await/actual.js @@ -1,4 +1,4 @@ f() -/> - <- [for now x of arr: + <- [...for now x of arr: <- x ] diff --git a/test/fixtures/enhanced-comprehensions/await/options.json b/test/fixtures/enhanced-comprehensions/await/options.json index 9f42101..1a90745 100644 --- a/test/fixtures/enhanced-comprehensions/await/options.json +++ b/test/fixtures/enhanced-comprehensions/await/options.json @@ -1,3 +1,3 @@ { - "throws": "`await` is not allowed within Comprehensions; instead, await the Comprehension (eg; `y <- [for x of xs: x]`)." + "throws": "`await` is not allowed within Comprehensions; instead, await the Comprehension." } diff --git a/test/fixtures/enhanced-comprehensions/basic/actual.js b/test/fixtures/enhanced-comprehensions/basic/actual.js index 249ca01..6bae461 100644 --- a/test/fixtures/enhanced-comprehensions/basic/actual.js +++ b/test/fixtures/enhanced-comprehensions/basic/actual.js @@ -1 +1 @@ -[for elem x in y: x] +[...for elem x in y: x] diff --git a/test/fixtures/enhanced-comprehensions/closure-nested-deep/actual.js b/test/fixtures/enhanced-comprehensions/closure-nested-deep/actual.js index d47e125..d0313df 100644 --- a/test/fixtures/enhanced-comprehensions/closure-nested-deep/actual.js +++ b/test/fixtures/enhanced-comprehensions/closure-nested-deep/actual.js @@ -1,9 +1,9 @@ -[for idx i in Array(10): +[...for idx i in Array(10): for idx j in a: if i < 5: f() -> - {for idx k in Array(10): + {...for idx k in Array(10): if k > 7: - (k, g() -> function h() { [i,j,k] }) + {[k]: g() -> function h() { [i,j,k] }} } ] diff --git a/test/fixtures/enhanced-comprehensions/closure-nested-semantic.js b/test/fixtures/enhanced-comprehensions/closure-nested-semantic.js deleted file mode 100644 index b998cde..0000000 --- a/test/fixtures/enhanced-comprehensions/closure-nested-semantic.js +++ /dev/null @@ -1,4 +0,0 @@ -closures = [ for idx i in Array(10): f() -> g() -> i ] -closureResults = [ for elem f in closures: f()() ] - -assert.deepEqual(closureResults, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) diff --git a/test/fixtures/enhanced-comprehensions/closure-nested/actual.js b/test/fixtures/enhanced-comprehensions/closure-nested/actual.js index 560c836..452805e 100644 --- a/test/fixtures/enhanced-comprehensions/closure-nested/actual.js +++ b/test/fixtures/enhanced-comprehensions/closure-nested/actual.js @@ -1 +1 @@ -[ for idx i in Array(10): f() -> g() -> i ] +[ ...for idx i in Array(10): f() -> g() -> i ] diff --git a/test/fixtures/enhanced-comprehensions/closure-nested/exec.js b/test/fixtures/enhanced-comprehensions/closure-nested/exec.js new file mode 100644 index 0000000..7d1298c --- /dev/null +++ b/test/fixtures/enhanced-comprehensions/closure-nested/exec.js @@ -0,0 +1,4 @@ +closures = [ ...for idx i in Array(10): f() -> g() -> i ] +closureResults = [ ...for elem f in closures: f()() ] + +assert.deepEqual(closureResults, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) diff --git a/test/fixtures/enhanced-comprehensions/closure-semantic.js b/test/fixtures/enhanced-comprehensions/closure-semantic.js deleted file mode 100644 index 8f54d23..0000000 --- a/test/fixtures/enhanced-comprehensions/closure-semantic.js +++ /dev/null @@ -1,4 +0,0 @@ -closures = [ for idx i in Array(10): f() -> i ] -closureResults = [ for elem f in closures: f() ] - -assert.deepEqual(closureResults, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) diff --git a/test/fixtures/enhanced-comprehensions/closure/actual.js b/test/fixtures/enhanced-comprehensions/closure/actual.js index 137eee4..49f49dd 100644 --- a/test/fixtures/enhanced-comprehensions/closure/actual.js +++ b/test/fixtures/enhanced-comprehensions/closure/actual.js @@ -1 +1 @@ -[ for idx i in Array(10): f() -> i ] +[ ...for idx i in Array(10): f() -> i ] diff --git a/test/fixtures/enhanced-comprehensions/closure/exec.js b/test/fixtures/enhanced-comprehensions/closure/exec.js new file mode 100644 index 0000000..a153b2d --- /dev/null +++ b/test/fixtures/enhanced-comprehensions/closure/exec.js @@ -0,0 +1,4 @@ +closures = [ ...for idx i in Array(10): f() -> i ] +closureResults = [ ...for elem f in closures: f() ] + +assert.deepEqual(closureResults, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) diff --git a/test/fixtures/enhanced-comprehensions/declared-inner-function-semantic.js b/test/fixtures/enhanced-comprehensions/declared-inner-function-semantic.js deleted file mode 100644 index 021ee58..0000000 --- a/test/fixtures/enhanced-comprehensions/declared-inner-function-semantic.js +++ /dev/null @@ -1,7 +0,0 @@ -closures = [for idx i in Array(3): - x = g(i) - g(x) -> x+i -] -results = [for elem f in closures: f(1)] - -assert.deepEqual(results, [1,2,3]) diff --git a/test/fixtures/enhanced-comprehensions/declared-inner-function/actual.js b/test/fixtures/enhanced-comprehensions/declared-inner-function/actual.js index 9689883..555c65c 100644 --- a/test/fixtures/enhanced-comprehensions/declared-inner-function/actual.js +++ b/test/fixtures/enhanced-comprehensions/declared-inner-function/actual.js @@ -1,4 +1,4 @@ -closures = [for idx i in Array(3): +closures = [...for idx i in Array(3): x = g(i) g(x) -> x+1 ] diff --git a/test/fixtures/enhanced-comprehensions/declared-inner-function/exec.js b/test/fixtures/enhanced-comprehensions/declared-inner-function/exec.js new file mode 100644 index 0000000..a9aff27 --- /dev/null +++ b/test/fixtures/enhanced-comprehensions/declared-inner-function/exec.js @@ -0,0 +1,7 @@ +closures = [...for idx i in Array(3): + x = g(i) + g(x) -> x+i +] +results = [...for elem f in closures: f(1)] + +assert.deepEqual(results, [1,2,3]) diff --git a/test/fixtures/enhanced-comprehensions/from.js b/test/fixtures/enhanced-comprehensions/from.js index 131da82..bc0d28d 100644 --- a/test/fixtures/enhanced-comprehensions/from.js +++ b/test/fixtures/enhanced-comprehensions/from.js @@ -1,4 +1,4 @@ arr = [4, 5, 6] -c = [ for idx i, elem x in arr: [i, x] ] +c = [ ...for idx i, elem x in arr: [i, x] ] assert.deepEqual(c, [[0, 4], [1, 5], [2, 6]]) diff --git a/test/fixtures/enhanced-comprehensions/if-elif.js b/test/fixtures/enhanced-comprehensions/if-elif.js index d9d6005..980a500 100644 --- a/test/fixtures/enhanced-comprehensions/if-elif.js +++ b/test/fixtures/enhanced-comprehensions/if-elif.js @@ -1,2 +1,2 @@ -c = [ for let i=0; i<10; i++: if i > 5: i elif i > 3: i * 2 ] +c = [ ...for let i=0; i<10; i++: if i > 5: i elif i > 3: i * 2 ] assert.deepEqual(c, [8, 10, 6, 7, 8, 9]) diff --git a/test/fixtures/enhanced-comprehensions/if-else-if.js b/test/fixtures/enhanced-comprehensions/if-else-if.js index 7ed0f10..417c71a 100644 --- a/test/fixtures/enhanced-comprehensions/if-else-if.js +++ b/test/fixtures/enhanced-comprehensions/if-else-if.js @@ -1,2 +1,2 @@ -c = [ for let i=0; i<10; i++: if i > 5: i else if i > 3: i * 2 ] +c = [ ...for let i=0; i<10; i++: if i > 5: i else if i > 3: i * 2 ] assert.deepEqual(c, [8, 10, 6, 7, 8, 9]) diff --git a/test/fixtures/enhanced-comprehensions/if-else.js b/test/fixtures/enhanced-comprehensions/if-else.js index 33a7694..c7f0b41 100644 --- a/test/fixtures/enhanced-comprehensions/if-else.js +++ b/test/fixtures/enhanced-comprehensions/if-else.js @@ -1,2 +1,2 @@ -c = [ for let i=0; i<10; i++: if i > 5: i else: 0 ] +c = [ ...for let i=0; i<10; i++: if i > 5: i else: 0 ] assert.deepEqual(c, [0, 0, 0, 0, 0, 0, 6, 7, 8, 9]) diff --git a/test/fixtures/enhanced-comprehensions/if.js b/test/fixtures/enhanced-comprehensions/if.js index e4f8fe3..582fe49 100644 --- a/test/fixtures/enhanced-comprehensions/if.js +++ b/test/fixtures/enhanced-comprehensions/if.js @@ -1,2 +1,2 @@ -c = [ for let i=0; i<10; i++: if i > 5: i ] +c = [ ...for let i=0; i<10; i++: if i > 5: i ] assert.deepEqual(c, [6, 7, 8, 9]) diff --git a/test/fixtures/enhanced-comprehensions/in.js b/test/fixtures/enhanced-comprehensions/in.js index 9017a3d..2b4526a 100644 --- a/test/fixtures/enhanced-comprehensions/in.js +++ b/test/fixtures/enhanced-comprehensions/in.js @@ -1,7 +1,7 @@ arr = [4, 5, 6] -x = [ for const i in arr: parseInt(i) ] +x = [ ...for const i in arr: parseInt(i) ] assert.deepEqual(x, [0, 1, 2]) -y = [ for const i in arr: parseInt(i) + 1 ] +y = [ ...for const i in arr: parseInt(i) + 1 ] assert.deepEqual(y, [1, 2, 3]) diff --git a/test/fixtures/enhanced-comprehensions/multi/actual.js b/test/fixtures/enhanced-comprehensions/multi/actual.js index 6122b38..0f2f20f 100644 --- a/test/fixtures/enhanced-comprehensions/multi/actual.js +++ b/test/fixtures/enhanced-comprehensions/multi/actual.js @@ -1,10 +1,10 @@ [ 1 2 - for elem e in ["buckle", "my", "shoe"]: e - case true: 3 + ...for elem e in ["buckle", "my", "shoe"]: e + ...if true: 3 4 - for elem e in ["shut", "the", "door"]: e + ...for elem e in ["shut", "the", "door"]: e 5 6 "pickup sticks" diff --git a/test/fixtures/enhanced-comprehensions/multiple-for.js b/test/fixtures/enhanced-comprehensions/multiple-for.js index 076ab16..5d5e859 100644 --- a/test/fixtures/enhanced-comprehensions/multiple-for.js +++ b/test/fixtures/enhanced-comprehensions/multiple-for.js @@ -1,5 +1,5 @@ -c = [ for let i=0;i<3;i++: for let j=5;j<7;j++: [i, j] ] +c = [ ...for let i=0;i<3;i++: for let j=5;j<7;j++: [i, j] ] assert.deepEqual(c, [ [0, 5], [0, 6], [1, 5], [1, 6], [2, 5], [2, 6] ]) -d = [ for let i=0;i<3;i++: for let j=5;j<7;j++: if i > 1: [i, j] ] +d = [ ...for let i=0;i<3;i++: for let j=5;j<7;j++: if i > 1: [i, j] ] assert.deepEqual(d, [ [2, 5], [2, 6] ]) diff --git a/test/fixtures/enhanced-comprehensions/nested/actual.js b/test/fixtures/enhanced-comprehensions/nested/actual.js new file mode 100644 index 0000000..9424fb3 --- /dev/null +++ b/test/fixtures/enhanced-comprehensions/nested/actual.js @@ -0,0 +1 @@ +[...for elem e in x: [...for elem d in y: [d]]] diff --git a/test/fixtures/enhanced-comprehensions/nested.js b/test/fixtures/enhanced-comprehensions/nested/exec.js similarity index 50% rename from test/fixtures/enhanced-comprehensions/nested.js rename to test/fixtures/enhanced-comprehensions/nested/exec.js index cdd2f68..d4b75e4 100644 --- a/test/fixtures/enhanced-comprehensions/nested.js +++ b/test/fixtures/enhanced-comprehensions/nested/exec.js @@ -1,2 +1,2 @@ -c = [ for let i=0; i<4; i++: [ for let i=0; i<3; i++: 2 ] ] +c = [ ...for let i=0; i<4; i++: [ ...for let i=0; i<3; i++: 2 ] ] assert.deepEqual(c, [ [2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2] ]) diff --git a/test/fixtures/enhanced-comprehensions/nested/expected.js b/test/fixtures/enhanced-comprehensions/nested/expected.js new file mode 100644 index 0000000..535fd01 --- /dev/null +++ b/test/fixtures/enhanced-comprehensions/nested/expected.js @@ -0,0 +1,9 @@ +(() => { + const _arr = [];for (let _i = 0, _len = x.length; _i < _len; _i++) { + const e = x[_i];_arr.push((() => { + const _arr2 = [];for (let _i2 = 0, _len2 = y.length; _i2 < _len2; _i2++) { + const d = y[_i2];_arr2.push([d]); + }return _arr2; + })()); + }return _arr; +})(); \ No newline at end of file diff --git a/test/fixtures/enhanced-comprehensions/object-basic/actual.js b/test/fixtures/enhanced-comprehensions/object-basic/actual.js index ba794bd..15f3835 100644 --- a/test/fixtures/enhanced-comprehensions/object-basic/actual.js +++ b/test/fixtures/enhanced-comprehensions/object-basic/actual.js @@ -1 +1 @@ -{for elem x in arr: (x, f(x))} +{ ...for elem x in arr: ({[x]: f(x)}) } diff --git a/test/fixtures/enhanced-comprehensions/object.js b/test/fixtures/enhanced-comprehensions/object-basic/exec.js similarity index 51% rename from test/fixtures/enhanced-comprehensions/object.js rename to test/fixtures/enhanced-comprehensions/object-basic/exec.js index 274603a..c6d28e8 100644 --- a/test/fixtures/enhanced-comprehensions/object.js +++ b/test/fixtures/enhanced-comprehensions/object-basic/exec.js @@ -1,3 +1,3 @@ -obj = {for elem e in [1,2,3]: (e, 2*e)} +obj = {...for elem e in [1,2,3]: ({[e]: 2*e}) } assert.deepEqual(obj, { "1": 2, "2": 4, "3": 6}) diff --git a/test/fixtures/enhanced-comprehensions/object-declared-inner-function/actual.js b/test/fixtures/enhanced-comprehensions/object-declared-inner-function/actual.js index 0768ecf..73511f2 100644 --- a/test/fixtures/enhanced-comprehensions/object-declared-inner-function/actual.js +++ b/test/fixtures/enhanced-comprehensions/object-declared-inner-function/actual.js @@ -1,4 +1,4 @@ -{for idx i in Array(3): +{...for idx i in Array(3): x = g(i) - (i, g(x) -> x+1) + {[i]: g(x) -> x+1} } diff --git a/test/fixtures/enhanced-comprehensions/object-declared-inner-function/expected.js b/test/fixtures/enhanced-comprehensions/object-declared-inner-function/expected.js index 9060eff..f6b84c6 100644 --- a/test/fixtures/enhanced-comprehensions/object-declared-inner-function/expected.js +++ b/test/fixtures/enhanced-comprehensions/object-declared-inner-function/expected.js @@ -4,6 +4,5 @@ _obj[i] = function g(x) { return x + 1; }; - } - return _obj; + }return _obj; })(); \ No newline at end of file diff --git a/test/fixtures/enhanced-comprehensions/object-if.js b/test/fixtures/enhanced-comprehensions/object-if.js index e592931..ec3f073 100644 --- a/test/fixtures/enhanced-comprehensions/object-if.js +++ b/test/fixtures/enhanced-comprehensions/object-if.js @@ -1,3 +1,3 @@ -obj = {for idx i in Array(10): if i > 8: (i, i)} +obj = {...for idx i in Array(10): if i > 8: ({[i]: i}) } assert.deepEqual(obj, { "9": 9 }) diff --git a/test/fixtures/enhanced-comprehensions/object-malformed-expr-1/actual.js b/test/fixtures/enhanced-comprehensions/object-malformed-expr-1/actual.js index 61f3311..fcbd863 100644 --- a/test/fixtures/enhanced-comprehensions/object-malformed-expr-1/actual.js +++ b/test/fixtures/enhanced-comprehensions/object-malformed-expr-1/actual.js @@ -1 +1 @@ -{for elem x in arr: 1} +{...for elem x in arr: 1} diff --git a/test/fixtures/enhanced-comprehensions/object-malformed-expr-1/options.json b/test/fixtures/enhanced-comprehensions/object-malformed-expr-1/options.json index a9ba4ae..ca8109e 100644 --- a/test/fixtures/enhanced-comprehensions/object-malformed-expr-1/options.json +++ b/test/fixtures/enhanced-comprehensions/object-malformed-expr-1/options.json @@ -1,3 +1,3 @@ { - "throws": "Object comprehensions must end with a (key, value) pair." + "throws": "Object comprehensions must end with an object expression." } diff --git a/test/fixtures/enhanced-comprehensions/object-malformed-expr-2/actual.js b/test/fixtures/enhanced-comprehensions/object-malformed-expr-2/actual.js index 2bf0e9b..d00125e 100644 --- a/test/fixtures/enhanced-comprehensions/object-malformed-expr-2/actual.js +++ b/test/fixtures/enhanced-comprehensions/object-malformed-expr-2/actual.js @@ -1 +1 @@ -{for elem x in arr: a, b, c} +{...for elem x in arr: a, b, c} diff --git a/test/fixtures/enhanced-comprehensions/object-malformed-expr-2/options.json b/test/fixtures/enhanced-comprehensions/object-malformed-expr-2/options.json index a9ba4ae..ca8109e 100644 --- a/test/fixtures/enhanced-comprehensions/object-malformed-expr-2/options.json +++ b/test/fixtures/enhanced-comprehensions/object-malformed-expr-2/options.json @@ -1,3 +1,3 @@ { - "throws": "Object comprehensions must end with a (key, value) pair." + "throws": "Object comprehensions must end with an object expression." } diff --git a/test/fixtures/enhanced-comprehensions/object-nested.js b/test/fixtures/enhanced-comprehensions/object-nested.js index 7a7607f..cd21c01 100644 --- a/test/fixtures/enhanced-comprehensions/object-nested.js +++ b/test/fixtures/enhanced-comprehensions/object-nested.js @@ -1,3 +1,3 @@ -obj = { for idx i in Array(3): for idx j in Array(2): if i < 2: (`${i}*${j}`, i*j) } +obj = { ...for idx i in Array(3): for idx j in Array(2): if i < 2: ({[`${i}*${j}`]: i*j}) } assert.deepEqual(obj, {"0*0": 0, "0*1": 0, "1*0": 0, "1*1": 1}) diff --git a/test/fixtures/enhanced-comprehensions/of.js b/test/fixtures/enhanced-comprehensions/of.js index f896179..b05ba85 100644 --- a/test/fixtures/enhanced-comprehensions/of.js +++ b/test/fixtures/enhanced-comprehensions/of.js @@ -1,7 +1,7 @@ arr = [4, 5, 6] -x = [ for const x of arr: x ] +x = [ ...for const x of arr: x ] assert.deepEqual(x, [4, 5, 6]) -y = [ for const y of arr: y + 1 ] +y = [ ...for const y of arr: y + 1 ] assert.deepEqual(y, [5, 6, 7]) diff --git a/test/fixtures/enhanced-comprehensions/return/actual.js b/test/fixtures/enhanced-comprehensions/return/actual.js index 74a521d..309e6c5 100644 --- a/test/fixtures/enhanced-comprehensions/return/actual.js +++ b/test/fixtures/enhanced-comprehensions/return/actual.js @@ -1,7 +1,7 @@ arr = [4, 5, 6] f() -> - c = [ for now x of arr: + c = [...for now x of arr: if x == 4: return x ] diff --git a/test/fixtures/enhanced-comprehensions/semi.js b/test/fixtures/enhanced-comprehensions/semi.js index f398c81..7d5f050 100644 --- a/test/fixtures/enhanced-comprehensions/semi.js +++ b/test/fixtures/enhanced-comprehensions/semi.js @@ -1,4 +1,4 @@ arr = [4, 5, 6] -c = [ for let i = 0; i < arr.length; i++: [i, arr[i]] ] +c = [ ...for let i = 0; i < arr.length; i++: [i, arr[i]] ] assert.deepEqual(c, [[0, 4], [1, 5], [2, 6]]) diff --git a/test/fixtures/enhanced-comprehensions/variable-decl/actual.js b/test/fixtures/enhanced-comprehensions/variable-decl/actual.js index 8fec97f..24b5055 100644 --- a/test/fixtures/enhanced-comprehensions/variable-decl/actual.js +++ b/test/fixtures/enhanced-comprehensions/variable-decl/actual.js @@ -1,3 +1,3 @@ -[for idx i in Array(10): +[...for idx i in Array(10): x = f(i) ] diff --git a/test/fixtures/enhanced-comprehensions/yield/actual.js b/test/fixtures/enhanced-comprehensions/yield/actual.js index 0467fd4..52f69d5 100644 --- a/test/fixtures/enhanced-comprehensions/yield/actual.js +++ b/test/fixtures/enhanced-comprehensions/yield/actual.js @@ -1,4 +1,4 @@ arr = [4, 5, 6] f() -*> - c = [ for now x of arr: yield x ] + c = [...for now x of arr: yield x ]