From e6e3a68a392a9d54080aeb95cbc3ec6bb5d0bac0 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 27 Jul 2015 00:06:26 +0100 Subject: [PATCH] make flow transformer use internal state to track whether we're in a type or not - fixes #2083 --- src/plugins/flow.js | 27 +- .../flow/regression/issue-2083/actual.js | 11 + .../flow/regression/issue-2083/expected.json | 487 ++++++++++++++++++ .../jsx/regression/issue-2083/actual.js | 1 + .../jsx/regression/issue-2083/expected.json | 182 +++++++ 5 files changed, 694 insertions(+), 14 deletions(-) create mode 100644 test/fixtures/flow/regression/issue-2083/actual.js create mode 100644 test/fixtures/flow/regression/issue-2083/expected.json create mode 100644 test/fixtures/jsx/regression/issue-2083/actual.js create mode 100644 test/fixtures/jsx/regression/issue-2083/expected.json diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 2f1c190ae5..52df63b5c0 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -4,11 +4,11 @@ import Parser from "../parser"; var pp = Parser.prototype; pp.flowParseTypeInitialiser = function (tok) { - var oldInType = this.inType; - this.inType = true; + var oldInType = this.state.inType; + this.state.inType = true; this.expect(tok || tt.colon); var type = this.flowParseType(); - this.inType = oldInType; + this.state.inType = oldInType; return type; }; @@ -173,10 +173,10 @@ pp.flowParseTypeParameterDeclaration = function () { }; pp.flowParseTypeParameterInstantiation = function () { - var node = this.startNode(), oldInType = this.inType; + var node = this.startNode(), oldInType = this.state.inType; node.params = []; - this.inType = true; + this.state.inType = true; this.expectRelational("<"); while (!this.isRelational(">")) { @@ -187,7 +187,7 @@ pp.flowParseTypeParameterInstantiation = function () { } this.expectRelational(">"); - this.inType = oldInType; + this.state.inType = oldInType; return this.finishNode(node, "TypeParameterInstantiation"); }; @@ -551,10 +551,10 @@ pp.flowParseUnionType = function () { }; pp.flowParseType = function () { - var oldInType = this.inType; - this.inType = true; + var oldInType = this.state.inType; + this.state.inType = true; var type = this.flowParseUnionType(); - this.inType = oldInType; + this.state.inType = oldInType; return type; }; @@ -677,7 +677,7 @@ export default function (instance) { // and set startExpr instance.extend("isKeyword", function (inner) { return function (name) { - if (this.inType && name === "void") { + if (this.state.inType && name === "void") { return false; } else { return inner.call(this, name); @@ -687,7 +687,7 @@ export default function (instance) { instance.extend("readToken", function (inner) { return function (code) { - if (this.inType && (code === 62 || code === 60)) { + if (this.state.inType && (code === 62 || code === 60)) { return this.finishOp(tt.relational, 1); } else { return inner.call(this, code); @@ -697,7 +697,7 @@ export default function (instance) { instance.extend("jsx_readToken", function (inner) { return function () { - if (!this.inType) return inner.call(this); + if (!this.state.inType) return inner.call(this); }; }); @@ -888,9 +888,8 @@ export default function (instance) { // var foo = (foo): number => {}; let node = inner.call(this, startPos, startLoc, canBeArrow, isAsync); - var state = this.state.clone(); - if (this.match(tt.colon)) { + var state = this.state.clone(); try { return this.parseParenItem(node, startPos, startLoc, true); } catch (err) { diff --git a/test/fixtures/flow/regression/issue-2083/actual.js b/test/fixtures/flow/regression/issue-2083/actual.js new file mode 100644 index 0000000000..033cc11823 --- /dev/null +++ b/test/fixtures/flow/regression/issue-2083/actual.js @@ -0,0 +1,11 @@ +class Foo { + foo() { + switch (1) { + case (MatrixType.IsScaling | MatrixType.IsTranslation): + } + } + + bar() { + switch ((typeA << 4) | typeB) {} + } +} diff --git a/test/fixtures/flow/regression/issue-2083/expected.json b/test/fixtures/flow/regression/issue-2083/expected.json new file mode 100644 index 0000000000..41723449a1 --- /dev/null +++ b/test/fixtures/flow/regression/issue-2083/expected.json @@ -0,0 +1,487 @@ +{ + "type": "File", + "start": 0, + "end": 164, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 11, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 164, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 11, + "column": 1 + } + }, + "sourceType": "module", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 164, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 11, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 10, + "end": 164, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 11, + "column": 1 + } + }, + "body": [ + { + "type": "MethodDefinition", + "start": 14, + "end": 110, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 14, + "end": 17, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 5 + } + }, + "name": "foo" + }, + "static": false, + "kind": "method", + "value": { + "type": "FunctionExpression", + "start": 17, + "end": 110, + "loc": { + "start": { + "line": 2, + "column": 5 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 20, + "end": 110, + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 6, + "column": 3 + } + }, + "body": [ + { + "type": "SwitchStatement", + "start": 26, + "end": 106, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 5, + "column": 5 + } + }, + "discriminant": { + "type": "Literal", + "start": 34, + "end": 35, + "loc": { + "start": { + "line": 3, + "column": 12 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "value": 1, + "rawValue": 1, + "raw": "1" + }, + "cases": [ + { + "type": "SwitchCase", + "start": 45, + "end": 100, + "loc": { + "start": { + "line": 4, + "column": 6 + }, + "end": { + "line": 4, + "column": 61 + } + }, + "consequent": [], + "test": { + "type": "BinaryExpression", + "start": 51, + "end": 98, + "loc": { + "start": { + "line": 4, + "column": 12 + }, + "end": { + "line": 4, + "column": 59 + } + }, + "left": { + "type": "MemberExpression", + "start": 51, + "end": 71, + "loc": { + "start": { + "line": 4, + "column": 12 + }, + "end": { + "line": 4, + "column": 32 + } + }, + "object": { + "type": "Identifier", + "start": 51, + "end": 61, + "loc": { + "start": { + "line": 4, + "column": 12 + }, + "end": { + "line": 4, + "column": 22 + } + }, + "name": "MatrixType" + }, + "property": { + "type": "Identifier", + "start": 62, + "end": 71, + "loc": { + "start": { + "line": 4, + "column": 23 + }, + "end": { + "line": 4, + "column": 32 + } + }, + "name": "IsScaling" + }, + "computed": false + }, + "operator": "|", + "right": { + "type": "MemberExpression", + "start": 74, + "end": 98, + "loc": { + "start": { + "line": 4, + "column": 35 + }, + "end": { + "line": 4, + "column": 59 + } + }, + "object": { + "type": "Identifier", + "start": 74, + "end": 84, + "loc": { + "start": { + "line": 4, + "column": 35 + }, + "end": { + "line": 4, + "column": 45 + } + }, + "name": "MatrixType" + }, + "property": { + "type": "Identifier", + "start": 85, + "end": 98, + "loc": { + "start": { + "line": 4, + "column": 46 + }, + "end": { + "line": 4, + "column": 59 + } + }, + "name": "IsTranslation" + }, + "computed": false + }, + "parenthesizedExpression": true + } + } + ] + } + ] + } + } + }, + { + "type": "MethodDefinition", + "start": 114, + "end": 162, + "loc": { + "start": { + "line": 8, + "column": 2 + }, + "end": { + "line": 10, + "column": 3 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 114, + "end": 117, + "loc": { + "start": { + "line": 8, + "column": 2 + }, + "end": { + "line": 8, + "column": 5 + } + }, + "name": "bar" + }, + "static": false, + "kind": "method", + "value": { + "type": "FunctionExpression", + "start": 117, + "end": 162, + "loc": { + "start": { + "line": 8, + "column": 5 + }, + "end": { + "line": 10, + "column": 3 + } + }, + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 120, + "end": 162, + "loc": { + "start": { + "line": 8, + "column": 8 + }, + "end": { + "line": 10, + "column": 3 + } + }, + "body": [ + { + "type": "SwitchStatement", + "start": 126, + "end": 158, + "loc": { + "start": { + "line": 9, + "column": 4 + }, + "end": { + "line": 9, + "column": 36 + } + }, + "discriminant": { + "type": "BinaryExpression", + "start": 134, + "end": 154, + "loc": { + "start": { + "line": 9, + "column": 12 + }, + "end": { + "line": 9, + "column": 32 + } + }, + "left": { + "type": "BinaryExpression", + "start": 135, + "end": 145, + "loc": { + "start": { + "line": 9, + "column": 13 + }, + "end": { + "line": 9, + "column": 23 + } + }, + "left": { + "type": "Identifier", + "start": 135, + "end": 140, + "loc": { + "start": { + "line": 9, + "column": 13 + }, + "end": { + "line": 9, + "column": 18 + } + }, + "name": "typeA" + }, + "operator": "<<", + "right": { + "type": "Literal", + "start": 144, + "end": 145, + "loc": { + "start": { + "line": 9, + "column": 22 + }, + "end": { + "line": 9, + "column": 23 + } + }, + "value": 4, + "rawValue": 4, + "raw": "4" + }, + "parenthesizedExpression": true + }, + "operator": "|", + "right": { + "type": "Identifier", + "start": 149, + "end": 154, + "loc": { + "start": { + "line": 9, + "column": 27 + }, + "end": { + "line": 9, + "column": 32 + } + }, + "name": "typeB" + } + }, + "cases": [] + } + ] + } + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/fixtures/jsx/regression/issue-2083/actual.js b/test/fixtures/jsx/regression/issue-2083/actual.js new file mode 100644 index 0000000000..12e1febc3f --- /dev/null +++ b/test/fixtures/jsx/regression/issue-2083/actual.js @@ -0,0 +1 @@ +true ? (
) :
; diff --git a/test/fixtures/jsx/regression/issue-2083/expected.json b/test/fixtures/jsx/regression/issue-2083/expected.json new file mode 100644 index 0000000000..258d659c46 --- /dev/null +++ b/test/fixtures/jsx/regression/issue-2083/expected.json @@ -0,0 +1,182 @@ +{ + "type": "File", + "start": 0, + "end": 27, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 27 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 27, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 27 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 27, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 27 + } + }, + "expression": { + "type": "ConditionalExpression", + "start": 0, + "end": 26, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 26 + } + }, + "test": { + "type": "Literal", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "value": true, + "rawValue": true, + "raw": "true" + }, + "consequent": { + "type": "JSXElement", + "start": 8, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "openingElement": { + "type": "JSXOpeningElement", + "start": 8, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 9, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "name": "div" + }, + "selfClosing": true + }, + "closingElement": null, + "children": [], + "parenthesizedExpression": true + }, + "alternate": { + "type": "JSXElement", + "start": 19, + "end": 26, + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 26 + } + }, + "openingElement": { + "type": "JSXOpeningElement", + "start": 19, + "end": 26, + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 26 + } + }, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 20, + "end": 23, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 23 + } + }, + "name": "div" + }, + "selfClosing": true + }, + "closingElement": null, + "children": [] + } + } + } + ] + } +} \ No newline at end of file