From 0e5208861ab50661cb77cae958b5d473121f0a54 Mon Sep 17 00:00:00 2001 From: "William C. Johnson" Date: Mon, 9 Oct 2017 01:13:41 -0400 Subject: [PATCH] Clean up parsing re: flow typecasts Addresses https://github.com/wcjohnson/lightscript/issues/22 --- src/plugins/bangCall.js | 16 +- src/plugins/safeCallExistential.js | 1 + src/plugins/spreadLoop.js | 1 + .../actual.js | 0 .../punctuation/like-typecast/expected.json | 154 +++++++++++ .../options.json | 3 - test/fixtures/flow/typecasts/call-2/actual.js | 1 + .../flow/typecasts/call-2/expected.json | 251 ++++++++++++++++++ 8 files changed, 422 insertions(+), 5 deletions(-) rename test/fixtures/bang-call/punctuation/{paren-free-flow-typecast-unfortunate => like-typecast}/actual.js (100%) create mode 100644 test/fixtures/bang-call/punctuation/like-typecast/expected.json delete mode 100644 test/fixtures/bang-call/punctuation/paren-free-flow-typecast-unfortunate/options.json create mode 100644 test/fixtures/flow/typecasts/call-2/actual.js create mode 100644 test/fixtures/flow/typecasts/call-2/expected.json diff --git a/src/plugins/bangCall.js b/src/plugins/bangCall.js index 919b2d721e..035007f818 100644 --- a/src/plugins/bangCall.js +++ b/src/plugins/bangCall.js @@ -18,6 +18,17 @@ export default function(parser) { ); }; + // c/p parseExprListItem + pp.parseBangArg = function () { + let elt; + if (this.match(tt.ellipsis)) { + elt = this.parseSpread(); + } else { + elt = this.parseMaybeAssign(false); + } + return elt; + }; + // Parse `!` followed by an arg list. Returns truthy if further subscripting // is legal. pp.parseBangCall = function(node, nodeType) { @@ -57,7 +68,7 @@ export default function(parser) { // Comma-separated arg and first arg skip ASI/whitespace checks if (first || this.eat(tt.comma)) { - node.arguments.push(this.parseExprListItem(false)); + node.arguments.push(this.parseBangArg()); first = false; } else { // ASI: unwind if not at proper indent level @@ -70,7 +81,7 @@ export default function(parser) { } } - node.arguments.push(this.parseExprListItem(false)); + node.arguments.push(this.parseBangArg()); } if (this.isLineBreak()) { @@ -87,6 +98,7 @@ export default function(parser) { this.state.bangUnwindLevel = oldBangUnwindLevel; this.state.bangWhiteBlockLevel = oldBangWhiteBlockLevel; + this.toReferencedList(node.arguments); node = this.finishNode(node, nodeType); // Subscript only on new line. diff --git a/src/plugins/safeCallExistential.js b/src/plugins/safeCallExistential.js index 8c4ed2a2f8..0aef774a8b 100644 --- a/src/plugins/safeCallExistential.js +++ b/src/plugins/safeCallExistential.js @@ -18,6 +18,7 @@ export default function(parser) { } else { this.expect(tt.parenL); node.arguments = this.parseCallExpressionArguments(tt.parenR, false); + this.toReferencedList(node.arguments); return [this.finishNode(node, "CallExpression"), true]; } }; diff --git a/src/plugins/spreadLoop.js b/src/plugins/spreadLoop.js index a3aae9aacb..1fc5ce8305 100644 --- a/src/plugins/spreadLoop.js +++ b/src/plugins/spreadLoop.js @@ -41,6 +41,7 @@ export default function(parser) { } node.elements = elts; + this.toReferencedList(node.elements); return hasSpreadLoop; }; diff --git a/test/fixtures/bang-call/punctuation/paren-free-flow-typecast-unfortunate/actual.js b/test/fixtures/bang-call/punctuation/like-typecast/actual.js similarity index 100% rename from test/fixtures/bang-call/punctuation/paren-free-flow-typecast-unfortunate/actual.js rename to test/fixtures/bang-call/punctuation/like-typecast/actual.js diff --git a/test/fixtures/bang-call/punctuation/like-typecast/expected.json b/test/fixtures/bang-call/punctuation/like-typecast/expected.json new file mode 100644 index 0000000000..fadf7c8be6 --- /dev/null +++ b/test/fixtures/bang-call/punctuation/like-typecast/expected.json @@ -0,0 +1,154 @@ +{ + "type": "File", + "start": 0, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "sourceType": "script", + "body": [ + { + "type": "IfStatement", + "start": 0, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "test": { + "type": "CallExpression", + "start": 3, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "callee": { + "type": "Identifier", + "start": 5, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 6 + }, + "identifierName": "b" + }, + "name": "b" + }, + "arguments": [ + { + "type": "Identifier", + "start": 3, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 4 + }, + "identifierName": "a" + }, + "name": "a" + }, + { + "type": "Identifier", + "start": 8, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 9 + }, + "identifierName": "c" + }, + "name": "c" + } + ], + "extra": { + "bang": true + }, + "tilde": true + }, + "consequent": { + "type": "ExpressionStatement", + "start": 11, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "expression": { + "type": "Identifier", + "start": 11, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + }, + "identifierName": "d" + }, + "name": "d" + } + }, + "alternate": null + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/bang-call/punctuation/paren-free-flow-typecast-unfortunate/options.json b/test/fixtures/bang-call/punctuation/paren-free-flow-typecast-unfortunate/options.json deleted file mode 100644 index 6b5243adc0..0000000000 --- a/test/fixtures/bang-call/punctuation/paren-free-flow-typecast-unfortunate/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Paren-free test expressions must be followed by braces or a colon. (1:12)" -} diff --git a/test/fixtures/flow/typecasts/call-2/actual.js b/test/fixtures/flow/typecasts/call-2/actual.js new file mode 100644 index 0000000000..34114109c6 --- /dev/null +++ b/test/fixtures/flow/typecasts/call-2/actual.js @@ -0,0 +1 @@ +callee((castee: CastTo), (castee2: CastTo2)) diff --git a/test/fixtures/flow/typecasts/call-2/expected.json b/test/fixtures/flow/typecasts/call-2/expected.json new file mode 100644 index 0000000000..6ea717d84c --- /dev/null +++ b/test/fixtures/flow/typecasts/call-2/expected.json @@ -0,0 +1,251 @@ +{ + "type": "File", + "start": 0, + "end": 44, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 44 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 44, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 44 + } + }, + "sourceType": "module", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 44, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 44 + } + }, + "expression": { + "type": "CallExpression", + "start": 0, + "end": 44, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 44 + } + }, + "callee": { + "type": "Identifier", + "start": 0, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 6 + }, + "identifierName": "callee" + }, + "name": "callee" + }, + "arguments": [ + { + "type": "TypeCastExpression", + "start": 8, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 22 + } + }, + "expression": { + "type": "Identifier", + "start": 8, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 14 + }, + "identifierName": "castee" + }, + "name": "castee" + }, + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 14, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 22 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 16, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 22 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 16, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 22 + }, + "identifierName": "CastTo" + }, + "name": "CastTo" + } + } + }, + "extra": { + "parenthesized": true, + "parenStart": 7 + } + }, + { + "type": "TypeCastExpression", + "start": 26, + "end": 42, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 42 + } + }, + "expression": { + "type": "Identifier", + "start": 26, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 33 + }, + "identifierName": "castee2" + }, + "name": "castee2" + }, + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 33, + "end": 42, + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 1, + "column": 42 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 35, + "end": 42, + "loc": { + "start": { + "line": 1, + "column": 35 + }, + "end": { + "line": 1, + "column": 42 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 35, + "end": 42, + "loc": { + "start": { + "line": 1, + "column": 35 + }, + "end": { + "line": 1, + "column": 42 + }, + "identifierName": "CastTo2" + }, + "name": "CastTo2" + } + } + }, + "extra": { + "parenthesized": true, + "parenStart": 25 + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file