diff --git a/src/plugins/flow.js b/src/plugins/flow.js index ef9a73a073..f74de36944 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -1049,6 +1049,18 @@ export default function (instance) { }; }); + instance.extend("parseMaybeDefault", function (inner) { + return function (...args) { + const node = inner.apply(this, args); + + if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) { + this.raise(node.typeAnnotation.start, "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`"); + } + + return node; + }; + }); + // parse typeof and type imports instance.extend("parseImportSpecifiers", function (inner) { diff --git a/test/fixtures/flow/type-annotations/105/actual.js b/test/fixtures/flow/type-annotations/105/actual.js index 457dd3366d..5e860ef08e 100644 --- a/test/fixtures/flow/type-annotations/105/actual.js +++ b/test/fixtures/flow/type-annotations/105/actual.js @@ -1 +1 @@ -function g(a:number=1, e=1:number) {} +function g(a:number=1, e:number=1) {} diff --git a/test/fixtures/flow/type-annotations/105/expected.json b/test/fixtures/flow/type-annotations/105/expected.json index 48c65c3448..a8d2cfdcfd 100644 --- a/test/fixtures/flow/type-annotations/105/expected.json +++ b/test/fixtures/flow/type-annotations/105/expected.json @@ -54,7 +54,8 @@ "end": { "line": 1, "column": 10 - } + }, + "identifierName": "g" }, "name": "g" }, @@ -88,7 +89,8 @@ "end": { "line": 1, "column": 19 - } + }, + "identifierName": "a" }, "name": "a", "typeAnnotation": { @@ -160,7 +162,7 @@ "left": { "type": "Identifier", "start": 23, - "end": 24, + "end": 31, "loc": { "start": { "line": 1, @@ -168,23 +170,54 @@ }, "end": { "line": 1, - "column": 24 - } + "column": 31 + }, + "identifierName": "e" }, - "name": "e" + "name": "e", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 24, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 25, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 25 + }, + "end": { + "line": 1, + "column": 31 + } + } + } + } }, "right": { "type": "NumericLiteral", - "start": 25, - "end": 26, + "start": 32, + "end": 33, "loc": { "start": { "line": 1, - "column": 25 + "column": 32 }, "end": { "line": 1, - "column": 26 + "column": 33 } }, "extra": { @@ -192,36 +225,6 @@ "raw": "1" }, "value": 1 - }, - "typeAnnotation": { - "type": "TypeAnnotation", - "start": 26, - "end": 33, - "loc": { - "start": { - "line": 1, - "column": 26 - }, - "end": { - "line": 1, - "column": 33 - } - }, - "typeAnnotation": { - "type": "NumberTypeAnnotation", - "start": 27, - "end": 33, - "loc": { - "start": { - "line": 1, - "column": 27 - }, - "end": { - "line": 1, - "column": 33 - } - } - } } } ], @@ -246,4 +249,4 @@ ], "directives": [] } -} +} \ No newline at end of file diff --git a/test/fixtures/flow/type-annotations/with-default-invalid/actual.js b/test/fixtures/flow/type-annotations/with-default-invalid/actual.js new file mode 100644 index 0000000000..93f01d1350 --- /dev/null +++ b/test/fixtures/flow/type-annotations/with-default-invalid/actual.js @@ -0,0 +1 @@ +function x(foo = "1": string) {} \ No newline at end of file diff --git a/test/fixtures/flow/type-annotations/with-default-invalid/options.json b/test/fixtures/flow/type-annotations/with-default-invalid/options.json new file mode 100644 index 0000000000..95ca28398b --- /dev/null +++ b/test/fixtures/flow/type-annotations/with-default-invalid/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25` (1:20)" +} \ No newline at end of file diff --git a/test/fixtures/flow/type-annotations/with-default-valid/actual.js b/test/fixtures/flow/type-annotations/with-default-valid/actual.js new file mode 100644 index 0000000000..d35b6a534c --- /dev/null +++ b/test/fixtures/flow/type-annotations/with-default-valid/actual.js @@ -0,0 +1 @@ +function x(foo: string = "1") {} diff --git a/test/fixtures/flow/type-annotations/with-default-valid/expected.json b/test/fixtures/flow/type-annotations/with-default-valid/expected.json new file mode 100644 index 0000000000..49e6fd1fae --- /dev/null +++ b/test/fixtures/flow/type-annotations/with-default-valid/expected.json @@ -0,0 +1,170 @@ +{ + "type": "File", + "start": 0, + "end": 32, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 32 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 32, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 32 + } + }, + "sourceType": "module", + "body": [ + { + "type": "FunctionDeclaration", + "start": 0, + "end": 32, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 32 + } + }, + "id": { + "type": "Identifier", + "start": 9, + "end": 10, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 10 + }, + "identifierName": "x" + }, + "name": "x" + }, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "AssignmentPattern", + "start": 11, + "end": 28, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 28 + } + }, + "left": { + "type": "Identifier", + "start": 11, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 22 + }, + "identifierName": "foo" + }, + "name": "foo", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 14, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 22 + } + }, + "typeAnnotation": { + "type": "StringTypeAnnotation", + "start": 16, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 22 + } + } + } + } + }, + "right": { + "type": "StringLiteral", + "start": 25, + "end": 28, + "loc": { + "start": { + "line": 1, + "column": 25 + }, + "end": { + "line": 1, + "column": 28 + } + }, + "extra": { + "rawValue": "1", + "raw": "\"1\"" + }, + "value": "1" + } + } + ], + "body": { + "type": "BlockStatement", + "start": 30, + "end": 32, + "loc": { + "start": { + "line": 1, + "column": 30 + }, + "end": { + "line": 1, + "column": 32 + } + }, + "body": [], + "directives": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file