From 17f2a2036c1fb8442eaa5bd7b9ad3c5d270d36e0 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Wed, 19 Apr 2017 06:59:49 -0500 Subject: [PATCH 01/73] Allow namespace exotic to be exported as default (#474) --- src/parser/statement.js | 2 +- .../export-extensions/ns-default/actual.js | 1 + .../ns-default/expected.json | 103 ++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/experimental/export-extensions/ns-default/actual.js create mode 100644 test/fixtures/experimental/export-extensions/ns-default/expected.json diff --git a/src/parser/statement.js b/src/parser/statement.js index 3a1eafa407..08885a009c 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -816,7 +816,7 @@ pp.parseExport = function (node) { const specifier = this.startNode(); this.next(); if (this.hasPlugin("exportExtensions") && this.eatContextual("as")) { - specifier.exported = this.parseIdentifier(); + specifier.exported = this.parseIdentifier(true); node.specifiers = [this.finishNode(specifier, "ExportNamespaceSpecifier")]; this.parseExportSpecifiersMaybe(node); this.parseExportFrom(node, true); diff --git a/test/fixtures/experimental/export-extensions/ns-default/actual.js b/test/fixtures/experimental/export-extensions/ns-default/actual.js new file mode 100644 index 0000000000..871cd28fa8 --- /dev/null +++ b/test/fixtures/experimental/export-extensions/ns-default/actual.js @@ -0,0 +1 @@ +export * as default from "foo"; diff --git a/test/fixtures/experimental/export-extensions/ns-default/expected.json b/test/fixtures/experimental/export-extensions/ns-default/expected.json new file mode 100644 index 0000000000..38c5f40bd5 --- /dev/null +++ b/test/fixtures/experimental/export-extensions/ns-default/expected.json @@ -0,0 +1,103 @@ +{ + "type": "File", + "start": 0, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "sourceType": "module", + "body": [ + { + "type": "ExportNamedDeclaration", + "start": 0, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "specifiers": [ + { + "type": "ExportNamespaceSpecifier", + "start": 7, + "end": 19, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 19 + } + }, + "exported": { + "type": "Identifier", + "start": 12, + "end": 19, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 19 + }, + "identifierName": "default" + }, + "name": "default" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 25, + "end": 30, + "loc": { + "start": { + "line": 1, + "column": 25 + }, + "end": { + "line": 1, + "column": 30 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + } + } + ], + "directives": [] + } +} \ No newline at end of file From 2ef436641ee62d2f7f023f2425ee946b17424d78 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Wed, 19 Apr 2017 07:08:51 -0500 Subject: [PATCH 02/73] Ensure locations in ObjectTypeAnnotations do not include semi or comma (#472) --- src/plugins/flow.js | 12 ++----- .../flow/call-properties/2/expected.json | 4 +-- .../flow/call-properties/3/expected.json | 8 ++--- .../flow/call-properties/4/expected.json | 4 +-- .../flow/call-properties/5/expected.json | 4 +-- .../named-static/expected.json | 4 +-- .../flow/declare-module/5/expected.json | 4 +-- .../flow/declare-module/6/expected.json | 4 +-- .../flow/declare-statements/10/expected.json | 4 +-- .../flow/declare-statements/17/expected.json | 12 +++---- .../flow/declare-statements/7/expected.json | 4 +-- .../10/expected.json | 12 +++---- .../4/expected.json | 4 +-- .../5/expected.json | 4 +-- .../flow/type-annotations/108/expected.json | 28 ++++++++-------- .../flow/type-annotations/135/expected.json | 4 +-- .../flow/type-annotations/136/expected.json | 8 ++--- .../flow/type-annotations/33/expected.json | 4 +-- .../flow/type-annotations/34/expected.json | 4 +-- .../flow/type-annotations/36/expected.json | 4 +-- .../flow/type-annotations/39/expected.json | 4 +-- .../flow/type-annotations/40/expected.json | 4 +-- .../flow/type-annotations/43/expected.json | 4 +-- .../flow/type-annotations/60/expected.json | 4 +-- .../flow/type-annotations/63/expected.json | 4 +-- .../flow/type-annotations/98/expected.json | 12 +++---- .../expected.json | 32 +++++++++---------- .../expected.json | 16 +++++----- .../interface-reserved-word/expected.json | 16 +++++----- .../type-object-reserved-word/expected.json | 16 +++++----- test/fixtures/flow/typecasts/2/expected.json | 4 +-- 31 files changed, 123 insertions(+), 129 deletions(-) diff --git a/src/plugins/flow.js b/src/plugins/flow.js index ba54902303..15302e40dd 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -352,11 +352,7 @@ pp.flowParseObjectTypeIndexer = function (node, isStatic, variance) { node.value = this.flowParseTypeInitialiser(); node.variance = variance; - // Finish node first to not include a possible semicolon in the locations - const indexer = this.finishNode(node, "ObjectTypeIndexer"); - this.flowObjectTypeSemicolon(); - - return indexer; + return this.finishNode(node, "ObjectTypeIndexer"); }; pp.flowParseObjectTypeMethodish = function (node) { @@ -391,7 +387,6 @@ pp.flowParseObjectTypeMethod = function (startPos, startLoc, isStatic, key) { node.static = isStatic; node.key = key; node.optional = false; - this.flowObjectTypeSemicolon(); return this.finishNode(node, "ObjectTypeProperty"); }; @@ -399,7 +394,6 @@ pp.flowParseObjectTypeCallProperty = function (node, isStatic) { const valueNode = this.startNode(); node.static = isStatic; node.value = this.flowParseObjectTypeMethodish(valueNode); - this.flowObjectTypeSemicolon(); return this.finishNode(node, "ObjectTypeCallProperty"); }; @@ -462,7 +456,6 @@ pp.flowParseObjectType = function (allowStatic, allowExact, allowSpread) { } this.expect(tt.ellipsis); node.argument = this.flowParseType(); - this.flowObjectTypeSemicolon(); nodeStart.properties.push(this.finishNode(node, "ObjectTypeSpreadProperty")); } else { propertyKey = this.flowParseObjectPropertyKey(); @@ -481,12 +474,13 @@ pp.flowParseObjectType = function (allowStatic, allowExact, allowSpread) { node.optional = optional; node.static = isStatic; node.variance = variance; - this.flowObjectTypeSemicolon(); nodeStart.properties.push(this.finishNode(node, "ObjectTypeProperty")); } } } + this.flowObjectTypeSemicolon(); + isStatic = false; } diff --git a/test/fixtures/flow/call-properties/2/expected.json b/test/fixtures/flow/call-properties/2/expected.json index 2efe8bd9d6..87148b542a 100644 --- a/test/fixtures/flow/call-properties/2/expected.json +++ b/test/fixtures/flow/call-properties/2/expected.json @@ -105,7 +105,7 @@ { "type": "ObjectTypeCallProperty", "start": 10, - "end": 21, + "end": 20, "loc": { "start": { "line": 1, @@ -113,7 +113,7 @@ }, "end": { "line": 1, - "column": 21 + "column": 20 } }, "static": false, diff --git a/test/fixtures/flow/call-properties/3/expected.json b/test/fixtures/flow/call-properties/3/expected.json index e1c7645c97..d5d5d6599e 100644 --- a/test/fixtures/flow/call-properties/3/expected.json +++ b/test/fixtures/flow/call-properties/3/expected.json @@ -105,7 +105,7 @@ { "type": "ObjectTypeCallProperty", "start": 10, - "end": 21, + "end": 20, "loc": { "start": { "line": 1, @@ -113,7 +113,7 @@ }, "end": { "line": 1, - "column": 21 + "column": 20 } }, "static": false, @@ -254,7 +254,7 @@ { "type": "ObjectTypeProperty", "start": 22, - "end": 32, + "end": 31, "loc": { "start": { "line": 1, @@ -262,7 +262,7 @@ }, "end": { "line": 1, - "column": 32 + "column": 31 } }, "key": { diff --git a/test/fixtures/flow/call-properties/4/expected.json b/test/fixtures/flow/call-properties/4/expected.json index bbfa2011f1..08e9c26694 100644 --- a/test/fixtures/flow/call-properties/4/expected.json +++ b/test/fixtures/flow/call-properties/4/expected.json @@ -105,7 +105,7 @@ { "type": "ObjectTypeCallProperty", "start": 10, - "end": 28, + "end": 27, "loc": { "start": { "line": 1, @@ -113,7 +113,7 @@ }, "end": { "line": 1, - "column": 28 + "column": 27 } }, "static": false, diff --git a/test/fixtures/flow/call-properties/5/expected.json b/test/fixtures/flow/call-properties/5/expected.json index c836470490..74587ef411 100644 --- a/test/fixtures/flow/call-properties/5/expected.json +++ b/test/fixtures/flow/call-properties/5/expected.json @@ -80,7 +80,7 @@ { "type": "ObjectTypeCallProperty", "start": 14, - "end": 25, + "end": 24, "loc": { "start": { "line": 1, @@ -88,7 +88,7 @@ }, "end": { "line": 1, - "column": 25 + "column": 24 } }, "static": false, diff --git a/test/fixtures/flow/class-properties/named-static/expected.json b/test/fixtures/flow/class-properties/named-static/expected.json index e3d5623c98..61bf3d6674 100644 --- a/test/fixtures/flow/class-properties/named-static/expected.json +++ b/test/fixtures/flow/class-properties/named-static/expected.json @@ -81,7 +81,7 @@ { "type": "ObjectTypeProperty", "start": 20, - "end": 30, + "end": 29, "loc": { "start": { "line": 2, @@ -89,7 +89,7 @@ }, "end": { "line": 2, - "column": 12 + "column": 11 } }, "key": { diff --git a/test/fixtures/flow/declare-module/5/expected.json b/test/fixtures/flow/declare-module/5/expected.json index 2933f44c40..27fad53409 100644 --- a/test/fixtures/flow/declare-module/5/expected.json +++ b/test/fixtures/flow/declare-module/5/expected.json @@ -127,7 +127,7 @@ { "type": "ObjectTypeProperty", "start": 37, - "end": 51, + "end": 50, "loc": { "start": { "line": 1, @@ -135,7 +135,7 @@ }, "end": { "line": 1, - "column": 51 + "column": 50 } }, "value": { diff --git a/test/fixtures/flow/declare-module/6/expected.json b/test/fixtures/flow/declare-module/6/expected.json index cd42bf7057..8024e7d3d1 100644 --- a/test/fixtures/flow/declare-module/6/expected.json +++ b/test/fixtures/flow/declare-module/6/expected.json @@ -121,7 +121,7 @@ { "type": "ObjectTypeProperty", "start": 45, - "end": 59, + "end": 58, "loc": { "start": { "line": 1, @@ -129,7 +129,7 @@ }, "end": { "line": 1, - "column": 59 + "column": 58 } }, "value": { diff --git a/test/fixtures/flow/declare-statements/10/expected.json b/test/fixtures/flow/declare-statements/10/expected.json index a047f9c004..2e0049fb41 100644 --- a/test/fixtures/flow/declare-statements/10/expected.json +++ b/test/fixtures/flow/declare-statements/10/expected.json @@ -81,7 +81,7 @@ { "type": "ObjectTypeProperty", "start": 18, - "end": 39, + "end": 38, "loc": { "start": { "line": 1, @@ -89,7 +89,7 @@ }, "end": { "line": 1, - "column": 39 + "column": 38 } }, "value": { diff --git a/test/fixtures/flow/declare-statements/17/expected.json b/test/fixtures/flow/declare-statements/17/expected.json index 292b96e24c..381229ee19 100644 --- a/test/fixtures/flow/declare-statements/17/expected.json +++ b/test/fixtures/flow/declare-statements/17/expected.json @@ -81,7 +81,7 @@ { "type": "ObjectTypeProperty", "start": 19, - "end": 29, + "end": 28, "loc": { "start": { "line": 2, @@ -89,7 +89,7 @@ }, "end": { "line": 2, - "column": 11 + "column": 10 } }, "key": { @@ -131,7 +131,7 @@ { "type": "ObjectTypeProperty", "start": 31, - "end": 48, + "end": 47, "loc": { "start": { "line": 3, @@ -139,7 +139,7 @@ }, "end": { "line": 3, - "column": 18 + "column": 17 } }, "key": { @@ -181,7 +181,7 @@ { "type": "ObjectTypeProperty", "start": 50, - "end": 60, + "end": 59, "loc": { "start": { "line": 4, @@ -189,7 +189,7 @@ }, "end": { "line": 4, - "column": 11 + "column": 10 } }, "key": { diff --git a/test/fixtures/flow/declare-statements/7/expected.json b/test/fixtures/flow/declare-statements/7/expected.json index 1fd92b3412..776a6a6a9e 100644 --- a/test/fixtures/flow/declare-statements/7/expected.json +++ b/test/fixtures/flow/declare-statements/7/expected.json @@ -81,7 +81,7 @@ { "type": "ObjectTypeProperty", "start": 29, - "end": 72, + "end": 71, "loc": { "start": { "line": 1, @@ -89,7 +89,7 @@ }, "end": { "line": 1, - "column": 72 + "column": 71 } }, "value": { diff --git a/test/fixtures/flow/interfaces-module-and-script/10/expected.json b/test/fixtures/flow/interfaces-module-and-script/10/expected.json index ea68f99b99..4c7e6d03c9 100644 --- a/test/fixtures/flow/interfaces-module-and-script/10/expected.json +++ b/test/fixtures/flow/interfaces-module-and-script/10/expected.json @@ -80,7 +80,7 @@ { "type": "ObjectTypeCallProperty", "start": 33, - "end": 49, + "end": 48, "loc": { "start": { "line": 3, @@ -88,7 +88,7 @@ }, "end": { "line": 3, - "column": 18 + "column": 17 } }, "static": true, @@ -131,7 +131,7 @@ { "type": "ObjectTypeProperty", "start": 19, - "end": 30, + "end": 29, "loc": { "start": { "line": 2, @@ -139,7 +139,7 @@ }, "end": { "line": 2, - "column": 13 + "column": 12 } }, "key": { @@ -181,7 +181,7 @@ { "type": "ObjectTypeProperty", "start": 52, - "end": 70, + "end": 69, "loc": { "start": { "line": 4, @@ -189,7 +189,7 @@ }, "end": { "line": 4, - "column": 20 + "column": 19 } }, "key": { diff --git a/test/fixtures/flow/interfaces-module-and-script/4/expected.json b/test/fixtures/flow/interfaces-module-and-script/4/expected.json index b6b9f6d2c7..1099bd54e8 100644 --- a/test/fixtures/flow/interfaces-module-and-script/4/expected.json +++ b/test/fixtures/flow/interfaces-module-and-script/4/expected.json @@ -81,7 +81,7 @@ { "type": "ObjectTypeProperty", "start": 14, - "end": 32, + "end": 31, "loc": { "start": { "line": 1, @@ -89,7 +89,7 @@ }, "end": { "line": 1, - "column": 32 + "column": 31 } }, "key": { diff --git a/test/fixtures/flow/interfaces-module-and-script/5/expected.json b/test/fixtures/flow/interfaces-module-and-script/5/expected.json index 58cbc95f06..042154f2d0 100644 --- a/test/fixtures/flow/interfaces-module-and-script/5/expected.json +++ b/test/fixtures/flow/interfaces-module-and-script/5/expected.json @@ -81,7 +81,7 @@ { "type": "ObjectTypeProperty", "start": 48, - "end": 63, + "end": 62, "loc": { "start": { "line": 1, @@ -89,7 +89,7 @@ }, "end": { "line": 1, - "column": 63 + "column": 62 } }, "key": { diff --git a/test/fixtures/flow/type-annotations/108/expected.json b/test/fixtures/flow/type-annotations/108/expected.json index ae2c71d275..cc7cae44e2 100644 --- a/test/fixtures/flow/type-annotations/108/expected.json +++ b/test/fixtures/flow/type-annotations/108/expected.json @@ -106,7 +106,7 @@ { "type": "ObjectTypeProperty", "start": 11, - "end": 21, + "end": 20, "loc": { "start": { "line": 1, @@ -114,7 +114,7 @@ }, "end": { "line": 1, - "column": 21 + "column": 20 } }, "key": { @@ -418,7 +418,7 @@ { "type": "ObjectTypeProperty", "start": 68, - "end": 78, + "end": 77, "loc": { "start": { "line": 2, @@ -426,7 +426,7 @@ }, "end": { "line": 2, - "column": 21 + "column": 20 } }, "key": { @@ -468,7 +468,7 @@ { "type": "ObjectTypeProperty", "start": 79, - "end": 89, + "end": 88, "loc": { "start": { "line": 2, @@ -476,7 +476,7 @@ }, "end": { "line": 2, - "column": 32 + "column": 31 } }, "key": { @@ -830,7 +830,7 @@ { "type": "ObjectTypeProperty", "start": 145, - "end": 175, + "end": 174, "loc": { "start": { "line": 4, @@ -838,7 +838,7 @@ }, "end": { "line": 4, - "column": 40 + "column": 39 } }, "key": { @@ -877,7 +877,7 @@ { "type": "ObjectTypeProperty", "start": 151, - "end": 161, + "end": 160, "loc": { "start": { "line": 4, @@ -885,7 +885,7 @@ }, "end": { "line": 4, - "column": 26 + "column": 25 } }, "key": { @@ -1350,7 +1350,7 @@ { "type": "ObjectTypeProperty", "start": 239, - "end": 267, + "end": 266, "loc": { "start": { "line": 5, @@ -1358,7 +1358,7 @@ }, "end": { "line": 5, - "column": 39 + "column": 38 } }, "key": { @@ -1397,7 +1397,7 @@ { "type": "ObjectTypeProperty", "start": 244, - "end": 254, + "end": 253, "loc": { "start": { "line": 5, @@ -1405,7 +1405,7 @@ }, "end": { "line": 5, - "column": 26 + "column": 25 } }, "key": { diff --git a/test/fixtures/flow/type-annotations/135/expected.json b/test/fixtures/flow/type-annotations/135/expected.json index 6f973de0f6..14027b107e 100644 --- a/test/fixtures/flow/type-annotations/135/expected.json +++ b/test/fixtures/flow/type-annotations/135/expected.json @@ -79,7 +79,7 @@ { "type": "ObjectTypeSpreadProperty", "start": 12, - "end": 19, + "end": 18, "loc": { "start": { "line": 2, @@ -87,7 +87,7 @@ }, "end": { "line": 2, - "column": 8 + "column": 7 } }, "argument": { diff --git a/test/fixtures/flow/type-annotations/136/expected.json b/test/fixtures/flow/type-annotations/136/expected.json index 18d746c433..ca0bd530db 100644 --- a/test/fixtures/flow/type-annotations/136/expected.json +++ b/test/fixtures/flow/type-annotations/136/expected.json @@ -79,7 +79,7 @@ { "type": "ObjectTypeProperty", "start": 12, - "end": 18, + "end": 17, "loc": { "start": { "line": 2, @@ -87,7 +87,7 @@ }, "end": { "line": 2, - "column": 7 + "column": 6 } }, "key": { @@ -133,7 +133,7 @@ { "type": "ObjectTypeSpreadProperty", "start": 20, - "end": 26, + "end": 25, "loc": { "start": { "line": 3, @@ -141,7 +141,7 @@ }, "end": { "line": 3, - "column": 7 + "column": 6 } }, "argument": { diff --git a/test/fixtures/flow/type-annotations/33/expected.json b/test/fixtures/flow/type-annotations/33/expected.json index 9c2bc6c2da..7739fea5f1 100644 --- a/test/fixtures/flow/type-annotations/33/expected.json +++ b/test/fixtures/flow/type-annotations/33/expected.json @@ -106,7 +106,7 @@ { "type": "ObjectTypeProperty", "start": 8, - "end": 23, + "end": 22, "loc": { "start": { "line": 1, @@ -114,7 +114,7 @@ }, "end": { "line": 1, - "column": 23 + "column": 22 } }, "key": { diff --git a/test/fixtures/flow/type-annotations/34/expected.json b/test/fixtures/flow/type-annotations/34/expected.json index a9ca235616..aa0ad93518 100644 --- a/test/fixtures/flow/type-annotations/34/expected.json +++ b/test/fixtures/flow/type-annotations/34/expected.json @@ -106,7 +106,7 @@ { "type": "ObjectTypeProperty", "start": 8, - "end": 23, + "end": 22, "loc": { "start": { "line": 1, @@ -114,7 +114,7 @@ }, "end": { "line": 1, - "column": 23 + "column": 22 } }, "key": { diff --git a/test/fixtures/flow/type-annotations/36/expected.json b/test/fixtures/flow/type-annotations/36/expected.json index 4ef8af37d3..4ccc7c692f 100644 --- a/test/fixtures/flow/type-annotations/36/expected.json +++ b/test/fixtures/flow/type-annotations/36/expected.json @@ -106,7 +106,7 @@ { "type": "ObjectTypeProperty", "start": 8, - "end": 23, + "end": 22, "loc": { "start": { "line": 1, @@ -114,7 +114,7 @@ }, "end": { "line": 1, - "column": 23 + "column": 22 } }, "key": { diff --git a/test/fixtures/flow/type-annotations/39/expected.json b/test/fixtures/flow/type-annotations/39/expected.json index aeb80942b7..ba0346f3e3 100644 --- a/test/fixtures/flow/type-annotations/39/expected.json +++ b/test/fixtures/flow/type-annotations/39/expected.json @@ -106,7 +106,7 @@ { "type": "ObjectTypeProperty", "start": 8, - "end": 23, + "end": 22, "loc": { "start": { "line": 1, @@ -114,7 +114,7 @@ }, "end": { "line": 1, - "column": 23 + "column": 22 } }, "key": { diff --git a/test/fixtures/flow/type-annotations/40/expected.json b/test/fixtures/flow/type-annotations/40/expected.json index 57f986dc1b..bd5b46e71f 100644 --- a/test/fixtures/flow/type-annotations/40/expected.json +++ b/test/fixtures/flow/type-annotations/40/expected.json @@ -106,7 +106,7 @@ { "type": "ObjectTypeProperty", "start": 8, - "end": 23, + "end": 22, "loc": { "start": { "line": 1, @@ -114,7 +114,7 @@ }, "end": { "line": 1, - "column": 23 + "column": 22 } }, "key": { diff --git a/test/fixtures/flow/type-annotations/43/expected.json b/test/fixtures/flow/type-annotations/43/expected.json index f74ef8a76c..d888673773 100644 --- a/test/fixtures/flow/type-annotations/43/expected.json +++ b/test/fixtures/flow/type-annotations/43/expected.json @@ -106,7 +106,7 @@ { "type": "ObjectTypeProperty", "start": 9, - "end": 24, + "end": 23, "loc": { "start": { "line": 1, @@ -114,7 +114,7 @@ }, "end": { "line": 1, - "column": 24 + "column": 23 } }, "value": { diff --git a/test/fixtures/flow/type-annotations/60/expected.json b/test/fixtures/flow/type-annotations/60/expected.json index 41854c7041..71d0a6e5f9 100644 --- a/test/fixtures/flow/type-annotations/60/expected.json +++ b/test/fixtures/flow/type-annotations/60/expected.json @@ -161,7 +161,7 @@ { "type": "ObjectTypeProperty", "start": 10, - "end": 20, + "end": 19, "loc": { "start": { "line": 1, @@ -169,7 +169,7 @@ }, "end": { "line": 1, - "column": 20 + "column": 19 } }, "key": { diff --git a/test/fixtures/flow/type-annotations/63/expected.json b/test/fixtures/flow/type-annotations/63/expected.json index e9bbce62ed..e0bbfe124f 100644 --- a/test/fixtures/flow/type-annotations/63/expected.json +++ b/test/fixtures/flow/type-annotations/63/expected.json @@ -167,7 +167,7 @@ { "type": "ObjectTypeProperty", "start": 20, - "end": 30, + "end": 29, "loc": { "start": { "line": 1, @@ -175,7 +175,7 @@ }, "end": { "line": 1, - "column": 30 + "column": 29 } }, "key": { diff --git a/test/fixtures/flow/type-annotations/98/expected.json b/test/fixtures/flow/type-annotations/98/expected.json index 230760de3a..7100fa77f8 100644 --- a/test/fixtures/flow/type-annotations/98/expected.json +++ b/test/fixtures/flow/type-annotations/98/expected.json @@ -106,7 +106,7 @@ { "type": "ObjectTypeProperty", "start": 8, - "end": 24, + "end": 23, "loc": { "start": { "line": 1, @@ -114,7 +114,7 @@ }, "end": { "line": 1, - "column": 24 + "column": 23 } }, "key": { @@ -156,7 +156,7 @@ { "type": "ObjectTypeProperty", "start": 25, - "end": 40, + "end": 39, "loc": { "start": { "line": 1, @@ -164,7 +164,7 @@ }, "end": { "line": 1, - "column": 40 + "column": 39 } }, "key": { @@ -206,7 +206,7 @@ { "type": "ObjectTypeProperty", "start": 41, - "end": 56, + "end": 55, "loc": { "start": { "line": 1, @@ -214,7 +214,7 @@ }, "end": { "line": 1, - "column": 56 + "column": 55 } }, "key": { diff --git a/test/fixtures/flow/type-parameter-declaration/declare-class-method-reserved-word/expected.json b/test/fixtures/flow/type-parameter-declaration/declare-class-method-reserved-word/expected.json index a18b53c12e..df4896c159 100644 --- a/test/fixtures/flow/type-parameter-declaration/declare-class-method-reserved-word/expected.json +++ b/test/fixtures/flow/type-parameter-declaration/declare-class-method-reserved-word/expected.json @@ -81,7 +81,7 @@ { "type": "ObjectTypeProperty", "start": 20, - "end": 38, + "end": 37, "loc": { "start": { "line": 2, @@ -89,7 +89,7 @@ }, "end": { "line": 2, - "column": 20 + "column": 19 } }, "value": { @@ -181,7 +181,7 @@ { "type": "ObjectTypeProperty", "start": 41, - "end": 59, + "end": 58, "loc": { "start": { "line": 3, @@ -189,7 +189,7 @@ }, "end": { "line": 3, - "column": 20 + "column": 19 } }, "value": { @@ -281,7 +281,7 @@ { "type": "ObjectTypeProperty", "start": 62, - "end": 79, + "end": 78, "loc": { "start": { "line": 4, @@ -289,7 +289,7 @@ }, "end": { "line": 4, - "column": 19 + "column": 18 } }, "value": { @@ -381,7 +381,7 @@ { "type": "ObjectTypeProperty", "start": 82, - "end": 96, + "end": 95, "loc": { "start": { "line": 5, @@ -389,7 +389,7 @@ }, "end": { "line": 5, - "column": 16 + "column": 15 } }, "value": { @@ -481,7 +481,7 @@ { "type": "ObjectTypeProperty", "start": 99, - "end": 124, + "end": 123, "loc": { "start": { "line": 6, @@ -489,7 +489,7 @@ }, "end": { "line": 6, - "column": 27 + "column": 26 } }, "value": { @@ -581,7 +581,7 @@ { "type": "ObjectTypeProperty", "start": 127, - "end": 152, + "end": 151, "loc": { "start": { "line": 7, @@ -589,7 +589,7 @@ }, "end": { "line": 7, - "column": 27 + "column": 26 } }, "value": { @@ -681,7 +681,7 @@ { "type": "ObjectTypeProperty", "start": 155, - "end": 179, + "end": 178, "loc": { "start": { "line": 8, @@ -689,7 +689,7 @@ }, "end": { "line": 8, - "column": 26 + "column": 25 } }, "value": { @@ -781,7 +781,7 @@ { "type": "ObjectTypeProperty", "start": 182, - "end": 203, + "end": 202, "loc": { "start": { "line": 9, @@ -789,7 +789,7 @@ }, "end": { "line": 9, - "column": 23 + "column": 22 } }, "value": { diff --git a/test/fixtures/flow/type-parameter-declaration/declare-interface-method-reserved-word/expected.json b/test/fixtures/flow/type-parameter-declaration/declare-interface-method-reserved-word/expected.json index 834cc17454..d6ee0660f0 100644 --- a/test/fixtures/flow/type-parameter-declaration/declare-interface-method-reserved-word/expected.json +++ b/test/fixtures/flow/type-parameter-declaration/declare-interface-method-reserved-word/expected.json @@ -81,7 +81,7 @@ { "type": "ObjectTypeProperty", "start": 24, - "end": 42, + "end": 41, "loc": { "start": { "line": 2, @@ -89,7 +89,7 @@ }, "end": { "line": 2, - "column": 20 + "column": 19 } }, "value": { @@ -181,7 +181,7 @@ { "type": "ObjectTypeProperty", "start": 45, - "end": 63, + "end": 62, "loc": { "start": { "line": 3, @@ -189,7 +189,7 @@ }, "end": { "line": 3, - "column": 20 + "column": 19 } }, "value": { @@ -281,7 +281,7 @@ { "type": "ObjectTypeProperty", "start": 66, - "end": 83, + "end": 82, "loc": { "start": { "line": 4, @@ -289,7 +289,7 @@ }, "end": { "line": 4, - "column": 19 + "column": 18 } }, "value": { @@ -381,7 +381,7 @@ { "type": "ObjectTypeProperty", "start": 86, - "end": 100, + "end": 99, "loc": { "start": { "line": 5, @@ -389,7 +389,7 @@ }, "end": { "line": 5, - "column": 16 + "column": 15 } }, "value": { diff --git a/test/fixtures/flow/type-parameter-declaration/interface-reserved-word/expected.json b/test/fixtures/flow/type-parameter-declaration/interface-reserved-word/expected.json index 61ca321ecd..d14c0aa7a3 100644 --- a/test/fixtures/flow/type-parameter-declaration/interface-reserved-word/expected.json +++ b/test/fixtures/flow/type-parameter-declaration/interface-reserved-word/expected.json @@ -81,7 +81,7 @@ { "type": "ObjectTypeProperty", "start": 16, - "end": 34, + "end": 33, "loc": { "start": { "line": 2, @@ -89,7 +89,7 @@ }, "end": { "line": 2, - "column": 20 + "column": 19 } }, "value": { @@ -181,7 +181,7 @@ { "type": "ObjectTypeProperty", "start": 37, - "end": 55, + "end": 54, "loc": { "start": { "line": 3, @@ -189,7 +189,7 @@ }, "end": { "line": 3, - "column": 20 + "column": 19 } }, "value": { @@ -281,7 +281,7 @@ { "type": "ObjectTypeProperty", "start": 58, - "end": 75, + "end": 74, "loc": { "start": { "line": 4, @@ -289,7 +289,7 @@ }, "end": { "line": 4, - "column": 19 + "column": 18 } }, "value": { @@ -381,7 +381,7 @@ { "type": "ObjectTypeProperty", "start": 78, - "end": 92, + "end": 91, "loc": { "start": { "line": 5, @@ -389,7 +389,7 @@ }, "end": { "line": 5, - "column": 16 + "column": 15 } }, "value": { diff --git a/test/fixtures/flow/type-parameter-declaration/type-object-reserved-word/expected.json b/test/fixtures/flow/type-parameter-declaration/type-object-reserved-word/expected.json index 3f2bac500b..c3bb865167 100644 --- a/test/fixtures/flow/type-parameter-declaration/type-object-reserved-word/expected.json +++ b/test/fixtures/flow/type-parameter-declaration/type-object-reserved-word/expected.json @@ -79,7 +79,7 @@ { "type": "ObjectTypeProperty", "start": 13, - "end": 31, + "end": 30, "loc": { "start": { "line": 2, @@ -87,7 +87,7 @@ }, "end": { "line": 2, - "column": 20 + "column": 19 } }, "value": { @@ -179,7 +179,7 @@ { "type": "ObjectTypeProperty", "start": 34, - "end": 52, + "end": 51, "loc": { "start": { "line": 3, @@ -187,7 +187,7 @@ }, "end": { "line": 3, - "column": 20 + "column": 19 } }, "value": { @@ -279,7 +279,7 @@ { "type": "ObjectTypeProperty", "start": 55, - "end": 72, + "end": 71, "loc": { "start": { "line": 4, @@ -287,7 +287,7 @@ }, "end": { "line": 4, - "column": 19 + "column": 18 } }, "value": { @@ -379,7 +379,7 @@ { "type": "ObjectTypeProperty", "start": 75, - "end": 89, + "end": 88, "loc": { "start": { "line": 5, @@ -387,7 +387,7 @@ }, "end": { "line": 5, - "column": 16 + "column": 15 } }, "value": { diff --git a/test/fixtures/flow/typecasts/2/expected.json b/test/fixtures/flow/typecasts/2/expected.json index 5e58fe24de..e9f527ccb8 100644 --- a/test/fixtures/flow/typecasts/2/expected.json +++ b/test/fixtures/flow/typecasts/2/expected.json @@ -216,7 +216,7 @@ { "type": "ObjectTypeProperty", "start": 24, - "end": 36, + "end": 35, "loc": { "start": { "line": 1, @@ -224,7 +224,7 @@ }, "end": { "line": 1, - "column": 36 + "column": 35 } }, "key": { From a4ca1cc645e02fb0d2965a63391e99fb7f2979d7 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 20 Apr 2017 16:40:55 +0100 Subject: [PATCH 03/73] Cherry-pick #418 to 6.x (#476) * Add support for flow type spread (#418) * Add support for flow type spread * Broaden spreadable types from primary to all, more tests * Eliminate variance sigil for type spreads, better errors, fix tests # Conflicts: # src/plugins/flow.js * Fix tests --- src/plugins/flow.js | 56 ++-- .../flow/type-annotations/112/options.json | 2 +- .../flow/type-annotations/113/options.json | 2 +- .../flow/type-annotations/125/options.json | 2 +- .../flow/type-annotations/135/actual.js | 3 + .../flow/type-annotations/135/expected.json | 117 ++++++++ .../flow/type-annotations/136/actual.js | 4 + .../flow/type-annotations/136/expected.json | 175 +++++++++++ .../flow/type-annotations/137/actual.js | 3 + .../flow/type-annotations/137/options.json | 3 + .../flow/type-annotations/138/actual.js | 5 + .../flow/type-annotations/138/expected.json | 283 ++++++++++++++++++ .../flow/type-annotations/139/actual.js | 4 + .../flow/type-annotations/139/options.json | 3 + 14 files changed, 639 insertions(+), 23 deletions(-) create mode 100644 test/fixtures/flow/type-annotations/135/actual.js create mode 100644 test/fixtures/flow/type-annotations/135/expected.json create mode 100644 test/fixtures/flow/type-annotations/136/actual.js create mode 100644 test/fixtures/flow/type-annotations/136/expected.json create mode 100644 test/fixtures/flow/type-annotations/137/actual.js create mode 100644 test/fixtures/flow/type-annotations/137/options.json create mode 100644 test/fixtures/flow/type-annotations/138/actual.js create mode 100644 test/fixtures/flow/type-annotations/138/expected.json create mode 100644 test/fixtures/flow/type-annotations/139/actual.js create mode 100644 test/fixtures/flow/type-annotations/139/options.json diff --git a/src/plugins/flow.js b/src/plugins/flow.js index d30545b113..ab6003aa2a 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -194,7 +194,7 @@ pp.flowParseDeclareInterface = function (node) { // Interfaces -pp.flowParseInterfaceish = function (node, allowStatic) { +pp.flowParseInterfaceish = function (node) { node.id = this.parseIdentifier(); if (this.isRelational("<")) { @@ -219,7 +219,7 @@ pp.flowParseInterfaceish = function (node, allowStatic) { } while (this.eat(tt.comma)); } - node.body = this.flowParseObjectType(allowStatic); + node.body = this.flowParseObjectType(true, false, false); }; pp.flowParseInterfaceExtends = function () { @@ -400,7 +400,7 @@ pp.flowParseObjectTypeCallProperty = function (node, isStatic) { return this.finishNode(node, "ObjectTypeCallProperty"); }; -pp.flowParseObjectType = function (allowStatic, allowExact) { +pp.flowParseObjectType = function (allowStatic, allowExact, allowSpread) { const oldInType = this.state.inType; this.state.inType = true; @@ -448,24 +448,40 @@ pp.flowParseObjectType = function (allowStatic, allowExact) { } nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic)); } else { - propertyKey = this.flowParseObjectPropertyKey(); - if (this.isRelational("<") || this.match(tt.parenL)) { - // This is a method property + if (this.match(tt.ellipsis)) { + if (!allowSpread) { + this.unexpected( + null, + "Spread operator cannnot appear in class or interface definitions" + ); + } if (variance) { - this.unexpected(variancePos); + this.unexpected(variance.start, "Spread properties cannot have variance"); } - nodeStart.properties.push(this.flowParseObjectTypeMethod(startPos, startLoc, isStatic, propertyKey)); - } else { - if (this.eat(tt.question)) { - optional = true; - } - node.key = propertyKey; - node.value = this.flowParseTypeInitialiser(); - node.optional = optional; - node.static = isStatic; - node.variance = variance; + this.expect(tt.ellipsis); + node.argument = this.flowParseType(); this.flowObjectTypeSemicolon(); - nodeStart.properties.push(this.finishNode(node, "ObjectTypeProperty")); + nodeStart.properties.push(this.finishNode(node, "ObjectTypeSpreadProperty")); + } else { + propertyKey = this.flowParseObjectPropertyKey(); + if (this.isRelational("<") || this.match(tt.parenL)) { + // This is a method property + if (variance) { + this.unexpected(variance.start); + } + nodeStart.properties.push(this.flowParseObjectTypeMethod(startPos, startLoc, isStatic, propertyKey)); + } else { + if (this.eat(tt.question)) { + optional = true; + } + node.key = propertyKey; + node.value = this.flowParseTypeInitialiser(); + node.optional = optional; + node.static = isStatic; + node.variance = variance; + this.flowObjectTypeSemicolon(); + nodeStart.properties.push(this.finishNode(node, "ObjectTypeProperty")); + } } } @@ -627,10 +643,10 @@ pp.flowParsePrimaryType = function () { return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier()); case tt.braceL: - return this.flowParseObjectType(false, false); + return this.flowParseObjectType(false, false, true); case tt.braceBarL: - return this.flowParseObjectType(false, true); + return this.flowParseObjectType(false, true, true); case tt.bracketL: return this.flowParseTupleType(); diff --git a/test/fixtures/flow/type-annotations/112/options.json b/test/fixtures/flow/type-annotations/112/options.json index 89bfc2d73f..9e093bfdcd 100644 --- a/test/fixtures/flow/type-annotations/112/options.json +++ b/test/fixtures/flow/type-annotations/112/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected token (1:10)" + "throws": "Unexpected token (1:12)" } diff --git a/test/fixtures/flow/type-annotations/113/options.json b/test/fixtures/flow/type-annotations/113/options.json index 89bfc2d73f..9e093bfdcd 100644 --- a/test/fixtures/flow/type-annotations/113/options.json +++ b/test/fixtures/flow/type-annotations/113/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected token (1:10)" + "throws": "Unexpected token (1:12)" } diff --git a/test/fixtures/flow/type-annotations/125/options.json b/test/fixtures/flow/type-annotations/125/options.json index 2e4647b080..6079f138a6 100644 --- a/test/fixtures/flow/type-annotations/125/options.json +++ b/test/fixtures/flow/type-annotations/125/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected token (1:26)" + "throws": "Unexpected token (1:29)" } diff --git a/test/fixtures/flow/type-annotations/135/actual.js b/test/fixtures/flow/type-annotations/135/actual.js new file mode 100644 index 0000000000..b79dc870ee --- /dev/null +++ b/test/fixtures/flow/type-annotations/135/actual.js @@ -0,0 +1,3 @@ +type A = { + ...any, +}; diff --git a/test/fixtures/flow/type-annotations/135/expected.json b/test/fixtures/flow/type-annotations/135/expected.json new file mode 100644 index 0000000000..6f973de0f6 --- /dev/null +++ b/test/fixtures/flow/type-annotations/135/expected.json @@ -0,0 +1,117 @@ +{ + "type": "File", + "start": 0, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 2 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 2 + } + }, + "sourceType": "module", + "body": [ + { + "type": "TypeAlias", + "start": 0, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 2 + } + }, + "id": { + "type": "Identifier", + "start": 5, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 6 + }, + "identifierName": "A" + }, + "name": "A" + }, + "typeParameters": null, + "right": { + "type": "ObjectTypeAnnotation", + "start": 9, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "callProperties": [], + "properties": [ + { + "type": "ObjectTypeSpreadProperty", + "start": 12, + "end": 19, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 8 + } + }, + "argument": { + "type": "AnyTypeAnnotation", + "start": 15, + "end": 18, + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 7 + } + } + } + } + ], + "indexers": [], + "exact": false + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/type-annotations/136/actual.js b/test/fixtures/flow/type-annotations/136/actual.js new file mode 100644 index 0000000000..09c0a04398 --- /dev/null +++ b/test/fixtures/flow/type-annotations/136/actual.js @@ -0,0 +1,4 @@ +type A = { + p: {}, + ...{}, +}; diff --git a/test/fixtures/flow/type-annotations/136/expected.json b/test/fixtures/flow/type-annotations/136/expected.json new file mode 100644 index 0000000000..18d746c433 --- /dev/null +++ b/test/fixtures/flow/type-annotations/136/expected.json @@ -0,0 +1,175 @@ +{ + "type": "File", + "start": 0, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 4, + "column": 2 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 4, + "column": 2 + } + }, + "sourceType": "module", + "body": [ + { + "type": "TypeAlias", + "start": 0, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 4, + "column": 2 + } + }, + "id": { + "type": "Identifier", + "start": 5, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 6 + }, + "identifierName": "A" + }, + "name": "A" + }, + "typeParameters": null, + "right": { + "type": "ObjectTypeAnnotation", + "start": 9, + "end": 28, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 4, + "column": 1 + } + }, + "callProperties": [], + "properties": [ + { + "type": "ObjectTypeProperty", + "start": 12, + "end": 18, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 7 + } + }, + "key": { + "type": "Identifier", + "start": 12, + "end": 13, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 2 + }, + "identifierName": "p" + }, + "name": "p" + }, + "value": { + "type": "ObjectTypeAnnotation", + "start": 15, + "end": 17, + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 6 + } + }, + "callProperties": [], + "properties": [], + "indexers": [], + "exact": false + }, + "optional": false, + "static": false, + "variance": null + }, + { + "type": "ObjectTypeSpreadProperty", + "start": 20, + "end": 26, + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 3, + "column": 7 + } + }, + "argument": { + "type": "ObjectTypeAnnotation", + "start": 23, + "end": 25, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 6 + } + }, + "callProperties": [], + "properties": [], + "indexers": [], + "exact": false + } + } + ], + "indexers": [], + "exact": false + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/type-annotations/137/actual.js b/test/fixtures/flow/type-annotations/137/actual.js new file mode 100644 index 0000000000..b039a41ed2 --- /dev/null +++ b/test/fixtures/flow/type-annotations/137/actual.js @@ -0,0 +1,3 @@ +interface A { + ...any, +}; diff --git a/test/fixtures/flow/type-annotations/137/options.json b/test/fixtures/flow/type-annotations/137/options.json new file mode 100644 index 0000000000..79756f8c33 --- /dev/null +++ b/test/fixtures/flow/type-annotations/137/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Spread operator cannnot appear in class or interface definitions (2:1)" +} diff --git a/test/fixtures/flow/type-annotations/138/actual.js b/test/fixtures/flow/type-annotations/138/actual.js new file mode 100644 index 0000000000..9a607c669f --- /dev/null +++ b/test/fixtures/flow/type-annotations/138/actual.js @@ -0,0 +1,5 @@ +class A {} +class B {} +type C = { + ...A&B +}; diff --git a/test/fixtures/flow/type-annotations/138/expected.json b/test/fixtures/flow/type-annotations/138/expected.json new file mode 100644 index 0000000000..3aabc9dfd3 --- /dev/null +++ b/test/fixtures/flow/type-annotations/138/expected.json @@ -0,0 +1,283 @@ +{ + "type": "File", + "start": 0, + "end": 43, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 2 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 43, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 2 + } + }, + "sourceType": "module", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 10, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 10 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + }, + "identifierName": "A" + }, + "name": "A" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 8, + "end": 10, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 10 + } + }, + "body": [] + } + }, + { + "type": "ClassDeclaration", + "start": 11, + "end": 21, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 10 + } + }, + "id": { + "type": "Identifier", + "start": 17, + "end": 18, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 7 + }, + "identifierName": "B" + }, + "name": "B" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 19, + "end": 21, + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 10 + } + }, + "body": [] + } + }, + { + "type": "TypeAlias", + "start": 22, + "end": 43, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 5, + "column": 2 + } + }, + "id": { + "type": "Identifier", + "start": 27, + "end": 28, + "loc": { + "start": { + "line": 3, + "column": 5 + }, + "end": { + "line": 3, + "column": 6 + }, + "identifierName": "C" + }, + "name": "C" + }, + "typeParameters": null, + "right": { + "type": "ObjectTypeAnnotation", + "start": 31, + "end": 42, + "loc": { + "start": { + "line": 3, + "column": 9 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "callProperties": [], + "properties": [ + { + "type": "ObjectTypeSpreadProperty", + "start": 34, + "end": 40, + "loc": { + "start": { + "line": 4, + "column": 1 + }, + "end": { + "line": 4, + "column": 7 + } + }, + "argument": { + "type": "IntersectionTypeAnnotation", + "start": 37, + "end": 40, + "loc": { + "start": { + "line": 4, + "column": 4 + }, + "end": { + "line": 4, + "column": 7 + } + }, + "types": [ + { + "type": "GenericTypeAnnotation", + "start": 37, + "end": 38, + "loc": { + "start": { + "line": 4, + "column": 4 + }, + "end": { + "line": 4, + "column": 5 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 37, + "end": 38, + "loc": { + "start": { + "line": 4, + "column": 4 + }, + "end": { + "line": 4, + "column": 5 + }, + "identifierName": "A" + }, + "name": "A" + } + }, + { + "type": "GenericTypeAnnotation", + "start": 39, + "end": 40, + "loc": { + "start": { + "line": 4, + "column": 6 + }, + "end": { + "line": 4, + "column": 7 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 39, + "end": 40, + "loc": { + "start": { + "line": 4, + "column": 6 + }, + "end": { + "line": 4, + "column": 7 + }, + "identifierName": "B" + }, + "name": "B" + } + } + ] + } + } + ], + "indexers": [], + "exact": false + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/type-annotations/139/actual.js b/test/fixtures/flow/type-annotations/139/actual.js new file mode 100644 index 0000000000..fbc1330612 --- /dev/null +++ b/test/fixtures/flow/type-annotations/139/actual.js @@ -0,0 +1,4 @@ +class A {} +type C = { + -...A +}; diff --git a/test/fixtures/flow/type-annotations/139/options.json b/test/fixtures/flow/type-annotations/139/options.json new file mode 100644 index 0000000000..fe5ad00277 --- /dev/null +++ b/test/fixtures/flow/type-annotations/139/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Spread properties cannot have variance (3:2)" +} From 2e17e5bc399b9615baa4017f792ab2bac41cae13 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 20 Apr 2017 16:41:23 +0100 Subject: [PATCH 04/73] 6.17.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eb5642d926..a7adfa725b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "babylon", - "version": "6.16.1", + "version": "6.17.0", "description": "A JavaScript parser", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", From a2c143299af5d259dd686ef0078d325f793a049f Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 20 Apr 2017 16:43:47 +0100 Subject: [PATCH 05/73] Add changelog --- CHANGELOG.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb482fc5c7..dda35be878 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,15 @@ _Note: Gaps between patch versions are faulty, broken or test releases._ See the [Babel Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) for the pre-6.8.0 version Changelog. +## 6.17.0 (2017-04-20) + + * Cherry-pick #418 to 6.x ([#476](https://github.com/babel/babylon/pull/476)) (Sebastian McKenzie) + * Add support for invalid escapes in tagged templates ([#274](https://github.com/babel/babylon/pull/274)) (Kevin Gibbons) + * Throw error if new.target is used outside of a function ([#402](https://github.com/babel/babylon/pull/402)) (Brian Ng) + * Fix parsing of class properties ([#351](https://github.com/babel/babylon/pull/351)) (Kevin Gibbons) + * Fix parsing yield with dynamicImport ([#383](https://github.com/babel/babylon/pull/383)) (Brian Ng) + * Ensure consistent start args for parseParenItem ([#386](https://github.com/babel/babylon/pull/386)) (Brian Ng) + ## 6.16.0 (2017-02-23) ### :rocket: New Feature @@ -172,7 +181,7 @@ Update API documentation ([#330](https://github.com/babel/babylon/pull/330)) (Ti Added keywords to package.json ([#323](https://github.com/babel/babylon/pull/323)) (Dmytro) AST spec: fix casing of `RegExpLiteral` ([#318](https://github.com/babel/babylon/pull/318)) (Mathias Bynens) - + ## 6.15.0 (2017-01-10) ### :eyeglasses: Spec Compliancy @@ -313,20 +322,20 @@ type C = { [string]: number }; ``` Parse flow nested array type annotations like `number[][]` ([#219](https://github.com/babel/babylon/pull/219)) (Bernhard Häussner) - + Supports these form now of specifying array types: ```js var a: number[][][][]; var b: string[][]; ``` - + ### :bug: Bug Fix Correctly eat semicolon at the end of `DelcareModuleExports` ([#223](https://github.com/babel/babylon/pull/223)) (Daniel Tschinder) ``` -declare module "foo" { declare module.exports: number } +declare module "foo" { declare module.exports: number } declare module "foo" { declare module.exports: number; } // also allowed now ``` @@ -414,7 +423,7 @@ Readd missin .eslinignore for IDEs (Daniel Tschinder) Error on missing expected.json fixture in CI ([#188](https://github.com/babel/babylon/pull/188)) (Moti Zilberman) Add .gitattributes and .editorconfig for LF line endings ([#179](https://github.com/babel/babylon/pull/179)) (Moti Zilberman) - + Fixes two tests that are failing after the merge of #172 ([#177](https://github.com/babel/babylon/pull/177)) (Moti Zilberman) ## v6.12.0 (2016-10-14) @@ -627,7 +636,7 @@ function something({ set = null, get = null }) {} ```js // regression with duplicate export check SyntaxError: ./typography.js: `undefined` has already been exported. Exported identifiers must be unique. (22:13) - 20 | + 20 | 21 | export const { rhythm } = typography; > 22 | export const { TypographyStyle } = typography ``` @@ -932,7 +941,7 @@ var obj = { There is also a new node type, `ForAwaitStatement`. -> [Async generators and for-await](https://github.com/tc39/proposal-async-iteration) are now a [stage 2 proposal](https://github.com/tc39/ecma262#current-proposals). +> [Async generators and for-await](https://github.com/tc39/proposal-async-iteration) are now a [stage 2 proposal](https://github.com/tc39/ecma262#current-proposals). Example: From ad284d5c36ef5b62c48bf30b24bfa7df297b02c5 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 21 Apr 2017 04:53:51 -0700 Subject: [PATCH 06/73] Convert each plugin to a function from a class to an overriding class (#459) * Convert each plugin to a function from a class to an overriding class * Handle undefined options * Fix indentation * Fix double space --- src/index.js | 40 +- src/parser/index.js | 41 +- src/plugins/estree.js | 348 +++++++-------- src/plugins/flow.js | 895 ++++++++++++++++++--------------------- src/plugins/jsx/index.js | 110 +++-- 5 files changed, 671 insertions(+), 763 deletions(-) diff --git a/src/index.js b/src/index.js index c2911f455f..a797b55f15 100755 --- a/src/index.js +++ b/src/index.js @@ -19,11 +19,11 @@ plugins.flow = flowPlugin; plugins.jsx = jsxPlugin; export function parse(input, options) { - return new Parser(options, input).parse(); + return getParser(options, input).parse(); } export function parseExpression(input, options) { - const parser = new Parser(options, input); + const parser = getParser(options, input); if (parser.options.strictMode) { parser.state.strict = true; } @@ -32,3 +32,39 @@ export function parseExpression(input, options) { export { tokTypes }; + +function getParser(options, input) { + const cls = options && options.plugins ? getParserClass(options.plugins) : Parser; + return new cls(options, input); +} + +const parserClassCache = {}; + +/** Get a Parser class with plugins applied. */ +function getParserClass(pluginsFromOptions) { + // Filter out just the plugins that have an actual mixin associated with them. + let pluginList = pluginsFromOptions.filter((p) => p === "estree" || p === "flow" || p === "jsx"); + + if (pluginList.indexOf("flow") >= 0) { + // ensure flow plugin loads last + pluginList = pluginList.filter((plugin) => plugin !== "flow"); + pluginList.push("flow"); + } + + if (pluginList.indexOf("estree") >= 0) { + // ensure estree plugin loads first + pluginList = pluginList.filter((plugin) => plugin !== "estree"); + pluginList.unshift("estree"); + } + + const key = pluginList.join("/"); + let cls = parserClassCache[key]; + if (!cls) { + cls = Parser; + for (const plugin of pluginList) { + cls = plugins[plugin](cls); + } + parserClassCache[key] = cls; + } + return cls; +} diff --git a/src/parser/index.js b/src/parser/index.js index 2a4768affb..9600040c5f 100644 --- a/src/parser/index.js +++ b/src/parser/index.js @@ -12,7 +12,7 @@ export default class Parser extends Tokenizer { this.options = options; this.inModule = this.options.sourceType === "module"; this.input = input; - this.plugins = this.loadPlugins(this.options.plugins); + this.plugins = pluginsMap(this.options.plugins); this.filename = options.sourceFilename; // If enabled, skip leading hashbang line. @@ -33,37 +33,6 @@ export default class Parser extends Tokenizer { return !!this.plugins[name]; } - extend(name: string, f: Function) { - this[name] = f(this[name]); - } - - loadPlugins(pluginList: Array): { [key: string]: boolean } { - const pluginMap = {}; - - if (pluginList.indexOf("flow") >= 0) { - // ensure flow plugin loads last - pluginList = pluginList.filter((plugin) => plugin !== "flow"); - pluginList.push("flow"); - } - - if (pluginList.indexOf("estree") >= 0) { - // ensure estree plugin loads first - pluginList = pluginList.filter((plugin) => plugin !== "estree"); - pluginList.unshift("estree"); - } - - for (const name of pluginList) { - if (!pluginMap[name]) { - pluginMap[name] = true; - - const plugin = plugins[name]; - if (plugin) plugin(this); - } - } - - return pluginMap; - } - parse(): { type: "File", program: { @@ -77,3 +46,11 @@ export default class Parser extends Tokenizer { return this.parseTopLevel(file, program); } } + +function pluginsMap(pluginList: $ReadOnlyArray): { [key: string]: boolean } { + const pluginMap = {}; + for (const name of pluginList) { + pluginMap[name] = true; + } + return pluginMap; +} diff --git a/src/plugins/estree.js b/src/plugins/estree.js index 3502e311bf..585cd7dc2b 100644 --- a/src/plugins/estree.js +++ b/src/plugins/estree.js @@ -43,206 +43,178 @@ function isSimpleProperty(node) { node.method === false; } -export default function (instance) { - instance.extend("checkDeclaration", function(inner) { - return function (node) { - if (isSimpleProperty(node)) { - this.checkDeclaration(node.value); +export default (superClass) => class extends superClass { + checkDeclaration(node) { + if (isSimpleProperty(node)) { + this.checkDeclaration(node.value); + } else { + super.checkDeclaration(node); + } + } + + checkGetterSetterParamCount(prop) { + const paramCount = prop.kind === "get" ? 0 : 1; + if (prop.value.params.length !== paramCount) { + const start = prop.start; + if (prop.kind === "get") { + this.raise(start, "getter should have no params"); } else { - inner.call(this, node); + this.raise(start, "setter should have exactly one param"); } - }; - }); + } + } - instance.extend("checkGetterSetterParamCount", function() { - return function (prop) { - const paramCount = prop.kind === "get" ? 0 : 1; - if (prop.value.params.length !== paramCount) { - const start = prop.start; - if (prop.kind === "get") { - this.raise(start, "getter should have no params"); + checkLVal(expr, isBinding, checkClashes, ...args) { + switch (expr.type) { + case "ObjectPattern": + expr.properties.forEach((prop) => { + this.checkLVal( + prop.type === "Property" ? prop.value : prop, + isBinding, + checkClashes, + "object destructuring pattern" + ); + }); + break; + default: + super.checkLVal(expr, isBinding, checkClashes, ...args); + } + } + + checkPropClash(prop, propHash) { + if (prop.computed || !isSimpleProperty(prop)) return; + + const key = prop.key; + // It is either an Identifier or a String/NumericLiteral + const name = key.type === "Identifier" ? key.name : String(key.value); + + if (name === "__proto__") { + if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property"); + propHash.proto = true; + } + } + + isStrictBody(node, isExpression) { + if (!isExpression && node.body.body.length > 0) { + for (const directive of (node.body.body: Array)) { + if (directive.type === "ExpressionStatement" && directive.expression.type === "Literal") { + if (directive.expression.value === "use strict") return true; } else { - this.raise(start, "setter should have exactly one param"); - } - } - }; - }); - - instance.extend("checkLVal", function(inner) { - return function (expr, isBinding, checkClashes, ...args) { - switch (expr.type) { - case "ObjectPattern": - expr.properties.forEach((prop) => { - this.checkLVal( - prop.type === "Property" ? prop.value : prop, - isBinding, - checkClashes, - "object destructuring pattern" - ); - }); + // Break for the first non literal expression break; - default: - inner.call(this, expr, isBinding, checkClashes, ...args); + } } - }; - }); + } - instance.extend("checkPropClash", function () { - return function (prop, propHash) { - if (prop.computed || !isSimpleProperty(prop)) return; + return false; + } - const key = prop.key; - // It is either an Identifier or a String/NumericLiteral - const name = key.type === "Identifier" ? key.name : String(key.value); + isValidDirective(stmt) { + return stmt.type === "ExpressionStatement" && + stmt.expression.type === "Literal" && + typeof stmt.expression.value === "string" && + (!stmt.expression.extra || !stmt.expression.extra.parenthesized); + } - if (name === "__proto__") { - if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property"); - propHash.proto = true; - } - }; - }); + parseBlockBody(node, ...args) { + super.parseBlockBody(node, ...args); - instance.extend("isStrictBody", function () { - return function (node, isExpression) { - if (!isExpression && node.body.body.length > 0) { - for (const directive of (node.body.body: Array)) { - if (directive.type === "ExpressionStatement" && directive.expression.type === "Literal") { - if (directive.expression.value === "use strict") return true; - } else { - // Break for the first non literal expression - break; - } + node.directives.reverse().forEach((directive) => { + node.body.unshift(this.directiveToStmt(directive)); + }); + delete node.directives; + } + + parseClassMethod(classBody, ...args) { + super.parseClassMethod(classBody, ...args); + + const body = classBody.body; + body[body.length - 1].type = "MethodDefinition"; + } + + parseExprAtom(...args) { + switch (this.state.type) { + case tt.regexp: + return this.estreeParseRegExpLiteral(this.state.value); + + case tt.num: + case tt.string: + return this.estreeParseLiteral(this.state.value); + + case tt._null: + return this.estreeParseLiteral(null); + + case tt._true: + return this.estreeParseLiteral(true); + + case tt._false: + return this.estreeParseLiteral(false); + + default: + return super.parseExprAtom(...args); + } + } + + parseLiteral(...args) { + const node = super.parseLiteral(...args); + node.raw = node.extra.raw; + delete node.extra; + + return node; + } + + parseMethod(node, ...args) { + let funcNode = this.startNode(); + funcNode.kind = node.kind; // provide kind, so super method correctly sets state + funcNode = super.parseMethod(funcNode, ...args); + delete funcNode.kind; + node.value = this.finishNode(funcNode, "FunctionExpression"); + + return node; + } + + parseObjectMethod(...args) { + const node = super.parseObjectMethod(...args); + + if (node) { + if (node.kind === "method") node.kind = "init"; + node.type = "Property"; + } + + return node; + } + + parseObjectProperty(...args) { + const node = super.parseObjectProperty(...args); + + if (node) { + node.kind = "init"; + node.type = "Property"; + } + + return node; + } + + toAssignable(node, isBinding, ...args) { + if (isSimpleProperty(node)) { + this.toAssignable(node.value, isBinding, ...args); + + return node; + } else if (node.type === "ObjectExpression") { + node.type = "ObjectPattern"; + for (const prop of (node.properties: Array)) { + if (prop.kind === "get" || prop.kind === "set") { + this.raise(prop.key.start, "Object pattern can't contain getter or setter"); + } else if (prop.method) { + this.raise(prop.key.start, "Object pattern can't contain methods"); + } else { + this.toAssignable(prop, isBinding, "object destructuring pattern"); } } - return false; - }; - }); - - instance.extend("isValidDirective", function () { - return function (stmt) { - return stmt.type === "ExpressionStatement" && - stmt.expression.type === "Literal" && - typeof stmt.expression.value === "string" && - (!stmt.expression.extra || !stmt.expression.extra.parenthesized); - }; - }); - - instance.extend("parseBlockBody", function (inner) { - return function (node, ...args) { - inner.call(this, node, ...args); - - node.directives.reverse().forEach((directive) => { - node.body.unshift(this.directiveToStmt(directive)); - }); - delete node.directives; - }; - }); - - instance.extend("parseClassMethod", function (inner) { - return function (classBody, ...args) { - inner.call(this, classBody, ...args); - - const body = classBody.body; - body[body.length - 1].type = "MethodDefinition"; - }; - }); - - instance.extend("parseExprAtom", function(inner) { - return function (...args) { - switch (this.state.type) { - case tt.regexp: - return this.estreeParseRegExpLiteral(this.state.value); - - case tt.num: - case tt.string: - return this.estreeParseLiteral(this.state.value); - - case tt._null: - return this.estreeParseLiteral(null); - - case tt._true: - return this.estreeParseLiteral(true); - - case tt._false: - return this.estreeParseLiteral(false); - - default: - return inner.call(this, ...args); - } - }; - }); - - instance.extend("parseLiteral", function(inner) { - return function (...args) { - const node = inner.call(this, ...args); - node.raw = node.extra.raw; - delete node.extra; - return node; - }; - }); + } - instance.extend("parseMethod", function(inner) { - return function (node, ...args) { - let funcNode = this.startNode(); - funcNode.kind = node.kind; // provide kind, so inner method correctly sets state - funcNode = inner.call(this, funcNode, ...args); - delete funcNode.kind; - node.value = this.finishNode(funcNode, "FunctionExpression"); - - return node; - }; - }); - - instance.extend("parseObjectMethod", function(inner) { - return function (...args) { - const node = inner.call(this, ...args); - - if (node) { - if (node.kind === "method") node.kind = "init"; - node.type = "Property"; - } - - return node; - }; - }); - - instance.extend("parseObjectProperty", function(inner) { - return function (...args) { - const node = inner.call(this, ...args); - - if (node) { - node.kind = "init"; - node.type = "Property"; - } - - return node; - }; - }); - - instance.extend("toAssignable", function(inner) { - return function (node, isBinding, ...args) { - if (isSimpleProperty(node)) { - this.toAssignable(node.value, isBinding, ...args); - - return node; - } else if (node.type === "ObjectExpression") { - node.type = "ObjectPattern"; - for (const prop of (node.properties: Array)) { - if (prop.kind === "get" || prop.kind === "set") { - this.raise(prop.key.start, "Object pattern can't contain getter or setter"); - } else if (prop.method) { - this.raise(prop.key.start, "Object pattern can't contain methods"); - } else { - this.toAssignable(prop, isBinding, "object destructuring pattern"); - } - } - - return node; - } - - return inner.call(this, node, isBinding, ...args); - }; - }); -} + return super.toAssignable(node, isBinding, ...args); + } +}; diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 15302e40dd..2eed420119 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -865,498 +865,433 @@ pp.flowParseVariance = function() { return variance; }; -export default function (instance) { +export default (superClass) => class extends superClass { // plain function return types: function name(): string {} - instance.extend("parseFunctionBody", function (inner) { - return function (node, allowExpression) { - if (this.match(tt.colon) && !allowExpression) { - // if allowExpression is true then we're parsing an arrow function and if - // there's a return type then it's been handled elsewhere - const typeNode = this.startNode(); - [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); + parseFunctionBody(node, allowExpression) { + if (this.match(tt.colon) && !allowExpression) { + // if allowExpression is true then we're parsing an arrow function and if + // there's a return type then it's been handled elsewhere + const typeNode = this.startNode(); + [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); - node.returnType = typeNode.typeAnnotation - ? this.finishNode(typeNode, "TypeAnnotation") - : null; - } + node.returnType = typeNode.typeAnnotation + ? this.finishNode(typeNode, "TypeAnnotation") + : null; + } - return inner.call(this, node, allowExpression); - }; - }); + return super.parseFunctionBody(node, allowExpression); + } // interfaces - instance.extend("parseStatement", function (inner) { - return function (declaration, topLevel) { - // strict mode handling of `interface` since it's a reserved word - if (this.state.strict && this.match(tt.name) && this.state.value === "interface") { - const node = this.startNode(); - this.next(); - return this.flowParseInterface(node); - } else { - return inner.call(this, declaration, topLevel); - } - }; - }); + parseStatement(declaration, topLevel) { + // strict mode handling of `interface` since it's a reserved word + if (this.state.strict && this.match(tt.name) && this.state.value === "interface") { + const node = this.startNode(); + this.next(); + return this.flowParseInterface(node); + } else { + return super.parseStatement(declaration, topLevel); + } + } // declares, interfaces and type aliases - instance.extend("parseExpressionStatement", function (inner) { - return function (node, expr) { - if (expr.type === "Identifier") { - if (expr.name === "declare") { - if (this.match(tt._class) || this.match(tt.name) || this.match(tt._function) || this.match(tt._var)) { - return this.flowParseDeclare(node); - } - } else if (this.match(tt.name)) { - if (expr.name === "interface") { - return this.flowParseInterface(node); - } else if (expr.name === "type") { - return this.flowParseTypeAlias(node); - } + parseExpressionStatement(node, expr) { + if (expr.type === "Identifier") { + if (expr.name === "declare") { + if (this.match(tt._class) || this.match(tt.name) || this.match(tt._function) || this.match(tt._var)) { + return this.flowParseDeclare(node); + } + } else if (this.match(tt.name)) { + if (expr.name === "interface") { + return this.flowParseInterface(node); + } else if (expr.name === "type") { + return this.flowParseTypeAlias(node); } } + } - return inner.call(this, node, expr); - }; - }); + return super.parseExpressionStatement(node, expr); + } // export type - instance.extend("shouldParseExportDeclaration", function (inner) { - return function () { - return this.isContextual("type") - || this.isContextual("interface") - || inner.call(this); - }; - }); + shouldParseExportDeclaration() { + return this.isContextual("type") + || this.isContextual("interface") + || super.shouldParseExportDeclaration(); + } - instance.extend("parseConditional", function (inner) { - return function (expr, noIn, startPos, startLoc, refNeedsArrowPos) { - // only do the expensive clone if there is a question mark - // and if we come from inside parens - if (refNeedsArrowPos && this.match(tt.question)) { - const state = this.state.clone(); - try { - return inner.call(this, expr, noIn, startPos, startLoc); - } catch (err) { - if (err instanceof SyntaxError) { - this.state = state; - refNeedsArrowPos.start = err.pos || this.state.start; - return expr; - } else { - // istanbul ignore next: no such error is expected - throw err; - } - } - } - - return inner.call(this, expr, noIn, startPos, startLoc); - }; - }); - - instance.extend("parseParenItem", function (inner) { - return function (node, startPos, startLoc) { - node = inner.call(this, node, startPos, startLoc); - if (this.eat(tt.question)) { - node.optional = true; - } - - if (this.match(tt.colon)) { - const typeCastNode = this.startNodeAt(startPos, startLoc); - typeCastNode.expression = node; - typeCastNode.typeAnnotation = this.flowParseTypeAnnotation(); - - return this.finishNode(typeCastNode, "TypeCastExpression"); - } - - return node; - }; - }); - - instance.extend("parseExport", function (inner) { - return function (node) { - node = inner.call(this, node); - if (node.type === "ExportNamedDeclaration") { - node.exportKind = node.exportKind || "value"; - } - return node; - }; - }); - - instance.extend("parseExportDeclaration", function (inner) { - return function (node) { - if (this.isContextual("type")) { - node.exportKind = "type"; - - const declarationNode = this.startNode(); - this.next(); - - if (this.match(tt.braceL)) { - // export type { foo, bar }; - node.specifiers = this.parseExportSpecifiers(); - this.parseExportFrom(node); - return null; + parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos) { + // only do the expensive clone if there is a question mark + // and if we come from inside parens + if (refNeedsArrowPos && this.match(tt.question)) { + const state = this.state.clone(); + try { + return super.parseConditional(expr, noIn, startPos, startLoc); + } catch (err) { + if (err instanceof SyntaxError) { + this.state = state; + refNeedsArrowPos.start = err.pos || this.state.start; + return expr; } else { - // export type Foo = Bar; - return this.flowParseTypeAlias(declarationNode); + // istanbul ignore next: no such error is expected + throw err; } - } else if (this.isContextual("interface")) { - node.exportKind = "type"; - const declarationNode = this.startNode(); - this.next(); - return this.flowParseInterface(declarationNode); - } else { - return inner.call(this, node); } - }; - }); + } - instance.extend("parseClassId", function (inner) { - return function (node) { - inner.apply(this, arguments); - if (this.isRelational("<")) { - node.typeParameters = this.flowParseTypeParameterDeclaration(); + return super.parseConditional(expr, noIn, startPos, startLoc); + } + + parseParenItem(node, startPos, startLoc) { + node = super.parseParenItem(node, startPos, startLoc); + if (this.eat(tt.question)) { + node.optional = true; + } + + if (this.match(tt.colon)) { + const typeCastNode = this.startNodeAt(startPos, startLoc); + typeCastNode.expression = node; + typeCastNode.typeAnnotation = this.flowParseTypeAnnotation(); + + return this.finishNode(typeCastNode, "TypeCastExpression"); + } + + return node; + } + + parseExport(node) { + node = super.parseExport(node); + if (node.type === "ExportNamedDeclaration") { + node.exportKind = node.exportKind || "value"; + } + return node; + } + + parseExportDeclaration(node) { + if (this.isContextual("type")) { + node.exportKind = "type"; + + const declarationNode = this.startNode(); + this.next(); + + if (this.match(tt.braceL)) { + // export type { foo, bar }; + node.specifiers = this.parseExportSpecifiers(); + this.parseExportFrom(node); + return null; + } else { + // export type Foo = Bar; + return this.flowParseTypeAlias(declarationNode); } - }; - }); + } else if (this.isContextual("interface")) { + node.exportKind = "type"; + const declarationNode = this.startNode(); + this.next(); + return this.flowParseInterface(declarationNode); + } else { + return super.parseExportDeclaration(node); + } + } + + parseClassId(node, ...args) { + super.parseClassId(node, ...args); + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } + } // don't consider `void` to be a keyword as then it'll use the void token type // and set startExpr - instance.extend("isKeyword", function (inner) { - return function (name) { - if (this.state.inType && name === "void") { - return false; - } else { - return inner.call(this, name); - } - }; - }); + isKeyword(name) { + if (this.state.inType && name === "void") { + return false; + } else { + return super.isKeyword(name); + } + } // ensure that inside flow types, we bypass the jsx parser plugin - instance.extend("readToken", function (inner) { - return function (code) { - if (this.state.inType && (code === 62 || code === 60)) { - return this.finishOp(tt.relational, 1); - } else { - return inner.call(this, code); - } - }; - }); + readToken(code) { + if (this.state.inType && (code === 62 || code === 60)) { + return this.finishOp(tt.relational, 1); + } else { + return super.readToken(code); + } + } // don't lex any token as a jsx one inside a flow type - instance.extend("jsx_readToken", function (inner) { - return function () { - if (!this.state.inType) return inner.call(this); - }; - }); + jsx_readToken() { + if (!this.state.inType) return super.jsx_readToken(); + } - instance.extend("toAssignable", function (inner) { - return function (node, isBinding, contextDescription) { - if (node.type === "TypeCastExpression") { - return inner.call(this, this.typeCastToParameter(node), isBinding, contextDescription); - } else { - return inner.call(this, node, isBinding, contextDescription); - } - }; - }); + toAssignable(node, isBinding, contextDescription) { + if (node.type === "TypeCastExpression") { + return super.toAssignable(this.typeCastToParameter(node), isBinding, contextDescription); + } else { + return super.toAssignable(node, isBinding, contextDescription); + } + } // turn type casts that we found in function parameter head into type annotated params - instance.extend("toAssignableList", function (inner) { - return function (exprList, isBinding, contextDescription) { - for (let i = 0; i < exprList.length; i++) { - const expr = exprList[i]; - if (expr && expr.type === "TypeCastExpression") { - exprList[i] = this.typeCastToParameter(expr); - } + toAssignableList(exprList, isBinding, contextDescription) { + for (let i = 0; i < exprList.length; i++) { + const expr = exprList[i]; + if (expr && expr.type === "TypeCastExpression") { + exprList[i] = this.typeCastToParameter(expr); } - return inner.call(this, exprList, isBinding, contextDescription); - }; - }); + } + return super.toAssignableList(exprList, isBinding, contextDescription); + } // this is a list of nodes, from something like a call expression, we need to filter the // type casts that we've found that are illegal in this context - instance.extend("toReferencedList", function () { - return function (exprList) { - for (let i = 0; i < exprList.length; i++) { - const expr = exprList[i]; - if (expr && expr._exprListItem && expr.type === "TypeCastExpression") { - this.raise(expr.start, "Unexpected type cast"); - } + toReferencedList(exprList) { + for (let i = 0; i < exprList.length; i++) { + const expr = exprList[i]; + if (expr && expr._exprListItem && expr.type === "TypeCastExpression") { + this.raise(expr.start, "Unexpected type cast"); } + } - return exprList; - }; - }); + return exprList; + } // parse an item inside a expression list eg. `(NODE, NODE)` where NODE represents // the position where this function is called - instance.extend("parseExprListItem", function (inner) { - return function (...args) { - const container = this.startNode(); - const node = inner.call(this, ...args); - if (this.match(tt.colon)) { - container._exprListItem = true; - container.expression = node; - container.typeAnnotation = this.flowParseTypeAnnotation(); - return this.finishNode(container, "TypeCastExpression"); - } else { - return node; - } - }; - }); + parseExprListItem(...args) { + const container = this.startNode(); + const node = super.parseExprListItem(...args); + if (this.match(tt.colon)) { + container._exprListItem = true; + container.expression = node; + container.typeAnnotation = this.flowParseTypeAnnotation(); + return this.finishNode(container, "TypeCastExpression"); + } else { + return node; + } + } - instance.extend("checkLVal", function (inner) { - return function (node) { - if (node.type !== "TypeCastExpression") { - return inner.apply(this, arguments); - } - }; - }); + checkLVal(node, ...args) { + if (node.type !== "TypeCastExpression") { + return super.checkLVal(node, ...args); + } + } // parse class property type annotations - instance.extend("parseClassProperty", function (inner) { - return function (node) { - if (this.match(tt.colon)) { - node.typeAnnotation = this.flowParseTypeAnnotation(); - } - return inner.call(this, node); - }; - }); + parseClassProperty(node) { + if (this.match(tt.colon)) { + node.typeAnnotation = this.flowParseTypeAnnotation(); + } + return super.parseClassProperty(node); + } // determine whether or not we're currently in the position where a class method would appear - instance.extend("isClassMethod", function (inner) { - return function () { - return this.isRelational("<") || inner.call(this); - }; - }); + isClassMethod() { + return this.isRelational("<") || super.isClassMethod(); + } // determine whether or not we're currently in the position where a class property would appear - instance.extend("isClassProperty", function (inner) { - return function () { - return this.match(tt.colon) || inner.call(this); - }; - }); + isClassProperty() { + return this.match(tt.colon) || super.isClassProperty(); + } // parse type parameters for class methods - instance.extend("parseClassMethod", function (inner) { - return function (classBody, method, ...args) { - if (method.variance) { - this.unexpected(method.variance.start); - } - delete method.variance; - if (this.isRelational("<")) { - method.typeParameters = this.flowParseTypeParameterDeclaration(); - } + parseClassMethod(classBody, method, ...args) { + if (method.variance) { + this.unexpected(method.variance.start); + } + delete method.variance; + if (this.isRelational("<")) { + method.typeParameters = this.flowParseTypeParameterDeclaration(); + } - inner.call(this, classBody, method, ...args); - }; - }); + super.parseClassMethod(classBody, method, ...args); + } // parse a the super class type parameters and implements - instance.extend("parseClassSuper", function (inner) { - return function (node, isStatement) { - inner.call(this, node, isStatement); - if (node.superClass && this.isRelational("<")) { - node.superTypeParameters = this.flowParseTypeParameterInstantiation(); - } - if (this.isContextual("implements")) { - this.next(); - const implemented = node.implements = []; - do { - const node = this.startNode(); - node.id = this.parseIdentifier(); - if (this.isRelational("<")) { - node.typeParameters = this.flowParseTypeParameterInstantiation(); - } else { - node.typeParameters = null; - } - implemented.push(this.finishNode(node, "ClassImplements")); - } while (this.eat(tt.comma)); - } - }; - }); + parseClassSuper(node, isStatement) { + super.parseClassSuper(node, isStatement); + if (node.superClass && this.isRelational("<")) { + node.superTypeParameters = this.flowParseTypeParameterInstantiation(); + } + if (this.isContextual("implements")) { + this.next(); + const implemented = node.implements = []; + do { + const node = this.startNode(); + node.id = this.parseIdentifier(); + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterInstantiation(); + } else { + node.typeParameters = null; + } + implemented.push(this.finishNode(node, "ClassImplements")); + } while (this.eat(tt.comma)); + } + } - instance.extend("parsePropertyName", function (inner) { - return function (node) { - const variance = this.flowParseVariance(); - const key = inner.call(this, node); - node.variance = variance; - return key; - }; - }); + parsePropertyName(node) { + const variance = this.flowParseVariance(); + const key = super.parsePropertyName(node); + node.variance = variance; + return key; + } // parse type parameters for object method shorthand - instance.extend("parseObjPropValue", function (inner) { - return function (prop) { - if (prop.variance) { - this.unexpected(prop.variance.start); - } - delete prop.variance; + parseObjPropValue(prop, ...args) { + if (prop.variance) { + this.unexpected(prop.variance.start); + } + delete prop.variance; - let typeParameters; + let typeParameters; - // method shorthand - if (this.isRelational("<")) { - typeParameters = this.flowParseTypeParameterDeclaration(); - if (!this.match(tt.parenL)) this.unexpected(); - } + // method shorthand + if (this.isRelational("<")) { + typeParameters = this.flowParseTypeParameterDeclaration(); + if (!this.match(tt.parenL)) this.unexpected(); + } - inner.apply(this, arguments); + super.parseObjPropValue(prop, ...args); - // add typeParameters if we found them - if (typeParameters) { - (prop.value || prop).typeParameters = typeParameters; - } - }; - }); + // add typeParameters if we found them + if (typeParameters) { + (prop.value || prop).typeParameters = typeParameters; + } + } - instance.extend("parseAssignableListItemTypes", function () { - return function (param) { - if (this.eat(tt.question)) { - param.optional = true; - } - if (this.match(tt.colon)) { - param.typeAnnotation = this.flowParseTypeAnnotation(); - } - this.finishNode(param, param.type); - return param; - }; - }); + parseAssignableListItemTypes(param) { + if (this.eat(tt.question)) { + param.optional = true; + } + if (this.match(tt.colon)) { + param.typeAnnotation = this.flowParseTypeAnnotation(); + } + this.finishNode(param, param.type); + return param; + } - instance.extend("parseMaybeDefault", function (inner) { - return function (...args) { - const node = inner.apply(this, args); + parseMaybeDefault(...args) { + const node = super.parseMaybeDefault(...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; - }; - }); + 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) { - return function (node) { - node.importKind = "value"; + parseImportSpecifiers(node) { + node.importKind = "value"; - let kind = null; - if (this.match(tt._typeof)) { - kind = "typeof"; - } else if (this.isContextual("type")) { - kind = "type"; - } - if (kind) { - const lh = this.lookahead(); - if ((lh.type === tt.name && lh.value !== "from") || lh.type === tt.braceL || lh.type === tt.star) { - this.next(); - node.importKind = kind; - } + let kind = null; + if (this.match(tt._typeof)) { + kind = "typeof"; + } else if (this.isContextual("type")) { + kind = "type"; + } + if (kind) { + const lh = this.lookahead(); + if ((lh.type === tt.name && lh.value !== "from") || lh.type === tt.braceL || lh.type === tt.star) { + this.next(); + node.importKind = kind; } + } - inner.call(this, node); - }; - }); + super.parseImportSpecifiers(node); + } // parse import-type/typeof shorthand - instance.extend("parseImportSpecifier", function () { - return function (node) { - const specifier = this.startNode(); - const firstIdentLoc = this.state.start; - const firstIdent = this.parseIdentifier(true); + parseImportSpecifier(node) { + const specifier = this.startNode(); + const firstIdentLoc = this.state.start; + const firstIdent = this.parseIdentifier(true); - let specifierTypeKind = null; - if (firstIdent.name === "type") { - specifierTypeKind = "type"; - } else if (firstIdent.name === "typeof") { - specifierTypeKind = "typeof"; - } + let specifierTypeKind = null; + if (firstIdent.name === "type") { + specifierTypeKind = "type"; + } else if (firstIdent.name === "typeof") { + specifierTypeKind = "typeof"; + } - let isBinding = false; - if (this.isContextual("as")) { - const as_ident = this.parseIdentifier(true); - if (specifierTypeKind !== null && !this.match(tt.name) && !this.state.type.keyword) { - // `import {type as ,` or `import {type as }` - specifier.imported = as_ident; - specifier.importKind = specifierTypeKind; - specifier.local = as_ident.__clone(); - } else { - // `import {type as foo` - specifier.imported = firstIdent; - specifier.importKind = null; - specifier.local = this.parseIdentifier(); - } - } else if (specifierTypeKind !== null && (this.match(tt.name) || this.state.type.keyword)) { - // `import {type foo` - specifier.imported = this.parseIdentifier(true); + let isBinding = false; + if (this.isContextual("as")) { + const as_ident = this.parseIdentifier(true); + if (specifierTypeKind !== null && !this.match(tt.name) && !this.state.type.keyword) { + // `import {type as ,` or `import {type as }` + specifier.imported = as_ident; specifier.importKind = specifierTypeKind; - if (this.eatContextual("as")) { - specifier.local = this.parseIdentifier(); - } else { - isBinding = true; - specifier.local = specifier.imported.__clone(); - } + specifier.local = as_ident.__clone(); } else { - isBinding = true; + // `import {type as foo` specifier.imported = firstIdent; specifier.importKind = null; + specifier.local = this.parseIdentifier(); + } + } else if (specifierTypeKind !== null && (this.match(tt.name) || this.state.type.keyword)) { + // `import {type foo` + specifier.imported = this.parseIdentifier(true); + specifier.importKind = specifierTypeKind; + if (this.eatContextual("as")) { + specifier.local = this.parseIdentifier(); + } else { + isBinding = true; specifier.local = specifier.imported.__clone(); } + } else { + isBinding = true; + specifier.imported = firstIdent; + specifier.importKind = null; + specifier.local = specifier.imported.__clone(); + } - if ( - (node.importKind === "type" || node.importKind === "typeof") && - (specifier.importKind === "type" || specifier.importKind === "typeof") - ) { - this.raise(firstIdentLoc, "`The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements`"); - } + if ( + (node.importKind === "type" || node.importKind === "typeof") && + (specifier.importKind === "type" || specifier.importKind === "typeof") + ) { + this.raise(firstIdentLoc, "`The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements`"); + } - if (isBinding) this.checkReservedWord(specifier.local.name, specifier.start, true, true); + if (isBinding) this.checkReservedWord(specifier.local.name, specifier.start, true, true); - this.checkLVal(specifier.local, true, undefined, "import specifier"); - node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); - }; - }); + this.checkLVal(specifier.local, true, undefined, "import specifier"); + node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); + } // parse function type parameters - function foo() {} - instance.extend("parseFunctionParams", function (inner) { - return function (node) { - if (this.isRelational("<")) { - node.typeParameters = this.flowParseTypeParameterDeclaration(); - } - inner.call(this, node); - }; - }); + parseFunctionParams(node) { + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } + super.parseFunctionParams(node); + } // parse flow type annotations on variable declarator heads - let foo: string = bar - instance.extend("parseVarHead", function (inner) { - return function (decl) { - inner.call(this, decl); - if (this.match(tt.colon)) { - decl.id.typeAnnotation = this.flowParseTypeAnnotation(); - this.finishNode(decl.id, decl.id.type); - } - }; - }); + parseVarHead(decl) { + super.parseVarHead(decl); + if (this.match(tt.colon)) { + decl.id.typeAnnotation = this.flowParseTypeAnnotation(); + this.finishNode(decl.id, decl.id.type); + } + } // parse the return type of an async arrow function - let foo = (async (): number => {}); - instance.extend("parseAsyncArrowFromCallExpression", function (inner) { - return function (node, call) { - if (this.match(tt.colon)) { - const oldNoAnonFunctionType = this.state.noAnonFunctionType; - this.state.noAnonFunctionType = true; - node.returnType = this.flowParseTypeAnnotation(); - this.state.noAnonFunctionType = oldNoAnonFunctionType; - } + parseAsyncArrowFromCallExpression(node, call) { + if (this.match(tt.colon)) { + const oldNoAnonFunctionType = this.state.noAnonFunctionType; + this.state.noAnonFunctionType = true; + node.returnType = this.flowParseTypeAnnotation(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; + } - return inner.call(this, node, call); - }; - }); + return super.parseAsyncArrowFromCallExpression(node, call); + } // todo description - instance.extend("shouldParseAsyncArrow", function (inner) { - return function () { - return this.match(tt.colon) || inner.call(this); - }; - }); + shouldParseAsyncArrow() { + return this.match(tt.colon) || super.shouldParseAsyncArrow(); + } // We need to support type parameter declarations for arrow functions. This // is tricky. There are three situations we need to handle @@ -1367,99 +1302,93 @@ export default function (instance) { // 2. This is an arrow function. We'll parse the type parameter declaration, // parse the rest, make sure the rest is an arrow function, and go from // there - // 3. This is neither. Just call the inner function - instance.extend("parseMaybeAssign", function (inner) { - return function (...args) { - let jsxError = null; - if (tt.jsxTagStart && this.match(tt.jsxTagStart)) { - const state = this.state.clone(); - try { - return inner.apply(this, args); - } catch (err) { - if (err instanceof SyntaxError) { - this.state = state; - jsxError = err; - } else { - // istanbul ignore next: no such error is expected - throw err; - } + // 3. This is neither. Just call the super method + parseMaybeAssign(...args) { + let jsxError = null; + if (tt.jsxTagStart && this.match(tt.jsxTagStart)) { + const state = this.state.clone(); + try { + return super.parseMaybeAssign(...args); + } catch (err) { + if (err instanceof SyntaxError) { + this.state = state; + jsxError = err; + } else { + // istanbul ignore next: no such error is expected + throw err; } } + } - if (jsxError != null || this.isRelational("<")) { - // Need to push something onto the context to stop - // the JSX plugin from messing with the tokens - this.state.context.push(ct.parenExpression); - let arrowExpression; - let typeParameters; - try { - typeParameters = this.flowParseTypeParameterDeclaration(); - - arrowExpression = inner.apply(this, args); - arrowExpression.typeParameters = typeParameters; - this.resetStartLocationFromNode(arrowExpression, typeParameters); - } catch (err) { - this.state.context.pop(); - - throw jsxError || err; - } + if (jsxError != null || this.isRelational("<")) { + // Need to push something onto the context to stop + // the JSX plugin from messing with the tokens + this.state.context.push(ct.parenExpression); + let arrowExpression; + let typeParameters; + try { + typeParameters = this.flowParseTypeParameterDeclaration(); + arrowExpression = super.parseMaybeAssign(...args); + arrowExpression.typeParameters = typeParameters; + this.resetStartLocationFromNode(arrowExpression, typeParameters); + } catch (err) { this.state.context.pop(); - if (arrowExpression.type === "ArrowFunctionExpression") { - return arrowExpression; - } else if (jsxError != null) { - throw jsxError; - } else { - this.raise( - typeParameters.start, - "Expected an arrow function after this type parameter declaration", - ); - } + throw jsxError || err; } - return inner.apply(this, args); - }; - }); + this.state.context.pop(); + + if (arrowExpression.type === "ArrowFunctionExpression") { + return arrowExpression; + } else if (jsxError != null) { + throw jsxError; + } else { + this.raise( + typeParameters.start, + "Expected an arrow function after this type parameter declaration", + ); + } + } + + return super.parseMaybeAssign(...args); + } // handle return types for arrow functions - instance.extend("parseArrow", function (inner) { - return function (node) { - if (this.match(tt.colon)) { - const state = this.state.clone(); - try { - const oldNoAnonFunctionType = this.state.noAnonFunctionType; - this.state.noAnonFunctionType = true; + parseArrow(node) { + if (this.match(tt.colon)) { + const state = this.state.clone(); + try { + const oldNoAnonFunctionType = this.state.noAnonFunctionType; + this.state.noAnonFunctionType = true; - const typeNode = this.startNode(); - [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); + const typeNode = this.startNode(); + [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); - this.state.noAnonFunctionType = oldNoAnonFunctionType; + this.state.noAnonFunctionType = oldNoAnonFunctionType; - if (this.canInsertSemicolon()) this.unexpected(); - if (!this.match(tt.arrow)) this.unexpected(); + if (this.canInsertSemicolon()) this.unexpected(); + if (!this.match(tt.arrow)) this.unexpected(); - // assign after it is clear it is an arrow - node.returnType = typeNode.typeAnnotation - ? this.finishNode(typeNode, "TypeAnnotation") - : null; - } catch (err) { - if (err instanceof SyntaxError) { - this.state = state; - } else { - // istanbul ignore next: no such error is expected - throw err; - } + // assign after it is clear it is an arrow + node.returnType = typeNode.typeAnnotation + ? this.finishNode(typeNode, "TypeAnnotation") + : null; + } catch (err) { + if (err instanceof SyntaxError) { + this.state = state; + } else { + // istanbul ignore next: no such error is expected + throw err; } } + } - return inner.call(this, node); - }; - }); + return super.parseArrow(node); + } - instance.extend("shouldParseArrow", function (inner) { - return function () { - return this.match(tt.colon) || inner.call(this); - }; - }); -} + shouldParseArrow() { + return this.match(tt.colon) || super.shouldParseArrow(); + } +}; diff --git a/src/plugins/jsx/index.js b/src/plugins/jsx/index.js index 49231318f4..7309fa9121 100644 --- a/src/plugins/jsx/index.js +++ b/src/plugins/jsx/index.js @@ -395,72 +395,66 @@ pp.jsxParseElement = function() { return this.jsxParseElementAt(startPos, startLoc); }; -export default function(instance) { - instance.extend("parseExprAtom", function(inner) { - return function(refShortHandDefaultPos) { - if (this.match(tt.jsxText)) { - return this.parseLiteral(this.state.value, "JSXText"); - } else if (this.match(tt.jsxTagStart)) { - return this.jsxParseElement(); - } else { - return inner.call(this, refShortHandDefaultPos); - } - }; - }); +export default (superClass) => class extends superClass { + parseExprAtom(refShortHandDefaultPos) { + if (this.match(tt.jsxText)) { + return this.parseLiteral(this.state.value, "JSXText"); + } else if (this.match(tt.jsxTagStart)) { + return this.jsxParseElement(); + } else { + return super.parseExprAtom(refShortHandDefaultPos); + } + } - instance.extend("readToken", function(inner) { - return function(code) { - if (this.state.inPropertyName) return inner.call(this, code); + readToken(code) { + if (this.state.inPropertyName) return super.readToken(code); - const context = this.curContext(); + const context = this.curContext(); - if (context === tc.j_expr) { - return this.jsxReadToken(); + if (context === tc.j_expr) { + return this.jsxReadToken(); + } + + if (context === tc.j_oTag || context === tc.j_cTag) { + if (isIdentifierStart(code)) { + return this.jsxReadWord(); } - if (context === tc.j_oTag || context === tc.j_cTag) { - if (isIdentifierStart(code)) { - return this.jsxReadWord(); - } - - if (code === 62) { - ++this.state.pos; - return this.finishToken(tt.jsxTagEnd); - } - - if ((code === 34 || code === 39) && context === tc.j_oTag) { - return this.jsxReadString(code); - } - } - - if (code === 60 && this.state.exprAllowed) { + if (code === 62) { ++this.state.pos; - return this.finishToken(tt.jsxTagStart); + return this.finishToken(tt.jsxTagEnd); } - return inner.call(this, code); - }; - }); + if ((code === 34 || code === 39) && context === tc.j_oTag) { + return this.jsxReadString(code); + } + } - instance.extend("updateContext", function(inner) { - return function(prevType) { - if (this.match(tt.braceL)) { - const curContext = this.curContext(); - if (curContext === tc.j_oTag) { - this.state.context.push(tc.braceExpression); - } else if (curContext === tc.j_expr) { - this.state.context.push(tc.templateQuasi); - } else { - inner.call(this, prevType); - } - this.state.exprAllowed = true; - } else if (this.match(tt.slash) && prevType === tt.jsxTagStart) { - this.state.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore - this.state.context.push(tc.j_cTag); // reconsider as closing tag context - this.state.exprAllowed = false; + if (code === 60 && this.state.exprAllowed) { + ++this.state.pos; + return this.finishToken(tt.jsxTagStart); + } + + return super.readToken(code); + } + + updateContext(prevType) { + if (this.match(tt.braceL)) { + const curContext = this.curContext(); + if (curContext === tc.j_oTag) { + this.state.context.push(tc.braceExpression); + } else if (curContext === tc.j_expr) { + this.state.context.push(tc.templateQuasi); } else { - return inner.call(this, prevType); + super.updateContext(prevType); } - }; - }); -} + this.state.exprAllowed = true; + } else if (this.match(tt.slash) && prevType === tt.jsxTagStart) { + this.state.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore + this.state.context.push(tc.j_cTag); // reconsider as closing tag context + this.state.exprAllowed = false; + } else { + return super.updateContext(prevType); + } + } +}; From 5e156310ca303a2c32d455f385a03ee51b4ff22b Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 21 Apr 2017 05:25:31 -0700 Subject: [PATCH 07/73] Type-check tokenizer/index.js (#460) * Type-check tokenizer/index.js * Update test baselines --- src/tokenizer/index.js | 105 ++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 42 deletions(-) diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index 076b636381..b9137487ef 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -1,9 +1,13 @@ /* eslint max-len: 0 */ +// @flow + import type { TokenType } from "./types"; +import type { Options } from "../options"; +import type { Position } from "../util/location"; import { isIdentifierStart, isIdentifierChar, isKeyword } from "../util/identifier"; import { types as tt, keywords as keywordTypes } from "./types"; -import { types as ct } from "./context"; +import { type TokContext, types as ct } from "./context"; import { SourceLocation } from "../util/location"; import { lineBreak, lineBreakG, isNewLine, nonASCIIwhitespace } from "../util/whitespace"; import State from "./state"; @@ -13,7 +17,7 @@ import State from "./state"; // used for the onToken callback and the external tokenizer. export class Token { - constructor(state) { + constructor(state: State) { this.type = state.type; this.value = state.value; this.start = state.start; @@ -30,7 +34,7 @@ export class Token { // ## Tokenizer -function codePointToString(code) { +function codePointToString(code: number): string { // UTF-16 Decoding if (code <= 0xFFFF) { return String.fromCharCode(code); @@ -40,14 +44,28 @@ function codePointToString(code) { } export default class Tokenizer { - constructor(options, input) { + // Forward-declarations + // location.js + +raise: (pos: number, message: string) => empty; + // comments.js (TODO: Better type for the parameter) + +addComment: (comment: Object) => void; + // parser/index.js + +hasPlugin: (name: string) => boolean; + // parser/util.js + +unexpected: (pos?: ?number, messageOrType?: string | TokenType) => empty; + + state: State; + isLookahead: boolean; + input: string; + + constructor(options: Options, input: string) { this.state = new State; this.state.init(options, input); } // Move to the next token - next() { + next(): void { if (!this.isLookahead) { this.state.tokens.push(new Token(this.state)); } @@ -61,7 +79,7 @@ export default class Tokenizer { // TODO - eat(type) { + eat(type: TokenType): boolean { if (this.match(type)) { this.next(); return true; @@ -72,19 +90,19 @@ export default class Tokenizer { // TODO - match(type) { + match(type: TokenType): boolean { return this.state.type === type; } // TODO - isKeyword(word) { + isKeyword(word: string): boolean { return isKeyword(word); } // TODO - lookahead() { + lookahead(): State { const old = this.state; this.state = old.clone(true); @@ -100,7 +118,7 @@ export default class Tokenizer { // Toggle strict mode. Re-reads the next number or string to please // pedantic tests (`"use strict"; 010;` should fail). - setStrict(strict) { + setStrict(strict: boolean): void { this.state.strict = strict; if (!this.match(tt.num) && !this.match(tt.string)) return; this.state.pos = this.state.start; @@ -111,14 +129,14 @@ export default class Tokenizer { this.nextToken(); } - curContext() { + curContext(): TokContext { return this.state.context[this.state.context.length - 1]; } // Read a single token, updating the parser object's token-related // properties. - nextToken() { + nextToken(): void { const curContext = this.curContext(); if (!curContext || !curContext.preserveSpace) this.skipSpace(); @@ -135,7 +153,7 @@ export default class Tokenizer { } } - readToken(code) { + readToken(code: number): void { // Identifier or keyword. '\uXXXX' sequences are allowed in // identifiers, so '\' also dispatches to that. if (isIdentifierStart(code) || code === 92 /* '\' */) { @@ -145,7 +163,7 @@ export default class Tokenizer { } } - fullCharCodeAtPos() { + fullCharCodeAtPos(): number { const code = this.input.charCodeAt(this.state.pos); if (code <= 0xd7ff || code >= 0xe000) return code; @@ -153,7 +171,7 @@ export default class Tokenizer { return (code << 10) + next - 0x35fdc00; } - pushComment(block, text, start, end, startLoc, endLoc) { + pushComment(block: boolean, text: string, start: number, end: number, startLoc: Position, endLoc: Position): void { const comment = { type: block ? "CommentBlock" : "CommentLine", value: text, @@ -169,7 +187,7 @@ export default class Tokenizer { } } - skipBlockComment() { + skipBlockComment(): void { const startLoc = this.state.curPosition(); const start = this.state.pos; const end = this.input.indexOf("*/", this.state.pos += 2); @@ -186,7 +204,7 @@ export default class Tokenizer { this.pushComment(true, this.input.slice(start + 2, end), start, this.state.pos, startLoc, this.state.curPosition()); } - skipLineComment(startSkip) { + skipLineComment(startSkip: number): void { const start = this.state.pos; const startLoc = this.state.curPosition(); let ch = this.input.charCodeAt(this.state.pos += startSkip); @@ -201,7 +219,7 @@ export default class Tokenizer { // Called at the start of the parse and after every token. Skips // whitespace and comments, and. - skipSpace() { + skipSpace(): void { loop: while (this.state.pos < this.input.length) { const ch = this.input.charCodeAt(this.state.pos); switch (ch) { @@ -250,7 +268,7 @@ export default class Tokenizer { // the token, so that the next one's `start` will point at the // right position. - finishToken(type, val) { + finishToken(type: TokenType, val: any): void { this.state.end = this.state.pos; this.state.endLoc = this.state.curPosition(); const prevType = this.state.type; @@ -269,7 +287,7 @@ export default class Tokenizer { // // All in the name of speed. // - readToken_dot() { + readToken_dot(): void { const next = this.input.charCodeAt(this.state.pos + 1); if (next >= 48 && next <= 57) { return this.readNumber(true); @@ -285,7 +303,7 @@ export default class Tokenizer { } } - readToken_slash() { // '/' + readToken_slash(): void { // '/' if (this.state.exprAllowed) { ++this.state.pos; return this.readRegexp(); @@ -299,7 +317,7 @@ export default class Tokenizer { } } - readToken_mult_modulo(code) { // '%*' + readToken_mult_modulo(code: number): void { // '%*' let type = code === 42 ? tt.star : tt.modulo; let width = 1; let next = this.input.charCodeAt(this.state.pos + 1); @@ -318,7 +336,7 @@ export default class Tokenizer { return this.finishOp(type, width); } - readToken_pipe_amp(code) { // '|&' + readToken_pipe_amp(code: number): void { // '|&' const next = this.input.charCodeAt(this.state.pos + 1); if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2); if (next === 61) return this.finishOp(tt.assign, 2); @@ -326,7 +344,7 @@ export default class Tokenizer { return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1); } - readToken_caret() { // '^' + readToken_caret(): void { // '^' const next = this.input.charCodeAt(this.state.pos + 1); if (next === 61) { return this.finishOp(tt.assign, 2); @@ -335,7 +353,7 @@ export default class Tokenizer { } } - readToken_plus_min(code) { // '+-' + readToken_plus_min(code: number): void { // '+-' const next = this.input.charCodeAt(this.state.pos + 1); if (next === code) { @@ -355,7 +373,7 @@ export default class Tokenizer { } } - readToken_lt_gt(code) { // '<>' + readToken_lt_gt(code: number): void { // '<>' const next = this.input.charCodeAt(this.state.pos + 1); let size = 1; @@ -381,7 +399,7 @@ export default class Tokenizer { return this.finishOp(tt.relational, size); } - readToken_eq_excl(code) { // '=!' + readToken_eq_excl(code: number): void { // '=!' const next = this.input.charCodeAt(this.state.pos + 1); if (next === 61) return this.finishOp(tt.equality, this.input.charCodeAt(this.state.pos + 2) === 61 ? 3 : 2); if (code === 61 && next === 62) { // '=>' @@ -391,7 +409,7 @@ export default class Tokenizer { return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1); } - getTokenFromCode(code) { + getTokenFromCode(code: number): void { switch (code) { // The interpretation of a dot depends on whether it is followed // by a digit or another two dots. @@ -479,13 +497,13 @@ export default class Tokenizer { this.raise(this.state.pos, `Unexpected character '${codePointToString(code)}'`); } - finishOp(type, size) { + finishOp(type: TokenType, size: number): void { const str = this.input.slice(this.state.pos, this.state.pos + size); this.state.pos += size; return this.finishToken(type, str); } - readRegexp() { + readRegexp(): void { const start = this.state.pos; let escaped, inClass; for (;;) { @@ -527,7 +545,7 @@ export default class Tokenizer { // were read, the integer value otherwise. When `len` is given, this // will return `null` unless the integer has exactly `len` digits. - readInt(radix, len) { + readInt(radix: number, len?: number): number | null { const start = this.state.pos; let total = 0; @@ -552,7 +570,7 @@ export default class Tokenizer { return total; } - readRadixNumber(radix) { + readRadixNumber(radix: number): void { this.state.pos += 2; // 0x const val = this.readInt(radix); if (val == null) this.raise(this.state.start + 2, "Expected number in radix " + radix); @@ -562,7 +580,7 @@ export default class Tokenizer { // Read an integer, octal integer, or floating-point number. - readNumber(startsWithDot) { + readNumber(startsWithDot: boolean): void { const start = this.state.pos; const firstIsZero = this.input.charCodeAt(start) === 48; // '0' let isFloat = false; @@ -601,7 +619,7 @@ export default class Tokenizer { // Read a string value, interpreting backslash-escapes. - readCodePoint(throwOnInvalid) { + readCodePoint(throwOnInvalid: boolean): number | null { const ch = this.input.charCodeAt(this.state.pos); let code; @@ -625,7 +643,7 @@ export default class Tokenizer { return code; } - readString(quote) { + readString(quote: number): void { let out = "", chunkStart = ++this.state.pos; for (;;) { if (this.state.pos >= this.input.length) this.raise(this.state.start, "Unterminated string constant"); @@ -633,6 +651,7 @@ export default class Tokenizer { if (ch === quote) break; if (ch === 92) { // '\' out += this.input.slice(chunkStart, this.state.pos); + // $FlowFixMe out += this.readEscapedChar(false); chunkStart = this.state.pos; } else { @@ -646,7 +665,7 @@ export default class Tokenizer { // Reads template string tokens. - readTmplToken() { + readTmplToken(): void { let out = "", chunkStart = this.state.pos, containsInvalid = false; for (;;) { if (this.state.pos >= this.input.length) this.raise(this.state.start, "Unterminated template"); @@ -697,7 +716,7 @@ export default class Tokenizer { // Used to read escaped characters - readEscapedChar(inTemplate) { + readEscapedChar(inTemplate: boolean): string | null { const throwOnInvalid = !inTemplate; const ch = this.input.charCodeAt(++this.state.pos); ++this.state.pos; @@ -724,6 +743,7 @@ export default class Tokenizer { default: if (ch >= 48 && ch <= 55) { const codePos = this.state.pos - 1; + // $FlowFixMe let octalStr = this.input.substr(this.state.pos - 1, 3).match(/^[0-7]+/)[0]; let octal = parseInt(octalStr, 8); if (octal > 255) { @@ -752,7 +772,7 @@ export default class Tokenizer { // Used to read character escape sequences ('\x', '\u'). - readHexChar(len, throwOnInvalid) { + readHexChar(len: number, throwOnInvalid: boolean): number | null { const codePos = this.state.pos; const n = this.readInt(16, len); if (n === null) { @@ -772,7 +792,7 @@ export default class Tokenizer { // Incrementally adds only escaped chars, adding other chunks as-is // as a micro-optimization. - readWord1() { + readWord1(): string { this.state.containsEsc = false; let word = "", first = true, chunkStart = this.state.pos; while (this.state.pos < this.input.length) { @@ -795,6 +815,7 @@ export default class Tokenizer { this.raise(escStart, "Invalid Unicode escape"); } + // $FlowFixMe word += codePointToString(esc); chunkStart = this.state.pos; } else { @@ -808,7 +829,7 @@ export default class Tokenizer { // Read an identifier or keyword token. Will check for reserved // words when necessary. - readWord() { + readWord(): void { const word = this.readWord1(); let type = tt.name; if (!this.state.containsEsc && this.isKeyword(word)) { @@ -817,7 +838,7 @@ export default class Tokenizer { return this.finishToken(type, word); } - braceIsBlock(prevType) { + braceIsBlock(prevType: TokenType): boolean { if (prevType === tt.colon) { const parent = this.curContext(); if (parent === ct.braceStatement || parent === ct.braceExpression) { @@ -840,7 +861,7 @@ export default class Tokenizer { return !this.state.exprAllowed; } - updateContext(prevType) { + updateContext(prevType: TokenType): void { const type = this.state.type; let update; From 28ccd05bab93dc6b026b51f22850db942885951b Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Fri, 21 Apr 2017 14:26:30 +0200 Subject: [PATCH 08/73] =?UTF-8?q?Update=20flow-bin=20to=20the=20latest=20v?= =?UTF-8?q?ersion=20=F0=9F=9A=80=20(#468)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(package): update flow-bin to version 0.44.0 https://greenkeeper.io/ * Update yarn.lock --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 3b00c3f6ff..3280a72a9a 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "eslint": "^3.7.1", "eslint-config-babel": "^6.0.0", "eslint-plugin-flowtype": "^2.20.0", - "flow-bin": "^0.43.0", + "flow-bin": "^0.44.0", "nyc": "^10.0.0", "rimraf": "^2.5.4", "rollup": "^0.41.0", diff --git a/yarn.lock b/yarn.lock index bf7311170c..f9d3433784 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1994,9 +1994,9 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -flow-bin@^0.43.0: - version "0.43.1" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.43.1.tgz#0733958b448fb8ad4b1576add7e87c31794c81bc" +flow-bin@^0.44.0: + version "0.44.2" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.44.2.tgz#3893c7db5de043ed82674f327a04b1309db208b5" fn-name@^2.0.0: version "2.0.1" From d1a5220b89e7bf0aac65773fae28af88173880b2 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder Date: Fri, 21 Apr 2017 14:41:59 +0200 Subject: [PATCH 09/73] Add support for declare export + fixes (#224) * Add support for declare export * Do not allow declare module inside declare module * Reallow module exports outside module * Add handling of `declare export default` Add check for multiple module.export declarations * Disallow export let/const/type Refactor parsing object properties to share more code and add support for getters and setters * Rename tests * Update test fixtures * Optimize for performance * disallow declare export interface outside of module * Refactor code to be more readable and less lookahead * Add comments * Add test for export star as * Test for number literal getter/setter * Add more tests * Fix tests * Allow union types and correctly eat semi after type * Use non computed keys * Fix tests --- .gitignore | 1 + src/parser/statement.js | 3 +- src/plugins/flow.js | 226 ++++-- .../flow/call-properties/3/expected.json | 7 +- .../class-properties/getter-setter/actual.js | 8 + .../getter-setter/expected.json | 656 ++++++++++++++++++ .../invalid-getter-setter/actual.js | 3 + .../invalid-getter-setter/options.json | 3 + .../invalid-named-static/expected.json | 33 + .../named-static/expected.json | 7 +- .../declare-export/export-class/actual.js | 1 + .../declare-export/export-class/expected.json | 275 ++++++++ .../export-default-arrow/actual.js | 1 + .../export-default-arrow/expected.json | 132 ++++ .../export-default-class/actual.js | 1 + .../export-default-class/expected.json | 119 ++++ .../export-default-function/actual.js | 1 + .../export-default-function/expected.json | 180 +++++ .../export-default-union/actual.js | 1 + .../export-default-union/expected.json | 150 ++++ .../flow/declare-export/export-from/actual.js | 1 + .../declare-export/export-from/expected.json | 175 +++++ .../declare-export/export-function/actual.js | 1 + .../export-function/expected.json | 233 +++++++ .../export-interface-and-var/actual.js | 1 + .../export-interface-and-var/expected.json | 237 +++++++ .../export-interface-commonjs/actual.js | 1 + .../export-interface-commonjs/expected.json | 204 ++++++ .../declare-export/export-interface/actual.js | 1 + .../export-interface/expected.json | 159 +++++ .../export-named-pattern/actual.js | 1 + .../export-named-pattern/expected.json | 156 +++++ .../declare-export/export-star-as/actual.js | 1 + .../export-star-as/expected.json | 104 +++ .../export-star-as/options.json | 3 + .../flow/declare-export/export-star/actual.js | 1 + .../declare-export/export-star/expected.json | 122 ++++ .../export-type-and-var/actual.js | 1 + .../export-type-and-var/expected.json | 231 ++++++ .../export-type-commonjs/actual.js | 1 + .../export-type-commonjs/expected.json | 198 ++++++ .../flow/declare-export/export-type/actual.js | 1 + .../declare-export/export-type/expected.json | 153 ++++ .../flow/declare-export/export-var/actual.js | 1 + .../declare-export/export-var/expected.json | 165 +++++ .../invalid-declare-export-type/actual.js | 1 + .../invalid-declare-export-type/options.json | 3 + .../invalid-export-arrow/actual.js | 1 + .../invalid-export-arrow/options.json | 3 + .../invalid-export-const/actual.js | 1 + .../invalid-export-const/options.json | 3 + .../invalid-export-default-function/actual.js | 1 + .../options.json | 3 + .../invalid-export-default-var/actual.js | 1 + .../invalid-export-default-var/options.json | 3 + .../invalid-export-interface/actual.js | 1 + .../invalid-export-interface/options.json | 3 + .../invalid-export-let/actual.js | 1 + .../invalid-export-let/options.json | 3 + .../flow/declare-module/1/expected.json | 3 +- .../fixtures/flow/declare-module/10/actual.js | 1 + .../flow/declare-module/10/expected.json | 152 ++++ .../flow/declare-module/2/expected.json | 3 +- .../flow/declare-module/3/expected.json | 3 +- .../flow/declare-module/4/expected.json | 3 +- .../flow/declare-module/5/expected.json | 40 +- .../flow/declare-module/6/expected.json | 40 +- .../flow/declare-module/9/expected.json | 3 +- .../flow/declare-module/import/expected.json | 3 +- .../invalid-commonjs-module/actual.js | 1 + .../invalid-commonjs-module/options.json | 3 + .../invalid-es-module/actual.js | 1 + .../invalid-es-module/options.json | 3 + .../invalid-module-in-module/actual.js | 1 + .../invalid-module-in-module/options.json | 3 + .../invalid-multiple-commonjs/actual.js | 1 + .../invalid-multiple-commonjs/options.json | 3 + .../flow/declare-statements/10/expected.json | 44 +- .../flow/declare-statements/15/expected.json | 14 +- .../flow/declare-statements/17/expected.json | 21 +- .../flow/declare-statements/7/expected.json | 37 +- .../flow/declare-statements/9/expected.json | 7 +- .../invalid-literal/actual.js | 1 + .../invalid-literal/options.json | 3 + .../10/expected.json | 14 +- .../4/expected.json | 7 +- .../5/expected.json | 7 +- .../invalid-getter-param-count/actual.js | 3 + .../invalid-getter-param-count/options.json | 3 + .../invalid-setter-param-count/actual.js | 3 + .../invalid-setter-param-count/options.json | 3 + test/fixtures/flow/type-alias/4/expected.json | 56 +- .../flow/type-annotations/108/expected.json | 84 ++- .../flow/type-annotations/110/expected.json | 7 +- .../flow/type-annotations/111/expected.json | 7 +- .../flow/type-annotations/136/expected.json | 7 +- .../flow/type-annotations/32/expected.json | 7 +- .../flow/type-annotations/33/expected.json | 7 +- .../flow/type-annotations/34/expected.json | 7 +- .../flow/type-annotations/35/expected.json | 7 +- .../flow/type-annotations/36/expected.json | 14 +- .../flow/type-annotations/37/expected.json | 14 +- .../flow/type-annotations/38/expected.json | 14 +- .../flow/type-annotations/39/expected.json | 14 +- .../flow/type-annotations/40/expected.json | 14 +- .../flow/type-annotations/42/expected.json | 37 +- .../flow/type-annotations/43/expected.json | 37 +- .../flow/type-annotations/60/expected.json | 7 +- .../flow/type-annotations/61/expected.json | 7 +- .../flow/type-annotations/63/expected.json | 7 +- .../flow/type-annotations/98/expected.json | 21 +- .../flow/type-exports/interface/expected.json | 14 +- .../expected.json | 296 ++++---- .../expected.json | 148 ++-- .../interface-reserved-word/expected.json | 148 ++-- .../type-object-reserved-word/expected.json | 148 ++-- test/fixtures/flow/typecasts/2/expected.json | 14 +- 117 files changed, 4857 insertions(+), 708 deletions(-) create mode 100644 test/fixtures/flow/class-properties/getter-setter/actual.js create mode 100644 test/fixtures/flow/class-properties/getter-setter/expected.json create mode 100644 test/fixtures/flow/class-properties/invalid-getter-setter/actual.js create mode 100644 test/fixtures/flow/class-properties/invalid-getter-setter/options.json create mode 100644 test/fixtures/flow/class-properties/invalid-named-static/expected.json create mode 100644 test/fixtures/flow/declare-export/export-class/actual.js create mode 100644 test/fixtures/flow/declare-export/export-class/expected.json create mode 100644 test/fixtures/flow/declare-export/export-default-arrow/actual.js create mode 100644 test/fixtures/flow/declare-export/export-default-arrow/expected.json create mode 100644 test/fixtures/flow/declare-export/export-default-class/actual.js create mode 100644 test/fixtures/flow/declare-export/export-default-class/expected.json create mode 100644 test/fixtures/flow/declare-export/export-default-function/actual.js create mode 100644 test/fixtures/flow/declare-export/export-default-function/expected.json create mode 100644 test/fixtures/flow/declare-export/export-default-union/actual.js create mode 100644 test/fixtures/flow/declare-export/export-default-union/expected.json create mode 100644 test/fixtures/flow/declare-export/export-from/actual.js create mode 100644 test/fixtures/flow/declare-export/export-from/expected.json create mode 100644 test/fixtures/flow/declare-export/export-function/actual.js create mode 100644 test/fixtures/flow/declare-export/export-function/expected.json create mode 100644 test/fixtures/flow/declare-export/export-interface-and-var/actual.js create mode 100644 test/fixtures/flow/declare-export/export-interface-and-var/expected.json create mode 100644 test/fixtures/flow/declare-export/export-interface-commonjs/actual.js create mode 100644 test/fixtures/flow/declare-export/export-interface-commonjs/expected.json create mode 100644 test/fixtures/flow/declare-export/export-interface/actual.js create mode 100644 test/fixtures/flow/declare-export/export-interface/expected.json create mode 100644 test/fixtures/flow/declare-export/export-named-pattern/actual.js create mode 100644 test/fixtures/flow/declare-export/export-named-pattern/expected.json create mode 100644 test/fixtures/flow/declare-export/export-star-as/actual.js create mode 100644 test/fixtures/flow/declare-export/export-star-as/expected.json create mode 100644 test/fixtures/flow/declare-export/export-star-as/options.json create mode 100644 test/fixtures/flow/declare-export/export-star/actual.js create mode 100644 test/fixtures/flow/declare-export/export-star/expected.json create mode 100644 test/fixtures/flow/declare-export/export-type-and-var/actual.js create mode 100644 test/fixtures/flow/declare-export/export-type-and-var/expected.json create mode 100644 test/fixtures/flow/declare-export/export-type-commonjs/actual.js create mode 100644 test/fixtures/flow/declare-export/export-type-commonjs/expected.json create mode 100644 test/fixtures/flow/declare-export/export-type/actual.js create mode 100644 test/fixtures/flow/declare-export/export-type/expected.json create mode 100644 test/fixtures/flow/declare-export/export-var/actual.js create mode 100644 test/fixtures/flow/declare-export/export-var/expected.json create mode 100644 test/fixtures/flow/declare-export/invalid-declare-export-type/actual.js create mode 100644 test/fixtures/flow/declare-export/invalid-declare-export-type/options.json create mode 100644 test/fixtures/flow/declare-export/invalid-export-arrow/actual.js create mode 100644 test/fixtures/flow/declare-export/invalid-export-arrow/options.json create mode 100644 test/fixtures/flow/declare-export/invalid-export-const/actual.js create mode 100644 test/fixtures/flow/declare-export/invalid-export-const/options.json create mode 100644 test/fixtures/flow/declare-export/invalid-export-default-function/actual.js create mode 100644 test/fixtures/flow/declare-export/invalid-export-default-function/options.json create mode 100644 test/fixtures/flow/declare-export/invalid-export-default-var/actual.js create mode 100644 test/fixtures/flow/declare-export/invalid-export-default-var/options.json create mode 100644 test/fixtures/flow/declare-export/invalid-export-interface/actual.js create mode 100644 test/fixtures/flow/declare-export/invalid-export-interface/options.json create mode 100644 test/fixtures/flow/declare-export/invalid-export-let/actual.js create mode 100644 test/fixtures/flow/declare-export/invalid-export-let/options.json create mode 100644 test/fixtures/flow/declare-module/10/actual.js create mode 100644 test/fixtures/flow/declare-module/10/expected.json create mode 100644 test/fixtures/flow/declare-module/invalid-commonjs-module/actual.js create mode 100644 test/fixtures/flow/declare-module/invalid-commonjs-module/options.json create mode 100644 test/fixtures/flow/declare-module/invalid-es-module/actual.js create mode 100644 test/fixtures/flow/declare-module/invalid-es-module/options.json create mode 100644 test/fixtures/flow/declare-module/invalid-module-in-module/actual.js create mode 100644 test/fixtures/flow/declare-module/invalid-module-in-module/options.json create mode 100644 test/fixtures/flow/declare-module/invalid-multiple-commonjs/actual.js create mode 100644 test/fixtures/flow/declare-module/invalid-multiple-commonjs/options.json create mode 100644 test/fixtures/flow/declare-statements/invalid-literal/actual.js create mode 100644 test/fixtures/flow/declare-statements/invalid-literal/options.json create mode 100644 test/fixtures/flow/object-types/invalid-getter-param-count/actual.js create mode 100644 test/fixtures/flow/object-types/invalid-getter-param-count/options.json create mode 100644 test/fixtures/flow/object-types/invalid-setter-param-count/actual.js create mode 100644 test/fixtures/flow/object-types/invalid-setter-param-count/options.json diff --git a/.gitignore b/.gitignore index 90283a241b..4dfb35cc7a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build coverage lib node_modules +npm-debug.log diff --git a/src/parser/statement.js b/src/parser/statement.js index 08885a009c..f4bd38fb2f 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -810,7 +810,8 @@ pp.parseClassSuper = function (node) { // Parses module export declaration. pp.parseExport = function (node) { - this.next(); + this.eat(tt._export); + // export * from '...' if (this.match(tt.star)) { const specifier = this.startNode(); diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 2eed420119..3d55c4e7a3 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -105,7 +105,7 @@ pp.flowParseDeclareFunction = function (node) { return this.finishNode(node, "DeclareFunction"); }; -pp.flowParseDeclare = function (node) { +pp.flowParseDeclare = function (node, insideModule) { if (this.match(tt._class)) { return this.flowParseDeclareClass(node); } else if (this.match(tt._function)) { @@ -116,12 +116,15 @@ pp.flowParseDeclare = function (node) { if (this.lookahead().type === tt.dot) { return this.flowParseDeclareModuleExports(node); } else { + if (insideModule) this.unexpected(null, "`declare module` cannot be used inside another `declare module`"); return this.flowParseDeclareModule(node); } } else if (this.isContextual("type")) { return this.flowParseDeclareTypeAlias(node); } else if (this.isContextual("interface")) { return this.flowParseDeclareInterface(node); + } else if (this.match(tt._export)) { + return this.flowParseDeclareExportDeclaration(node, insideModule); } else { this.unexpected(); } @@ -134,6 +137,17 @@ pp.flowParseDeclareVariable = function (node) { return this.finishNode(node, "DeclareVariable"); }; +function isEsModuleType(bodyElement) { + return bodyElement.type === "DeclareExportAllDeclaration" || + ( + bodyElement.type === "DeclareExportDeclaration" && + ( + !bodyElement.declaration || + (bodyElement.declaration.type !== "TypeAlias" && bodyElement.declaration.type !== "InterfaceDeclaration") + ) + ); +} + pp.flowParseDeclareModule = function (node) { this.next(); @@ -167,9 +181,94 @@ pp.flowParseDeclareModule = function (node) { this.expect(tt.braceR); this.finishNode(bodyNode, "BlockStatement"); + + let kind = null; + let hasModuleExport = false; + const errorMessage = "Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module"; + body.forEach((bodyElement) => { + if (isEsModuleType(bodyElement)) { + if (kind === "CommonJS") this.unexpected(bodyElement.start, errorMessage); + kind = "ES"; + } else if (bodyElement.type === "DeclareModuleExports") { + if (hasModuleExport) this.unexpected(bodyElement.start, "Duplicate `declare module.exports` statement"); + if (kind === "ES") this.unexpected(bodyElement.start, errorMessage); + kind = "CommonJS"; + hasModuleExport = true; + } + }); + + node.kind = kind || "CommonJS"; return this.finishNode(node, "DeclareModule"); }; +const exportSuggestions = { + const: "declare export var", + let: "declare export var", + type: "export type", + interface: "export interface", +}; + +pp.flowParseDeclareExportDeclaration = function (node, insideModule) { + this.expect(tt._export); + + if (this.eat(tt._default)) { + if (this.match(tt._function) || this.match(tt._class)) { + // declare export default class ... + // declare export default function ... + node.declaration = this.flowParseDeclare(this.startNode()); + } else { + // declare export default [type]; + node.declaration = this.flowParseType(); + this.semicolon(); + } + node.default = true; + + return this.finishNode(node, "DeclareExportDeclaration"); + } else { + if ( + this.match(tt._const) || this.match(tt._let) || + ( + (this.isContextual("type") || this.isContextual("interface")) && + !insideModule + ) + ) { + const label = this.state.value; + const suggestion = exportSuggestions[label]; + this.unexpected(this.state.start, `\`declare export ${label}\` is not supported. Use \`${suggestion}\` instead`); + } + + if ( + this.match(tt._var) || // declare export var ... + this.match(tt._function) || // declare export function ... + this.match(tt._class) // declare export class ... + ) { + node.declaration = this.flowParseDeclare(this.startNode()); + node.default = false; + + return this.finishNode(node, "DeclareExportDeclaration"); + } else if ( + this.match(tt.star) || // declare export * from '' + this.match(tt.braceL) || // declare export {} ... + this.isContextual("interface") || // declare export interface ... + this.isContextual("type") // declare export type ... + ) { + node = this.parseExport(node); + if (node.type === "ExportNamedDeclaration") { + // flow does not support the ExportNamedDeclaration + node.type = "ExportDeclaration"; + node.default = false; + delete node.exportKind; + } + + node.type = "Declare" + node.type; + + return node; + } + } + + this.unexpected(); +}; + pp.flowParseDeclareModuleExports = function (node) { this.expectContextual("module"); this.expect(tt.dot); @@ -381,15 +480,6 @@ pp.flowParseObjectTypeMethodish = function (node) { return this.finishNode(node, "FunctionTypeAnnotation"); }; -pp.flowParseObjectTypeMethod = function (startPos, startLoc, isStatic, key) { - const node = this.startNodeAt(startPos, startLoc); - node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(startPos, startLoc)); - node.static = isStatic; - node.key = key; - node.optional = false; - return this.finishNode(node, "ObjectTypeProperty"); -}; - pp.flowParseObjectTypeCallProperty = function (node, isStatic) { const valueNode = this.startNode(); node.static = isStatic; @@ -402,9 +492,6 @@ pp.flowParseObjectType = function (allowStatic, allowExact, allowSpread) { this.state.inType = true; const nodeStart = this.startNode(); - let node; - let propertyKey; - let isStatic = false; nodeStart.callProperties = []; nodeStart.properties = []; @@ -425,10 +512,8 @@ pp.flowParseObjectType = function (allowStatic, allowExact, allowSpread) { nodeStart.exact = exact; while (!this.match(endDelim)) { - let optional = false; - const startPos = this.state.start; - const startLoc = this.state.startLoc; - node = this.startNode(); + let isStatic = false; + const node = this.startNode(); if (allowStatic && this.isContextual("static") && this.lookahead().type !== tt.colon) { this.next(); isStatic = true; @@ -444,44 +529,24 @@ pp.flowParseObjectType = function (allowStatic, allowExact, allowSpread) { } nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic)); } else { - if (this.match(tt.ellipsis)) { - if (!allowSpread) { - this.unexpected( - null, - "Spread operator cannot appear in class or interface definitions" - ); - } - if (variance) { - this.unexpected(variance.start, "Spread properties cannot have variance"); - } - this.expect(tt.ellipsis); - node.argument = this.flowParseType(); - nodeStart.properties.push(this.finishNode(node, "ObjectTypeSpreadProperty")); - } else { - propertyKey = this.flowParseObjectPropertyKey(); - if (this.isRelational("<") || this.match(tt.parenL)) { - // This is a method property - if (variance) { - this.unexpected(variance.start); - } - nodeStart.properties.push(this.flowParseObjectTypeMethod(startPos, startLoc, isStatic, propertyKey)); - } else { - if (this.eat(tt.question)) { - optional = true; - } - node.key = propertyKey; - node.value = this.flowParseTypeInitialiser(); - node.optional = optional; - node.static = isStatic; - node.variance = variance; - nodeStart.properties.push(this.finishNode(node, "ObjectTypeProperty")); + let kind = "init"; + + if (this.isContextual("get") || this.isContextual("set")) { + const lookahead = this.lookahead(); + if ( + lookahead.type === tt.name || + lookahead.type === tt.string || + lookahead.type === tt.num + ) { + kind = this.state.value; + this.next(); } } + + nodeStart.properties.push(this.flowParseObjectTypeProperty(node, isStatic, variance, kind, allowSpread)); } this.flowObjectTypeSemicolon(); - - isStatic = false; } this.expect(endDelim); @@ -493,6 +558,65 @@ pp.flowParseObjectType = function (allowStatic, allowExact, allowSpread) { return out; }; +pp.flowParseObjectTypeProperty = function (node, isStatic, variance, kind, allowSpread) { + if (this.match(tt.ellipsis)) { + if (!allowSpread) { + this.unexpected( + null, + "Spread operator cannot appear in class or interface definitions" + ); + } + if (variance) { + this.unexpected(variance.start, "Spread properties cannot have variance"); + } + this.expect(tt.ellipsis); + node.argument = this.flowParseType(); + + return this.finishNode(node, "ObjectTypeSpreadProperty"); + } else { + node.key = this.flowParseObjectPropertyKey(); + node.static = isStatic; + node.kind = kind; + + let optional = false; + if (this.isRelational("<") || this.match(tt.parenL)) { + // This is a method property + if (variance) { + this.unexpected(variance.start); + } + + node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start)); + if (kind === "get" || kind === "set") this.flowCheckGetterSetterParamCount(node); + } else { + if (kind !== "init") this.unexpected(); + if (this.eat(tt.question)) { + optional = true; + } + node.value = this.flowParseTypeInitialiser(); + node.variance = variance; + + } + + node.optional = optional; + + return this.finishNode(node, "ObjectTypeProperty"); + } +}; + +// This is similar to checkGetterSetterParamCount, but as +// babylon uses non estree properties we cannot reuse it here +pp.flowCheckGetterSetterParamCount = function (property) { + const paramCount = property.kind === "get" ? 0 : 1; + if (property.value.params.length !== paramCount) { + const start = property.start; + if (property.kind === "get") { + this.raise(start, "getter should have no params"); + } else { + this.raise(start, "setter should have exactly one param"); + } + } +}; + pp.flowObjectTypeSemicolon = function () { if (!this.eat(tt.semi) && !this.eat(tt.comma) && !this.match(tt.braceR) && !this.match(tt.braceBarR)) { @@ -898,7 +1022,7 @@ export default (superClass) => class extends superClass { parseExpressionStatement(node, expr) { if (expr.type === "Identifier") { if (expr.name === "declare") { - if (this.match(tt._class) || this.match(tt.name) || this.match(tt._function) || this.match(tt._var)) { + if (this.match(tt._class) || this.match(tt.name) || this.match(tt._function) || this.match(tt._var) || this.match(tt._export)) { return this.flowParseDeclare(node); } } else if (this.match(tt.name)) { diff --git a/test/fixtures/flow/call-properties/3/expected.json b/test/fixtures/flow/call-properties/3/expected.json index d5d5d6599e..acd2bf6782 100644 --- a/test/fixtures/flow/call-properties/3/expected.json +++ b/test/fixtures/flow/call-properties/3/expected.json @@ -282,6 +282,8 @@ }, "name": "y" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 25, @@ -297,9 +299,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/class-properties/getter-setter/actual.js b/test/fixtures/flow/class-properties/getter-setter/actual.js new file mode 100644 index 0000000000..7a6fc4985b --- /dev/null +++ b/test/fixtures/flow/class-properties/getter-setter/actual.js @@ -0,0 +1,8 @@ +declare class B { + get a(): number; + set b(a: number): void; + get "c"(): number; + set "d"(a: number): void; + get 1(): number; + set 2(a: number): void; +} diff --git a/test/fixtures/flow/class-properties/getter-setter/expected.json b/test/fixtures/flow/class-properties/getter-setter/expected.json new file mode 100644 index 0000000000..13744ddb93 --- /dev/null +++ b/test/fixtures/flow/class-properties/getter-setter/expected.json @@ -0,0 +1,656 @@ +{ + "type": "File", + "start": 0, + "end": 158, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 8, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 158, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 8, + "column": 1 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareClass", + "start": 0, + "end": 158, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 8, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 14, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 15 + }, + "identifierName": "B" + }, + "name": "B" + }, + "typeParameters": null, + "extends": [], + "mixins": [], + "body": { + "type": "ObjectTypeAnnotation", + "start": 16, + "end": 158, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 8, + "column": 1 + } + }, + "callProperties": [], + "properties": [ + { + "type": "ObjectTypeProperty", + "start": 20, + "end": 35, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 17 + } + }, + "key": { + "type": "Identifier", + "start": 24, + "end": 25, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 7 + }, + "identifierName": "a" + }, + "name": "a" + }, + "static": false, + "kind": "get", + "value": { + "type": "FunctionTypeAnnotation", + "start": 20, + "end": 35, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 17 + } + }, + "params": [], + "rest": null, + "typeParameters": null, + "returnType": { + "type": "NumberTypeAnnotation", + "start": 29, + "end": 35, + "loc": { + "start": { + "line": 2, + "column": 11 + }, + "end": { + "line": 2, + "column": 17 + } + } + } + }, + "optional": false + }, + { + "type": "ObjectTypeProperty", + "start": 39, + "end": 61, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 24 + } + }, + "key": { + "type": "Identifier", + "start": 43, + "end": 44, + "loc": { + "start": { + "line": 3, + "column": 6 + }, + "end": { + "line": 3, + "column": 7 + }, + "identifierName": "b" + }, + "name": "b" + }, + "static": false, + "kind": "set", + "value": { + "type": "FunctionTypeAnnotation", + "start": 39, + "end": 61, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 24 + } + }, + "params": [ + { + "type": "FunctionTypeParam", + "start": 45, + "end": 54, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 17 + } + }, + "name": { + "type": "Identifier", + "start": 45, + "end": 46, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 9 + }, + "identifierName": "a" + }, + "name": "a" + }, + "optional": false, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 48, + "end": 54, + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 17 + } + } + } + } + ], + "rest": null, + "typeParameters": null, + "returnType": { + "type": "VoidTypeAnnotation", + "start": 57, + "end": 61, + "loc": { + "start": { + "line": 3, + "column": 20 + }, + "end": { + "line": 3, + "column": 24 + } + } + } + }, + "optional": false + }, + { + "type": "ObjectTypeProperty", + "start": 65, + "end": 82, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 4, + "column": 19 + } + }, + "key": { + "type": "StringLiteral", + "start": 69, + "end": 72, + "loc": { + "start": { + "line": 4, + "column": 6 + }, + "end": { + "line": 4, + "column": 9 + } + }, + "extra": { + "rawValue": "c", + "raw": "\"c\"" + }, + "value": "c" + }, + "static": false, + "kind": "get", + "value": { + "type": "FunctionTypeAnnotation", + "start": 65, + "end": 82, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 4, + "column": 19 + } + }, + "params": [], + "rest": null, + "typeParameters": null, + "returnType": { + "type": "NumberTypeAnnotation", + "start": 76, + "end": 82, + "loc": { + "start": { + "line": 4, + "column": 13 + }, + "end": { + "line": 4, + "column": 19 + } + } + } + }, + "optional": false + }, + { + "type": "ObjectTypeProperty", + "start": 86, + "end": 110, + "loc": { + "start": { + "line": 5, + "column": 2 + }, + "end": { + "line": 5, + "column": 26 + } + }, + "key": { + "type": "StringLiteral", + "start": 90, + "end": 93, + "loc": { + "start": { + "line": 5, + "column": 6 + }, + "end": { + "line": 5, + "column": 9 + } + }, + "extra": { + "rawValue": "d", + "raw": "\"d\"" + }, + "value": "d" + }, + "static": false, + "kind": "set", + "value": { + "type": "FunctionTypeAnnotation", + "start": 86, + "end": 110, + "loc": { + "start": { + "line": 5, + "column": 2 + }, + "end": { + "line": 5, + "column": 26 + } + }, + "params": [ + { + "type": "FunctionTypeParam", + "start": 94, + "end": 103, + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 19 + } + }, + "name": { + "type": "Identifier", + "start": 94, + "end": 95, + "loc": { + "start": { + "line": 5, + "column": 10 + }, + "end": { + "line": 5, + "column": 11 + }, + "identifierName": "a" + }, + "name": "a" + }, + "optional": false, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 97, + "end": 103, + "loc": { + "start": { + "line": 5, + "column": 13 + }, + "end": { + "line": 5, + "column": 19 + } + } + } + } + ], + "rest": null, + "typeParameters": null, + "returnType": { + "type": "VoidTypeAnnotation", + "start": 106, + "end": 110, + "loc": { + "start": { + "line": 5, + "column": 22 + }, + "end": { + "line": 5, + "column": 26 + } + } + } + }, + "optional": false + }, + { + "type": "ObjectTypeProperty", + "start": 114, + "end": 129, + "loc": { + "start": { + "line": 6, + "column": 2 + }, + "end": { + "line": 6, + "column": 17 + } + }, + "key": { + "type": "NumericLiteral", + "start": 118, + "end": 119, + "loc": { + "start": { + "line": 6, + "column": 6 + }, + "end": { + "line": 6, + "column": 7 + } + }, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + }, + "static": false, + "kind": "get", + "value": { + "type": "FunctionTypeAnnotation", + "start": 114, + "end": 129, + "loc": { + "start": { + "line": 6, + "column": 2 + }, + "end": { + "line": 6, + "column": 17 + } + }, + "params": [], + "rest": null, + "typeParameters": null, + "returnType": { + "type": "NumberTypeAnnotation", + "start": 123, + "end": 129, + "loc": { + "start": { + "line": 6, + "column": 11 + }, + "end": { + "line": 6, + "column": 17 + } + } + } + }, + "optional": false + }, + { + "type": "ObjectTypeProperty", + "start": 133, + "end": 155, + "loc": { + "start": { + "line": 7, + "column": 2 + }, + "end": { + "line": 7, + "column": 24 + } + }, + "key": { + "type": "NumericLiteral", + "start": 137, + "end": 138, + "loc": { + "start": { + "line": 7, + "column": 6 + }, + "end": { + "line": 7, + "column": 7 + } + }, + "extra": { + "rawValue": 2, + "raw": "2" + }, + "value": 2 + }, + "static": false, + "kind": "set", + "value": { + "type": "FunctionTypeAnnotation", + "start": 133, + "end": 155, + "loc": { + "start": { + "line": 7, + "column": 2 + }, + "end": { + "line": 7, + "column": 24 + } + }, + "params": [ + { + "type": "FunctionTypeParam", + "start": 139, + "end": 148, + "loc": { + "start": { + "line": 7, + "column": 8 + }, + "end": { + "line": 7, + "column": 17 + } + }, + "name": { + "type": "Identifier", + "start": 139, + "end": 140, + "loc": { + "start": { + "line": 7, + "column": 8 + }, + "end": { + "line": 7, + "column": 9 + }, + "identifierName": "a" + }, + "name": "a" + }, + "optional": false, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 142, + "end": 148, + "loc": { + "start": { + "line": 7, + "column": 11 + }, + "end": { + "line": 7, + "column": 17 + } + } + } + } + ], + "rest": null, + "typeParameters": null, + "returnType": { + "type": "VoidTypeAnnotation", + "start": 151, + "end": 155, + "loc": { + "start": { + "line": 7, + "column": 20 + }, + "end": { + "line": 7, + "column": 24 + } + } + } + }, + "optional": false + } + ], + "indexers": [], + "exact": false + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/class-properties/invalid-getter-setter/actual.js b/test/fixtures/flow/class-properties/invalid-getter-setter/actual.js new file mode 100644 index 0000000000..0cc1b7fa51 --- /dev/null +++ b/test/fixtures/flow/class-properties/invalid-getter-setter/actual.js @@ -0,0 +1,3 @@ +declare class B { + get a: number; +} diff --git a/test/fixtures/flow/class-properties/invalid-getter-setter/options.json b/test/fixtures/flow/class-properties/invalid-getter-setter/options.json new file mode 100644 index 0000000000..4e84114247 --- /dev/null +++ b/test/fixtures/flow/class-properties/invalid-getter-setter/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token (2:7)" +} diff --git a/test/fixtures/flow/class-properties/invalid-named-static/expected.json b/test/fixtures/flow/class-properties/invalid-named-static/expected.json new file mode 100644 index 0000000000..016fc254c0 --- /dev/null +++ b/test/fixtures/flow/class-properties/invalid-named-static/expected.json @@ -0,0 +1,33 @@ +{ + "type": "File", + "start": 0, + "end": 0, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 0 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 0, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 0 + } + }, + "sourceType": "module", + "body": [], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/class-properties/named-static/expected.json b/test/fixtures/flow/class-properties/named-static/expected.json index 61bf3d6674..eea8e7d6a6 100644 --- a/test/fixtures/flow/class-properties/named-static/expected.json +++ b/test/fixtures/flow/class-properties/named-static/expected.json @@ -109,6 +109,8 @@ }, "name": "static" }, + "static": false, + "kind": "init", "value": { "type": "GenericTypeAnnotation", "start": 28, @@ -142,9 +144,8 @@ "name": "T" } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/declare-export/export-class/actual.js b/test/fixtures/flow/declare-export/export-class/actual.js new file mode 100644 index 0000000000..07165a036a --- /dev/null +++ b/test/fixtures/flow/declare-export/export-class/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export class Foo { meth(p1: number): void; } } diff --git a/test/fixtures/flow/declare-export/export-class/expected.json b/test/fixtures/flow/declare-export/export-class/expected.json new file mode 100644 index 0000000000..d403da0296 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-class/expected.json @@ -0,0 +1,275 @@ +{ + "type": "File", + "start": 0, + "end": 77, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 77 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 77, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 77 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 77, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 77 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 77, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 77 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 75, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 75 + } + }, + "declaration": { + "type": "DeclareClass", + "start": 38, + "end": 75, + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 75 + } + }, + "id": { + "type": "Identifier", + "start": 44, + "end": 47, + "loc": { + "start": { + "line": 1, + "column": 44 + }, + "end": { + "line": 1, + "column": 47 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "typeParameters": null, + "extends": [], + "mixins": [], + "body": { + "type": "ObjectTypeAnnotation", + "start": 48, + "end": 75, + "loc": { + "start": { + "line": 1, + "column": 48 + }, + "end": { + "line": 1, + "column": 75 + } + }, + "callProperties": [], + "properties": [ + { + "type": "ObjectTypeProperty", + "start": 50, + "end": 72, + "loc": { + "start": { + "line": 1, + "column": 50 + }, + "end": { + "line": 1, + "column": 72 + } + }, + "key": { + "type": "Identifier", + "start": 50, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 50 + }, + "end": { + "line": 1, + "column": 54 + }, + "identifierName": "meth" + }, + "name": "meth" + }, + "static": false, + "kind": "init", + "value": { + "type": "FunctionTypeAnnotation", + "start": 50, + "end": 72, + "loc": { + "start": { + "line": 1, + "column": 50 + }, + "end": { + "line": 1, + "column": 72 + } + }, + "params": [ + { + "type": "FunctionTypeParam", + "start": 55, + "end": 65, + "loc": { + "start": { + "line": 1, + "column": 55 + }, + "end": { + "line": 1, + "column": 65 + } + }, + "name": { + "type": "Identifier", + "start": 55, + "end": 57, + "loc": { + "start": { + "line": 1, + "column": 55 + }, + "end": { + "line": 1, + "column": 57 + }, + "identifierName": "p1" + }, + "name": "p1" + }, + "optional": false, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 59, + "end": 65, + "loc": { + "start": { + "line": 1, + "column": 59 + }, + "end": { + "line": 1, + "column": 65 + } + } + } + } + ], + "rest": null, + "typeParameters": null, + "returnType": { + "type": "VoidTypeAnnotation", + "start": 68, + "end": 72, + "loc": { + "start": { + "line": 1, + "column": 68 + }, + "end": { + "line": 1, + "column": 72 + } + } + } + }, + "optional": false + } + ], + "indexers": [], + "exact": false + } + }, + "default": false + } + ] + }, + "kind": "ES" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-default-arrow/actual.js b/test/fixtures/flow/declare-export/export-default-arrow/actual.js new file mode 100644 index 0000000000..f6ae0263aa --- /dev/null +++ b/test/fixtures/flow/declare-export/export-default-arrow/actual.js @@ -0,0 +1 @@ +declare export default (a:number) => number diff --git a/test/fixtures/flow/declare-export/export-default-arrow/expected.json b/test/fixtures/flow/declare-export/export-default-arrow/expected.json new file mode 100644 index 0000000000..cd5ff0a411 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-default-arrow/expected.json @@ -0,0 +1,132 @@ +{ + "type": "File", + "start": 0, + "end": 43, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 43 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 43, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 43 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 0, + "end": 43, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 43 + } + }, + "declaration": { + "type": "FunctionTypeAnnotation", + "start": 23, + "end": 43, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 43 + } + }, + "params": [ + { + "type": "FunctionTypeParam", + "start": 24, + "end": 32, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 32 + } + }, + "name": { + "type": "Identifier", + "start": 24, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 25 + }, + "identifierName": "a" + }, + "name": "a" + }, + "optional": false, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 26, + "end": 32, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 32 + } + } + } + } + ], + "rest": null, + "returnType": { + "type": "NumberTypeAnnotation", + "start": 37, + "end": 43, + "loc": { + "start": { + "line": 1, + "column": 37 + }, + "end": { + "line": 1, + "column": 43 + } + } + }, + "typeParameters": null + }, + "default": true + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-default-class/actual.js b/test/fixtures/flow/declare-export/export-default-class/actual.js new file mode 100644 index 0000000000..c26ec8d304 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-default-class/actual.js @@ -0,0 +1 @@ +declare export default class A {}; diff --git a/test/fixtures/flow/declare-export/export-default-class/expected.json b/test/fixtures/flow/declare-export/export-default-class/expected.json new file mode 100644 index 0000000000..62d258e3a7 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-default-class/expected.json @@ -0,0 +1,119 @@ +{ + "type": "File", + "start": 0, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 34 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 34 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 0, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "declaration": { + "type": "DeclareClass", + "start": 23, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "id": { + "type": "Identifier", + "start": 29, + "end": 30, + "loc": { + "start": { + "line": 1, + "column": 29 + }, + "end": { + "line": 1, + "column": 30 + }, + "identifierName": "A" + }, + "name": "A" + }, + "typeParameters": null, + "extends": [], + "mixins": [], + "body": { + "type": "ObjectTypeAnnotation", + "start": 31, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "callProperties": [], + "properties": [], + "indexers": [], + "exact": false + } + }, + "default": true + }, + { + "type": "EmptyStatement", + "start": 33, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 1, + "column": 34 + } + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-default-function/actual.js b/test/fixtures/flow/declare-export/export-default-function/actual.js new file mode 100644 index 0000000000..7f28065f5c --- /dev/null +++ b/test/fixtures/flow/declare-export/export-default-function/actual.js @@ -0,0 +1 @@ +declare export default function bar(p1: number): string; diff --git a/test/fixtures/flow/declare-export/export-default-function/expected.json b/test/fixtures/flow/declare-export/export-default-function/expected.json new file mode 100644 index 0000000000..b433681f6b --- /dev/null +++ b/test/fixtures/flow/declare-export/export-default-function/expected.json @@ -0,0 +1,180 @@ +{ + "type": "File", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "declaration": { + "type": "DeclareFunction", + "start": 23, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "id": { + "type": "Identifier", + "start": 32, + "end": 55, + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 55 + }, + "identifierName": "bar" + }, + "name": "bar", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 35, + "end": 55, + "loc": { + "start": { + "line": 1, + "column": 35 + }, + "end": { + "line": 1, + "column": 55 + } + }, + "typeAnnotation": { + "type": "FunctionTypeAnnotation", + "start": 35, + "end": 55, + "loc": { + "start": { + "line": 1, + "column": 35 + }, + "end": { + "line": 1, + "column": 55 + } + }, + "typeParameters": null, + "params": [ + { + "type": "FunctionTypeParam", + "start": 36, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 36 + }, + "end": { + "line": 1, + "column": 46 + } + }, + "name": { + "type": "Identifier", + "start": 36, + "end": 38, + "loc": { + "start": { + "line": 1, + "column": 36 + }, + "end": { + "line": 1, + "column": 38 + }, + "identifierName": "p1" + }, + "name": "p1" + }, + "optional": false, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 40, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 40 + }, + "end": { + "line": 1, + "column": 46 + } + } + } + } + ], + "rest": null, + "returnType": { + "type": "StringTypeAnnotation", + "start": 49, + "end": 55, + "loc": { + "start": { + "line": 1, + "column": 49 + }, + "end": { + "line": 1, + "column": 55 + } + } + } + } + } + }, + "predicate": null + }, + "default": true + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-default-union/actual.js b/test/fixtures/flow/declare-export/export-default-union/actual.js new file mode 100644 index 0000000000..ec6a2fb669 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-default-union/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export default number|string; } \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-default-union/expected.json b/test/fixtures/flow/declare-export/export-default-union/expected.json new file mode 100644 index 0000000000..331f6890a2 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-default-union/expected.json @@ -0,0 +1,150 @@ +{ + "type": "File", + "start": 0, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 62 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 62 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 62 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 62 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 60, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 60 + } + }, + "declaration": { + "type": "UnionTypeAnnotation", + "start": 46, + "end": 59, + "loc": { + "start": { + "line": 1, + "column": 46 + }, + "end": { + "line": 1, + "column": 59 + } + }, + "types": [ + { + "type": "NumberTypeAnnotation", + "start": 46, + "end": 52, + "loc": { + "start": { + "line": 1, + "column": 46 + }, + "end": { + "line": 1, + "column": 52 + } + } + }, + { + "type": "StringTypeAnnotation", + "start": 53, + "end": 59, + "loc": { + "start": { + "line": 1, + "column": 53 + }, + "end": { + "line": 1, + "column": 59 + } + } + } + ] + }, + "default": true + } + ] + }, + "kind": "ES" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-from/actual.js b/test/fixtures/flow/declare-export/export-from/actual.js new file mode 100644 index 0000000000..516e8e2100 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-from/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export {a,} from "bar"; } diff --git a/test/fixtures/flow/declare-export/export-from/expected.json b/test/fixtures/flow/declare-export/export-from/expected.json new file mode 100644 index 0000000000..6fde07ca48 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-from/expected.json @@ -0,0 +1,175 @@ +{ + "type": "File", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "declaration": null, + "specifiers": [ + { + "type": "ExportSpecifier", + "start": 39, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 39 + }, + "end": { + "line": 1, + "column": 40 + } + }, + "local": { + "type": "Identifier", + "start": 39, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 39 + }, + "end": { + "line": 1, + "column": 40 + }, + "identifierName": "a" + }, + "name": "a" + }, + "exported": { + "type": "Identifier", + "start": 39, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 39 + }, + "end": { + "line": 1, + "column": 40 + }, + "identifierName": "a" + }, + "name": "a" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 48, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 48 + }, + "end": { + "line": 1, + "column": 53 + } + }, + "extra": { + "rawValue": "bar", + "raw": "\"bar\"" + }, + "value": "bar" + }, + "default": false + } + ] + }, + "kind": "ES" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-function/actual.js b/test/fixtures/flow/declare-export/export-function/actual.js new file mode 100644 index 0000000000..4b0b254fe4 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-function/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export function bar(p1: number): string; } diff --git a/test/fixtures/flow/declare-export/export-function/expected.json b/test/fixtures/flow/declare-export/export-function/expected.json new file mode 100644 index 0000000000..79377de65a --- /dev/null +++ b/test/fixtures/flow/declare-export/export-function/expected.json @@ -0,0 +1,233 @@ +{ + "type": "File", + "start": 0, + "end": 73, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 73 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 73, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 73 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 73, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 73 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 73, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 73 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 71, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 71 + } + }, + "declaration": { + "type": "DeclareFunction", + "start": 38, + "end": 71, + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 71 + } + }, + "id": { + "type": "Identifier", + "start": 47, + "end": 70, + "loc": { + "start": { + "line": 1, + "column": 47 + }, + "end": { + "line": 1, + "column": 70 + }, + "identifierName": "bar" + }, + "name": "bar", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 50, + "end": 70, + "loc": { + "start": { + "line": 1, + "column": 50 + }, + "end": { + "line": 1, + "column": 70 + } + }, + "typeAnnotation": { + "type": "FunctionTypeAnnotation", + "start": 50, + "end": 70, + "loc": { + "start": { + "line": 1, + "column": 50 + }, + "end": { + "line": 1, + "column": 70 + } + }, + "typeParameters": null, + "params": [ + { + "type": "FunctionTypeParam", + "start": 51, + "end": 61, + "loc": { + "start": { + "line": 1, + "column": 51 + }, + "end": { + "line": 1, + "column": 61 + } + }, + "name": { + "type": "Identifier", + "start": 51, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 51 + }, + "end": { + "line": 1, + "column": 53 + }, + "identifierName": "p1" + }, + "name": "p1" + }, + "optional": false, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 55, + "end": 61, + "loc": { + "start": { + "line": 1, + "column": 55 + }, + "end": { + "line": 1, + "column": 61 + } + } + } + } + ], + "rest": null, + "returnType": { + "type": "StringTypeAnnotation", + "start": 64, + "end": 70, + "loc": { + "start": { + "line": 1, + "column": 64 + }, + "end": { + "line": 1, + "column": 70 + } + } + } + } + } + }, + "predicate": null + }, + "default": false + } + ] + }, + "kind": "ES" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-interface-and-var/actual.js b/test/fixtures/flow/declare-export/export-interface-and-var/actual.js new file mode 100644 index 0000000000..2f9a87e3ad --- /dev/null +++ b/test/fixtures/flow/declare-export/export-interface-and-var/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export interface bar {} declare export var baz: number; } diff --git a/test/fixtures/flow/declare-export/export-interface-and-var/expected.json b/test/fixtures/flow/declare-export/export-interface-and-var/expected.json new file mode 100644 index 0000000000..c793dc2bb5 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-interface-and-var/expected.json @@ -0,0 +1,237 @@ +{ + "type": "File", + "start": 0, + "end": 88, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 88 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 88, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 88 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 88, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 88 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 88, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 88 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "specifiers": [], + "source": null, + "declaration": { + "type": "InterfaceDeclaration", + "start": 38, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "id": { + "type": "Identifier", + "start": 48, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 48 + }, + "end": { + "line": 1, + "column": 51 + }, + "identifierName": "bar" + }, + "name": "bar" + }, + "typeParameters": null, + "extends": [], + "mixins": [], + "body": { + "type": "ObjectTypeAnnotation", + "start": 52, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 52 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "callProperties": [], + "properties": [], + "indexers": [], + "exact": false + } + }, + "default": false + }, + { + "type": "DeclareExportDeclaration", + "start": 55, + "end": 86, + "loc": { + "start": { + "line": 1, + "column": 55 + }, + "end": { + "line": 1, + "column": 86 + } + }, + "declaration": { + "type": "DeclareVariable", + "start": 70, + "end": 86, + "loc": { + "start": { + "line": 1, + "column": 70 + }, + "end": { + "line": 1, + "column": 86 + } + }, + "id": { + "type": "Identifier", + "start": 74, + "end": 85, + "loc": { + "start": { + "line": 1, + "column": 74 + }, + "end": { + "line": 1, + "column": 85 + }, + "identifierName": "baz" + }, + "name": "baz", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 77, + "end": 85, + "loc": { + "start": { + "line": 1, + "column": 77 + }, + "end": { + "line": 1, + "column": 85 + } + }, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 79, + "end": 85, + "loc": { + "start": { + "line": 1, + "column": 79 + }, + "end": { + "line": 1, + "column": 85 + } + } + } + } + } + }, + "default": false + } + ] + }, + "kind": "ES" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-interface-commonjs/actual.js b/test/fixtures/flow/declare-export/export-interface-commonjs/actual.js new file mode 100644 index 0000000000..d624036826 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-interface-commonjs/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export interface bar {} declare module.exports: number; } diff --git a/test/fixtures/flow/declare-export/export-interface-commonjs/expected.json b/test/fixtures/flow/declare-export/export-interface-commonjs/expected.json new file mode 100644 index 0000000000..9263cc2989 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-interface-commonjs/expected.json @@ -0,0 +1,204 @@ +{ + "type": "File", + "start": 0, + "end": 88, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 88 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 88, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 88 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 88, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 88 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 88, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 88 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "specifiers": [], + "source": null, + "declaration": { + "type": "InterfaceDeclaration", + "start": 38, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "id": { + "type": "Identifier", + "start": 48, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 48 + }, + "end": { + "line": 1, + "column": 51 + }, + "identifierName": "bar" + }, + "name": "bar" + }, + "typeParameters": null, + "extends": [], + "mixins": [], + "body": { + "type": "ObjectTypeAnnotation", + "start": 52, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 52 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "callProperties": [], + "properties": [], + "indexers": [], + "exact": false + } + }, + "default": false + }, + { + "type": "DeclareModuleExports", + "start": 55, + "end": 86, + "loc": { + "start": { + "line": 1, + "column": 55 + }, + "end": { + "line": 1, + "column": 86 + } + }, + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 77, + "end": 85, + "loc": { + "start": { + "line": 1, + "column": 77 + }, + "end": { + "line": 1, + "column": 85 + } + }, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 79, + "end": 85, + "loc": { + "start": { + "line": 1, + "column": 79 + }, + "end": { + "line": 1, + "column": 85 + } + } + } + } + } + ] + }, + "kind": "CommonJS" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-interface/actual.js b/test/fixtures/flow/declare-export/export-interface/actual.js new file mode 100644 index 0000000000..29047342e2 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-interface/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export interface bar {} } diff --git a/test/fixtures/flow/declare-export/export-interface/expected.json b/test/fixtures/flow/declare-export/export-interface/expected.json new file mode 100644 index 0000000000..2524845b73 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-interface/expected.json @@ -0,0 +1,159 @@ +{ + "type": "File", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "specifiers": [], + "source": null, + "declaration": { + "type": "InterfaceDeclaration", + "start": 38, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "id": { + "type": "Identifier", + "start": 48, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 48 + }, + "end": { + "line": 1, + "column": 51 + }, + "identifierName": "bar" + }, + "name": "bar" + }, + "typeParameters": null, + "extends": [], + "mixins": [], + "body": { + "type": "ObjectTypeAnnotation", + "start": 52, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 52 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "callProperties": [], + "properties": [], + "indexers": [], + "exact": false + } + }, + "default": false + } + ] + }, + "kind": "CommonJS" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-named-pattern/actual.js b/test/fixtures/flow/declare-export/export-named-pattern/actual.js new file mode 100644 index 0000000000..6a25a18365 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-named-pattern/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export {a,}; } diff --git a/test/fixtures/flow/declare-export/export-named-pattern/expected.json b/test/fixtures/flow/declare-export/export-named-pattern/expected.json new file mode 100644 index 0000000000..6e1791ff95 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-named-pattern/expected.json @@ -0,0 +1,156 @@ +{ + "type": "File", + "start": 0, + "end": 45, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 45 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 45, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 45 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 45, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 45 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 45, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 45 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 43, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 43 + } + }, + "declaration": null, + "specifiers": [ + { + "type": "ExportSpecifier", + "start": 39, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 39 + }, + "end": { + "line": 1, + "column": 40 + } + }, + "local": { + "type": "Identifier", + "start": 39, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 39 + }, + "end": { + "line": 1, + "column": 40 + }, + "identifierName": "a" + }, + "name": "a" + }, + "exported": { + "type": "Identifier", + "start": 39, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 39 + }, + "end": { + "line": 1, + "column": 40 + }, + "identifierName": "a" + }, + "name": "a" + } + } + ], + "source": null, + "default": false + } + ] + }, + "kind": "ES" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-star-as/actual.js b/test/fixtures/flow/declare-export/export-star-as/actual.js new file mode 100644 index 0000000000..3f0c9ebabf --- /dev/null +++ b/test/fixtures/flow/declare-export/export-star-as/actual.js @@ -0,0 +1 @@ +declare export * as test from '' diff --git a/test/fixtures/flow/declare-export/export-star-as/expected.json b/test/fixtures/flow/declare-export/export-star-as/expected.json new file mode 100644 index 0000000000..ecf6deda99 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-star-as/expected.json @@ -0,0 +1,104 @@ +{ + "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": "DeclareExportDeclaration", + "start": 0, + "end": 32, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 32 + } + }, + "specifiers": [ + { + "type": "ExportNamespaceSpecifier", + "start": 15, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "exported": { + "type": "Identifier", + "start": 20, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 24 + }, + "identifierName": "test" + }, + "name": "test" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 30, + "end": 32, + "loc": { + "start": { + "line": 1, + "column": 30 + }, + "end": { + "line": 1, + "column": 32 + } + }, + "extra": { + "rawValue": "", + "raw": "''" + }, + "value": "" + }, + "default": false + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-star-as/options.json b/test/fixtures/flow/declare-export/export-star-as/options.json new file mode 100644 index 0000000000..edcc382322 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-star-as/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["exportExtensions"] +} diff --git a/test/fixtures/flow/declare-export/export-star/actual.js b/test/fixtures/flow/declare-export/export-star/actual.js new file mode 100644 index 0000000000..25be792a09 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-star/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export * from "bar"; } diff --git a/test/fixtures/flow/declare-export/export-star/expected.json b/test/fixtures/flow/declare-export/export-star/expected.json new file mode 100644 index 0000000000..16df6ff122 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-star/expected.json @@ -0,0 +1,122 @@ +{ + "type": "File", + "start": 0, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 53 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 53 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 53 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 53 + } + }, + "body": [ + { + "type": "DeclareExportAllDeclaration", + "start": 23, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 51 + } + }, + "source": { + "type": "StringLiteral", + "start": 45, + "end": 50, + "loc": { + "start": { + "line": 1, + "column": 45 + }, + "end": { + "line": 1, + "column": 50 + } + }, + "extra": { + "rawValue": "bar", + "raw": "\"bar\"" + }, + "value": "bar" + } + } + ] + }, + "kind": "ES" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-type-and-var/actual.js b/test/fixtures/flow/declare-export/export-type-and-var/actual.js new file mode 100644 index 0000000000..f4de1e146f --- /dev/null +++ b/test/fixtures/flow/declare-export/export-type-and-var/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export type bar = number; declare export var baz: number; } diff --git a/test/fixtures/flow/declare-export/export-type-and-var/expected.json b/test/fixtures/flow/declare-export/export-type-and-var/expected.json new file mode 100644 index 0000000000..1b6544a294 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-type-and-var/expected.json @@ -0,0 +1,231 @@ +{ + "type": "File", + "start": 0, + "end": 90, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 90 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 90, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 90 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 90, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 90 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 90, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 90 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "specifiers": [], + "source": null, + "declaration": { + "type": "TypeAlias", + "start": 38, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "id": { + "type": "Identifier", + "start": 43, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 43 + }, + "end": { + "line": 1, + "column": 46 + }, + "identifierName": "bar" + }, + "name": "bar" + }, + "typeParameters": null, + "right": { + "type": "NumberTypeAnnotation", + "start": 49, + "end": 55, + "loc": { + "start": { + "line": 1, + "column": 49 + }, + "end": { + "line": 1, + "column": 55 + } + } + } + }, + "default": false + }, + { + "type": "DeclareExportDeclaration", + "start": 57, + "end": 88, + "loc": { + "start": { + "line": 1, + "column": 57 + }, + "end": { + "line": 1, + "column": 88 + } + }, + "declaration": { + "type": "DeclareVariable", + "start": 72, + "end": 88, + "loc": { + "start": { + "line": 1, + "column": 72 + }, + "end": { + "line": 1, + "column": 88 + } + }, + "id": { + "type": "Identifier", + "start": 76, + "end": 87, + "loc": { + "start": { + "line": 1, + "column": 76 + }, + "end": { + "line": 1, + "column": 87 + }, + "identifierName": "baz" + }, + "name": "baz", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 79, + "end": 87, + "loc": { + "start": { + "line": 1, + "column": 79 + }, + "end": { + "line": 1, + "column": 87 + } + }, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 81, + "end": 87, + "loc": { + "start": { + "line": 1, + "column": 81 + }, + "end": { + "line": 1, + "column": 87 + } + } + } + } + } + }, + "default": false + } + ] + }, + "kind": "ES" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-type-commonjs/actual.js b/test/fixtures/flow/declare-export/export-type-commonjs/actual.js new file mode 100644 index 0000000000..21cd35d78d --- /dev/null +++ b/test/fixtures/flow/declare-export/export-type-commonjs/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export type bar = number; declare module.exports: number; } diff --git a/test/fixtures/flow/declare-export/export-type-commonjs/expected.json b/test/fixtures/flow/declare-export/export-type-commonjs/expected.json new file mode 100644 index 0000000000..c97883f7d0 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-type-commonjs/expected.json @@ -0,0 +1,198 @@ +{ + "type": "File", + "start": 0, + "end": 90, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 90 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 90, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 90 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 90, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 90 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 90, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 90 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "specifiers": [], + "source": null, + "declaration": { + "type": "TypeAlias", + "start": 38, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "id": { + "type": "Identifier", + "start": 43, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 43 + }, + "end": { + "line": 1, + "column": 46 + }, + "identifierName": "bar" + }, + "name": "bar" + }, + "typeParameters": null, + "right": { + "type": "NumberTypeAnnotation", + "start": 49, + "end": 55, + "loc": { + "start": { + "line": 1, + "column": 49 + }, + "end": { + "line": 1, + "column": 55 + } + } + } + }, + "default": false + }, + { + "type": "DeclareModuleExports", + "start": 57, + "end": 88, + "loc": { + "start": { + "line": 1, + "column": 57 + }, + "end": { + "line": 1, + "column": 88 + } + }, + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 79, + "end": 87, + "loc": { + "start": { + "line": 1, + "column": 79 + }, + "end": { + "line": 1, + "column": 87 + } + }, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 81, + "end": 87, + "loc": { + "start": { + "line": 1, + "column": 81 + }, + "end": { + "line": 1, + "column": 87 + } + } + } + } + } + ] + }, + "kind": "CommonJS" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-type/actual.js b/test/fixtures/flow/declare-export/export-type/actual.js new file mode 100644 index 0000000000..422ea5547e --- /dev/null +++ b/test/fixtures/flow/declare-export/export-type/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export type bar = number; } diff --git a/test/fixtures/flow/declare-export/export-type/expected.json b/test/fixtures/flow/declare-export/export-type/expected.json new file mode 100644 index 0000000000..aa03bfa368 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-type/expected.json @@ -0,0 +1,153 @@ +{ + "type": "File", + "start": 0, + "end": 58, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 58 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 58, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 58 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 58, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 58 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 58, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 58 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "specifiers": [], + "source": null, + "declaration": { + "type": "TypeAlias", + "start": 38, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 56 + } + }, + "id": { + "type": "Identifier", + "start": 43, + "end": 46, + "loc": { + "start": { + "line": 1, + "column": 43 + }, + "end": { + "line": 1, + "column": 46 + }, + "identifierName": "bar" + }, + "name": "bar" + }, + "typeParameters": null, + "right": { + "type": "NumberTypeAnnotation", + "start": 49, + "end": 55, + "loc": { + "start": { + "line": 1, + "column": 49 + }, + "end": { + "line": 1, + "column": 55 + } + } + } + }, + "default": false + } + ] + }, + "kind": "CommonJS" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/export-var/actual.js b/test/fixtures/flow/declare-export/export-var/actual.js new file mode 100644 index 0000000000..b14a9dda53 --- /dev/null +++ b/test/fixtures/flow/declare-export/export-var/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export var a: number; } diff --git a/test/fixtures/flow/declare-export/export-var/expected.json b/test/fixtures/flow/declare-export/export-var/expected.json new file mode 100644 index 0000000000..d176ea111b --- /dev/null +++ b/test/fixtures/flow/declare-export/export-var/expected.json @@ -0,0 +1,165 @@ +{ + "type": "File", + "start": 0, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModule", + "start": 0, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "id": { + "type": "StringLiteral", + "start": 15, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "body": { + "type": "BlockStatement", + "start": 21, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "body": [ + { + "type": "DeclareExportDeclaration", + "start": 23, + "end": 52, + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "declaration": { + "type": "DeclareVariable", + "start": 38, + "end": 52, + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "id": { + "type": "Identifier", + "start": 42, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 42 + }, + "end": { + "line": 1, + "column": 51 + }, + "identifierName": "a" + }, + "name": "a", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 43, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 43 + }, + "end": { + "line": 1, + "column": 51 + } + }, + "typeAnnotation": { + "type": "NumberTypeAnnotation", + "start": 45, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 45 + }, + "end": { + "line": 1, + "column": 51 + } + } + } + } + } + }, + "default": false + } + ] + }, + "kind": "ES" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-export/invalid-declare-export-type/actual.js b/test/fixtures/flow/declare-export/invalid-declare-export-type/actual.js new file mode 100644 index 0000000000..f2c105f061 --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-declare-export-type/actual.js @@ -0,0 +1 @@ +declare export type foo = number; diff --git a/test/fixtures/flow/declare-export/invalid-declare-export-type/options.json b/test/fixtures/flow/declare-export/invalid-declare-export-type/options.json new file mode 100644 index 0000000000..2f2a34e735 --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-declare-export-type/options.json @@ -0,0 +1,3 @@ +{ + "throws": "`declare export type` is not supported. Use `export type` instead (1:15)" +} diff --git a/test/fixtures/flow/declare-export/invalid-export-arrow/actual.js b/test/fixtures/flow/declare-export/invalid-export-arrow/actual.js new file mode 100644 index 0000000000..a5b27cf870 --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-arrow/actual.js @@ -0,0 +1 @@ +declare export (a:number) => number diff --git a/test/fixtures/flow/declare-export/invalid-export-arrow/options.json b/test/fixtures/flow/declare-export/invalid-export-arrow/options.json new file mode 100644 index 0000000000..98d7123790 --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-arrow/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token (1:15)" +} diff --git a/test/fixtures/flow/declare-export/invalid-export-const/actual.js b/test/fixtures/flow/declare-export/invalid-export-const/actual.js new file mode 100644 index 0000000000..8ee799daa5 --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-const/actual.js @@ -0,0 +1 @@ +declare export const foo: number diff --git a/test/fixtures/flow/declare-export/invalid-export-const/options.json b/test/fixtures/flow/declare-export/invalid-export-const/options.json new file mode 100644 index 0000000000..8466e2ca85 --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-const/options.json @@ -0,0 +1,3 @@ +{ + "throws": "`declare export const` is not supported. Use `declare export var` instead (1:15)" +} diff --git a/test/fixtures/flow/declare-export/invalid-export-default-function/actual.js b/test/fixtures/flow/declare-export/invalid-export-default-function/actual.js new file mode 100644 index 0000000000..237a1224ad --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-default-function/actual.js @@ -0,0 +1 @@ +declare export default function (p1: number): string; diff --git a/test/fixtures/flow/declare-export/invalid-export-default-function/options.json b/test/fixtures/flow/declare-export/invalid-export-default-function/options.json new file mode 100644 index 0000000000..40981abf7e --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-default-function/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token (1:32)" +} diff --git a/test/fixtures/flow/declare-export/invalid-export-default-var/actual.js b/test/fixtures/flow/declare-export/invalid-export-default-var/actual.js new file mode 100644 index 0000000000..c90458445b --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-default-var/actual.js @@ -0,0 +1 @@ +declare export default var a: number diff --git a/test/fixtures/flow/declare-export/invalid-export-default-var/options.json b/test/fixtures/flow/declare-export/invalid-export-default-var/options.json new file mode 100644 index 0000000000..562afcef48 --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-default-var/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token (1:23)" +} diff --git a/test/fixtures/flow/declare-export/invalid-export-interface/actual.js b/test/fixtures/flow/declare-export/invalid-export-interface/actual.js new file mode 100644 index 0000000000..aad1860f10 --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-interface/actual.js @@ -0,0 +1 @@ +declare export interface bar {} diff --git a/test/fixtures/flow/declare-export/invalid-export-interface/options.json b/test/fixtures/flow/declare-export/invalid-export-interface/options.json new file mode 100644 index 0000000000..3977f3c480 --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-interface/options.json @@ -0,0 +1,3 @@ +{ + "throws": "`declare export interface` is not supported. Use `export interface` instead (1:15)" +} diff --git a/test/fixtures/flow/declare-export/invalid-export-let/actual.js b/test/fixtures/flow/declare-export/invalid-export-let/actual.js new file mode 100644 index 0000000000..cffa3c63b6 --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-let/actual.js @@ -0,0 +1 @@ +declare export let foo: number diff --git a/test/fixtures/flow/declare-export/invalid-export-let/options.json b/test/fixtures/flow/declare-export/invalid-export-let/options.json new file mode 100644 index 0000000000..745a711f11 --- /dev/null +++ b/test/fixtures/flow/declare-export/invalid-export-let/options.json @@ -0,0 +1,3 @@ +{ + "throws": "`declare export let` is not supported. Use `declare export var` instead (1:15)" +} diff --git a/test/fixtures/flow/declare-module/1/expected.json b/test/fixtures/flow/declare-module/1/expected.json index 543af8e16b..f209133694 100644 --- a/test/fixtures/flow/declare-module/1/expected.json +++ b/test/fixtures/flow/declare-module/1/expected.json @@ -74,7 +74,8 @@ } }, "body": [] - } + }, + "kind": "CommonJS" } ], "directives": [] diff --git a/test/fixtures/flow/declare-module/10/actual.js b/test/fixtures/flow/declare-module/10/actual.js new file mode 100644 index 0000000000..ccbf397e99 --- /dev/null +++ b/test/fixtures/flow/declare-module/10/actual.js @@ -0,0 +1 @@ +declare module.exports: { foo(): number; } diff --git a/test/fixtures/flow/declare-module/10/expected.json b/test/fixtures/flow/declare-module/10/expected.json new file mode 100644 index 0000000000..5b28d3a95c --- /dev/null +++ b/test/fixtures/flow/declare-module/10/expected.json @@ -0,0 +1,152 @@ +{ + "type": "File", + "start": 0, + "end": 42, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 42 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 42, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 42 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareModuleExports", + "start": 0, + "end": 42, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 42 + } + }, + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 22, + "end": 42, + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 1, + "column": 42 + } + }, + "typeAnnotation": { + "type": "ObjectTypeAnnotation", + "start": 24, + "end": 42, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 42 + } + }, + "callProperties": [], + "properties": [ + { + "type": "ObjectTypeProperty", + "start": 26, + "end": 39, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 39 + } + }, + "key": { + "type": "Identifier", + "start": 26, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 29 + }, + "identifierName": "foo" + }, + "name": "foo" + }, + "static": false, + "kind": "init", + "value": { + "type": "FunctionTypeAnnotation", + "start": 26, + "end": 39, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 39 + } + }, + "params": [], + "rest": null, + "typeParameters": null, + "returnType": { + "type": "NumberTypeAnnotation", + "start": 33, + "end": 39, + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 1, + "column": 39 + } + } + } + }, + "optional": false + } + ], + "indexers": [], + "exact": false + } + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/declare-module/2/expected.json b/test/fixtures/flow/declare-module/2/expected.json index 887e105b6e..8643e9feaa 100644 --- a/test/fixtures/flow/declare-module/2/expected.json +++ b/test/fixtures/flow/declare-module/2/expected.json @@ -77,7 +77,8 @@ } }, "body": [] - } + }, + "kind": "CommonJS" } ], "directives": [] diff --git a/test/fixtures/flow/declare-module/3/expected.json b/test/fixtures/flow/declare-module/3/expected.json index b390a8eba8..8e61c95762 100644 --- a/test/fixtures/flow/declare-module/3/expected.json +++ b/test/fixtures/flow/declare-module/3/expected.json @@ -137,7 +137,8 @@ } } ] - } + }, + "kind": "CommonJS" } ], "directives": [] diff --git a/test/fixtures/flow/declare-module/4/expected.json b/test/fixtures/flow/declare-module/4/expected.json index a22533aca2..71deaaf280 100644 --- a/test/fixtures/flow/declare-module/4/expected.json +++ b/test/fixtures/flow/declare-module/4/expected.json @@ -156,7 +156,8 @@ "predicate": null } ] - } + }, + "kind": "CommonJS" } ], "directives": [] diff --git a/test/fixtures/flow/declare-module/5/expected.json b/test/fixtures/flow/declare-module/5/expected.json index 27fad53409..d6491c6f37 100644 --- a/test/fixtures/flow/declare-module/5/expected.json +++ b/test/fixtures/flow/declare-module/5/expected.json @@ -138,6 +138,25 @@ "column": 50 } }, + "key": { + "type": "Identifier", + "start": 37, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 37 + }, + "end": { + "line": 1, + "column": 40 + }, + "identifierName": "foo" + }, + "name": "foo" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 37, @@ -171,24 +190,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 37, - "end": 40, - "loc": { - "start": { - "line": 1, - "column": 37 - }, - "end": { - "line": 1, - "column": 40 - }, - "identifierName": "foo" - }, - "name": "foo" - }, "optional": false } ], @@ -197,7 +198,8 @@ } } ] - } + }, + "kind": "CommonJS" } ], "directives": [] diff --git a/test/fixtures/flow/declare-module/6/expected.json b/test/fixtures/flow/declare-module/6/expected.json index 8024e7d3d1..7b1772c283 100644 --- a/test/fixtures/flow/declare-module/6/expected.json +++ b/test/fixtures/flow/declare-module/6/expected.json @@ -132,6 +132,25 @@ "column": 58 } }, + "key": { + "type": "Identifier", + "start": 45, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 45 + }, + "end": { + "line": 1, + "column": 48 + }, + "identifierName": "foo" + }, + "name": "foo" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 45, @@ -165,24 +184,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 45, - "end": 48, - "loc": { - "start": { - "line": 1, - "column": 45 - }, - "end": { - "line": 1, - "column": 48 - }, - "identifierName": "foo" - }, - "name": "foo" - }, "optional": false } ], @@ -192,7 +193,8 @@ } } ] - } + }, + "kind": "CommonJS" } ], "directives": [] diff --git a/test/fixtures/flow/declare-module/9/expected.json b/test/fixtures/flow/declare-module/9/expected.json index d549499d21..37a6fe2711 100644 --- a/test/fixtures/flow/declare-module/9/expected.json +++ b/test/fixtures/flow/declare-module/9/expected.json @@ -120,7 +120,8 @@ } } ] - } + }, + "kind": "CommonJS" } ], "directives": [] diff --git a/test/fixtures/flow/declare-module/import/expected.json b/test/fixtures/flow/declare-module/import/expected.json index 391e0de595..f1f57afa41 100644 --- a/test/fixtures/flow/declare-module/import/expected.json +++ b/test/fixtures/flow/declare-module/import/expected.json @@ -148,7 +148,8 @@ } } ] - } + }, + "kind": "CommonJS" } ], "directives": [] diff --git a/test/fixtures/flow/declare-module/invalid-commonjs-module/actual.js b/test/fixtures/flow/declare-module/invalid-commonjs-module/actual.js new file mode 100644 index 0000000000..094feacb53 --- /dev/null +++ b/test/fixtures/flow/declare-module/invalid-commonjs-module/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare module.exports: number; declare export var a: number; } diff --git a/test/fixtures/flow/declare-module/invalid-commonjs-module/options.json b/test/fixtures/flow/declare-module/invalid-commonjs-module/options.json new file mode 100644 index 0000000000..adfde32363 --- /dev/null +++ b/test/fixtures/flow/declare-module/invalid-commonjs-module/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module (1:55)" +} diff --git a/test/fixtures/flow/declare-module/invalid-es-module/actual.js b/test/fixtures/flow/declare-module/invalid-es-module/actual.js new file mode 100644 index 0000000000..111a0c6927 --- /dev/null +++ b/test/fixtures/flow/declare-module/invalid-es-module/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare export var a: number; declare module.exports: number; } diff --git a/test/fixtures/flow/declare-module/invalid-es-module/options.json b/test/fixtures/flow/declare-module/invalid-es-module/options.json new file mode 100644 index 0000000000..b40239a560 --- /dev/null +++ b/test/fixtures/flow/declare-module/invalid-es-module/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module (1:53)" +} diff --git a/test/fixtures/flow/declare-module/invalid-module-in-module/actual.js b/test/fixtures/flow/declare-module/invalid-module-in-module/actual.js new file mode 100644 index 0000000000..7b0be343c3 --- /dev/null +++ b/test/fixtures/flow/declare-module/invalid-module-in-module/actual.js @@ -0,0 +1 @@ +declare module A { declare module B {} } diff --git a/test/fixtures/flow/declare-module/invalid-module-in-module/options.json b/test/fixtures/flow/declare-module/invalid-module-in-module/options.json new file mode 100644 index 0000000000..cd823bd7c4 --- /dev/null +++ b/test/fixtures/flow/declare-module/invalid-module-in-module/options.json @@ -0,0 +1,3 @@ +{ + "throws": "`declare module` cannot be used inside another `declare module` (1:27)" +} diff --git a/test/fixtures/flow/declare-module/invalid-multiple-commonjs/actual.js b/test/fixtures/flow/declare-module/invalid-multiple-commonjs/actual.js new file mode 100644 index 0000000000..3c6d3a0307 --- /dev/null +++ b/test/fixtures/flow/declare-module/invalid-multiple-commonjs/actual.js @@ -0,0 +1 @@ +declare module "foo" { declare module.exports: string; declare module.exports: number; } diff --git a/test/fixtures/flow/declare-module/invalid-multiple-commonjs/options.json b/test/fixtures/flow/declare-module/invalid-multiple-commonjs/options.json new file mode 100644 index 0000000000..1520d766b0 --- /dev/null +++ b/test/fixtures/flow/declare-module/invalid-multiple-commonjs/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Duplicate `declare module.exports` statement (1:55)" +} diff --git a/test/fixtures/flow/declare-statements/10/expected.json b/test/fixtures/flow/declare-statements/10/expected.json index 2e0049fb41..378c963659 100644 --- a/test/fixtures/flow/declare-statements/10/expected.json +++ b/test/fixtures/flow/declare-statements/10/expected.json @@ -92,6 +92,25 @@ "column": 38 } }, + "key": { + "type": "Identifier", + "start": 25, + "end": 28, + "loc": { + "start": { + "line": 1, + "column": 25 + }, + "end": { + "line": 1, + "column": 28 + }, + "identifierName": "foo" + }, + "name": "foo" + }, + "static": true, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 18, @@ -125,24 +144,6 @@ } } }, - "static": true, - "key": { - "type": "Identifier", - "start": 25, - "end": 28, - "loc": { - "start": { - "line": 1, - "column": 25 - }, - "end": { - "line": 1, - "column": 28 - }, - "identifierName": "foo" - }, - "name": "foo" - }, "optional": false }, { @@ -176,6 +177,8 @@ }, "name": "x" }, + "static": true, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 51, @@ -191,9 +194,8 @@ } } }, - "optional": false, - "static": true, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/declare-statements/15/expected.json b/test/fixtures/flow/declare-statements/15/expected.json index 0b5376ca37..6b3d9f0b04 100644 --- a/test/fixtures/flow/declare-statements/15/expected.json +++ b/test/fixtures/flow/declare-statements/15/expected.json @@ -109,6 +109,8 @@ }, "name": "foo" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 27, @@ -124,9 +126,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -247,6 +248,8 @@ }, "name": "foo" }, + "static": false, + "kind": "init", "value": { "type": "GenericTypeAnnotation", "start": 66, @@ -280,9 +283,8 @@ "name": "T" } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/declare-statements/17/expected.json b/test/fixtures/flow/declare-statements/17/expected.json index 381229ee19..2f4a6dc1cb 100644 --- a/test/fixtures/flow/declare-statements/17/expected.json +++ b/test/fixtures/flow/declare-statements/17/expected.json @@ -109,6 +109,8 @@ }, "name": "a" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 22, @@ -124,9 +126,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -159,6 +160,8 @@ }, "name": "b" }, + "static": true, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 41, @@ -174,9 +177,8 @@ } } }, - "optional": false, - "static": true, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -209,6 +211,8 @@ }, "name": "c" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 53, @@ -224,9 +228,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/declare-statements/7/expected.json b/test/fixtures/flow/declare-statements/7/expected.json index 776a6a6a9e..babd12a4f5 100644 --- a/test/fixtures/flow/declare-statements/7/expected.json +++ b/test/fixtures/flow/declare-statements/7/expected.json @@ -92,6 +92,25 @@ "column": 71 } }, + "key": { + "type": "Identifier", + "start": 29, + "end": 39, + "loc": { + "start": { + "line": 1, + "column": 29 + }, + "end": { + "line": 1, + "column": 39 + }, + "identifierName": "didAnimate" + }, + "name": "didAnimate" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 29, @@ -240,24 +259,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 29, - "end": 39, - "loc": { - "start": { - "line": 1, - "column": 29 - }, - "end": { - "line": 1, - "column": 39 - }, - "identifierName": "didAnimate" - }, - "name": "didAnimate" - }, "optional": false } ], diff --git a/test/fixtures/flow/declare-statements/9/expected.json b/test/fixtures/flow/declare-statements/9/expected.json index 1ac09b01e8..3bafe9b3ab 100644 --- a/test/fixtures/flow/declare-statements/9/expected.json +++ b/test/fixtures/flow/declare-statements/9/expected.json @@ -225,6 +225,8 @@ }, "name": "x" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 37, @@ -240,9 +242,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/declare-statements/invalid-literal/actual.js b/test/fixtures/flow/declare-statements/invalid-literal/actual.js new file mode 100644 index 0000000000..b70552565f --- /dev/null +++ b/test/fixtures/flow/declare-statements/invalid-literal/actual.js @@ -0,0 +1 @@ +declare 1; diff --git a/test/fixtures/flow/declare-statements/invalid-literal/options.json b/test/fixtures/flow/declare-statements/invalid-literal/options.json new file mode 100644 index 0000000000..1288082ab0 --- /dev/null +++ b/test/fixtures/flow/declare-statements/invalid-literal/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token, expected ; (1:8)" +} diff --git a/test/fixtures/flow/interfaces-module-and-script/10/expected.json b/test/fixtures/flow/interfaces-module-and-script/10/expected.json index 4c7e6d03c9..4fb5918fb1 100644 --- a/test/fixtures/flow/interfaces-module-and-script/10/expected.json +++ b/test/fixtures/flow/interfaces-module-and-script/10/expected.json @@ -159,6 +159,8 @@ }, "name": "x" }, + "static": false, + "kind": "init", "value": { "type": "BooleanTypeAnnotation", "start": 22, @@ -174,9 +176,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -209,6 +210,8 @@ }, "name": "y" }, + "static": true, + "kind": "init", "value": { "type": "BooleanTypeAnnotation", "start": 62, @@ -224,9 +227,8 @@ } } }, - "optional": false, - "static": true, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/interfaces-module-and-script/4/expected.json b/test/fixtures/flow/interfaces-module-and-script/4/expected.json index 1099bd54e8..83636e0555 100644 --- a/test/fixtures/flow/interfaces-module-and-script/4/expected.json +++ b/test/fixtures/flow/interfaces-module-and-script/4/expected.json @@ -109,6 +109,8 @@ }, "name": "foo" }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 19, @@ -142,9 +144,8 @@ }, "typeParameters": null }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/interfaces-module-and-script/5/expected.json b/test/fixtures/flow/interfaces-module-and-script/5/expected.json index 042154f2d0..da45e73fc6 100644 --- a/test/fixtures/flow/interfaces-module-and-script/5/expected.json +++ b/test/fixtures/flow/interfaces-module-and-script/5/expected.json @@ -109,6 +109,8 @@ }, "name": "length" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 56, @@ -124,9 +126,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [ diff --git a/test/fixtures/flow/object-types/invalid-getter-param-count/actual.js b/test/fixtures/flow/object-types/invalid-getter-param-count/actual.js new file mode 100644 index 0000000000..83d9b887fc --- /dev/null +++ b/test/fixtures/flow/object-types/invalid-getter-param-count/actual.js @@ -0,0 +1,3 @@ +type B = { + get a(foo:number): number; +} diff --git a/test/fixtures/flow/object-types/invalid-getter-param-count/options.json b/test/fixtures/flow/object-types/invalid-getter-param-count/options.json new file mode 100644 index 0000000000..8694117aee --- /dev/null +++ b/test/fixtures/flow/object-types/invalid-getter-param-count/options.json @@ -0,0 +1,3 @@ +{ + "throws": "getter should have no params (2:2)" +} diff --git a/test/fixtures/flow/object-types/invalid-setter-param-count/actual.js b/test/fixtures/flow/object-types/invalid-setter-param-count/actual.js new file mode 100644 index 0000000000..1ccbc71755 --- /dev/null +++ b/test/fixtures/flow/object-types/invalid-setter-param-count/actual.js @@ -0,0 +1,3 @@ +type B = { + set a(): void; +} diff --git a/test/fixtures/flow/object-types/invalid-setter-param-count/options.json b/test/fixtures/flow/object-types/invalid-setter-param-count/options.json new file mode 100644 index 0000000000..8ea95ab888 --- /dev/null +++ b/test/fixtures/flow/object-types/invalid-setter-param-count/options.json @@ -0,0 +1,3 @@ +{ + "throws": "setter should have exactly one param (2:2)" +} diff --git a/test/fixtures/flow/type-alias/4/expected.json b/test/fixtures/flow/type-alias/4/expected.json index 42a84bca7b..c45c0020b6 100644 --- a/test/fixtures/flow/type-alias/4/expected.json +++ b/test/fixtures/flow/type-alias/4/expected.json @@ -122,6 +122,8 @@ }, "name": "type" }, + "static": false, + "kind": "init", "value": { "type": "StringLiteralTypeAnnotation", "start": 23, @@ -142,9 +144,8 @@ }, "value": "A" }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -197,6 +198,8 @@ }, "name": "type" }, + "static": false, + "kind": "init", "value": { "type": "StringLiteralTypeAnnotation", "start": 38, @@ -217,9 +220,8 @@ }, "value": "B" }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -521,6 +523,8 @@ }, "name": "x" }, + "static": false, + "kind": "init", "value": { "type": "UnionTypeAnnotation", "start": 147, @@ -583,6 +587,8 @@ }, "name": "type" }, + "static": false, + "kind": "init", "value": { "type": "StringLiteralTypeAnnotation", "start": 156, @@ -603,9 +609,8 @@ }, "value": "A" }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -658,6 +663,8 @@ }, "name": "type" }, + "static": false, + "kind": "init", "value": { "type": "StringLiteralTypeAnnotation", "start": 174, @@ -678,9 +685,8 @@ }, "value": "B" }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -688,9 +694,8 @@ } ] }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -776,6 +781,8 @@ }, "name": "x" }, + "static": false, + "kind": "init", "value": { "type": "IntersectionTypeAnnotation", "start": 212, @@ -838,6 +845,8 @@ }, "name": "type" }, + "static": false, + "kind": "init", "value": { "type": "StringLiteralTypeAnnotation", "start": 221, @@ -858,9 +867,8 @@ }, "value": "A" }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -913,6 +921,8 @@ }, "name": "type" }, + "static": false, + "kind": "init", "value": { "type": "StringLiteralTypeAnnotation", "start": 239, @@ -933,9 +943,8 @@ }, "value": "B" }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -943,9 +952,8 @@ } ] }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/108/expected.json b/test/fixtures/flow/type-annotations/108/expected.json index cc7cae44e2..54aad24d12 100644 --- a/test/fixtures/flow/type-annotations/108/expected.json +++ b/test/fixtures/flow/type-annotations/108/expected.json @@ -134,6 +134,8 @@ }, "name": "x" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 14, @@ -149,9 +151,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -184,6 +185,8 @@ }, "name": "y" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 25, @@ -199,9 +202,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -446,6 +448,8 @@ }, "name": "x" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 71, @@ -461,9 +465,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -496,6 +499,8 @@ }, "name": "y" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 82, @@ -511,9 +516,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -858,6 +862,8 @@ }, "name": "a" }, + "static": false, + "kind": "init", "value": { "type": "ObjectTypeAnnotation", "start": 148, @@ -905,6 +911,8 @@ }, "name": "x" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 154, @@ -920,9 +928,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -955,6 +962,8 @@ }, "name": "y" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 165, @@ -970,17 +979,15 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], "exact": true }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -1013,6 +1020,8 @@ }, "name": "b" }, + "static": false, + "kind": "init", "value": { "type": "BooleanTypeAnnotation", "start": 179, @@ -1028,9 +1037,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -1378,6 +1386,8 @@ }, "name": "a" }, + "static": false, + "kind": "init", "value": { "type": "ObjectTypeAnnotation", "start": 242, @@ -1425,6 +1435,8 @@ }, "name": "x" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 247, @@ -1440,9 +1452,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -1475,6 +1486,8 @@ }, "name": "y" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 258, @@ -1490,17 +1503,15 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], "exact": false }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -1533,6 +1544,8 @@ }, "name": "b" }, + "static": false, + "kind": "init", "value": { "type": "BooleanTypeAnnotation", "start": 271, @@ -1548,9 +1561,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/110/expected.json b/test/fixtures/flow/type-annotations/110/expected.json index f637eb85b6..063bbf7e97 100644 --- a/test/fixtures/flow/type-annotations/110/expected.json +++ b/test/fixtures/flow/type-annotations/110/expected.json @@ -107,6 +107,8 @@ }, "name": "p" }, + "static": false, + "kind": "init", "value": { "type": "GenericTypeAnnotation", "start": 13, @@ -140,8 +142,6 @@ "name": "T" } }, - "optional": false, - "static": false, "variance": { "type": "Variance", "start": 10, @@ -157,7 +157,8 @@ } }, "kind": "plus" - } + }, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/111/expected.json b/test/fixtures/flow/type-annotations/111/expected.json index 088ac9c758..02766a4758 100644 --- a/test/fixtures/flow/type-annotations/111/expected.json +++ b/test/fixtures/flow/type-annotations/111/expected.json @@ -107,6 +107,8 @@ }, "name": "p" }, + "static": false, + "kind": "init", "value": { "type": "GenericTypeAnnotation", "start": 13, @@ -140,8 +142,6 @@ "name": "T" } }, - "optional": false, - "static": false, "variance": { "type": "Variance", "start": 10, @@ -157,7 +157,8 @@ } }, "kind": "minus" - } + }, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/136/expected.json b/test/fixtures/flow/type-annotations/136/expected.json index ca0bd530db..6ccd7002c9 100644 --- a/test/fixtures/flow/type-annotations/136/expected.json +++ b/test/fixtures/flow/type-annotations/136/expected.json @@ -107,6 +107,8 @@ }, "name": "p" }, + "static": false, + "kind": "init", "value": { "type": "ObjectTypeAnnotation", "start": 15, @@ -126,9 +128,8 @@ "indexers": [], "exact": false }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeSpreadProperty", diff --git a/test/fixtures/flow/type-annotations/32/expected.json b/test/fixtures/flow/type-annotations/32/expected.json index ce82a0dbf1..2009fe86e1 100644 --- a/test/fixtures/flow/type-annotations/32/expected.json +++ b/test/fixtures/flow/type-annotations/32/expected.json @@ -134,6 +134,8 @@ }, "name": "numVal" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 16, @@ -149,9 +151,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/33/expected.json b/test/fixtures/flow/type-annotations/33/expected.json index 7739fea5f1..20c064ef1a 100644 --- a/test/fixtures/flow/type-annotations/33/expected.json +++ b/test/fixtures/flow/type-annotations/33/expected.json @@ -134,6 +134,8 @@ }, "name": "numVal" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 16, @@ -149,9 +151,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/34/expected.json b/test/fixtures/flow/type-annotations/34/expected.json index aa0ad93518..8214472aee 100644 --- a/test/fixtures/flow/type-annotations/34/expected.json +++ b/test/fixtures/flow/type-annotations/34/expected.json @@ -134,6 +134,8 @@ }, "name": "numVal" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 16, @@ -149,9 +151,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [ diff --git a/test/fixtures/flow/type-annotations/35/expected.json b/test/fixtures/flow/type-annotations/35/expected.json index 226236359b..0a016d2518 100644 --- a/test/fixtures/flow/type-annotations/35/expected.json +++ b/test/fixtures/flow/type-annotations/35/expected.json @@ -148,6 +148,8 @@ }, "name": "numVal" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 17, @@ -163,9 +165,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/36/expected.json b/test/fixtures/flow/type-annotations/36/expected.json index 4ccc7c692f..31e1d58d02 100644 --- a/test/fixtures/flow/type-annotations/36/expected.json +++ b/test/fixtures/flow/type-annotations/36/expected.json @@ -134,6 +134,8 @@ }, "name": "numVal" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 16, @@ -149,9 +151,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -184,6 +185,8 @@ }, "name": "strVal" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 32, @@ -199,9 +202,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/37/expected.json b/test/fixtures/flow/type-annotations/37/expected.json index ef13a1423d..5c4dbc804f 100644 --- a/test/fixtures/flow/type-annotations/37/expected.json +++ b/test/fixtures/flow/type-annotations/37/expected.json @@ -134,6 +134,8 @@ }, "name": "subObj" }, + "static": false, + "kind": "init", "value": { "type": "ObjectTypeAnnotation", "start": 16, @@ -181,6 +183,8 @@ }, "name": "strVal" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 25, @@ -196,17 +200,15 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], "exact": false }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/38/expected.json b/test/fixtures/flow/type-annotations/38/expected.json index a37a224c5e..13365bd73e 100644 --- a/test/fixtures/flow/type-annotations/38/expected.json +++ b/test/fixtures/flow/type-annotations/38/expected.json @@ -134,6 +134,8 @@ }, "name": "subObj" }, + "static": false, + "kind": "init", "value": { "type": "NullableTypeAnnotation", "start": 16, @@ -195,6 +197,8 @@ }, "name": "strVal" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 26, @@ -210,18 +214,16 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], "exact": false } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/39/expected.json b/test/fixtures/flow/type-annotations/39/expected.json index ba0346f3e3..ff7898371e 100644 --- a/test/fixtures/flow/type-annotations/39/expected.json +++ b/test/fixtures/flow/type-annotations/39/expected.json @@ -134,6 +134,8 @@ }, "name": "param1" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 16, @@ -149,9 +151,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -184,6 +185,8 @@ }, "name": "param2" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 32, @@ -199,9 +202,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/40/expected.json b/test/fixtures/flow/type-annotations/40/expected.json index bd5b46e71f..fc457a1df3 100644 --- a/test/fixtures/flow/type-annotations/40/expected.json +++ b/test/fixtures/flow/type-annotations/40/expected.json @@ -134,6 +134,8 @@ }, "name": "param1" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 16, @@ -149,9 +151,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -184,6 +185,8 @@ }, "name": "param2" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 33, @@ -199,9 +202,8 @@ } } }, - "optional": true, - "static": false, - "variance": null + "variance": null, + "optional": true } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/42/expected.json b/test/fixtures/flow/type-annotations/42/expected.json index c02588c4e6..71e3447c35 100644 --- a/test/fixtures/flow/type-annotations/42/expected.json +++ b/test/fixtures/flow/type-annotations/42/expected.json @@ -117,6 +117,25 @@ "column": 47 } }, + "key": { + "type": "Identifier", + "start": 8, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "add" + }, + "name": "add" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 8, @@ -295,24 +314,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 8, - "end": 11, - "loc": { - "start": { - "line": 1, - "column": 8 - }, - "end": { - "line": 1, - "column": 11 - }, - "identifierName": "add" - }, - "name": "add" - }, "optional": false } ], diff --git a/test/fixtures/flow/type-annotations/43/expected.json b/test/fixtures/flow/type-annotations/43/expected.json index d888673773..07ba5008e4 100644 --- a/test/fixtures/flow/type-annotations/43/expected.json +++ b/test/fixtures/flow/type-annotations/43/expected.json @@ -117,6 +117,25 @@ "column": 23 } }, + "key": { + "type": "Identifier", + "start": 9, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "id" + }, + "name": "id" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 9, @@ -268,24 +287,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 9, - "end": 11, - "loc": { - "start": { - "line": 1, - "column": 9 - }, - "end": { - "line": 1, - "column": 11 - }, - "identifierName": "id" - }, - "name": "id" - }, "optional": false } ], diff --git a/test/fixtures/flow/type-annotations/60/expected.json b/test/fixtures/flow/type-annotations/60/expected.json index 71d0a6e5f9..7bcec9cc23 100644 --- a/test/fixtures/flow/type-annotations/60/expected.json +++ b/test/fixtures/flow/type-annotations/60/expected.json @@ -189,6 +189,8 @@ }, "name": "x" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 13, @@ -204,9 +206,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/61/expected.json b/test/fixtures/flow/type-annotations/61/expected.json index b08974f765..d67405b5b2 100644 --- a/test/fixtures/flow/type-annotations/61/expected.json +++ b/test/fixtures/flow/type-annotations/61/expected.json @@ -189,6 +189,8 @@ }, "name": "x" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 13, @@ -204,9 +206,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/63/expected.json b/test/fixtures/flow/type-annotations/63/expected.json index e0bbfe124f..9317604671 100644 --- a/test/fixtures/flow/type-annotations/63/expected.json +++ b/test/fixtures/flow/type-annotations/63/expected.json @@ -195,6 +195,8 @@ }, "name": "x" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 23, @@ -210,9 +212,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-annotations/98/expected.json b/test/fixtures/flow/type-annotations/98/expected.json index 7100fa77f8..0b51971251 100644 --- a/test/fixtures/flow/type-annotations/98/expected.json +++ b/test/fixtures/flow/type-annotations/98/expected.json @@ -134,6 +134,8 @@ }, "name": "param1" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 17, @@ -149,9 +151,8 @@ } } }, - "optional": true, - "static": false, - "variance": null + "variance": null, + "optional": true }, { "type": "ObjectTypeProperty", @@ -184,6 +185,8 @@ }, "name": "param2" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 33, @@ -199,9 +202,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -234,6 +236,8 @@ }, "name": "param3" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 49, @@ -249,9 +253,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-exports/interface/expected.json b/test/fixtures/flow/type-exports/interface/expected.json index 45366de3c4..f835d903ed 100644 --- a/test/fixtures/flow/type-exports/interface/expected.json +++ b/test/fixtures/flow/type-exports/interface/expected.json @@ -126,6 +126,8 @@ }, "name": "p" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 26, @@ -141,9 +143,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], @@ -297,6 +298,8 @@ }, "name": "p" }, + "static": false, + "kind": "init", "value": { "type": "GenericTypeAnnotation", "start": 65, @@ -330,9 +333,8 @@ "name": "T" } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], diff --git a/test/fixtures/flow/type-parameter-declaration/declare-class-method-reserved-word/expected.json b/test/fixtures/flow/type-parameter-declaration/declare-class-method-reserved-word/expected.json index df4896c159..c70f16d94e 100644 --- a/test/fixtures/flow/type-parameter-declaration/declare-class-method-reserved-word/expected.json +++ b/test/fixtures/flow/type-parameter-declaration/declare-class-method-reserved-word/expected.json @@ -92,6 +92,25 @@ "column": 19 } }, + "key": { + "type": "Identifier", + "start": 20, + "end": 26, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 8 + }, + "identifierName": "foobar" + }, + "name": "foobar" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 20, @@ -158,24 +177,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 20, - "end": 26, - "loc": { - "start": { - "line": 2, - "column": 2 - }, - "end": { - "line": 2, - "column": 8 - }, - "identifierName": "foobar" - }, - "name": "foobar" - }, "optional": false }, { @@ -192,6 +193,25 @@ "column": 19 } }, + "key": { + "type": "Identifier", + "start": 41, + "end": 47, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 8 + }, + "identifierName": "delete" + }, + "name": "delete" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 41, @@ -258,24 +278,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 41, - "end": 47, - "loc": { - "start": { - "line": 3, - "column": 2 - }, - "end": { - "line": 3, - "column": 8 - }, - "identifierName": "delete" - }, - "name": "delete" - }, "optional": false }, { @@ -292,6 +294,25 @@ "column": 18 } }, + "key": { + "type": "Identifier", + "start": 62, + "end": 67, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 4, + "column": 7 + }, + "identifierName": "yield" + }, + "name": "yield" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 62, @@ -358,24 +379,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 62, - "end": 67, - "loc": { - "start": { - "line": 4, - "column": 2 - }, - "end": { - "line": 4, - "column": 7 - }, - "identifierName": "yield" - }, - "name": "yield" - }, "optional": false }, { @@ -392,6 +395,25 @@ "column": 15 } }, + "key": { + "type": "Identifier", + "start": 82, + "end": 84, + "loc": { + "start": { + "line": 5, + "column": 2 + }, + "end": { + "line": 5, + "column": 4 + }, + "identifierName": "do" + }, + "name": "do" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 82, @@ -458,24 +480,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 82, - "end": 84, - "loc": { - "start": { - "line": 5, - "column": 2 - }, - "end": { - "line": 5, - "column": 4 - }, - "identifierName": "do" - }, - "name": "do" - }, "optional": false }, { @@ -492,6 +496,25 @@ "column": 26 } }, + "key": { + "type": "Identifier", + "start": 106, + "end": 112, + "loc": { + "start": { + "line": 6, + "column": 9 + }, + "end": { + "line": 6, + "column": 15 + }, + "identifierName": "foobar" + }, + "name": "foobar" + }, + "static": true, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 99, @@ -558,24 +581,6 @@ } } }, - "static": true, - "key": { - "type": "Identifier", - "start": 106, - "end": 112, - "loc": { - "start": { - "line": 6, - "column": 9 - }, - "end": { - "line": 6, - "column": 15 - }, - "identifierName": "foobar" - }, - "name": "foobar" - }, "optional": false }, { @@ -592,6 +597,25 @@ "column": 26 } }, + "key": { + "type": "Identifier", + "start": 134, + "end": 140, + "loc": { + "start": { + "line": 7, + "column": 9 + }, + "end": { + "line": 7, + "column": 15 + }, + "identifierName": "delete" + }, + "name": "delete" + }, + "static": true, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 127, @@ -658,24 +682,6 @@ } } }, - "static": true, - "key": { - "type": "Identifier", - "start": 134, - "end": 140, - "loc": { - "start": { - "line": 7, - "column": 9 - }, - "end": { - "line": 7, - "column": 15 - }, - "identifierName": "delete" - }, - "name": "delete" - }, "optional": false }, { @@ -692,6 +698,25 @@ "column": 25 } }, + "key": { + "type": "Identifier", + "start": 162, + "end": 167, + "loc": { + "start": { + "line": 8, + "column": 9 + }, + "end": { + "line": 8, + "column": 14 + }, + "identifierName": "yield" + }, + "name": "yield" + }, + "static": true, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 155, @@ -758,24 +783,6 @@ } } }, - "static": true, - "key": { - "type": "Identifier", - "start": 162, - "end": 167, - "loc": { - "start": { - "line": 8, - "column": 9 - }, - "end": { - "line": 8, - "column": 14 - }, - "identifierName": "yield" - }, - "name": "yield" - }, "optional": false }, { @@ -792,6 +799,25 @@ "column": 22 } }, + "key": { + "type": "Identifier", + "start": 189, + "end": 191, + "loc": { + "start": { + "line": 9, + "column": 9 + }, + "end": { + "line": 9, + "column": 11 + }, + "identifierName": "do" + }, + "name": "do" + }, + "static": true, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 182, @@ -858,24 +884,6 @@ } } }, - "static": true, - "key": { - "type": "Identifier", - "start": 189, - "end": 191, - "loc": { - "start": { - "line": 9, - "column": 9 - }, - "end": { - "line": 9, - "column": 11 - }, - "identifierName": "do" - }, - "name": "do" - }, "optional": false } ], diff --git a/test/fixtures/flow/type-parameter-declaration/declare-interface-method-reserved-word/expected.json b/test/fixtures/flow/type-parameter-declaration/declare-interface-method-reserved-word/expected.json index d6ee0660f0..1bc3f578c1 100644 --- a/test/fixtures/flow/type-parameter-declaration/declare-interface-method-reserved-word/expected.json +++ b/test/fixtures/flow/type-parameter-declaration/declare-interface-method-reserved-word/expected.json @@ -92,6 +92,25 @@ "column": 19 } }, + "key": { + "type": "Identifier", + "start": 24, + "end": 30, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 8 + }, + "identifierName": "foobar" + }, + "name": "foobar" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 24, @@ -158,24 +177,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 24, - "end": 30, - "loc": { - "start": { - "line": 2, - "column": 2 - }, - "end": { - "line": 2, - "column": 8 - }, - "identifierName": "foobar" - }, - "name": "foobar" - }, "optional": false }, { @@ -192,6 +193,25 @@ "column": 19 } }, + "key": { + "type": "Identifier", + "start": 45, + "end": 51, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 8 + }, + "identifierName": "delete" + }, + "name": "delete" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 45, @@ -258,24 +278,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 45, - "end": 51, - "loc": { - "start": { - "line": 3, - "column": 2 - }, - "end": { - "line": 3, - "column": 8 - }, - "identifierName": "delete" - }, - "name": "delete" - }, "optional": false }, { @@ -292,6 +294,25 @@ "column": 18 } }, + "key": { + "type": "Identifier", + "start": 66, + "end": 71, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 4, + "column": 7 + }, + "identifierName": "yield" + }, + "name": "yield" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 66, @@ -358,24 +379,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 66, - "end": 71, - "loc": { - "start": { - "line": 4, - "column": 2 - }, - "end": { - "line": 4, - "column": 7 - }, - "identifierName": "yield" - }, - "name": "yield" - }, "optional": false }, { @@ -392,6 +395,25 @@ "column": 15 } }, + "key": { + "type": "Identifier", + "start": 86, + "end": 88, + "loc": { + "start": { + "line": 5, + "column": 2 + }, + "end": { + "line": 5, + "column": 4 + }, + "identifierName": "do" + }, + "name": "do" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 86, @@ -458,24 +480,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 86, - "end": 88, - "loc": { - "start": { - "line": 5, - "column": 2 - }, - "end": { - "line": 5, - "column": 4 - }, - "identifierName": "do" - }, - "name": "do" - }, "optional": false } ], diff --git a/test/fixtures/flow/type-parameter-declaration/interface-reserved-word/expected.json b/test/fixtures/flow/type-parameter-declaration/interface-reserved-word/expected.json index d14c0aa7a3..42e5d3ce8b 100644 --- a/test/fixtures/flow/type-parameter-declaration/interface-reserved-word/expected.json +++ b/test/fixtures/flow/type-parameter-declaration/interface-reserved-word/expected.json @@ -92,6 +92,25 @@ "column": 19 } }, + "key": { + "type": "Identifier", + "start": 16, + "end": 22, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 8 + }, + "identifierName": "foobar" + }, + "name": "foobar" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 16, @@ -158,24 +177,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 16, - "end": 22, - "loc": { - "start": { - "line": 2, - "column": 2 - }, - "end": { - "line": 2, - "column": 8 - }, - "identifierName": "foobar" - }, - "name": "foobar" - }, "optional": false }, { @@ -192,6 +193,25 @@ "column": 19 } }, + "key": { + "type": "Identifier", + "start": 37, + "end": 43, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 8 + }, + "identifierName": "delete" + }, + "name": "delete" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 37, @@ -258,24 +278,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 37, - "end": 43, - "loc": { - "start": { - "line": 3, - "column": 2 - }, - "end": { - "line": 3, - "column": 8 - }, - "identifierName": "delete" - }, - "name": "delete" - }, "optional": false }, { @@ -292,6 +294,25 @@ "column": 18 } }, + "key": { + "type": "Identifier", + "start": 58, + "end": 63, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 4, + "column": 7 + }, + "identifierName": "yield" + }, + "name": "yield" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 58, @@ -358,24 +379,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 58, - "end": 63, - "loc": { - "start": { - "line": 4, - "column": 2 - }, - "end": { - "line": 4, - "column": 7 - }, - "identifierName": "yield" - }, - "name": "yield" - }, "optional": false }, { @@ -392,6 +395,25 @@ "column": 15 } }, + "key": { + "type": "Identifier", + "start": 78, + "end": 80, + "loc": { + "start": { + "line": 5, + "column": 2 + }, + "end": { + "line": 5, + "column": 4 + }, + "identifierName": "do" + }, + "name": "do" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 78, @@ -458,24 +480,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 78, - "end": 80, - "loc": { - "start": { - "line": 5, - "column": 2 - }, - "end": { - "line": 5, - "column": 4 - }, - "identifierName": "do" - }, - "name": "do" - }, "optional": false } ], diff --git a/test/fixtures/flow/type-parameter-declaration/type-object-reserved-word/expected.json b/test/fixtures/flow/type-parameter-declaration/type-object-reserved-word/expected.json index c3bb865167..5847ba7708 100644 --- a/test/fixtures/flow/type-parameter-declaration/type-object-reserved-word/expected.json +++ b/test/fixtures/flow/type-parameter-declaration/type-object-reserved-word/expected.json @@ -90,6 +90,25 @@ "column": 19 } }, + "key": { + "type": "Identifier", + "start": 13, + "end": 19, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 8 + }, + "identifierName": "foobar" + }, + "name": "foobar" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 13, @@ -156,24 +175,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 13, - "end": 19, - "loc": { - "start": { - "line": 2, - "column": 2 - }, - "end": { - "line": 2, - "column": 8 - }, - "identifierName": "foobar" - }, - "name": "foobar" - }, "optional": false }, { @@ -190,6 +191,25 @@ "column": 19 } }, + "key": { + "type": "Identifier", + "start": 34, + "end": 40, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 8 + }, + "identifierName": "delete" + }, + "name": "delete" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 34, @@ -256,24 +276,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 34, - "end": 40, - "loc": { - "start": { - "line": 3, - "column": 2 - }, - "end": { - "line": 3, - "column": 8 - }, - "identifierName": "delete" - }, - "name": "delete" - }, "optional": false }, { @@ -290,6 +292,25 @@ "column": 18 } }, + "key": { + "type": "Identifier", + "start": 55, + "end": 60, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 4, + "column": 7 + }, + "identifierName": "yield" + }, + "name": "yield" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 55, @@ -356,24 +377,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 55, - "end": 60, - "loc": { - "start": { - "line": 4, - "column": 2 - }, - "end": { - "line": 4, - "column": 7 - }, - "identifierName": "yield" - }, - "name": "yield" - }, "optional": false }, { @@ -390,6 +393,25 @@ "column": 15 } }, + "key": { + "type": "Identifier", + "start": 75, + "end": 77, + "loc": { + "start": { + "line": 5, + "column": 2 + }, + "end": { + "line": 5, + "column": 4 + }, + "identifierName": "do" + }, + "name": "do" + }, + "static": false, + "kind": "init", "value": { "type": "FunctionTypeAnnotation", "start": 75, @@ -456,24 +478,6 @@ } } }, - "static": false, - "key": { - "type": "Identifier", - "start": 75, - "end": 77, - "loc": { - "start": { - "line": 5, - "column": 2 - }, - "end": { - "line": 5, - "column": 4 - }, - "identifierName": "do" - }, - "name": "do" - }, "optional": false } ], diff --git a/test/fixtures/flow/typecasts/2/expected.json b/test/fixtures/flow/typecasts/2/expected.json index e9f527ccb8..e41a4f7b34 100644 --- a/test/fixtures/flow/typecasts/2/expected.json +++ b/test/fixtures/flow/typecasts/2/expected.json @@ -244,6 +244,8 @@ }, "name": "xxx" }, + "static": false, + "kind": "init", "value": { "type": "NumberTypeAnnotation", "start": 29, @@ -259,9 +261,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false }, { "type": "ObjectTypeProperty", @@ -294,6 +295,8 @@ }, "name": "yyy" }, + "static": false, + "kind": "init", "value": { "type": "StringTypeAnnotation", "start": 42, @@ -309,9 +312,8 @@ } } }, - "optional": false, - "static": false, - "variance": null + "variance": null, + "optional": false } ], "indexers": [], From 00d6db9fbb712e26f72d4fd5a5abe82b7754b0fe Mon Sep 17 00:00:00 2001 From: Alex Kuzmenko Date: Fri, 21 Apr 2017 16:22:50 +0300 Subject: [PATCH 10/73] Fixed invalid number literal parsing (#473) * Fixed invalid number literal parsing * Don't ignore period or E characters after octal numbers cherry-pick fix from acorn * Fix tests --- src/tokenizer/index.js | 12 ++++++++---- test/fixtures/core/uncategorised/554/actual.js | 1 + test/fixtures/core/uncategorised/554/options.json | 3 +++ 3 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/core/uncategorised/554/actual.js create mode 100644 test/fixtures/core/uncategorised/554/options.json diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index b9137487ef..74f03f3088 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -582,30 +582,34 @@ export default class Tokenizer { readNumber(startsWithDot: boolean): void { const start = this.state.pos; - const firstIsZero = this.input.charCodeAt(start) === 48; // '0' + let octal = this.input.charCodeAt(start) === 48; // '0' let isFloat = false; if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number"); + if (octal && this.state.pos == start + 1) octal = false; // number === 0 + let next = this.input.charCodeAt(this.state.pos); - if (next === 46) { // '.' + if (next === 46 && !octal) { // '.' ++this.state.pos; this.readInt(10); isFloat = true; next = this.input.charCodeAt(this.state.pos); } - if (next === 69 || next === 101) { // 'eE' + + if ((next === 69 || next === 101) && !octal) { // 'eE' next = this.input.charCodeAt(++this.state.pos); if (next === 43 || next === 45) ++this.state.pos; // '+-' if (this.readInt(10) === null) this.raise(start, "Invalid number"); isFloat = true; } + if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.state.pos, "Identifier directly after number"); const str = this.input.slice(start, this.state.pos); let val; if (isFloat) { val = parseFloat(str); - } else if (!firstIsZero || str.length === 1) { + } else if (!octal || str.length === 1) { val = parseInt(str, 10); } else if (this.state.strict) { this.raise(start, "Invalid number"); diff --git a/test/fixtures/core/uncategorised/554/actual.js b/test/fixtures/core/uncategorised/554/actual.js new file mode 100644 index 0000000000..204735a64f --- /dev/null +++ b/test/fixtures/core/uncategorised/554/actual.js @@ -0,0 +1 @@ +var a = 0123.; \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/554/options.json b/test/fixtures/core/uncategorised/554/options.json new file mode 100644 index 0000000000..e247a786c1 --- /dev/null +++ b/test/fixtures/core/uncategorised/554/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token (1:13)" +} From d975b91a5408ef78f7cf18594a07812f12c03252 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 21 Apr 2017 06:59:46 -0700 Subject: [PATCH 11/73] Refresh property ordering in baselines (#454) --- test/fixtures/flow/literal-types/string-double/expected.json | 2 +- test/fixtures/flow/literal-types/string-single/expected.json | 2 +- test/fixtures/flow/type-annotations/100/expected.json | 2 +- test/fixtures/flow/type-annotations/12/expected.json | 2 +- test/fixtures/flow/type-annotations/13/expected.json | 2 +- test/fixtures/flow/type-annotations/130/expected.json | 2 +- test/fixtures/flow/type-annotations/14/expected.json | 2 +- test/fixtures/flow/type-annotations/15/expected.json | 2 +- test/fixtures/flow/type-annotations/16/expected.json | 2 +- test/fixtures/flow/type-annotations/21/expected.json | 2 +- test/fixtures/flow/type-annotations/22/expected.json | 2 +- test/fixtures/flow/type-annotations/23/expected.json | 2 +- test/fixtures/flow/type-annotations/24/expected.json | 2 +- test/fixtures/flow/type-annotations/25/expected.json | 2 +- test/fixtures/flow/type-annotations/26/expected.json | 2 +- test/fixtures/flow/type-annotations/28/expected.json | 2 +- test/fixtures/flow/type-annotations/29/expected.json | 2 +- test/fixtures/flow/type-annotations/50/expected.json | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/test/fixtures/flow/literal-types/string-double/expected.json b/test/fixtures/flow/literal-types/string-double/expected.json index 97893a5689..010fa630f4 100644 --- a/test/fixtures/flow/literal-types/string-double/expected.json +++ b/test/fixtures/flow/literal-types/string-double/expected.json @@ -116,6 +116,7 @@ } } ], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 38, @@ -164,7 +165,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 55, diff --git a/test/fixtures/flow/literal-types/string-single/expected.json b/test/fixtures/flow/literal-types/string-single/expected.json index bbdf5f7e6c..bd14fc10ac 100644 --- a/test/fixtures/flow/literal-types/string-single/expected.json +++ b/test/fixtures/flow/literal-types/string-single/expected.json @@ -116,6 +116,7 @@ } } ], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 38, @@ -164,7 +165,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 55, diff --git a/test/fixtures/flow/type-annotations/100/expected.json b/test/fixtures/flow/type-annotations/100/expected.json index dee215f26f..a0e6a89d2c 100644 --- a/test/fixtures/flow/type-annotations/100/expected.json +++ b/test/fixtures/flow/type-annotations/100/expected.json @@ -114,6 +114,7 @@ "expression": false, "async": false, "params": [], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 17, @@ -145,7 +146,6 @@ "value": true } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 23, diff --git a/test/fixtures/flow/type-annotations/12/expected.json b/test/fixtures/flow/type-annotations/12/expected.json index 8643321a36..22f2c3c9df 100644 --- a/test/fixtures/flow/type-annotations/12/expected.json +++ b/test/fixtures/flow/type-annotations/12/expected.json @@ -63,6 +63,7 @@ "expression": false, "async": false, "params": [], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 14, @@ -93,7 +94,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 21, diff --git a/test/fixtures/flow/type-annotations/13/expected.json b/test/fixtures/flow/type-annotations/13/expected.json index 79007cd2cd..3a78824d22 100644 --- a/test/fixtures/flow/type-annotations/13/expected.json +++ b/test/fixtures/flow/type-annotations/13/expected.json @@ -63,6 +63,7 @@ "expression": false, "async": false, "params": [], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 14, @@ -111,7 +112,6 @@ "typeParameters": null } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 25, diff --git a/test/fixtures/flow/type-annotations/130/expected.json b/test/fixtures/flow/type-annotations/130/expected.json index 8fd8731f5c..15ad52dcb9 100644 --- a/test/fixtures/flow/type-annotations/130/expected.json +++ b/test/fixtures/flow/type-annotations/130/expected.json @@ -242,6 +242,7 @@ } } ], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 34, @@ -272,7 +273,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 43, diff --git a/test/fixtures/flow/type-annotations/14/expected.json b/test/fixtures/flow/type-annotations/14/expected.json index 9368eb0561..807aa5b5a4 100644 --- a/test/fixtures/flow/type-annotations/14/expected.json +++ b/test/fixtures/flow/type-annotations/14/expected.json @@ -63,6 +63,7 @@ "expression": false, "async": false, "params": [], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 14, @@ -160,7 +161,6 @@ "typeParameters": null } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 33, diff --git a/test/fixtures/flow/type-annotations/15/expected.json b/test/fixtures/flow/type-annotations/15/expected.json index 3e0cbfc4ee..9d52a5cde3 100644 --- a/test/fixtures/flow/type-annotations/15/expected.json +++ b/test/fixtures/flow/type-annotations/15/expected.json @@ -63,6 +63,7 @@ "expression": false, "async": false, "params": [], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 14, @@ -160,7 +161,6 @@ "typeParameters": null } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 34, diff --git a/test/fixtures/flow/type-annotations/16/expected.json b/test/fixtures/flow/type-annotations/16/expected.json index 16a7f500d7..51bc95587f 100644 --- a/test/fixtures/flow/type-annotations/16/expected.json +++ b/test/fixtures/flow/type-annotations/16/expected.json @@ -63,6 +63,7 @@ "expression": false, "async": false, "params": [], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 14, @@ -97,7 +98,6 @@ "exact": false } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 19, diff --git a/test/fixtures/flow/type-annotations/21/expected.json b/test/fixtures/flow/type-annotations/21/expected.json index 11ac28aa29..c5d4df45b5 100644 --- a/test/fixtures/flow/type-annotations/21/expected.json +++ b/test/fixtures/flow/type-annotations/21/expected.json @@ -178,6 +178,7 @@ } } ], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 28, @@ -208,7 +209,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 33, diff --git a/test/fixtures/flow/type-annotations/22/expected.json b/test/fixtures/flow/type-annotations/22/expected.json index 7e408c0077..3cbd6273d8 100644 --- a/test/fixtures/flow/type-annotations/22/expected.json +++ b/test/fixtures/flow/type-annotations/22/expected.json @@ -130,6 +130,7 @@ "expression": false, "async": false, "params": [], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 16, @@ -160,7 +161,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 23, diff --git a/test/fixtures/flow/type-annotations/23/expected.json b/test/fixtures/flow/type-annotations/23/expected.json index a0d584a412..05b77ef383 100644 --- a/test/fixtures/flow/type-annotations/23/expected.json +++ b/test/fixtures/flow/type-annotations/23/expected.json @@ -195,6 +195,7 @@ } } ], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 14, @@ -243,7 +244,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 18, diff --git a/test/fixtures/flow/type-annotations/24/expected.json b/test/fixtures/flow/type-annotations/24/expected.json index bef2f718ee..ffb6d1e92c 100644 --- a/test/fixtures/flow/type-annotations/24/expected.json +++ b/test/fixtures/flow/type-annotations/24/expected.json @@ -195,6 +195,7 @@ } } ], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 15, @@ -243,7 +244,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 19, diff --git a/test/fixtures/flow/type-annotations/25/expected.json b/test/fixtures/flow/type-annotations/25/expected.json index 17b2ed9260..cdf03fcf78 100644 --- a/test/fixtures/flow/type-annotations/25/expected.json +++ b/test/fixtures/flow/type-annotations/25/expected.json @@ -195,6 +195,7 @@ } } ], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 20, @@ -243,7 +244,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 24, diff --git a/test/fixtures/flow/type-annotations/26/expected.json b/test/fixtures/flow/type-annotations/26/expected.json index 3a317643db..9a5cf1d754 100644 --- a/test/fixtures/flow/type-annotations/26/expected.json +++ b/test/fixtures/flow/type-annotations/26/expected.json @@ -198,6 +198,7 @@ } } ], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 15, @@ -246,7 +247,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 19, diff --git a/test/fixtures/flow/type-annotations/28/expected.json b/test/fixtures/flow/type-annotations/28/expected.json index c67f48e7ca..4dc6a8495b 100644 --- a/test/fixtures/flow/type-annotations/28/expected.json +++ b/test/fixtures/flow/type-annotations/28/expected.json @@ -162,6 +162,7 @@ } } ], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 36, @@ -192,7 +193,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 41, diff --git a/test/fixtures/flow/type-annotations/29/expected.json b/test/fixtures/flow/type-annotations/29/expected.json index 47b047f5d5..14dda0a969 100644 --- a/test/fixtures/flow/type-annotations/29/expected.json +++ b/test/fixtures/flow/type-annotations/29/expected.json @@ -114,6 +114,7 @@ "expression": false, "async": false, "params": [], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 24, @@ -144,7 +145,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 31, diff --git a/test/fixtures/flow/type-annotations/50/expected.json b/test/fixtures/flow/type-annotations/50/expected.json index 8ca1334648..2682c49d27 100644 --- a/test/fixtures/flow/type-annotations/50/expected.json +++ b/test/fixtures/flow/type-annotations/50/expected.json @@ -182,6 +182,7 @@ "expression": false, "async": false, "params": [], + "predicate": null, "returnType": { "type": "TypeAnnotation", "start": 23, @@ -212,7 +213,6 @@ } } }, - "predicate": null, "body": { "type": "BlockStatement", "start": 31, From bc0719a1455d351f25aa66a1fdbebccfa992d038 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Fri, 21 Apr 2017 09:25:34 -0500 Subject: [PATCH 12/73] Ensure non pattern shorthand props are checked for reserved words (#479) --- src/parser/expression.js | 3 ++- test/fixtures/es2015/shorthand/1/actual.js | 1 + test/fixtures/es2015/shorthand/1/options.json | 3 +++ test/fixtures/es2015/shorthand/2/actual.js | 1 + test/fixtures/es2015/shorthand/2/options.json | 3 +++ 5 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/es2015/shorthand/1/actual.js create mode 100644 test/fixtures/es2015/shorthand/1/options.json create mode 100644 test/fixtures/es2015/shorthand/2/actual.js create mode 100644 test/fixtures/es2015/shorthand/2/options.json diff --git a/src/parser/expression.js b/src/parser/expression.js index aeb6464f8d..e813460314 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -878,8 +878,9 @@ pp.parseObjectProperty = function (prop, startPos, startLoc, isPattern, refShort } if (!prop.computed && prop.key.type === "Identifier") { + this.checkReservedWord(prop.key.name, prop.key.start, true, true); + if (isPattern) { - this.checkReservedWord(prop.key.name, prop.key.start, true, true); prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); } else if (this.match(tt.eq) && refShorthandDefaultPos) { if (!refShorthandDefaultPos.start) { diff --git a/test/fixtures/es2015/shorthand/1/actual.js b/test/fixtures/es2015/shorthand/1/actual.js new file mode 100644 index 0000000000..5ce7c9deac --- /dev/null +++ b/test/fixtures/es2015/shorthand/1/actual.js @@ -0,0 +1 @@ +var x = ({ const }); diff --git a/test/fixtures/es2015/shorthand/1/options.json b/test/fixtures/es2015/shorthand/1/options.json new file mode 100644 index 0000000000..a618f5e2ef --- /dev/null +++ b/test/fixtures/es2015/shorthand/1/options.json @@ -0,0 +1,3 @@ +{ + "throws": "const is a reserved word (1:11)" +} diff --git a/test/fixtures/es2015/shorthand/2/actual.js b/test/fixtures/es2015/shorthand/2/actual.js new file mode 100644 index 0000000000..fabf36837d --- /dev/null +++ b/test/fixtures/es2015/shorthand/2/actual.js @@ -0,0 +1 @@ +({ get, this, if }); diff --git a/test/fixtures/es2015/shorthand/2/options.json b/test/fixtures/es2015/shorthand/2/options.json new file mode 100644 index 0000000000..7691eb820f --- /dev/null +++ b/test/fixtures/es2015/shorthand/2/options.json @@ -0,0 +1,3 @@ +{ + "throws": "this is a reserved word (1:8)" +} From 8601f2f7da8285a49d5d7d3fb3bf76e096668e74 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 21 Apr 2017 10:48:09 -0700 Subject: [PATCH 13/73] Add type declarations for AST nodes (#480) --- src/types.js | 706 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 706 insertions(+) create mode 100644 src/types.js diff --git a/src/types.js b/src/types.js new file mode 100644 index 0000000000..d7d4f388f5 --- /dev/null +++ b/src/types.js @@ -0,0 +1,706 @@ +// @flow + +import type { Token } from "./tokenizer"; +import type { SourceLocation } from "./util/location"; + +/* + * If making any changes to the AST, update: + * - This repository: + * - This file + * - `ast` directory + * - Babel repository: + * - packages/babel-types/src/definitions + * - packages/babel-generators/src/generators + */ + +export type Comment = { + type: "CommentBlock" | "CommentLine"; + value: string; + start: number; + end: number; + loc: SourceLocation; +}; + +export interface NodeBase { + start: number; + end: number; + loc: SourceLocation; + range: [number, number]; + leadingComments?: ?Array; + trailingComments?: ?Array; + innerComments?: ?Array; + + extra: { [key: string]: any }; +} + +// Using a union type for `Node` makes type-checking too slow. +// Instead, add an index signature to allow a Node to be treated as anything. +export type Node = NodeBase & { [key: string]: any }; +export type Expression = Node; +export type Statement = Node; +export type Pattern = + | Identifier + | ObjectPattern + | ArrayPattern + | RestElement + | AssignmentPattern; +export type Declaration = + | VariableDeclaration + | ClassDeclaration + | FunctionDeclaration; +export type DeclarationBase = NodeBase; + +// TODO: Not in spec +export type HasDecorators = NodeBase & { + decorators?: $ReadOnlyArray; +}; + +export type Identifier = PatternBase & { + type: "Identifier"; + name: string; + + __clone(): Identifier; +}; + +// Literals + +export type Literal = RegExpLiteral | NullLiteral | StringLiteral | BooleanLiteral | NumericLiteral; + +export type RegExpLiteral = NodeBase & { + type: "RegExpLiteral"; + pattern: string; + flags: RegExp$flags; +}; + +export type NullLiteral = NodeBase & { + type: "NullLiteral"; +} + +export type StringLiteral = NodeBase & { + type: "StringLiteral"; + value: string; +}; + +export type BooleanLiteral = NodeBase & { + type: "BooleanLiteral"; + value: boolean; +}; + +export type NumericLiteral = NodeBase & { + type: "NumericLiteral"; + value: number; +}; + +// Programs + +export type BlockStatementLike = Program | BlockStatement; + +export type File = NodeBase & { + type: "File"; + program: Program; + comments: $ReadOnlyArray; + tokens: $ReadOnlyArray; +}; + +export type Program = NodeBase & { + type: "Program"; + sourceType: "script" | "module"; + body: Array; // TODO: $ReadOnlyArray + directives: $ReadOnlyArray; // TODO: Not in spec +}; + +// Functions + +export type Function = + NormalFunction | ArrowFunctionExpression | ObjectMethod | ClassMethod; + +export type NormalFunction = + FunctionDeclaration | FunctionExpression; + +export type FunctionBase = HasDecorators & { + id: ?Identifier; + params: $ReadOnlyArray; + body: BlockStatement; + generator: boolean; + async: boolean; + + expression: boolean; // TODO: Not in spec + typeParameters?: ?FlowTypeParameterDeclaration; // TODO: Not in spec + returnType?: ?FlowTypeAnnotation; // TODO: Not in spec +}; + +// Statements + +export type ExpressionStatement = NodeBase & { + type: "ExpressionStatement"; + expression: Expression; +}; + +export type BlockStatement = NodeBase & { + type: "BlockStatement"; + body: Array; // TODO: $ReadOnlyArray + directives: $ReadOnlyArray; +}; + +export type EmptyStatement = NodeBase & { + type: "EmptyStatement" +}; + +export type DebuggerStatement = NodeBase & { + type: "DebuggerStatement" +}; + +export type WithStatement = NodeBase & { + type: "WithStatement"; + object: Expression; + body: Statement; +}; + +export type ReturnStatement = NodeBase & { + type: "ReturnStatement"; + argument: ?Expression; +}; + +export type LabeledStatement = NodeBase & { + type: "LabeledStatement"; + label: Identifier; + body: Statement; +}; + +export type BreakStatement = NodeBase & { + type: "BreakStatement"; + label: ?Identifier; +}; + +export type ContinueStatement = NodeBase & { + type: "ContinueStatement"; + label: ?Identifier; +}; + +// Choice + +export type IfStatement = NodeBase & { + type: "IfStatement"; + test: Expression; + consequent: Statement; + alternate: ?Statement; +}; + +export type SwitchStatement = NodeBase & { + type: "SwitchStatement"; + discriminant: Expression; + cases: $ReadOnlyArray; +}; + +export type SwitchCase = NodeBase & { + type: "SwitchCase"; + test: ?Expression; + consequent: $ReadOnlyArray; +}; + +// Exceptions + +export type ThrowStatement = NodeBase & { + type: "ThrowStatement"; + argument: Expression; +}; + +export type TryStatement = NodeBase & { + type: "TryStatement"; + block: BlockStatement; + handler: CatchClause | null; + finalizer: BlockStatement | null; + + guardedHandlers: $ReadOnlyArray; // TODO: Not in spec +}; + +export type CatchClause = NodeBase & { + type: "CatchClause"; + param: Pattern; + body: BlockStatement; +}; + +// Loops + +export type WhileStatement = NodeBase & { + type: "WhileStatement"; + test: Expression; + body: Statement; +}; + +export type DoWhileStatement = NodeBase & { + type: "DoWhileStatement"; + body: Statement; + test: Expression; +}; + +export type ForLike = ForStatement | ForInOf; + +export type ForStatement = NodeBase & { + type: "ForStatement"; + init: ?(VariableDeclaration | Expression); + test: ?Expression; + update: ?Expression; + body: Statement; +}; + +export type ForInOf = ForInStatement | ForOfStatement; + +export type ForInOfBase = NodeBase & { + type: "ForInStatement"; + left: VariableDeclaration | Expression; + right: Expression; + body: Statement; +}; + +export type ForInStatement = ForInOfBase & { + type: "ForInStatement"; + // TODO: Shouldn't be here, but have to declare it because it's assigned to a ForInOf unconditionally. + await: boolean; +}; + +export type ForOfStatement = ForInOfBase & { + type: "ForOfStatement"; + await: boolean; +}; + +// Declarations + +export type FunctionDeclaration = FunctionBase & DeclarationBase & HasDecorators & { + type: "FunctionDeclaration"; + id: Identifier; +}; + +export type VariableDeclaration = DeclarationBase & HasDecorators & { + type: "VariableDeclaration"; + declarations: $ReadOnlyArray; + kind: "var" | "let" | "const"; +}; + +export type VariableDeclarator = NodeBase & { + type: "VariableDeclarator"; + id: Pattern; + init: ?Expression; +}; + +// Misc + +export type Decorator = NodeBase & { + type: "Decorator"; + expression: Expression; +}; + +export type Directive = NodeBase & { + type: "Directive"; + value: DirectiveLiteral; +}; + +export type DirectiveLiteral = StringLiteral & { type: "DirectiveLiteral" }; + +// Expressions + +export type Super = NodeBase & { type: "Super" }; + +export type Import = NodeBase & { type: "Import" }; + +export type ThisExpression = NodeBase & { type: "ThisExpression" }; + +export type ArrowFunctionExpression = FunctionBase & { + type: "ArrowFunctionExpression"; + body: BlockStatement | Expression; +}; + +export type YieldExpression = NodeBase & { + type: "YieldExpression"; + argument: ?Expression; + delegate: boolean; +}; + +export type AwaitExpression = NodeBase & { + type: "AwaitExpression"; + argument: ?Expression; +}; + +export type ArrayExpression = NodeBase & { + type: "ArrayExpression"; + elements: $ReadOnlyArray; +}; + +export type ObjectExpression = NodeBase & { + type: "ObjectExpression"; + properties: $ReadOnlyArray; +}; + +export type ObjectOrClassMember = ClassMethod | ClassProperty | ObjectMember; + +export type ObjectMember = ObjectProperty | ObjectMethod; + +export type ObjectMemberBase = NodeBase & { + key: Expression; + computed: boolean; + value: Expression; + decorators: $ReadOnlyArray; + kind?: "get" | "set" | "method"; + method: boolean; // TODO: Not in spec + + variance?: ?FlowVariance; // TODO: Not in spec +}; + +export type ObjectProperty = ObjectMemberBase & { + type: "ObjectProperty"; + shorthand: boolean; +}; + +export type ObjectMethod = ObjectMemberBase & MethodBase & { + type: "ObjectMethod"; + kind: "get" | "set" | "method"; // Never "constructor" +}; + +export type FunctionExpression = MethodBase & { + kind?: void; // never set + type: "FunctionExpression"; +}; + +// Unary operations + +export type UnaryExpression = NodeBase & { + type: "UnaryExpression"; + operator: UnaryOperator; + prefix: boolean; + argument: Expression; +}; + +export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"; + +export type UpdateExpression = NodeBase & { + type: "UpdateExpression"; + operator: UpdateOperator; + argument: Expression; + prefix: boolean; +}; + +export type UpdateOperator = "++" | "--"; + +// Binary operations + +export type BinaryExpression = NodeBase & { + type: "BinaryExpression"; + operator: BinaryOperator; + left: Expression; + right: Expression; +}; + +export type BinaryOperator = + | "==" | "!=" | "===" | "!==" + | "<" | "<=" | ">" | ">=" + | "<<" | ">>" | ">>>" + | "+" | "-" | "*" | "/" | "%" + | "|" | "^" | "&" | "in" + | "instanceof"; + +export type AssignmentExpression = NodeBase & { + type: "AssignmentExpression"; + operator: AssignmentOperator; + left: Pattern | Expression; + right: Expression; +}; + +export type AssignmentOperator = + | "=" | "+=" | "-=" | "*=" | "/=" | "%=" + | "<<=" | ">>=" | ">>>=" + | "|=" | "^=" | "&="; + +export type LogicalExpression = NodeBase & { + type: "LogicalExpression"; + operator: LogicalOperator; + left: Expression; + right: Expression; +}; + +export type LogicalOperator = "||" | "&&"; + +export type SpreadElement = NodeBase & { + type: "SpreadElement"; + argument: Expression; +}; + +export type MemberExpression = NodeBase & { + type: "MemberExpression"; + object: Expression | Super; + property: Expression; + computed: boolean; +} + +export type BindExpression = NodeBase & { + type: "BindExpression"; + object: $ReadOnlyArray; + callee: $ReadOnlyArray; +}; + +export type ConditionalExpression = NodeBase & { + type: "ConditionalExpression"; + test: Expression; + alternate: Expression; + consequent: Expression; +}; + +export type CallOrNewBase = NodeBase & { + callee: Expression | Super | Import; + arguments: Array; // TODO: $ReadOnlyArray +}; + +export type CallExpression = CallOrNewBase & { + type: "CallExpression"; +}; + +export type NewExpression = CallOrNewBase & { + type: "NewExpression"; +}; + +export type SequenceExpression = NodeBase & { + type: "SequenceExpression"; + expressions: $ReadOnlyArray; +}; + +// Template Literals + +export type TemplateLiteral = NodeBase & { + type: "TemplateLiteral"; + quasis: $ReadOnlyArray; + expressions: $ReadOnlyArray; +}; + +export type TaggedTmplateExpression = NodeBase & { + type: "TaggedTemplateExpression"; + tag: Expression; + quasi: TemplateLiteral; +}; + +export type TemplateElement = NodeBase & { + type: "TemplateElement"; + tail: boolean; + value: { + cooked: string; + raw: string; + } +}; + +// Patterns + +export type PatternBase = HasDecorators & { + // Flow only: + typeAnnotation?: ?FlowTypeAnnotation; +}; + +export type AssignmentProperty = ObjectProperty & { + value: Pattern; +}; + +export type ObjectPattern = PatternBase & { + type: "ObjectPattern"; + properties: $ReadOnlyArray; +}; + +export type ArrayPattern = PatternBase & { + type: "ArrayPattern"; + elements: $ReadOnlyArray; +}; + +export type RestElement = PatternBase & { + type: "RestElement"; + argument: Pattern; +}; + +export type AssignmentPattern = PatternBase & { + type: "AssignmentPattern"; + left: Pattern; + right: Expression; +}; + +// Classes + +export type Class = ClassDeclaration | ClassExpression; + +export type ClassBase = HasDecorators & { + id: ?Identifier; + superClass: ?Expression; + body: ClassBody; + decorators: $ReadOnlyArray; + + typeParameters?: ?FlowTypeParameterDeclaration; // TODO: Not in spec + superTypeParameters?: ?FlowTypeParameterInstantiation; // TODO: Not in spec + implements?: $ReadOnlyArray; +}; + +export type ClassBody = NodeBase & { + type: "ClassBody"; + body: Array; // TODO: $ReadOnlyArray +}; + +export type ClassMemberBase = NodeBase & HasDecorators & { + static: boolean; + computed: boolean; + // TypeScript only: + access?: ?Accessibility; + abstract?: ?true; + optional?: ?true; +} + +export type Accessibility = "public" | "protected" | "private"; + +export type ClassMember = ClassMethod | ClassProperty; + +export type MethodLike = ObjectMethod | FunctionExpression | ClassMethod; + +export type MethodBase = FunctionBase & { + +kind?: MethodKind; +}; + +export type MethodKind = "constructor" | "method" | "get" | "set"; + +export type ClassMethod = MethodBase & ClassMemberBase & { + type: "ClassMethod"; + key: Expression; + kind: MethodKind; + static: boolean; + decorators: $ReadOnlyArray; + + variance?: ?FlowVariance; // TODO: Not in spec +}; + +export type ClassProperty = ClassMemberBase & { + type: "ClassProperty"; + key: Identifier; + value: ?Expression; // TODO: Not in spec that this is nullable. + + typeAnnotation?: ?FlowTypeAnnotation; // TODO: Not in spec + variance?: ?FlowVariance; // TODO: Not in spec + + // TypeScript only: (TODO: Not in spec) + readonly?: true; +}; + +export type ClassDeclaration = ClassBase & DeclarationBase & HasDecorators & { + type: "ClassDeclaration"; + id: Identifier; + // TypeScript only + abstract?: ?true; +}; + +export type ClassExpression = ClassBase & { type: "ClassExpression" }; + +export type MetaProperty = NodeBase & { + type: "MetaProperty"; + meta: Identifier; + property: Identifier; +}; + +// Modules + +export type ModuleDeclaration = AnyImport | AnyExport; + +export type AnyImport = ImportDeclaration; + +export type AnyExport = + | ExportNamedDeclaration + | ExportDefaultDeclaration + | ExportAllDeclaration; + +export type ModuleSpecifier = NodeBase & { + local: Identifier; +}; + +// Imports + +export type ImportDeclaration = NodeBase & { + type: "ImportDeclaration"; + // TODO: $ReadOnlyArray + specifiers: Array; + source: Literal; + + importKind?: "type" | "typeof" | "value"; // TODO: Not in spec +}; + +export type ImportSpecifier = ModuleSpecifier & { + type: "ImportSpecifier"; + imported: Identifier; +}; + +export type ImportDefaultSpecifier = ModuleSpecifier & { + type: "ImportDefaultSpecifier" +}; + +export type ImportNamespaceSpecifier = ModuleSpecifier & { + type: "ImportNamespaceSpecifier" +}; + +// Exports + +export type ExportNamedDeclaration = NodeBase & { + type: "ExportNamedDeclaration"; + declaration: ?Declaration; + specifiers: Array; // TODO: $ReadOnlyArray + source: ?Literal; + + exportKind?: "type" | "value"; // TODO: Not in spec +}; + +export type ExportSpecifier = NodeBase & { + type: "ExportSpecifier"; + exported: Identifier; +}; + +export type ExportDefaultDeclaration = NodeBase & { + type: "ExportDefaultDeclaration"; + declaration: Declaration | Expression; +}; + +export type ExportAllDeclaration = NodeBase & { + type: "ExportAllDeclaration"; + source: Literal; +}; + +// JSX (TODO: Not in spec) + +export type JSXIdentifier = Node; +export type JSXNamespacedName = Node; +export type JSXMemberExpression = Node; +export type JSXEmptyExpression = Node; +export type JSXSpreadChild = Node; +export type JSXExpressionContainer = Node; +export type JSXAttribute = Node; +export type JSXOpeningElement = Node; +export type JSXClosingElement = Node; +export type JSXElement = Node; + +// Flow (TODO: Not in spec) + +export type FlowType = Node; +export type FlowPredicate = Node; +export type FlowDeclare = Node; +export type FlowDeclareClass = Node; +export type FlowDeclareFunction = Node; +export type FlowDeclareVariable = Node; +export type FlowDeclareModule = Node; +export type FlowDeclareModuleExports = Node; +export type FlowDeclareTypeAlias = Node; +export type FlowDeclareInterface = Node; +export type FlowInterface = Node; +export type FlowInterfaceExtends = Node; +export type FlowTypeAlias = Node; +export type FlowTypeParameter = Node; +export type FlowTypeParameterDeclaration = Node; +export type FlowTypeParameterInstantiation = Node; +export type FlowObjectTypeIndexer = Node; +export type FlowFunctionTypeAnnotation = Node; +export type FlowObjectTypeProperty = Node; +export type FlowObjectTypeCallProperty = Node; +export type FlowObjectTypeAnnotation = Node; +export type FlowQualifiedTypeIdentifier = Node; +export type FlowGenericTypeAnnotation = Node; +export type FlowTypeofTypeAnnotation = Node; +export type FlowTupleTypeAnnotation = Node; +export type FlowFunctionTypeParam = Node; +export type FlowTypeAnnotation = Node; +export type FlowVariance = Node; +export type FlowClassImplements = Node; From 2c1193b7daa0d342934404248ba26d6557808453 Mon Sep 17 00:00:00 2001 From: Andy Date: Sun, 23 Apr 2017 15:34:35 -0700 Subject: [PATCH 14/73] Move plugin helpers out of Parser.prototype and into the plugin itself (#482) --- src/plugins/estree.js | 74 +- src/plugins/flow.js | 1739 +++++++++++++++++++------------------- src/plugins/jsx/index.js | 695 +++++++-------- 3 files changed, 1256 insertions(+), 1252 deletions(-) diff --git a/src/plugins/estree.js b/src/plugins/estree.js index 585cd7dc2b..3d9f9477a7 100644 --- a/src/plugins/estree.js +++ b/src/plugins/estree.js @@ -1,40 +1,4 @@ import { types as tt } from "../tokenizer/types"; -import Parser from "../parser"; - -const pp = Parser.prototype; - -pp.estreeParseRegExpLiteral = function ({ pattern, flags }) { - let regex = null; - try { - regex = new RegExp(pattern, flags); - } catch (e) { - // In environments that don't support these flags value will - // be null as the regex can't be represented natively. - } - const node = this.estreeParseLiteral(regex); - node.regex = { pattern, flags }; - - return node; -}; - -pp.estreeParseLiteral = function (value) { - return this.parseLiteral(value, "Literal"); -}; - -pp.directiveToStmt = function (directive) { - const directiveLiteral = directive.value; - - const stmt = this.startNodeAt(directive.start, directive.loc.start); - const expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start); - - expression.value = directiveLiteral.value; - expression.raw = directiveLiteral.extra.raw; - - stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end); - stmt.directive = directiveLiteral.extra.raw.slice(1, -1); - - return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end); -}; function isSimpleProperty(node) { return node && @@ -44,6 +8,44 @@ function isSimpleProperty(node) { } export default (superClass) => class extends superClass { + estreeParseRegExpLiteral({ pattern, flags }) { + let regex = null; + try { + regex = new RegExp(pattern, flags); + } catch (e) { + // In environments that don't support these flags value will + // be null as the regex can't be represented natively. + } + const node = this.estreeParseLiteral(regex); + node.regex = { pattern, flags }; + + return node; + } + + estreeParseLiteral(value) { + return this.parseLiteral(value, "Literal"); + } + + directiveToStmt(directive) { + const directiveLiteral = directive.value; + + const stmt = this.startNodeAt(directive.start, directive.loc.start); + const expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start); + + expression.value = directiveLiteral.value; + expression.raw = directiveLiteral.extra.raw; + + stmt.expression = this.finishNodeAt( + expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end); + stmt.directive = directiveLiteral.extra.raw.slice(1, -1); + + return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end); + } + + // ================================== + // Overrides + // ================================== + checkDeclaration(node) { if (isSimpleProperty(node)) { this.checkDeclaration(node.value); diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 3d55c4e7a3..0dcf624fe9 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -2,7 +2,6 @@ import { types as tt } from "../tokenizer/types"; import { types as ct } from "../tokenizer/context"; -import Parser from "../parser"; const primitiveTypes = [ "any", @@ -16,127 +15,6 @@ const primitiveTypes = [ "null" ]; -const pp = Parser.prototype; - -pp.flowParseTypeInitialiser = function (tok) { - const oldInType = this.state.inType; - this.state.inType = true; - this.expect(tok || tt.colon); - - const type = this.flowParseType(); - this.state.inType = oldInType; - return type; -}; - -pp.flowParsePredicate = function() { - const node = this.startNode(); - const moduloLoc = this.state.startLoc; - const moduloPos = this.state.start; - this.expect(tt.modulo); - const checksLoc = this.state.startLoc; - this.expectContextual("checks"); - // Force '%' and 'checks' to be adjacent - if (moduloLoc.line !== checksLoc.line || moduloLoc.column !== checksLoc.column - 1) { - this.raise(moduloPos, "Spaces between ´%´ and ´checks´ are not allowed here."); - } - if (this.eat(tt.parenL)) { - node.value = this.parseExpression(); - this.expect(tt.parenR); - return this.finishNode(node, "DeclaredPredicate"); - } else { - return this.finishNode(node, "InferredPredicate"); - } -}; - -pp.flowParseTypeAndPredicateInitialiser = function () { - const oldInType = this.state.inType; - this.state.inType = true; - this.expect(tt.colon); - let type = null; - let predicate = null; - if (this.match(tt.modulo)) { - this.state.inType = oldInType; - predicate = this.flowParsePredicate(); - } else { - type = this.flowParseType(); - this.state.inType = oldInType; - if (this.match(tt.modulo)) { - predicate = this.flowParsePredicate(); - } - } - return [type, predicate]; -}; - -pp.flowParseDeclareClass = function (node) { - this.next(); - this.flowParseInterfaceish(node); - return this.finishNode(node, "DeclareClass"); -}; - -pp.flowParseDeclareFunction = function (node) { - this.next(); - - const id = node.id = this.parseIdentifier(); - - const typeNode = this.startNode(); - const typeContainer = this.startNode(); - - if (this.isRelational("<")) { - typeNode.typeParameters = this.flowParseTypeParameterDeclaration(); - } else { - typeNode.typeParameters = null; - } - - this.expect(tt.parenL); - const tmp = this.flowParseFunctionTypeParams(); - typeNode.params = tmp.params; - typeNode.rest = tmp.rest; - this.expect(tt.parenR); - - [typeNode.returnType, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); - typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation"); - - id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation"); - - this.finishNode(id, id.type); - - this.semicolon(); - - return this.finishNode(node, "DeclareFunction"); -}; - -pp.flowParseDeclare = function (node, insideModule) { - if (this.match(tt._class)) { - return this.flowParseDeclareClass(node); - } else if (this.match(tt._function)) { - return this.flowParseDeclareFunction(node); - } else if (this.match(tt._var)) { - return this.flowParseDeclareVariable(node); - } else if (this.isContextual("module")) { - if (this.lookahead().type === tt.dot) { - return this.flowParseDeclareModuleExports(node); - } else { - if (insideModule) this.unexpected(null, "`declare module` cannot be used inside another `declare module`"); - return this.flowParseDeclareModule(node); - } - } else if (this.isContextual("type")) { - return this.flowParseDeclareTypeAlias(node); - } else if (this.isContextual("interface")) { - return this.flowParseDeclareInterface(node); - } else if (this.match(tt._export)) { - return this.flowParseDeclareExportDeclaration(node, insideModule); - } else { - this.unexpected(); - } -}; - -pp.flowParseDeclareVariable = function (node) { - this.next(); - node.id = this.flowParseTypeAnnotatableIdentifier(); - this.semicolon(); - return this.finishNode(node, "DeclareVariable"); -}; - function isEsModuleType(bodyElement) { return bodyElement.type === "DeclareExportAllDeclaration" || ( @@ -148,59 +26,6 @@ function isEsModuleType(bodyElement) { ); } -pp.flowParseDeclareModule = function (node) { - this.next(); - - if (this.match(tt.string)) { - node.id = this.parseExprAtom(); - } else { - node.id = this.parseIdentifier(); - } - - const bodyNode = node.body = this.startNode(); - const body = bodyNode.body = []; - this.expect(tt.braceL); - while (!this.match(tt.braceR)) { - let bodyNode = this.startNode(); - - if (this.match(tt._import)) { - const lookahead = this.lookahead(); - if (lookahead.value !== "type" && lookahead.value !== "typeof") { - this.unexpected(null, "Imports within a `declare module` body must always be `import type` or `import typeof`"); - } - - this.parseImport(bodyNode); - } else { - this.expectContextual("declare", "Only declares and type imports are allowed inside declare module"); - - bodyNode = this.flowParseDeclare(bodyNode, true); - } - - body.push(bodyNode); - } - this.expect(tt.braceR); - - this.finishNode(bodyNode, "BlockStatement"); - - let kind = null; - let hasModuleExport = false; - const errorMessage = "Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module"; - body.forEach((bodyElement) => { - if (isEsModuleType(bodyElement)) { - if (kind === "CommonJS") this.unexpected(bodyElement.start, errorMessage); - kind = "ES"; - } else if (bodyElement.type === "DeclareModuleExports") { - if (hasModuleExport) this.unexpected(bodyElement.start, "Duplicate `declare module.exports` statement"); - if (kind === "ES") this.unexpected(bodyElement.start, errorMessage); - kind = "CommonJS"; - hasModuleExport = true; - } - }); - - node.kind = kind || "CommonJS"; - return this.finishNode(node, "DeclareModule"); -}; - const exportSuggestions = { const: "declare export var", let: "declare export var", @@ -208,788 +33,964 @@ const exportSuggestions = { interface: "export interface", }; -pp.flowParseDeclareExportDeclaration = function (node, insideModule) { - this.expect(tt._export); +export default (superClass) => class extends superClass { + flowParseTypeInitialiser(tok) { + const oldInType = this.state.inType; + this.state.inType = true; + this.expect(tok || tt.colon); - if (this.eat(tt._default)) { - if (this.match(tt._function) || this.match(tt._class)) { - // declare export default class ... - // declare export default function ... - node.declaration = this.flowParseDeclare(this.startNode()); + const type = this.flowParseType(); + this.state.inType = oldInType; + return type; + } + + flowParsePredicate() { + const node = this.startNode(); + const moduloLoc = this.state.startLoc; + const moduloPos = this.state.start; + this.expect(tt.modulo); + const checksLoc = this.state.startLoc; + this.expectContextual("checks"); + // Force '%' and 'checks' to be adjacent + if (moduloLoc.line !== checksLoc.line || moduloLoc.column !== checksLoc.column - 1) { + this.raise(moduloPos, "Spaces between ´%´ and ´checks´ are not allowed here."); + } + if (this.eat(tt.parenL)) { + node.value = this.parseExpression(); + this.expect(tt.parenR); + return this.finishNode(node, "DeclaredPredicate"); } else { - // declare export default [type]; - node.declaration = this.flowParseType(); - this.semicolon(); + return this.finishNode(node, "InferredPredicate"); } - node.default = true; + } - return this.finishNode(node, "DeclareExportDeclaration"); - } else { - if ( - this.match(tt._const) || this.match(tt._let) || - ( - (this.isContextual("type") || this.isContextual("interface")) && - !insideModule - ) - ) { - const label = this.state.value; - const suggestion = exportSuggestions[label]; - this.unexpected(this.state.start, `\`declare export ${label}\` is not supported. Use \`${suggestion}\` instead`); + flowParseTypeAndPredicateInitialiser() { + const oldInType = this.state.inType; + this.state.inType = true; + this.expect(tt.colon); + let type = null; + let predicate = null; + if (this.match(tt.modulo)) { + this.state.inType = oldInType; + predicate = this.flowParsePredicate(); + } else { + type = this.flowParseType(); + this.state.inType = oldInType; + if (this.match(tt.modulo)) { + predicate = this.flowParsePredicate(); + } + } + return [type, predicate]; + } + + flowParseDeclareClass(node) { + this.next(); + this.flowParseInterfaceish(node); + return this.finishNode(node, "DeclareClass"); + } + + flowParseDeclareFunction(node) { + this.next(); + + const id = node.id = this.parseIdentifier(); + + const typeNode = this.startNode(); + const typeContainer = this.startNode(); + + if (this.isRelational("<")) { + typeNode.typeParameters = this.flowParseTypeParameterDeclaration(); + } else { + typeNode.typeParameters = null; } - if ( - this.match(tt._var) || // declare export var ... - this.match(tt._function) || // declare export function ... - this.match(tt._class) // declare export class ... - ) { - node.declaration = this.flowParseDeclare(this.startNode()); - node.default = false; + this.expect(tt.parenL); + const tmp = this.flowParseFunctionTypeParams(); + typeNode.params = tmp.params; + typeNode.rest = tmp.rest; + this.expect(tt.parenR); - return this.finishNode(node, "DeclareExportDeclaration"); - } else if ( - this.match(tt.star) || // declare export * from '' - this.match(tt.braceL) || // declare export {} ... - this.isContextual("interface") || // declare export interface ... - this.isContextual("type") // declare export type ... - ) { - node = this.parseExport(node); - if (node.type === "ExportNamedDeclaration") { - // flow does not support the ExportNamedDeclaration - node.type = "ExportDeclaration"; - node.default = false; - delete node.exportKind; + [typeNode.returnType, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); + typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation"); + + id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation"); + + this.finishNode(id, id.type); + + this.semicolon(); + + return this.finishNode(node, "DeclareFunction"); + } + + flowParseDeclare(node, insideModule) { + if (this.match(tt._class)) { + return this.flowParseDeclareClass(node); + } else if (this.match(tt._function)) { + return this.flowParseDeclareFunction(node); + } else if (this.match(tt._var)) { + return this.flowParseDeclareVariable(node); + } else if (this.isContextual("module")) { + if (this.lookahead().type === tt.dot) { + return this.flowParseDeclareModuleExports(node); + } else { + if (insideModule) this.unexpected(null, "`declare module` cannot be used inside another `declare module`"); + return this.flowParseDeclareModule(node); + } + } else if (this.isContextual("type")) { + return this.flowParseDeclareTypeAlias(node); + } else if (this.isContextual("interface")) { + return this.flowParseDeclareInterface(node); + } else if (this.match(tt._export)) { + return this.flowParseDeclareExportDeclaration(node, insideModule); + } else { + this.unexpected(); + } + } + + flowParseDeclareVariable(node) { + this.next(); + node.id = this.flowParseTypeAnnotatableIdentifier(); + this.semicolon(); + return this.finishNode(node, "DeclareVariable"); + } + + flowParseDeclareModule(node) { + this.next(); + + if (this.match(tt.string)) { + node.id = this.parseExprAtom(); + } else { + node.id = this.parseIdentifier(); + } + + const bodyNode = node.body = this.startNode(); + const body = bodyNode.body = []; + this.expect(tt.braceL); + while (!this.match(tt.braceR)) { + let bodyNode = this.startNode(); + + if (this.match(tt._import)) { + const lookahead = this.lookahead(); + if (lookahead.value !== "type" && lookahead.value !== "typeof") { + this.unexpected(null, "Imports within a `declare module` body must always be `import type` or `import typeof`"); + } + + this.parseImport(bodyNode); + } else { + this.expectContextual("declare", "Only declares and type imports are allowed inside declare module"); + + bodyNode = this.flowParseDeclare(bodyNode, true); } - node.type = "Declare" + node.type; - - return node; + body.push(bodyNode); } + this.expect(tt.braceR); + + this.finishNode(bodyNode, "BlockStatement"); + + let kind = null; + let hasModuleExport = false; + const errorMessage = "Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module"; + body.forEach((bodyElement) => { + if (isEsModuleType(bodyElement)) { + if (kind === "CommonJS") this.unexpected(bodyElement.start, errorMessage); + kind = "ES"; + } else if (bodyElement.type === "DeclareModuleExports") { + if (hasModuleExport) this.unexpected(bodyElement.start, "Duplicate `declare module.exports` statement"); + if (kind === "ES") this.unexpected(bodyElement.start, errorMessage); + kind = "CommonJS"; + hasModuleExport = true; + } + }); + + node.kind = kind || "CommonJS"; + return this.finishNode(node, "DeclareModule"); } - this.unexpected(); -}; + flowParseDeclareExportDeclaration(node, insideModule) { + this.expect(tt._export); -pp.flowParseDeclareModuleExports = function (node) { - this.expectContextual("module"); - this.expect(tt.dot); - this.expectContextual("exports"); - node.typeAnnotation = this.flowParseTypeAnnotation(); - this.semicolon(); + if (this.eat(tt._default)) { + if (this.match(tt._function) || this.match(tt._class)) { + // declare export default class ... + // declare export default function ... + node.declaration = this.flowParseDeclare(this.startNode()); + } else { + // declare export default [type]; + node.declaration = this.flowParseType(); + this.semicolon(); + } + node.default = true; - return this.finishNode(node, "DeclareModuleExports"); -}; + return this.finishNode(node, "DeclareExportDeclaration"); + } else { + if ( + this.match(tt._const) || this.match(tt._let) || + ( + (this.isContextual("type") || this.isContextual("interface")) && + !insideModule + ) + ) { + const label = this.state.value; + const suggestion = exportSuggestions[label]; + this.unexpected(this.state.start, `\`declare export ${label}\` is not supported. Use \`${suggestion}\` instead`); + } -pp.flowParseDeclareTypeAlias = function (node) { - this.next(); - this.flowParseTypeAlias(node); - return this.finishNode(node, "DeclareTypeAlias"); -}; + if ( + this.match(tt._var) || // declare export var ... + this.match(tt._function) || // declare export function ... + this.match(tt._class) // declare export class ... + ) { + node.declaration = this.flowParseDeclare(this.startNode()); + node.default = false; -pp.flowParseDeclareInterface = function (node) { - this.next(); - this.flowParseInterfaceish(node); - return this.finishNode(node, "DeclareInterface"); -}; + return this.finishNode(node, "DeclareExportDeclaration"); + } else if ( + this.match(tt.star) || // declare export * from '' + this.match(tt.braceL) || // declare export {} ... + this.isContextual("interface") || // declare export interface ... + this.isContextual("type") // declare export type ... + ) { + node = this.parseExport(node); + if (node.type === "ExportNamedDeclaration") { + // flow does not support the ExportNamedDeclaration + node.type = "ExportDeclaration"; + node.default = false; + delete node.exportKind; + } -// Interfaces + node.type = "Declare" + node.type; -pp.flowParseInterfaceish = function (node) { - node.id = this.parseIdentifier(); + return node; + } + } - if (this.isRelational("<")) { - node.typeParameters = this.flowParseTypeParameterDeclaration(); - } else { - node.typeParameters = null; - } - - node.extends = []; - node.mixins = []; - - if (this.eat(tt._extends)) { - do { - node.extends.push(this.flowParseInterfaceExtends()); - } while (this.eat(tt.comma)); - } - - if (this.isContextual("mixins")) { - this.next(); - do { - node.mixins.push(this.flowParseInterfaceExtends()); - } while (this.eat(tt.comma)); - } - - node.body = this.flowParseObjectType(true, false, false); -}; - -pp.flowParseInterfaceExtends = function () { - const node = this.startNode(); - - node.id = this.flowParseQualifiedTypeIdentifier(); - if (this.isRelational("<")) { - node.typeParameters = this.flowParseTypeParameterInstantiation(); - } else { - node.typeParameters = null; - } - - return this.finishNode(node, "InterfaceExtends"); -}; - -pp.flowParseInterface = function (node) { - this.flowParseInterfaceish(node); - return this.finishNode(node, "InterfaceDeclaration"); -}; - -pp.flowParseRestrictedIdentifier = function(liberal) { - if (primitiveTypes.indexOf(this.state.value) > -1) { - this.raise(this.state.start, `Cannot overwrite primitive type ${this.state.value}`); - } - - return this.parseIdentifier(liberal); -}; - -// Type aliases - -pp.flowParseTypeAlias = function (node) { - node.id = this.flowParseRestrictedIdentifier(); - - if (this.isRelational("<")) { - node.typeParameters = this.flowParseTypeParameterDeclaration(); - } else { - node.typeParameters = null; - } - - node.right = this.flowParseTypeInitialiser(tt.eq); - this.semicolon(); - - return this.finishNode(node, "TypeAlias"); -}; - -// Type annotations - -pp.flowParseTypeParameter = function () { - const node = this.startNode(); - - const variance = this.flowParseVariance(); - - const ident = this.flowParseTypeAnnotatableIdentifier(); - node.name = ident.name; - node.variance = variance; - node.bound = ident.typeAnnotation; - - if (this.match(tt.eq)) { - this.eat(tt.eq); - node.default = this.flowParseType(); - } - - return this.finishNode(node, "TypeParameter"); -}; - -pp.flowParseTypeParameterDeclaration = function () { - const oldInType = this.state.inType; - const node = this.startNode(); - node.params = []; - - this.state.inType = true; - - // istanbul ignore else: this condition is already checked at all call sites - if (this.isRelational("<") || this.match(tt.jsxTagStart)) { - this.next(); - } else { this.unexpected(); } - do { - node.params.push(this.flowParseTypeParameter()); - if (!this.isRelational(">")) { - this.expect(tt.comma); + flowParseDeclareModuleExports(node) { + this.expectContextual("module"); + this.expect(tt.dot); + this.expectContextual("exports"); + node.typeAnnotation = this.flowParseTypeAnnotation(); + this.semicolon(); + + return this.finishNode(node, "DeclareModuleExports"); + } + + flowParseDeclareTypeAlias(node) { + this.next(); + this.flowParseTypeAlias(node); + return this.finishNode(node, "DeclareTypeAlias"); + } + + flowParseDeclareInterface(node) { + this.next(); + this.flowParseInterfaceish(node); + return this.finishNode(node, "DeclareInterface"); + } + + // Interfaces + + flowParseInterfaceish(node) { + node.id = this.parseIdentifier(); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } else { + node.typeParameters = null; } - } while (!this.isRelational(">")); - this.expectRelational(">"); - this.state.inType = oldInType; + node.extends = []; + node.mixins = []; - return this.finishNode(node, "TypeParameterDeclaration"); -}; - -pp.flowParseTypeParameterInstantiation = function () { - const node = this.startNode(); - const oldInType = this.state.inType; - node.params = []; - - this.state.inType = true; - - this.expectRelational("<"); - while (!this.isRelational(">")) { - node.params.push(this.flowParseType()); - if (!this.isRelational(">")) { - this.expect(tt.comma); + if (this.eat(tt._extends)) { + do { + node.extends.push(this.flowParseInterfaceExtends()); + } while (this.eat(tt.comma)); } - } - this.expectRelational(">"); - this.state.inType = oldInType; - - return this.finishNode(node, "TypeParameterInstantiation"); -}; - -pp.flowParseObjectPropertyKey = function () { - return (this.match(tt.num) || this.match(tt.string)) ? this.parseExprAtom() : this.parseIdentifier(true); -}; - -pp.flowParseObjectTypeIndexer = function (node, isStatic, variance) { - node.static = isStatic; - - this.expect(tt.bracketL); - if (this.lookahead().type === tt.colon) { - node.id = this.flowParseObjectPropertyKey(); - node.key = this.flowParseTypeInitialiser(); - } else { - node.id = null; - node.key = this.flowParseType(); - } - this.expect(tt.bracketR); - node.value = this.flowParseTypeInitialiser(); - node.variance = variance; - - return this.finishNode(node, "ObjectTypeIndexer"); -}; - -pp.flowParseObjectTypeMethodish = function (node) { - node.params = []; - node.rest = null; - node.typeParameters = null; - - if (this.isRelational("<")) { - node.typeParameters = this.flowParseTypeParameterDeclaration(); - } - - this.expect(tt.parenL); - while (this.match(tt.name)) { - node.params.push(this.flowParseFunctionTypeParam()); - if (!this.match(tt.parenR)) { - this.expect(tt.comma); - } - } - - if (this.eat(tt.ellipsis)) { - node.rest = this.flowParseFunctionTypeParam(); - } - this.expect(tt.parenR); - node.returnType = this.flowParseTypeInitialiser(); - - return this.finishNode(node, "FunctionTypeAnnotation"); -}; - -pp.flowParseObjectTypeCallProperty = function (node, isStatic) { - const valueNode = this.startNode(); - node.static = isStatic; - node.value = this.flowParseObjectTypeMethodish(valueNode); - return this.finishNode(node, "ObjectTypeCallProperty"); -}; - -pp.flowParseObjectType = function (allowStatic, allowExact, allowSpread) { - const oldInType = this.state.inType; - this.state.inType = true; - - const nodeStart = this.startNode(); - - nodeStart.callProperties = []; - nodeStart.properties = []; - nodeStart.indexers = []; - - let endDelim; - let exact; - if (allowExact && this.match(tt.braceBarL)) { - this.expect(tt.braceBarL); - endDelim = tt.braceBarR; - exact = true; - } else { - this.expect(tt.braceL); - endDelim = tt.braceR; - exact = false; - } - - nodeStart.exact = exact; - - while (!this.match(endDelim)) { - let isStatic = false; - const node = this.startNode(); - if (allowStatic && this.isContextual("static") && this.lookahead().type !== tt.colon) { + if (this.isContextual("mixins")) { this.next(); - isStatic = true; + do { + node.mixins.push(this.flowParseInterfaceExtends()); + } while (this.eat(tt.comma)); } + node.body = this.flowParseObjectType(true, false, false); + } + + flowParseInterfaceExtends() { + const node = this.startNode(); + + node.id = this.flowParseQualifiedTypeIdentifier(); + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterInstantiation(); + } else { + node.typeParameters = null; + } + + return this.finishNode(node, "InterfaceExtends"); + } + + flowParseInterface(node) { + this.flowParseInterfaceish(node); + return this.finishNode(node, "InterfaceDeclaration"); + } + + flowParseRestrictedIdentifier(liberal) { + if (primitiveTypes.indexOf(this.state.value) > -1) { + this.raise(this.state.start, `Cannot overwrite primitive type ${this.state.value}`); + } + + return this.parseIdentifier(liberal); + } + + // Type aliases + + flowParseTypeAlias(node) { + node.id = this.flowParseRestrictedIdentifier(); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } else { + node.typeParameters = null; + } + + node.right = this.flowParseTypeInitialiser(tt.eq); + this.semicolon(); + + return this.finishNode(node, "TypeAlias"); + } + + // Type annotations + + flowParseTypeParameter() { + const node = this.startNode(); + const variance = this.flowParseVariance(); - if (this.match(tt.bracketL)) { - nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance)); - } else if (this.match(tt.parenL) || this.isRelational("<")) { - if (variance) { - this.unexpected(variance.start); - } - nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic)); - } else { - let kind = "init"; + const ident = this.flowParseTypeAnnotatableIdentifier(); + node.name = ident.name; + node.variance = variance; + node.bound = ident.typeAnnotation; - if (this.isContextual("get") || this.isContextual("set")) { - const lookahead = this.lookahead(); - if ( - lookahead.type === tt.name || - lookahead.type === tt.string || - lookahead.type === tt.num - ) { - kind = this.state.value; - this.next(); - } - } - - nodeStart.properties.push(this.flowParseObjectTypeProperty(node, isStatic, variance, kind, allowSpread)); + if (this.match(tt.eq)) { + this.eat(tt.eq); + node.default = this.flowParseType(); } - this.flowObjectTypeSemicolon(); + return this.finishNode(node, "TypeParameter"); } - this.expect(endDelim); + flowParseTypeParameterDeclaration() { + const oldInType = this.state.inType; + const node = this.startNode(); + node.params = []; - const out = this.finishNode(nodeStart, "ObjectTypeAnnotation"); + this.state.inType = true; - this.state.inType = oldInType; - - return out; -}; - -pp.flowParseObjectTypeProperty = function (node, isStatic, variance, kind, allowSpread) { - if (this.match(tt.ellipsis)) { - if (!allowSpread) { - this.unexpected( - null, - "Spread operator cannot appear in class or interface definitions" - ); + // istanbul ignore else: this condition is already checked at all call sites + if (this.isRelational("<") || this.match(tt.jsxTagStart)) { + this.next(); + } else { + this.unexpected(); } - if (variance) { - this.unexpected(variance.start, "Spread properties cannot have variance"); - } - this.expect(tt.ellipsis); - node.argument = this.flowParseType(); - return this.finishNode(node, "ObjectTypeSpreadProperty"); - } else { - node.key = this.flowParseObjectPropertyKey(); + do { + node.params.push(this.flowParseTypeParameter()); + if (!this.isRelational(">")) { + this.expect(tt.comma); + } + } while (!this.isRelational(">")); + this.expectRelational(">"); + + this.state.inType = oldInType; + + return this.finishNode(node, "TypeParameterDeclaration"); + } + + flowParseTypeParameterInstantiation() { + const node = this.startNode(); + const oldInType = this.state.inType; + node.params = []; + + this.state.inType = true; + + this.expectRelational("<"); + while (!this.isRelational(">")) { + node.params.push(this.flowParseType()); + if (!this.isRelational(">")) { + this.expect(tt.comma); + } + } + this.expectRelational(">"); + + this.state.inType = oldInType; + + return this.finishNode(node, "TypeParameterInstantiation"); + } + + flowParseObjectPropertyKey() { + return (this.match(tt.num) || this.match(tt.string)) ? this.parseExprAtom() : this.parseIdentifier(true); + } + + flowParseObjectTypeIndexer(node, isStatic, variance) { node.static = isStatic; - node.kind = kind; - let optional = false; - if (this.isRelational("<") || this.match(tt.parenL)) { - // This is a method property - if (variance) { - this.unexpected(variance.start); + this.expect(tt.bracketL); + if (this.lookahead().type === tt.colon) { + node.id = this.flowParseObjectPropertyKey(); + node.key = this.flowParseTypeInitialiser(); + } else { + node.id = null; + node.key = this.flowParseType(); + } + this.expect(tt.bracketR); + node.value = this.flowParseTypeInitialiser(); + node.variance = variance; + + return this.finishNode(node, "ObjectTypeIndexer"); + } + + flowParseObjectTypeMethodish(node) { + node.params = []; + node.rest = null; + node.typeParameters = null; + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } + + this.expect(tt.parenL); + while (this.match(tt.name)) { + node.params.push(this.flowParseFunctionTypeParam()); + if (!this.match(tt.parenR)) { + this.expect(tt.comma); + } + } + + if (this.eat(tt.ellipsis)) { + node.rest = this.flowParseFunctionTypeParam(); + } + this.expect(tt.parenR); + node.returnType = this.flowParseTypeInitialiser(); + + return this.finishNode(node, "FunctionTypeAnnotation"); + } + + flowParseObjectTypeCallProperty(node, isStatic) { + const valueNode = this.startNode(); + node.static = isStatic; + node.value = this.flowParseObjectTypeMethodish(valueNode); + return this.finishNode(node, "ObjectTypeCallProperty"); + } + + flowParseObjectType(allowStatic, allowExact, allowSpread) { + const oldInType = this.state.inType; + this.state.inType = true; + + const nodeStart = this.startNode(); + + nodeStart.callProperties = []; + nodeStart.properties = []; + nodeStart.indexers = []; + + let endDelim; + let exact; + if (allowExact && this.match(tt.braceBarL)) { + this.expect(tt.braceBarL); + endDelim = tt.braceBarR; + exact = true; + } else { + this.expect(tt.braceL); + endDelim = tt.braceR; + exact = false; + } + + nodeStart.exact = exact; + + while (!this.match(endDelim)) { + let isStatic = false; + const node = this.startNode(); + if (allowStatic && this.isContextual("static") && this.lookahead().type !== tt.colon) { + this.next(); + isStatic = true; } - node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start)); - if (kind === "get" || kind === "set") this.flowCheckGetterSetterParamCount(node); + const variance = this.flowParseVariance(); + + if (this.match(tt.bracketL)) { + nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance)); + } else if (this.match(tt.parenL) || this.isRelational("<")) { + if (variance) { + this.unexpected(variance.start); + } + nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic)); + } else { + let kind = "init"; + + if (this.isContextual("get") || this.isContextual("set")) { + const lookahead = this.lookahead(); + if ( + lookahead.type === tt.name || + lookahead.type === tt.string || + lookahead.type === tt.num + ) { + kind = this.state.value; + this.next(); + } + } + + nodeStart.properties.push(this.flowParseObjectTypeProperty(node, isStatic, variance, kind, allowSpread)); + } + + this.flowObjectTypeSemicolon(); + } + + this.expect(endDelim); + + const out = this.finishNode(nodeStart, "ObjectTypeAnnotation"); + + this.state.inType = oldInType; + + return out; + } + + flowParseObjectTypeProperty(node, isStatic, variance, kind, allowSpread) { + if (this.match(tt.ellipsis)) { + if (!allowSpread) { + this.unexpected( + null, + "Spread operator cannot appear in class or interface definitions" + ); + } + if (variance) { + this.unexpected(variance.start, "Spread properties cannot have variance"); + } + this.expect(tt.ellipsis); + node.argument = this.flowParseType(); + + return this.finishNode(node, "ObjectTypeSpreadProperty"); } else { - if (kind !== "init") this.unexpected(); + node.key = this.flowParseObjectPropertyKey(); + node.static = isStatic; + node.kind = kind; + + let optional = false; + if (this.isRelational("<") || this.match(tt.parenL)) { + // This is a method property + if (variance) { + this.unexpected(variance.start); + } + + node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start)); + if (kind === "get" || kind === "set") this.flowCheckGetterSetterParamCount(node); + } else { + if (kind !== "init") this.unexpected(); + if (this.eat(tt.question)) { + optional = true; + } + node.value = this.flowParseTypeInitialiser(); + node.variance = variance; + + } + + node.optional = optional; + + return this.finishNode(node, "ObjectTypeProperty"); + } + } + + // This is similar to checkGetterSetterParamCount, but as + // babylon uses non estree properties we cannot reuse it here + flowCheckGetterSetterParamCount(property) { + const paramCount = property.kind === "get" ? 0 : 1; + if (property.value.params.length !== paramCount) { + const start = property.start; + if (property.kind === "get") { + this.raise(start, "getter should have no params"); + } else { + this.raise(start, "setter should have exactly one param"); + } + } + } + + flowObjectTypeSemicolon() { + if (!this.eat(tt.semi) && !this.eat(tt.comma) && + !this.match(tt.braceR) && !this.match(tt.braceBarR)) { + this.unexpected(); + } + } + + flowParseQualifiedTypeIdentifier(startPos, startLoc, id) { + startPos = startPos || this.state.start; + startLoc = startLoc || this.state.startLoc; + let node = id || this.parseIdentifier(); + + while (this.eat(tt.dot)) { + const node2 = this.startNodeAt(startPos, startLoc); + node2.qualification = node; + node2.id = this.parseIdentifier(); + node = this.finishNode(node2, "QualifiedTypeIdentifier"); + } + + return node; + } + + flowParseGenericType(startPos, startLoc, id) { + const node = this.startNodeAt(startPos, startLoc); + + node.typeParameters = null; + node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterInstantiation(); + } + + return this.finishNode(node, "GenericTypeAnnotation"); + } + + flowParseTypeofType() { + const node = this.startNode(); + this.expect(tt._typeof); + node.argument = this.flowParsePrimaryType(); + return this.finishNode(node, "TypeofTypeAnnotation"); + } + + flowParseTupleType() { + const node = this.startNode(); + node.types = []; + this.expect(tt.bracketL); + // We allow trailing commas + while (this.state.pos < this.input.length && !this.match(tt.bracketR)) { + node.types.push(this.flowParseType()); + if (this.match(tt.bracketR)) break; + this.expect(tt.comma); + } + this.expect(tt.bracketR); + return this.finishNode(node, "TupleTypeAnnotation"); + } + + flowParseFunctionTypeParam() { + let name = null; + let optional = false; + let typeAnnotation = null; + const node = this.startNode(); + const lh = this.lookahead(); + if (lh.type === tt.colon || + lh.type === tt.question) { + name = this.parseIdentifier(); if (this.eat(tt.question)) { optional = true; } - node.value = this.flowParseTypeInitialiser(); - node.variance = variance; - - } - - node.optional = optional; - - return this.finishNode(node, "ObjectTypeProperty"); - } -}; - -// This is similar to checkGetterSetterParamCount, but as -// babylon uses non estree properties we cannot reuse it here -pp.flowCheckGetterSetterParamCount = function (property) { - const paramCount = property.kind === "get" ? 0 : 1; - if (property.value.params.length !== paramCount) { - const start = property.start; - if (property.kind === "get") { - this.raise(start, "getter should have no params"); + typeAnnotation = this.flowParseTypeInitialiser(); } else { - this.raise(start, "setter should have exactly one param"); + typeAnnotation = this.flowParseType(); + } + node.name = name; + node.optional = optional; + node.typeAnnotation = typeAnnotation; + return this.finishNode(node, "FunctionTypeParam"); + } + + reinterpretTypeAsFunctionTypeParam(type) { + const node = this.startNodeAt(type.start, type.loc); + node.name = null; + node.optional = false; + node.typeAnnotation = type; + return this.finishNode(node, "FunctionTypeParam"); + } + + flowParseFunctionTypeParams(params = []) { + const ret = { params, rest: null }; + while (!this.match(tt.parenR) && !this.match(tt.ellipsis)) { + ret.params.push(this.flowParseFunctionTypeParam()); + if (!this.match(tt.parenR)) { + this.expect(tt.comma); + } + } + if (this.eat(tt.ellipsis)) { + ret.rest = this.flowParseFunctionTypeParam(); + } + return ret; + } + + flowIdentToTypeAnnotation(startPos, startLoc, node, id) { + switch (id.name) { + case "any": + return this.finishNode(node, "AnyTypeAnnotation"); + + case "void": + return this.finishNode(node, "VoidTypeAnnotation"); + + case "bool": + case "boolean": + return this.finishNode(node, "BooleanTypeAnnotation"); + + case "mixed": + return this.finishNode(node, "MixedTypeAnnotation"); + + case "empty": + return this.finishNode(node, "EmptyTypeAnnotation"); + + case "number": + return this.finishNode(node, "NumberTypeAnnotation"); + + case "string": + return this.finishNode(node, "StringTypeAnnotation"); + + default: + return this.flowParseGenericType(startPos, startLoc, id); } } -}; -pp.flowObjectTypeSemicolon = function () { - if (!this.eat(tt.semi) && !this.eat(tt.comma) && - !this.match(tt.braceR) && !this.match(tt.braceBarR)) { - this.unexpected(); - } -}; + // The parsing of types roughly parallels the parsing of expressions, and + // primary types are kind of like primary expressions...they're the + // primitives with which other types are constructed. + flowParsePrimaryType() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const node = this.startNode(); + let tmp; + let type; + let isGroupedType = false; + const oldNoAnonFunctionType = this.state.noAnonFunctionType; -pp.flowParseQualifiedTypeIdentifier = function (startPos, startLoc, id) { - startPos = startPos || this.state.start; - startLoc = startLoc || this.state.startLoc; - let node = id || this.parseIdentifier(); + switch (this.state.type) { + case tt.name: + return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier()); - while (this.eat(tt.dot)) { - const node2 = this.startNodeAt(startPos, startLoc); - node2.qualification = node; - node2.id = this.parseIdentifier(); - node = this.finishNode(node2, "QualifiedTypeIdentifier"); - } + case tt.braceL: + return this.flowParseObjectType(false, false, true); - return node; -}; + case tt.braceBarL: + return this.flowParseObjectType(false, true, true); -pp.flowParseGenericType = function (startPos, startLoc, id) { - const node = this.startNodeAt(startPos, startLoc); + case tt.bracketL: + return this.flowParseTupleType(); - node.typeParameters = null; - node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id); + case tt.relational: + if (this.state.value === "<") { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + this.expect(tt.parenL); + tmp = this.flowParseFunctionTypeParams(); + node.params = tmp.params; + node.rest = tmp.rest; + this.expect(tt.parenR); - if (this.isRelational("<")) { - node.typeParameters = this.flowParseTypeParameterInstantiation(); - } + this.expect(tt.arrow); - return this.finishNode(node, "GenericTypeAnnotation"); -}; + node.returnType = this.flowParseType(); -pp.flowParseTypeofType = function () { - const node = this.startNode(); - this.expect(tt._typeof); - node.argument = this.flowParsePrimaryType(); - return this.finishNode(node, "TypeofTypeAnnotation"); -}; + return this.finishNode(node, "FunctionTypeAnnotation"); + } + break; -pp.flowParseTupleType = function () { - const node = this.startNode(); - node.types = []; - this.expect(tt.bracketL); - // We allow trailing commas - while (this.state.pos < this.input.length && !this.match(tt.bracketR)) { - node.types.push(this.flowParseType()); - if (this.match(tt.bracketR)) break; - this.expect(tt.comma); - } - this.expect(tt.bracketR); - return this.finishNode(node, "TupleTypeAnnotation"); -}; + case tt.parenL: + this.next(); -pp.flowParseFunctionTypeParam = function () { - let name = null; - let optional = false; - let typeAnnotation = null; - const node = this.startNode(); - const lh = this.lookahead(); - if (lh.type === tt.colon || - lh.type === tt.question) { - name = this.parseIdentifier(); - if (this.eat(tt.question)) { - optional = true; - } - typeAnnotation = this.flowParseTypeInitialiser(); - } else { - typeAnnotation = this.flowParseType(); - } - node.name = name; - node.optional = optional; - node.typeAnnotation = typeAnnotation; - return this.finishNode(node, "FunctionTypeParam"); -}; + // Check to see if this is actually a grouped type + if (!this.match(tt.parenR) && !this.match(tt.ellipsis)) { + if (this.match(tt.name)) { + const token = this.lookahead().type; + isGroupedType = token !== tt.question && token !== tt.colon; + } else { + isGroupedType = true; + } + } -pp.reinterpretTypeAsFunctionTypeParam = function (type) { - const node = this.startNodeAt(type.start, type.loc); - node.name = null; - node.optional = false; - node.typeAnnotation = type; - return this.finishNode(node, "FunctionTypeParam"); -}; + if (isGroupedType) { + this.state.noAnonFunctionType = false; + type = this.flowParseType(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; -pp.flowParseFunctionTypeParams = function (params = []) { - const ret = { params, rest: null }; - while (!this.match(tt.parenR) && !this.match(tt.ellipsis)) { - ret.params.push(this.flowParseFunctionTypeParam()); - if (!this.match(tt.parenR)) { - this.expect(tt.comma); - } - } - if (this.eat(tt.ellipsis)) { - ret.rest = this.flowParseFunctionTypeParam(); - } - return ret; -}; + // A `,` or a `) =>` means this is an anonymous function type + if (this.state.noAnonFunctionType || + !(this.match(tt.comma) || + (this.match(tt.parenR) && this.lookahead().type === tt.arrow))) { + this.expect(tt.parenR); + return type; + } else { + // Eat a comma if there is one + this.eat(tt.comma); + } + } -pp.flowIdentToTypeAnnotation = function (startPos, startLoc, node, id) { - switch (id.name) { - case "any": - return this.finishNode(node, "AnyTypeAnnotation"); + if (type) { + tmp = this.flowParseFunctionTypeParams( + [this.reinterpretTypeAsFunctionTypeParam(type)], + ); + } else { + tmp = this.flowParseFunctionTypeParams(); + } - case "void": - return this.finishNode(node, "VoidTypeAnnotation"); - - case "bool": - case "boolean": - return this.finishNode(node, "BooleanTypeAnnotation"); - - case "mixed": - return this.finishNode(node, "MixedTypeAnnotation"); - - case "empty": - return this.finishNode(node, "EmptyTypeAnnotation"); - - case "number": - return this.finishNode(node, "NumberTypeAnnotation"); - - case "string": - return this.finishNode(node, "StringTypeAnnotation"); - - default: - return this.flowParseGenericType(startPos, startLoc, id); - } -}; - -// The parsing of types roughly parallels the parsing of expressions, and -// primary types are kind of like primary expressions...they're the -// primitives with which other types are constructed. -pp.flowParsePrimaryType = function () { - const startPos = this.state.start; - const startLoc = this.state.startLoc; - const node = this.startNode(); - let tmp; - let type; - let isGroupedType = false; - const oldNoAnonFunctionType = this.state.noAnonFunctionType; - - switch (this.state.type) { - case tt.name: - return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier()); - - case tt.braceL: - return this.flowParseObjectType(false, false, true); - - case tt.braceBarL: - return this.flowParseObjectType(false, true, true); - - case tt.bracketL: - return this.flowParseTupleType(); - - case tt.relational: - if (this.state.value === "<") { - node.typeParameters = this.flowParseTypeParameterDeclaration(); - this.expect(tt.parenL); - tmp = this.flowParseFunctionTypeParams(); node.params = tmp.params; node.rest = tmp.rest; + this.expect(tt.parenR); this.expect(tt.arrow); node.returnType = this.flowParseType(); + node.typeParameters = null; + return this.finishNode(node, "FunctionTypeAnnotation"); - } - break; - case tt.parenL: - this.next(); + case tt.string: + return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation"); - // Check to see if this is actually a grouped type - if (!this.match(tt.parenR) && !this.match(tt.ellipsis)) { - if (this.match(tt.name)) { - const token = this.lookahead().type; - isGroupedType = token !== tt.question && token !== tt.colon; - } else { - isGroupedType = true; - } - } - - if (isGroupedType) { - this.state.noAnonFunctionType = false; - type = this.flowParseType(); - this.state.noAnonFunctionType = oldNoAnonFunctionType; - - // A `,` or a `) =>` means this is an anonymous function type - if (this.state.noAnonFunctionType || - !(this.match(tt.comma) || - (this.match(tt.parenR) && this.lookahead().type === tt.arrow))) { - this.expect(tt.parenR); - return type; - } else { - // Eat a comma if there is one - this.eat(tt.comma); - } - } - - if (type) { - tmp = this.flowParseFunctionTypeParams( - [this.reinterpretTypeAsFunctionTypeParam(type)], - ); - } else { - tmp = this.flowParseFunctionTypeParams(); - } - - node.params = tmp.params; - node.rest = tmp.rest; - - this.expect(tt.parenR); - - this.expect(tt.arrow); - - node.returnType = this.flowParseType(); - - node.typeParameters = null; - - return this.finishNode(node, "FunctionTypeAnnotation"); - - case tt.string: - return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation"); - - case tt._true: case tt._false: - node.value = this.match(tt._true); - this.next(); - return this.finishNode(node, "BooleanLiteralTypeAnnotation"); - - case tt.plusMin: - if (this.state.value === "-") { + case tt._true: case tt._false: + node.value = this.match(tt._true); this.next(); - if (!this.match(tt.num)) this.unexpected(null, "Unexpected token, expected number"); + return this.finishNode(node, "BooleanLiteralTypeAnnotation"); - return this.parseLiteral(-this.state.value, "NumberLiteralTypeAnnotation", node.start, node.loc.start); - } + case tt.plusMin: + if (this.state.value === "-") { + this.next(); + if (!this.match(tt.num)) this.unexpected(null, "Unexpected token, expected number"); - this.unexpected(); - case tt.num: - return this.parseLiteral(this.state.value, "NumberLiteralTypeAnnotation"); + return this.parseLiteral(-this.state.value, "NumberLiteralTypeAnnotation", node.start, node.loc.start); + } - case tt._null: - node.value = this.match(tt._null); - this.next(); - return this.finishNode(node, "NullLiteralTypeAnnotation"); + this.unexpected(); + case tt.num: + return this.parseLiteral(this.state.value, "NumberLiteralTypeAnnotation"); - case tt._this: - node.value = this.match(tt._this); - this.next(); - return this.finishNode(node, "ThisTypeAnnotation"); + case tt._null: + node.value = this.match(tt._null); + this.next(); + return this.finishNode(node, "NullLiteralTypeAnnotation"); - case tt.star: - this.next(); - return this.finishNode(node, "ExistsTypeAnnotation"); + case tt._this: + node.value = this.match(tt._this); + this.next(); + return this.finishNode(node, "ThisTypeAnnotation"); - default: - if (this.state.type.keyword === "typeof") { - return this.flowParseTypeofType(); - } - } + case tt.star: + this.next(); + return this.finishNode(node, "ExistsTypeAnnotation"); - this.unexpected(); -}; - -pp.flowParsePostfixType = function () { - const startPos = this.state.start, startLoc = this.state.startLoc; - let type = this.flowParsePrimaryType(); - while (!this.canInsertSemicolon() && this.match(tt.bracketL)) { - const node = this.startNodeAt(startPos, startLoc); - node.elementType = type; - this.expect(tt.bracketL); - this.expect(tt.bracketR); - type = this.finishNode(node, "ArrayTypeAnnotation"); - } - return type; -}; - -pp.flowParsePrefixType = function () { - const node = this.startNode(); - if (this.eat(tt.question)) { - node.typeAnnotation = this.flowParsePrefixType(); - return this.finishNode(node, "NullableTypeAnnotation"); - } else { - return this.flowParsePostfixType(); - } -}; - -pp.flowParseAnonFunctionWithoutParens = function () { - const param = this.flowParsePrefixType(); - if (!this.state.noAnonFunctionType && this.eat(tt.arrow)) { - const node = this.startNodeAt(param.start, param.loc); - node.params = [this.reinterpretTypeAsFunctionTypeParam(param)]; - node.rest = null; - node.returnType = this.flowParseType(); - node.typeParameters = null; - return this.finishNode(node, "FunctionTypeAnnotation"); - } - return param; -}; - -pp.flowParseIntersectionType = function () { - const node = this.startNode(); - this.eat(tt.bitwiseAND); - const type = this.flowParseAnonFunctionWithoutParens(); - node.types = [type]; - while (this.eat(tt.bitwiseAND)) { - node.types.push(this.flowParseAnonFunctionWithoutParens()); - } - return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation"); -}; - -pp.flowParseUnionType = function () { - const node = this.startNode(); - this.eat(tt.bitwiseOR); - const type = this.flowParseIntersectionType(); - node.types = [type]; - while (this.eat(tt.bitwiseOR)) { - node.types.push(this.flowParseIntersectionType()); - } - return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation"); -}; - -pp.flowParseType = function () { - const oldInType = this.state.inType; - this.state.inType = true; - const type = this.flowParseUnionType(); - this.state.inType = oldInType; - return type; -}; - -pp.flowParseTypeAnnotation = function () { - const node = this.startNode(); - node.typeAnnotation = this.flowParseTypeInitialiser(); - return this.finishNode(node, "TypeAnnotation"); -}; - -pp.flowParseTypeAnnotatableIdentifier = function () { - const ident = this.flowParseRestrictedIdentifier(); - if (this.match(tt.colon)) { - ident.typeAnnotation = this.flowParseTypeAnnotation(); - this.finishNode(ident, ident.type); - } - return ident; -}; - -pp.typeCastToParameter = function (node) { - node.expression.typeAnnotation = node.typeAnnotation; - - return this.finishNodeAt( - node.expression, - node.expression.type, - node.typeAnnotation.end, - node.typeAnnotation.loc.end - ); -}; - -pp.flowParseVariance = function() { - let variance = null; - if (this.match(tt.plusMin)) { - variance = this.startNode(); - if (this.state.value === "+") { - variance.kind = "plus"; - } else { - variance.kind = "minus"; + default: + if (this.state.type.keyword === "typeof") { + return this.flowParseTypeofType(); + } } - this.next(); - this.finishNode(variance, "Variance"); - } - return variance; -}; -export default (superClass) => class extends superClass { + this.unexpected(); + } + + flowParsePostfixType() { + const startPos = this.state.start, startLoc = this.state.startLoc; + let type = this.flowParsePrimaryType(); + while (!this.canInsertSemicolon() && this.match(tt.bracketL)) { + const node = this.startNodeAt(startPos, startLoc); + node.elementType = type; + this.expect(tt.bracketL); + this.expect(tt.bracketR); + type = this.finishNode(node, "ArrayTypeAnnotation"); + } + return type; + } + + flowParsePrefixType() { + const node = this.startNode(); + if (this.eat(tt.question)) { + node.typeAnnotation = this.flowParsePrefixType(); + return this.finishNode(node, "NullableTypeAnnotation"); + } else { + return this.flowParsePostfixType(); + } + } + + flowParseAnonFunctionWithoutParens() { + const param = this.flowParsePrefixType(); + if (!this.state.noAnonFunctionType && this.eat(tt.arrow)) { + const node = this.startNodeAt(param.start, param.loc); + node.params = [this.reinterpretTypeAsFunctionTypeParam(param)]; + node.rest = null; + node.returnType = this.flowParseType(); + node.typeParameters = null; + return this.finishNode(node, "FunctionTypeAnnotation"); + } + return param; + } + + flowParseIntersectionType() { + const node = this.startNode(); + this.eat(tt.bitwiseAND); + const type = this.flowParseAnonFunctionWithoutParens(); + node.types = [type]; + while (this.eat(tt.bitwiseAND)) { + node.types.push(this.flowParseAnonFunctionWithoutParens()); + } + return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation"); + } + + flowParseUnionType() { + const node = this.startNode(); + this.eat(tt.bitwiseOR); + const type = this.flowParseIntersectionType(); + node.types = [type]; + while (this.eat(tt.bitwiseOR)) { + node.types.push(this.flowParseIntersectionType()); + } + return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation"); + } + + flowParseType() { + const oldInType = this.state.inType; + this.state.inType = true; + const type = this.flowParseUnionType(); + this.state.inType = oldInType; + return type; + } + + flowParseTypeAnnotation() { + const node = this.startNode(); + node.typeAnnotation = this.flowParseTypeInitialiser(); + return this.finishNode(node, "TypeAnnotation"); + } + + flowParseTypeAnnotatableIdentifier() { + const ident = this.flowParseRestrictedIdentifier(); + if (this.match(tt.colon)) { + ident.typeAnnotation = this.flowParseTypeAnnotation(); + this.finishNode(ident, ident.type); + } + return ident; + } + + typeCastToParameter(node) { + node.expression.typeAnnotation = node.typeAnnotation; + + return this.finishNodeAt( + node.expression, + node.expression.type, + node.typeAnnotation.end, + node.typeAnnotation.loc.end + ); + } + + flowParseVariance() { + let variance = null; + if (this.match(tt.plusMin)) { + variance = this.startNode(); + if (this.state.value === "+") { + variance.kind = "plus"; + } else { + variance.kind = "minus"; + } + this.next(); + this.finishNode(variance, "Variance"); + } + return variance; + } + + // ================================== + // Overrides + // ================================== + // plain function return types: function name(): string {} parseFunctionBody(node, allowExpression) { if (this.match(tt.colon) && !allowExpression) { diff --git a/src/plugins/jsx/index.js b/src/plugins/jsx/index.js index 7309fa9121..c309d2c965 100644 --- a/src/plugins/jsx/index.js +++ b/src/plugins/jsx/index.js @@ -1,7 +1,6 @@ import XHTMLEntities from "./xhtml"; import { TokenType, types as tt } from "../../tokenizer/types"; import { TokContext, types as tc } from "../../tokenizer/context"; -import Parser from "../../parser"; import { isIdentifierChar, isIdentifierStart } from "../../util/identifier"; import { isNewLine } from "../../util/whitespace"; @@ -33,144 +32,6 @@ tt.jsxTagEnd.updateContext = function(prevType) { } }; -const pp = Parser.prototype; - -// Reads inline JSX contents token. - -pp.jsxReadToken = function() { - let out = ""; - let chunkStart = this.state.pos; - for (;;) { - if (this.state.pos >= this.input.length) { - this.raise(this.state.start, "Unterminated JSX contents"); - } - - const ch = this.input.charCodeAt(this.state.pos); - - switch (ch) { - case 60: // "<" - case 123: // "{" - if (this.state.pos === this.state.start) { - if (ch === 60 && this.state.exprAllowed) { - ++this.state.pos; - return this.finishToken(tt.jsxTagStart); - } - return this.getTokenFromCode(ch); - } - out += this.input.slice(chunkStart, this.state.pos); - return this.finishToken(tt.jsxText, out); - - case 38: // "&" - out += this.input.slice(chunkStart, this.state.pos); - out += this.jsxReadEntity(); - chunkStart = this.state.pos; - break; - - default: - if (isNewLine(ch)) { - out += this.input.slice(chunkStart, this.state.pos); - out += this.jsxReadNewLine(true); - chunkStart = this.state.pos; - } else { - ++this.state.pos; - } - } - } -}; - -pp.jsxReadNewLine = function(normalizeCRLF) { - const ch = this.input.charCodeAt(this.state.pos); - let out; - ++this.state.pos; - if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) { - ++this.state.pos; - out = normalizeCRLF ? "\n" : "\r\n"; - } else { - out = String.fromCharCode(ch); - } - ++this.state.curLine; - this.state.lineStart = this.state.pos; - - return out; -}; - -pp.jsxReadString = function(quote) { - let out = ""; - let chunkStart = ++this.state.pos; - for (;;) { - if (this.state.pos >= this.input.length) { - this.raise(this.state.start, "Unterminated string constant"); - } - - const ch = this.input.charCodeAt(this.state.pos); - if (ch === quote) break; - if (ch === 38) { // "&" - out += this.input.slice(chunkStart, this.state.pos); - out += this.jsxReadEntity(); - chunkStart = this.state.pos; - } else if (isNewLine(ch)) { - out += this.input.slice(chunkStart, this.state.pos); - out += this.jsxReadNewLine(false); - chunkStart = this.state.pos; - } else { - ++this.state.pos; - } - } - out += this.input.slice(chunkStart, this.state.pos++); - return this.finishToken(tt.string, out); -}; - -pp.jsxReadEntity = function() { - let str = ""; - let count = 0; - let entity; - let ch = this.input[this.state.pos]; - - const startPos = ++this.state.pos; - while (this.state.pos < this.input.length && count++ < 10) { - ch = this.input[this.state.pos++]; - if (ch === ";") { - if (str[0] === "#") { - if (str[1] === "x") { - str = str.substr(2); - if (HEX_NUMBER.test(str)) - entity = String.fromCodePoint(parseInt(str, 16)); - } else { - str = str.substr(1); - if (DECIMAL_NUMBER.test(str)) - entity = String.fromCodePoint(parseInt(str, 10)); - } - } else { - entity = XHTMLEntities[str]; - } - break; - } - str += ch; - } - if (!entity) { - this.state.pos = startPos; - return "&"; - } - return entity; -}; - - -// Read a JSX identifier (valid tag or attribute name). -// -// Optimized version since JSX identifiers can"t contain -// escape characters and so can be read as single slice. -// Also assumes that first character was already checked -// by isIdentifierStart in readToken. - -pp.jsxReadWord = function() { - let ch; - const start = this.state.pos; - do { - ch = this.input.charCodeAt(++this.state.pos); - } while (isIdentifierChar(ch) || ch === 45); // "-" - return this.finishToken(tt.jsxName, this.input.slice(start, this.state.pos)); -}; - // Transforms JSX element name to string. function getQualifiedJSXName(object) { @@ -187,215 +48,355 @@ function getQualifiedJSXName(object) { } } -// Parse next token as JSX identifier - -pp.jsxParseIdentifier = function() { - const node = this.startNode(); - if (this.match(tt.jsxName)) { - node.name = this.state.value; - } else if (this.state.type.keyword) { - node.name = this.state.type.keyword; - } else { - this.unexpected(); - } - this.next(); - return this.finishNode(node, "JSXIdentifier"); -}; - -// Parse namespaced identifier. - -pp.jsxParseNamespacedName = function() { - const startPos = this.state.start; - const startLoc = this.state.startLoc; - const name = this.jsxParseIdentifier(); - if (!this.eat(tt.colon)) return name; - - const node = this.startNodeAt(startPos, startLoc); - node.namespace = name; - node.name = this.jsxParseIdentifier(); - return this.finishNode(node, "JSXNamespacedName"); -}; - -// Parses element name in any form - namespaced, member -// or single identifier. - -pp.jsxParseElementName = function() { - const startPos = this.state.start; - const startLoc = this.state.startLoc; - let node = this.jsxParseNamespacedName(); - while (this.eat(tt.dot)) { - const newNode = this.startNodeAt(startPos, startLoc); - newNode.object = node; - newNode.property = this.jsxParseIdentifier(); - node = this.finishNode(newNode, "JSXMemberExpression"); - } - return node; -}; - -// Parses any type of JSX attribute value. - -pp.jsxParseAttributeValue = function() { - let node; - switch (this.state.type) { - case tt.braceL: - node = this.jsxParseExpressionContainer(); - if (node.expression.type === "JSXEmptyExpression") { - this.raise(node.start, "JSX attributes must only be assigned a non-empty expression"); - } else { - return node; - } - - case tt.jsxTagStart: - case tt.string: - return this.parseExprAtom(); - - default: - this.raise(this.state.start, "JSX value should be either an expression or a quoted JSX text"); - } -}; - -// JSXEmptyExpression is unique type since it doesn't actually parse anything, -// and so it should start at the end of last read token (left brace) and finish -// at the beginning of the next one (right brace). - -pp.jsxParseEmptyExpression = function() { - const node = this.startNodeAt(this.state.lastTokEnd, this.state.lastTokEndLoc); - return this.finishNodeAt(node, "JSXEmptyExpression", this.state.start, this.state.startLoc); -}; - -// Parse JSX spread child - -pp.jsxParseSpreadChild = function() { - const node = this.startNode(); - this.expect(tt.braceL); - this.expect(tt.ellipsis); - node.expression = this.parseExpression(); - this.expect(tt.braceR); - - return this.finishNode(node, "JSXSpreadChild"); -}; - -// Parses JSX expression enclosed into curly brackets. - - -pp.jsxParseExpressionContainer = function() { - const node = this.startNode(); - this.next(); - if (this.match(tt.braceR)) { - node.expression = this.jsxParseEmptyExpression(); - } else { - node.expression = this.parseExpression(); - } - this.expect(tt.braceR); - return this.finishNode(node, "JSXExpressionContainer"); -}; - -// Parses following JSX attribute name-value pair. - -pp.jsxParseAttribute = function() { - const node = this.startNode(); - if (this.eat(tt.braceL)) { - this.expect(tt.ellipsis); - node.argument = this.parseMaybeAssign(); - this.expect(tt.braceR); - return this.finishNode(node, "JSXSpreadAttribute"); - } - node.name = this.jsxParseNamespacedName(); - node.value = this.eat(tt.eq) ? this.jsxParseAttributeValue() : null; - return this.finishNode(node, "JSXAttribute"); -}; - -// Parses JSX opening tag starting after "<". - -pp.jsxParseOpeningElementAt = function(startPos, startLoc) { - const node = this.startNodeAt(startPos, startLoc); - node.attributes = []; - node.name = this.jsxParseElementName(); - while (!this.match(tt.slash) && !this.match(tt.jsxTagEnd)) { - node.attributes.push(this.jsxParseAttribute()); - } - node.selfClosing = this.eat(tt.slash); - this.expect(tt.jsxTagEnd); - return this.finishNode(node, "JSXOpeningElement"); -}; - -// Parses JSX closing tag starting after "" - ); - } - } - - node.openingElement = openingElement; - node.closingElement = closingElement; - node.children = children; - if (this.match(tt.relational) && this.state.value === "<") { - this.raise(this.state.start, "Adjacent JSX elements must be wrapped in an enclosing tag"); - } - return this.finishNode(node, "JSXElement"); -}; - -// Parses entire JSX element from current position. - -pp.jsxParseElement = function() { - const startPos = this.state.start; - const startLoc = this.state.startLoc; - this.next(); - return this.jsxParseElementAt(startPos, startLoc); -}; - export default (superClass) => class extends superClass { + // Reads inline JSX contents token. + + jsxReadToken() { + let out = ""; + let chunkStart = this.state.pos; + for (;;) { + if (this.state.pos >= this.input.length) { + this.raise(this.state.start, "Unterminated JSX contents"); + } + + const ch = this.input.charCodeAt(this.state.pos); + + switch (ch) { + case 60: // "<" + case 123: // "{" + if (this.state.pos === this.state.start) { + if (ch === 60 && this.state.exprAllowed) { + ++this.state.pos; + return this.finishToken(tt.jsxTagStart); + } + return this.getTokenFromCode(ch); + } + out += this.input.slice(chunkStart, this.state.pos); + return this.finishToken(tt.jsxText, out); + + case 38: // "&" + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadEntity(); + chunkStart = this.state.pos; + break; + + default: + if (isNewLine(ch)) { + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadNewLine(true); + chunkStart = this.state.pos; + } else { + ++this.state.pos; + } + } + } + } + + jsxReadNewLine(normalizeCRLF) { + const ch = this.input.charCodeAt(this.state.pos); + let out; + ++this.state.pos; + if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) { + ++this.state.pos; + out = normalizeCRLF ? "\n" : "\r\n"; + } else { + out = String.fromCharCode(ch); + } + ++this.state.curLine; + this.state.lineStart = this.state.pos; + + return out; + } + + jsxReadString(quote) { + let out = ""; + let chunkStart = ++this.state.pos; + for (;;) { + if (this.state.pos >= this.input.length) { + this.raise(this.state.start, "Unterminated string constant"); + } + + const ch = this.input.charCodeAt(this.state.pos); + if (ch === quote) break; + if (ch === 38) { // "&" + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadEntity(); + chunkStart = this.state.pos; + } else if (isNewLine(ch)) { + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadNewLine(false); + chunkStart = this.state.pos; + } else { + ++this.state.pos; + } + } + out += this.input.slice(chunkStart, this.state.pos++); + return this.finishToken(tt.string, out); + } + + jsxReadEntity() { + let str = ""; + let count = 0; + let entity; + let ch = this.input[this.state.pos]; + + const startPos = ++this.state.pos; + while (this.state.pos < this.input.length && count++ < 10) { + ch = this.input[this.state.pos++]; + if (ch === ";") { + if (str[0] === "#") { + if (str[1] === "x") { + str = str.substr(2); + if (HEX_NUMBER.test(str)) + entity = String.fromCodePoint(parseInt(str, 16)); + } else { + str = str.substr(1); + if (DECIMAL_NUMBER.test(str)) + entity = String.fromCodePoint(parseInt(str, 10)); + } + } else { + entity = XHTMLEntities[str]; + } + break; + } + str += ch; + } + if (!entity) { + this.state.pos = startPos; + return "&"; + } + return entity; + } + + + // Read a JSX identifier (valid tag or attribute name). + // + // Optimized version since JSX identifiers can"t contain + // escape characters and so can be read as single slice. + // Also assumes that first character was already checked + // by isIdentifierStart in readToken. + + jsxReadWord() { + let ch; + const start = this.state.pos; + do { + ch = this.input.charCodeAt(++this.state.pos); + } while (isIdentifierChar(ch) || ch === 45); // "-" + return this.finishToken(tt.jsxName, this.input.slice(start, this.state.pos)); + } + + // Parse next token as JSX identifier + + jsxParseIdentifier() { + const node = this.startNode(); + if (this.match(tt.jsxName)) { + node.name = this.state.value; + } else if (this.state.type.keyword) { + node.name = this.state.type.keyword; + } else { + this.unexpected(); + } + this.next(); + return this.finishNode(node, "JSXIdentifier"); + } + + // Parse namespaced identifier. + + jsxParseNamespacedName() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const name = this.jsxParseIdentifier(); + if (!this.eat(tt.colon)) return name; + + const node = this.startNodeAt(startPos, startLoc); + node.namespace = name; + node.name = this.jsxParseIdentifier(); + return this.finishNode(node, "JSXNamespacedName"); + } + + // Parses element name in any form - namespaced, member + // or single identifier. + + jsxParseElementName() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let node = this.jsxParseNamespacedName(); + while (this.eat(tt.dot)) { + const newNode = this.startNodeAt(startPos, startLoc); + newNode.object = node; + newNode.property = this.jsxParseIdentifier(); + node = this.finishNode(newNode, "JSXMemberExpression"); + } + return node; + } + + // Parses any type of JSX attribute value. + + jsxParseAttributeValue() { + let node; + switch (this.state.type) { + case tt.braceL: + node = this.jsxParseExpressionContainer(); + if (node.expression.type === "JSXEmptyExpression") { + this.raise(node.start, "JSX attributes must only be assigned a non-empty expression"); + } else { + return node; + } + + case tt.jsxTagStart: + case tt.string: + return this.parseExprAtom(); + + default: + this.raise(this.state.start, "JSX value should be either an expression or a quoted JSX text"); + } + } + + // JSXEmptyExpression is unique type since it doesn't actually parse anything, + // and so it should start at the end of last read token (left brace) and finish + // at the beginning of the next one (right brace). + + jsxParseEmptyExpression() { + const node = this.startNodeAt(this.state.lastTokEnd, this.state.lastTokEndLoc); + return this.finishNodeAt(node, "JSXEmptyExpression", this.state.start, this.state.startLoc); + } + + // Parse JSX spread child + + jsxParseSpreadChild() { + const node = this.startNode(); + this.expect(tt.braceL); + this.expect(tt.ellipsis); + node.expression = this.parseExpression(); + this.expect(tt.braceR); + + return this.finishNode(node, "JSXSpreadChild"); + } + + // Parses JSX expression enclosed into curly brackets. + + + jsxParseExpressionContainer() { + const node = this.startNode(); + this.next(); + if (this.match(tt.braceR)) { + node.expression = this.jsxParseEmptyExpression(); + } else { + node.expression = this.parseExpression(); + } + this.expect(tt.braceR); + return this.finishNode(node, "JSXExpressionContainer"); + } + + // Parses following JSX attribute name-value pair. + + jsxParseAttribute() { + const node = this.startNode(); + if (this.eat(tt.braceL)) { + this.expect(tt.ellipsis); + node.argument = this.parseMaybeAssign(); + this.expect(tt.braceR); + return this.finishNode(node, "JSXSpreadAttribute"); + } + node.name = this.jsxParseNamespacedName(); + node.value = this.eat(tt.eq) ? this.jsxParseAttributeValue() : null; + return this.finishNode(node, "JSXAttribute"); + } + + // Parses JSX opening tag starting after "<". + + jsxParseOpeningElementAt(startPos, startLoc) { + const node = this.startNodeAt(startPos, startLoc); + node.attributes = []; + node.name = this.jsxParseElementName(); + while (!this.match(tt.slash) && !this.match(tt.jsxTagEnd)) { + node.attributes.push(this.jsxParseAttribute()); + } + node.selfClosing = this.eat(tt.slash); + this.expect(tt.jsxTagEnd); + return this.finishNode(node, "JSXOpeningElement"); + } + + // Parses JSX closing tag starting after "" + ); + } + } + + node.openingElement = openingElement; + node.closingElement = closingElement; + node.children = children; + if (this.match(tt.relational) && this.state.value === "<") { + this.raise(this.state.start, "Adjacent JSX elements must be wrapped in an enclosing tag"); + } + return this.finishNode(node, "JSXElement"); + } + + // Parses entire JSX element from current position. + + jsxParseElement() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + this.next(); + return this.jsxParseElementAt(startPos, startLoc); + } + + // ================================== + // Overrides + // ================================== + parseExprAtom(refShortHandDefaultPos) { if (this.match(tt.jsxText)) { return this.parseLiteral(this.state.value, "JSXText"); From c4fb3fe742c61ee2dd0ab1b1197a254d3c9f6a55 Mon Sep 17 00:00:00 2001 From: Andy Date: Sun, 23 Apr 2017 15:40:49 -0700 Subject: [PATCH 15/73] Convert each file with parser methods to a class in an inheritance chain (#481) --- src/parser/base.js | 24 + src/parser/comments.js | 222 ++--- src/parser/expression.js | 1928 ++++++++++++++++++------------------ src/parser/index.js | 31 +- src/parser/location.js | 22 +- src/parser/lval.js | 475 ++++----- src/parser/node.js | 73 +- src/parser/statement.js | 2031 +++++++++++++++++++------------------- src/parser/util.js | 154 +-- src/tokenizer/index.js | 10 +- 10 files changed, 2487 insertions(+), 2483 deletions(-) create mode 100644 src/parser/base.js diff --git a/src/parser/base.js b/src/parser/base.js new file mode 100644 index 0000000000..fa1fc13539 --- /dev/null +++ b/src/parser/base.js @@ -0,0 +1,24 @@ +// @flow + +import type { Options } from "../options"; +import { reservedWords } from "../util/identifier"; + +export default class BaseParser { + // Properties set by constructor in index.js + options: Options; + inModule: boolean; + plugins: { [key: string]: boolean }; + filename: ?string; + + isReservedWord(word: string): boolean { + if (word === "await") { + return this.inModule; + } else { + return reservedWords[6](word); + } + } + + hasPlugin(name: string): boolean { + return !!this.plugins[name]; + } +} diff --git a/src/parser/comments.js b/src/parser/comments.js index c032e85e07..a634491848 100644 --- a/src/parser/comments.js +++ b/src/parser/comments.js @@ -24,133 +24,133 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import Parser from "./index"; +import BaseParser from "./base"; function last(stack) { return stack[stack.length - 1]; } -const pp = Parser.prototype; - -pp.addComment = function (comment) { - if (this.filename) comment.loc.filename = this.filename; - this.state.trailingComments.push(comment); - this.state.leadingComments.push(comment); -}; - -pp.processComment = function (node) { - if (node.type === "Program" && node.body.length > 0) return; - - const stack = this.state.commentStack; - - let lastChild, trailingComments, i, j; - - if (this.state.trailingComments.length > 0) { - // If the first comment in trailingComments comes after the - // current node, then we're good - all comments in the array will - // come after the node and so it's safe to add them as official - // trailingComments. - if (this.state.trailingComments[0].start >= node.end) { - trailingComments = this.state.trailingComments; - this.state.trailingComments = []; - } else { - // Otherwise, if the first comment doesn't come after the - // current node, that means we have a mix of leading and trailing - // comments in the array and that leadingComments contains the - // same items as trailingComments. Reset trailingComments to - // zero items and we'll handle this by evaluating leadingComments - // later. - this.state.trailingComments.length = 0; - } - } else { - const lastInStack = last(stack); - if (stack.length > 0 && lastInStack.trailingComments && lastInStack.trailingComments[0].start >= node.end) { - trailingComments = lastInStack.trailingComments; - lastInStack.trailingComments = null; - } +export default class CommentsParser extends BaseParser { + addComment(comment) { + if (this.filename) comment.loc.filename = this.filename; + this.state.trailingComments.push(comment); + this.state.leadingComments.push(comment); } - // Eating the stack. - while (stack.length > 0 && last(stack).start >= node.start) { - lastChild = stack.pop(); - } + processComment(node) { + if (node.type === "Program" && node.body.length > 0) return; - if (lastChild) { - if (lastChild.leadingComments) { - if (lastChild !== node && last(lastChild.leadingComments).end <= node.start) { - node.leadingComments = lastChild.leadingComments; - lastChild.leadingComments = null; + const stack = this.state.commentStack; + + let lastChild, trailingComments, i, j; + + if (this.state.trailingComments.length > 0) { + // If the first comment in trailingComments comes after the + // current node, then we're good - all comments in the array will + // come after the node and so it's safe to add them as official + // trailingComments. + if (this.state.trailingComments[0].start >= node.end) { + trailingComments = this.state.trailingComments; + this.state.trailingComments = []; } else { - // A leading comment for an anonymous class had been stolen by its first ClassMethod, - // so this takes back the leading comment. - // See also: https://github.com/eslint/espree/issues/158 - for (i = lastChild.leadingComments.length - 2; i >= 0; --i) { - if (lastChild.leadingComments[i].end <= node.start) { - node.leadingComments = lastChild.leadingComments.splice(0, i + 1); + // Otherwise, if the first comment doesn't come after the + // current node, that means we have a mix of leading and trailing + // comments in the array and that leadingComments contains the + // same items as trailingComments. Reset trailingComments to + // zero items and we'll handle this by evaluating leadingComments + // later. + this.state.trailingComments.length = 0; + } + } else { + const lastInStack = last(stack); + if (stack.length > 0 && lastInStack.trailingComments && lastInStack.trailingComments[0].start >= node.end) { + trailingComments = lastInStack.trailingComments; + lastInStack.trailingComments = null; + } + } + + // Eating the stack. + while (stack.length > 0 && last(stack).start >= node.start) { + lastChild = stack.pop(); + } + + if (lastChild) { + if (lastChild.leadingComments) { + if (lastChild !== node && last(lastChild.leadingComments).end <= node.start) { + node.leadingComments = lastChild.leadingComments; + lastChild.leadingComments = null; + } else { + // A leading comment for an anonymous class had been stolen by its first ClassMethod, + // so this takes back the leading comment. + // See also: https://github.com/eslint/espree/issues/158 + for (i = lastChild.leadingComments.length - 2; i >= 0; --i) { + if (lastChild.leadingComments[i].end <= node.start) { + node.leadingComments = lastChild.leadingComments.splice(0, i + 1); + break; + } + } + } + } + } else if (this.state.leadingComments.length > 0) { + if (last(this.state.leadingComments).end <= node.start) { + if (this.state.commentPreviousNode) { + for (j = 0; j < this.state.leadingComments.length; j++) { + if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) { + this.state.leadingComments.splice(j, 1); + j--; + } + } + } + if (this.state.leadingComments.length > 0) { + node.leadingComments = this.state.leadingComments; + this.state.leadingComments = []; + } + } else { + // https://github.com/eslint/espree/issues/2 + // + // In special cases, such as return (without a value) and + // debugger, all comments will end up as leadingComments and + // will otherwise be eliminated. This step runs when the + // commentStack is empty and there are comments left + // in leadingComments. + // + // This loop figures out the stopping point between the actual + // leading and trailing comments by finding the location of the + // first comment that comes after the given node. + for (i = 0; i < this.state.leadingComments.length; i++) { + if (this.state.leadingComments[i].end > node.start) { break; } } - } - } - } else if (this.state.leadingComments.length > 0) { - if (last(this.state.leadingComments).end <= node.start) { - if (this.state.commentPreviousNode) { - for (j = 0; j < this.state.leadingComments.length; j++) { - if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) { - this.state.leadingComments.splice(j, 1); - j--; - } - } - } - if (this.state.leadingComments.length > 0) { - node.leadingComments = this.state.leadingComments; - this.state.leadingComments = []; - } - } else { - // https://github.com/eslint/espree/issues/2 - // - // In special cases, such as return (without a value) and - // debugger, all comments will end up as leadingComments and - // will otherwise be eliminated. This step runs when the - // commentStack is empty and there are comments left - // in leadingComments. - // - // This loop figures out the stopping point between the actual - // leading and trailing comments by finding the location of the - // first comment that comes after the given node. - for (i = 0; i < this.state.leadingComments.length; i++) { - if (this.state.leadingComments[i].end > node.start) { - break; + + // Split the array based on the location of the first comment + // that comes after the node. Keep in mind that this could + // result in an empty array, and if so, the array must be + // deleted. + node.leadingComments = this.state.leadingComments.slice(0, i); + if ((node.leadingComments: Array).length === 0) { + node.leadingComments = null; + } + + // Similarly, trailing comments are attached later. The variable + // must be reset to null if there are no trailing comments. + trailingComments = this.state.leadingComments.slice(i); + if (trailingComments.length === 0) { + trailingComments = null; } } + } - // Split the array based on the location of the first comment - // that comes after the node. Keep in mind that this could - // result in an empty array, and if so, the array must be - // deleted. - node.leadingComments = this.state.leadingComments.slice(0, i); - if ((node.leadingComments: Array).length === 0) { - node.leadingComments = null; - } + this.state.commentPreviousNode = node; - // Similarly, trailing comments are attached later. The variable - // must be reset to null if there are no trailing comments. - trailingComments = this.state.leadingComments.slice(i); - if (trailingComments.length === 0) { - trailingComments = null; + if (trailingComments) { + if (trailingComments.length && trailingComments[0].start >= node.start && last(trailingComments).end <= node.end) { + node.innerComments = trailingComments; + } else { + node.trailingComments = trailingComments; } } + + stack.push(node); } - - this.state.commentPreviousNode = node; - - if (trailingComments) { - if (trailingComments.length && trailingComments[0].start >= node.start && last(trailingComments).end <= node.end) { - node.innerComments = trailingComments; - } else { - node.trailingComments = trailingComments; - } - } - - stack.push(node); -}; +} diff --git a/src/parser/expression.js b/src/parser/expression.js index e813460314..168e595415 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -19,1104 +19,1104 @@ // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser import { types as tt } from "../tokenizer/types"; -import Parser from "./index"; +import LValParser from "./lval"; import { reservedWords } from "../util/identifier"; -const pp = Parser.prototype; +export default class ExpressionParser extends LValParser { + // Check if property name clashes with already added. + // Object/class getters and setters are not allowed to clash — + // either with each other or with an init property — and in + // strict mode, init properties are also not allowed to be repeated. -// Check if property name clashes with already added. -// Object/class getters and setters are not allowed to clash — -// either with each other or with an init property — and in -// strict mode, init properties are also not allowed to be repeated. + checkPropClash(prop, propHash) { + if (prop.computed || prop.kind) return; -pp.checkPropClash = function (prop, propHash) { - if (prop.computed || prop.kind) return; + const key = prop.key; + // It is either an Identifier or a String/NumericLiteral + const name = key.type === "Identifier" ? key.name : String(key.value); - const key = prop.key; - // It is either an Identifier or a String/NumericLiteral - const name = key.type === "Identifier" ? key.name : String(key.value); - - if (name === "__proto__") { - if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property"); - propHash.proto = true; - } -}; - -// Convenience method to parse an Expression only -pp.getExpression = function() { - this.nextToken(); - const expr = this.parseExpression(); - if (!this.match(tt.eof)) { - this.unexpected(); - } - return expr; -}; - -// ### Expression parsing - -// These nest, from the most general expression type at the top to -// 'atomic', nondivisible expression types at the bottom. Most of -// the functions will simply let the function (s) below them parse, -// and, *if* the syntactic construct they handle is present, wrap -// the AST node that the inner parser gave them in another node. - -// Parse a full expression. The optional arguments are used to -// forbid the `in` operator (in for loops initialization expressions) -// and provide reference for storing '=' operator inside shorthand -// property assignment in contexts where both object expression -// and object pattern might appear (so it's possible to raise -// delayed syntax error at correct position). - -pp.parseExpression = function (noIn, refShorthandDefaultPos) { - const startPos = this.state.start; - const startLoc = this.state.startLoc; - const expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos); - if (this.match(tt.comma)) { - const node = this.startNodeAt(startPos, startLoc); - node.expressions = [expr]; - while (this.eat(tt.comma)) { - node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos)); + if (name === "__proto__") { + if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property"); + propHash.proto = true; } - this.toReferencedList(node.expressions); - return this.finishNode(node, "SequenceExpression"); - } - return expr; -}; - -// Parse an assignment expression. This includes applications of -// operators like `+=`. - -pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse, refNeedsArrowPos) { - const startPos = this.state.start; - const startLoc = this.state.startLoc; - - if (this.match(tt._yield) && this.state.inGenerator) { - let left = this.parseYield(); - if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc); - return left; } - let failOnShorthandAssign; - if (refShorthandDefaultPos) { - failOnShorthandAssign = false; - } else { - refShorthandDefaultPos = { start: 0 }; - failOnShorthandAssign = true; - } - - if (this.match(tt.parenL) || this.match(tt.name)) { - this.state.potentialArrowAt = this.state.start; - } - - let left = this.parseMaybeConditional(noIn, refShorthandDefaultPos, refNeedsArrowPos); - if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc); - if (this.state.type.isAssign) { - const node = this.startNodeAt(startPos, startLoc); - node.operator = this.state.value; - node.left = this.match(tt.eq) ? this.toAssignable(left, undefined, "assignment expression") : left; - refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly - - this.checkLVal(left, undefined, undefined, "assignment expression"); - - if (left.extra && left.extra.parenthesized) { - let errorMsg; - if (left.type === "ObjectPattern") { - errorMsg = "`({a}) = 0` use `({a} = 0)`"; - } else if (left.type === "ArrayPattern") { - errorMsg = "`([a]) = 0` use `([a] = 0)`"; - } - if (errorMsg) { - this.raise(left.start, `You're trying to assign to a parenthesized expression, eg. instead of ${errorMsg}`); - } + // Convenience method to parse an Expression only + getExpression() { + this.nextToken(); + const expr = this.parseExpression(); + if (!this.match(tt.eof)) { + this.unexpected(); } - - this.next(); - node.right = this.parseMaybeAssign(noIn); - return this.finishNode(node, "AssignmentExpression"); - } else if (failOnShorthandAssign && refShorthandDefaultPos.start) { - this.unexpected(refShorthandDefaultPos.start); - } - - return left; -}; - -// Parse a ternary conditional (`?:`) operator. - -pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos, refNeedsArrowPos) { - const startPos = this.state.start; - const startLoc = this.state.startLoc; - const expr = this.parseExprOps(noIn, refShorthandDefaultPos); - if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; - - return this.parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos); -}; - -pp.parseConditional = function (expr, noIn, startPos, startLoc) { - if (this.eat(tt.question)) { - const node = this.startNodeAt(startPos, startLoc); - node.test = expr; - node.consequent = this.parseMaybeAssign(); - this.expect(tt.colon); - node.alternate = this.parseMaybeAssign(noIn); - return this.finishNode(node, "ConditionalExpression"); - } - return expr; -}; - -// Start the precedence parser. - -pp.parseExprOps = function (noIn, refShorthandDefaultPos) { - const startPos = this.state.start; - const startLoc = this.state.startLoc; - const expr = this.parseMaybeUnary(refShorthandDefaultPos); - if (refShorthandDefaultPos && refShorthandDefaultPos.start) { return expr; - } else { - return this.parseExprOp(expr, startPos, startLoc, -1, noIn); } -}; -// Parse binary operators with the operator precedence parsing -// algorithm. `left` is the left-hand side of the operator. -// `minPrec` provides context that allows the function to stop and -// defer further parser to one of its callers when it encounters an -// operator that has a lower precedence than the set it is parsing. + // ### Expression parsing -pp.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { - const prec = this.state.type.binop; - if (prec != null && (!noIn || !this.match(tt._in))) { - if (prec > minPrec) { - const node = this.startNodeAt(leftStartPos, leftStartLoc); - node.left = left; + // These nest, from the most general expression type at the top to + // 'atomic', nondivisible expression types at the bottom. Most of + // the functions will simply let the function (s) below them parse, + // and, *if* the syntactic construct they handle is present, wrap + // the AST node that the inner parser gave them in another node. + + // Parse a full expression. The optional arguments are used to + // forbid the `in` operator (in for loops initialization expressions) + // and provide reference for storing '=' operator inside shorthand + // property assignment in contexts where both object expression + // and object pattern might appear (so it's possible to raise + // delayed syntax error at correct position). + + parseExpression(noIn, refShorthandDefaultPos) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos); + if (this.match(tt.comma)) { + const node = this.startNodeAt(startPos, startLoc); + node.expressions = [expr]; + while (this.eat(tt.comma)) { + node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos)); + } + this.toReferencedList(node.expressions); + return this.finishNode(node, "SequenceExpression"); + } + return expr; + } + + // Parse an assignment expression. This includes applications of + // operators like `+=`. + + parseMaybeAssign(noIn, refShorthandDefaultPos, afterLeftParse, refNeedsArrowPos) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + + if (this.match(tt._yield) && this.state.inGenerator) { + let left = this.parseYield(); + if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc); + return left; + } + + let failOnShorthandAssign; + if (refShorthandDefaultPos) { + failOnShorthandAssign = false; + } else { + refShorthandDefaultPos = { start: 0 }; + failOnShorthandAssign = true; + } + + if (this.match(tt.parenL) || this.match(tt.name)) { + this.state.potentialArrowAt = this.state.start; + } + + let left = this.parseMaybeConditional(noIn, refShorthandDefaultPos, refNeedsArrowPos); + if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc); + if (this.state.type.isAssign) { + const node = this.startNodeAt(startPos, startLoc); node.operator = this.state.value; + node.left = this.match(tt.eq) ? this.toAssignable(left, undefined, "assignment expression") : left; + refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly - if ( - node.operator === "**" && - left.type === "UnaryExpression" && - left.extra && - !left.extra.parenthesizedArgument && - !left.extra.parenthesized - ) { - this.raise(left.argument.start, "Illegal expression. Wrap left hand side or entire exponentiation in parentheses."); + this.checkLVal(left, undefined, undefined, "assignment expression"); + + if (left.extra && left.extra.parenthesized) { + let errorMsg; + if (left.type === "ObjectPattern") { + errorMsg = "`({a}) = 0` use `({a} = 0)`"; + } else if (left.type === "ArrayPattern") { + errorMsg = "`([a]) = 0` use `([a] = 0)`"; + } + if (errorMsg) { + this.raise(left.start, `You're trying to assign to a parenthesized expression, eg. instead of ${errorMsg}`); + } } - const op = this.state.type; this.next(); - - const startPos = this.state.start; - const startLoc = this.state.startLoc; - node.right = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, op.rightAssociative ? prec - 1 : prec, noIn); - - this.finishNode(node, (op === tt.logicalOR || op === tt.logicalAND) ? "LogicalExpression" : "BinaryExpression"); - return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn); - } - } - return left; -}; - -// Parse unary operators, both prefix and postfix. - -pp.parseMaybeUnary = function (refShorthandDefaultPos) { - if (this.state.type.prefix) { - const node = this.startNode(); - const update = this.match(tt.incDec); - node.operator = this.state.value; - node.prefix = true; - this.next(); - - const argType = this.state.type; - node.argument = this.parseMaybeUnary(); - - this.addExtra(node, "parenthesizedArgument", argType === tt.parenL && (!node.argument.extra || !node.argument.extra.parenthesized)); - - if (refShorthandDefaultPos && refShorthandDefaultPos.start) { + node.right = this.parseMaybeAssign(noIn); + return this.finishNode(node, "AssignmentExpression"); + } else if (failOnShorthandAssign && refShorthandDefaultPos.start) { this.unexpected(refShorthandDefaultPos.start); } - if (update) { - this.checkLVal(node.argument, undefined, undefined, "prefix operation"); - } else if (this.state.strict && node.operator === "delete" && node.argument.type === "Identifier") { - this.raise(node.start, "Deleting local variable in strict mode"); + return left; + } + + // Parse a ternary conditional (`?:`) operator. + + parseMaybeConditional(noIn, refShorthandDefaultPos, refNeedsArrowPos) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const expr = this.parseExprOps(noIn, refShorthandDefaultPos); + if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; + + return this.parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos); + } + + parseConditional(expr, noIn, startPos, startLoc) { + if (this.eat(tt.question)) { + const node = this.startNodeAt(startPos, startLoc); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + this.expect(tt.colon); + node.alternate = this.parseMaybeAssign(noIn); + return this.finishNode(node, "ConditionalExpression"); } - - return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); - } - - const startPos = this.state.start; - const startLoc = this.state.startLoc; - let expr = this.parseExprSubscripts(refShorthandDefaultPos); - if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; - while (this.state.type.postfix && !this.canInsertSemicolon()) { - const node = this.startNodeAt(startPos, startLoc); - node.operator = this.state.value; - node.prefix = false; - node.argument = expr; - this.checkLVal(expr, undefined, undefined, "postfix operation"); - this.next(); - expr = this.finishNode(node, "UpdateExpression"); - } - return expr; -}; - -// Parse call, dot, and `[]`-subscript expressions. - -pp.parseExprSubscripts = function (refShorthandDefaultPos) { - const startPos = this.state.start; - const startLoc = this.state.startLoc; - const potentialArrowAt = this.state.potentialArrowAt; - const expr = this.parseExprAtom(refShorthandDefaultPos); - - if (expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt) { return expr; } - if (refShorthandDefaultPos && refShorthandDefaultPos.start) { - return expr; - } + // Start the precedence parser. - return this.parseSubscripts(expr, startPos, startLoc); -}; - -pp.parseSubscripts = function (base, startPos, startLoc, noCalls) { - for (;;) { - if (!noCalls && this.eat(tt.doubleColon)) { - const node = this.startNodeAt(startPos, startLoc); - node.object = base; - node.callee = this.parseNoCallExpr(); - return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls); - } else if (this.eat(tt.dot)) { - const node = this.startNodeAt(startPos, startLoc); - node.object = base; - node.property = this.parseIdentifier(true); - node.computed = false; - base = this.finishNode(node, "MemberExpression"); - } else if (this.eat(tt.bracketL)) { - const node = this.startNodeAt(startPos, startLoc); - node.object = base; - node.property = this.parseExpression(); - node.computed = true; - this.expect(tt.bracketR); - base = this.finishNode(node, "MemberExpression"); - } else if (!noCalls && this.match(tt.parenL)) { - const possibleAsync = this.state.potentialArrowAt === base.start && base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon(); - this.next(); - - const node = this.startNodeAt(startPos, startLoc); - node.callee = base; - node.arguments = this.parseCallExpressionArguments(tt.parenR, possibleAsync); - if (node.callee.type === "Import" && node.arguments.length !== 1) { - this.raise(node.start, "import() requires exactly one argument"); - } - base = this.finishNode(node, "CallExpression"); - - if (possibleAsync && this.shouldParseAsyncArrow()) { - return this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node); - } else { - this.toReferencedList(node.arguments); - } - } else if (this.match(tt.backQuote)) { - const node = this.startNodeAt(startPos, startLoc); - node.tag = base; - node.quasi = this.parseTemplate(true); - base = this.finishNode(node, "TaggedTemplateExpression"); + parseExprOps(noIn, refShorthandDefaultPos) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const expr = this.parseMaybeUnary(refShorthandDefaultPos); + if (refShorthandDefaultPos && refShorthandDefaultPos.start) { + return expr; } else { - return base; + return this.parseExprOp(expr, startPos, startLoc, -1, noIn); } } -}; -pp.parseCallExpressionArguments = function (close, possibleAsyncArrow) { - const elts = []; - let innerParenStart; - let first = true; + // Parse binary operators with the operator precedence parsing + // algorithm. `left` is the left-hand side of the operator. + // `minPrec` provides context that allows the function to stop and + // defer further parser to one of its callers when it encounters an + // operator that has a lower precedence than the set it is parsing. - while (!this.eat(close)) { - if (first) { - first = false; - } else { - this.expect(tt.comma); - if (this.eat(close)) break; - } + parseExprOp(left, leftStartPos, leftStartLoc, minPrec, noIn) { + const prec = this.state.type.binop; + if (prec != null && (!noIn || !this.match(tt._in))) { + if (prec > minPrec) { + const node = this.startNodeAt(leftStartPos, leftStartLoc); + node.left = left; + node.operator = this.state.value; - // we need to make sure that if this is an async arrow functions, that we don't allow inner parens inside the params - if (this.match(tt.parenL) && !innerParenStart) { - innerParenStart = this.state.start; - } - - elts.push(this.parseExprListItem(false, possibleAsyncArrow ? { start: 0 } : undefined, possibleAsyncArrow ? { start: 0 } : undefined)); - } - - // we found an async arrow function so let's not allow any inner parens - if (possibleAsyncArrow && innerParenStart && this.shouldParseAsyncArrow()) { - this.unexpected(); - } - - return elts; -}; - -pp.shouldParseAsyncArrow = function () { - return this.match(tt.arrow); -}; - -pp.parseAsyncArrowFromCallExpression = function (node, call) { - this.expect(tt.arrow); - return this.parseArrowExpression(node, call.arguments, true); -}; - -// Parse a no-call expression (like argument of `new` or `::` operators). - -pp.parseNoCallExpr = function () { - const startPos = this.state.start; - const startLoc = this.state.startLoc; - return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); -}; - -// Parse an atomic expression — either a single token that is an -// expression, an expression started by a keyword like `function` or -// `new`, or an expression wrapped in punctuation like `()`, `[]`, -// or `{}`. - -pp.parseExprAtom = function (refShorthandDefaultPos) { - const canBeArrow = this.state.potentialArrowAt === this.state.start; - let node; - - switch (this.state.type) { - case tt._super: - if (!this.state.inMethod && !this.options.allowSuperOutsideMethod) { - this.raise(this.state.start, "'super' outside of function or class"); - } - - node = this.startNode(); - this.next(); - if (!this.match(tt.parenL) && !this.match(tt.bracketL) && !this.match(tt.dot)) { - this.unexpected(); - } - if (this.match(tt.parenL) && this.state.inMethod !== "constructor" && !this.options.allowSuperOutsideMethod) { - this.raise(node.start, "super() is only valid inside a class constructor. Make sure the method name is spelled exactly as 'constructor'."); - } - return this.finishNode(node, "Super"); - - case tt._import: - if (!this.hasPlugin("dynamicImport")) this.unexpected(); - - node = this.startNode(); - this.next(); - if (!this.match(tt.parenL)) { - this.unexpected(null, tt.parenL); - } - return this.finishNode(node, "Import"); - - case tt._this: - node = this.startNode(); - this.next(); - return this.finishNode(node, "ThisExpression"); - - case tt._yield: - if (this.state.inGenerator) this.unexpected(); - - case tt.name: - node = this.startNode(); - const allowAwait = this.state.value === "await" && this.state.inAsync; - const allowYield = this.shouldAllowYieldIdentifier(); - const id = this.parseIdentifier(allowAwait || allowYield); - - if (id.name === "await") { - if (this.state.inAsync || this.inModule) { - return this.parseAwait(node); + if ( + node.operator === "**" && + left.type === "UnaryExpression" && + left.extra && + !left.extra.parenthesizedArgument && + !left.extra.parenthesized + ) { + this.raise(left.argument.start, "Illegal expression. Wrap left hand side or entire exponentiation in parentheses."); } - } else if (id.name === "async" && this.match(tt._function) && !this.canInsertSemicolon()) { + + const op = this.state.type; this.next(); - return this.parseFunction(node, false, false, true); - } else if (canBeArrow && id.name === "async" && this.match(tt.name)) { - const params = [this.parseIdentifier()]; - this.expect(tt.arrow); - // let foo = bar => {}; - return this.parseArrowExpression(node, params, true); + + const startPos = this.state.start; + const startLoc = this.state.startLoc; + node.right = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, op.rightAssociative ? prec - 1 : prec, noIn); + + this.finishNode(node, (op === tt.logicalOR || op === tt.logicalAND) ? "LogicalExpression" : "BinaryExpression"); + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn); + } + } + return left; + } + + // Parse unary operators, both prefix and postfix. + + parseMaybeUnary(refShorthandDefaultPos) { + if (this.state.type.prefix) { + const node = this.startNode(); + const update = this.match(tt.incDec); + node.operator = this.state.value; + node.prefix = true; + this.next(); + + const argType = this.state.type; + node.argument = this.parseMaybeUnary(); + + this.addExtra(node, "parenthesizedArgument", argType === tt.parenL && (!node.argument.extra || !node.argument.extra.parenthesized)); + + if (refShorthandDefaultPos && refShorthandDefaultPos.start) { + this.unexpected(refShorthandDefaultPos.start); } - if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { - return this.parseArrowExpression(node, [id]); + if (update) { + this.checkLVal(node.argument, undefined, undefined, "prefix operation"); + } else if (this.state.strict && node.operator === "delete" && node.argument.type === "Identifier") { + this.raise(node.start, "Deleting local variable in strict mode"); } - return id; + return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); + } - case tt._do: - if (this.hasPlugin("doExpressions")) { - const node = this.startNode(); + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let expr = this.parseExprSubscripts(refShorthandDefaultPos); + if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr; + while (this.state.type.postfix && !this.canInsertSemicolon()) { + const node = this.startNodeAt(startPos, startLoc); + node.operator = this.state.value; + node.prefix = false; + node.argument = expr; + this.checkLVal(expr, undefined, undefined, "postfix operation"); + this.next(); + expr = this.finishNode(node, "UpdateExpression"); + } + return expr; + } + + // Parse call, dot, and `[]`-subscript expressions. + + parseExprSubscripts(refShorthandDefaultPos) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const potentialArrowAt = this.state.potentialArrowAt; + const expr = this.parseExprAtom(refShorthandDefaultPos); + + if (expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt) { + return expr; + } + + if (refShorthandDefaultPos && refShorthandDefaultPos.start) { + return expr; + } + + return this.parseSubscripts(expr, startPos, startLoc); + } + + parseSubscripts(base, startPos, startLoc, noCalls) { + for (;;) { + if (!noCalls && this.eat(tt.doubleColon)) { + const node = this.startNodeAt(startPos, startLoc); + node.object = base; + node.callee = this.parseNoCallExpr(); + return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls); + } else if (this.eat(tt.dot)) { + const node = this.startNodeAt(startPos, startLoc); + node.object = base; + node.property = this.parseIdentifier(true); + node.computed = false; + base = this.finishNode(node, "MemberExpression"); + } else if (this.eat(tt.bracketL)) { + const node = this.startNodeAt(startPos, startLoc); + node.object = base; + node.property = this.parseExpression(); + node.computed = true; + this.expect(tt.bracketR); + base = this.finishNode(node, "MemberExpression"); + } else if (!noCalls && this.match(tt.parenL)) { + const possibleAsync = this.state.potentialArrowAt === base.start && base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon(); this.next(); - const oldInFunction = this.state.inFunction; - const oldLabels = this.state.labels; - this.state.labels = []; - this.state.inFunction = false; - node.body = this.parseBlock(false, true); - this.state.inFunction = oldInFunction; - this.state.labels = oldLabels; - return this.finishNode(node, "DoExpression"); - } - case tt.regexp: - const value = this.state.value; - node = this.parseLiteral(value.value, "RegExpLiteral"); - node.pattern = value.pattern; - node.flags = value.flags; - return node; + const node = this.startNodeAt(startPos, startLoc); + node.callee = base; + node.arguments = this.parseCallExpressionArguments(tt.parenR, possibleAsync); + if (node.callee.type === "Import" && node.arguments.length !== 1) { + this.raise(node.start, "import() requires exactly one argument"); + } + base = this.finishNode(node, "CallExpression"); - case tt.num: - return this.parseLiteral(this.state.value, "NumericLiteral"); - - case tt.string: - return this.parseLiteral(this.state.value, "StringLiteral"); - - case tt._null: - node = this.startNode(); - this.next(); - return this.finishNode(node, "NullLiteral"); - - case tt._true: case tt._false: - node = this.startNode(); - node.value = this.match(tt._true); - this.next(); - return this.finishNode(node, "BooleanLiteral"); - - case tt.parenL: - return this.parseParenAndDistinguishExpression(null, null, canBeArrow); - - case tt.bracketL: - node = this.startNode(); - this.next(); - node.elements = this.parseExprList(tt.bracketR, true, refShorthandDefaultPos); - this.toReferencedList(node.elements); - return this.finishNode(node, "ArrayExpression"); - - case tt.braceL: - return this.parseObj(false, refShorthandDefaultPos); - - case tt._function: - return this.parseFunctionExpression(); - - case tt.at: - this.parseDecorators(); - - case tt._class: - node = this.startNode(); - this.takeDecorators(node); - return this.parseClass(node, false); - - case tt._new: - return this.parseNew(); - - case tt.backQuote: - return this.parseTemplate(false); - - case tt.doubleColon: - node = this.startNode(); - this.next(); - node.object = null; - const callee = node.callee = this.parseNoCallExpr(); - if (callee.type === "MemberExpression") { - return this.finishNode(node, "BindExpression"); + if (possibleAsync && this.shouldParseAsyncArrow()) { + return this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node); + } else { + this.toReferencedList(node.arguments); + } + } else if (this.match(tt.backQuote)) { + const node = this.startNodeAt(startPos, startLoc); + node.tag = base; + node.quasi = this.parseTemplate(true); + base = this.finishNode(node, "TaggedTemplateExpression"); } else { - this.raise(callee.start, "Binding should be performed on object property."); + return base; + } + } + } + + parseCallExpressionArguments(close, possibleAsyncArrow) { + const elts = []; + let innerParenStart; + let first = true; + + while (!this.eat(close)) { + if (first) { + first = false; + } else { + this.expect(tt.comma); + if (this.eat(close)) break; } - default: + // we need to make sure that if this is an async arrow functions, that we don't allow inner parens inside the params + if (this.match(tt.parenL) && !innerParenStart) { + innerParenStart = this.state.start; + } + + elts.push(this.parseExprListItem(false, possibleAsyncArrow ? { start: 0 } : undefined, possibleAsyncArrow ? { start: 0 } : undefined)); + } + + // we found an async arrow function so let's not allow any inner parens + if (possibleAsyncArrow && innerParenStart && this.shouldParseAsyncArrow()) { this.unexpected(); - } -}; + } -pp.parseFunctionExpression = function () { - const node = this.startNode(); - const meta = this.parseIdentifier(true); - if (this.state.inGenerator && this.eat(tt.dot) && this.hasPlugin("functionSent")) { - return this.parseMetaProperty(node, meta, "sent"); - } else { - return this.parseFunction(node, false); - } -}; - -pp.parseMetaProperty = function (node, meta, propertyName) { - node.meta = meta; - node.property = this.parseIdentifier(true); - - if (node.property.name !== propertyName) { - this.raise(node.property.start, `The only valid meta property for new is ${meta.name}.${propertyName}`); + return elts; } - return this.finishNode(node, "MetaProperty"); -}; + shouldParseAsyncArrow() { + return this.match(tt.arrow); + } -pp.parseLiteral = function (value, type, startPos, startLoc) { - startPos = startPos || this.state.start; - startLoc = startLoc || this.state.startLoc; + parseAsyncArrowFromCallExpression(node, call) { + this.expect(tt.arrow); + return this.parseArrowExpression(node, call.arguments, true); + } - const node = this.startNodeAt(startPos, startLoc); - this.addExtra(node, "rawValue", value); - this.addExtra(node, "raw", this.input.slice(startPos, this.state.end)); - node.value = value; - this.next(); - return this.finishNode(node, type); -}; + // Parse a no-call expression (like argument of `new` or `::` operators). -pp.parseParenExpression = function () { - this.expect(tt.parenL); - const val = this.parseExpression(); - this.expect(tt.parenR); - return val; -}; + parseNoCallExpr() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); + } -pp.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArrow) { - startPos = startPos || this.state.start; - startLoc = startLoc || this.state.startLoc; + // Parse an atomic expression — either a single token that is an + // expression, an expression started by a keyword like `function` or + // `new`, or an expression wrapped in punctuation like `()`, `[]`, + // or `{}`. - let val; - this.expect(tt.parenL); + parseExprAtom(refShorthandDefaultPos) { + const canBeArrow = this.state.potentialArrowAt === this.state.start; + let node; - const innerStartPos = this.state.start; - const innerStartLoc = this.state.startLoc; - const exprList = []; - const refShorthandDefaultPos = { start: 0 }; - const refNeedsArrowPos = { start: 0 }; - let first = true; - let spreadStart; - let optionalCommaStart; + switch (this.state.type) { + case tt._super: + if (!this.state.inMethod && !this.options.allowSuperOutsideMethod) { + this.raise(this.state.start, "'super' outside of function or class"); + } - while (!this.match(tt.parenR)) { - if (first) { - first = false; + node = this.startNode(); + this.next(); + if (!this.match(tt.parenL) && !this.match(tt.bracketL) && !this.match(tt.dot)) { + this.unexpected(); + } + if (this.match(tt.parenL) && this.state.inMethod !== "constructor" && !this.options.allowSuperOutsideMethod) { + this.raise(node.start, "super() is only valid inside a class constructor. Make sure the method name is spelled exactly as 'constructor'."); + } + return this.finishNode(node, "Super"); + + case tt._import: + if (!this.hasPlugin("dynamicImport")) this.unexpected(); + + node = this.startNode(); + this.next(); + if (!this.match(tt.parenL)) { + this.unexpected(null, tt.parenL); + } + return this.finishNode(node, "Import"); + + case tt._this: + node = this.startNode(); + this.next(); + return this.finishNode(node, "ThisExpression"); + + case tt._yield: + if (this.state.inGenerator) this.unexpected(); + + case tt.name: + node = this.startNode(); + const allowAwait = this.state.value === "await" && this.state.inAsync; + const allowYield = this.shouldAllowYieldIdentifier(); + const id = this.parseIdentifier(allowAwait || allowYield); + + if (id.name === "await") { + if (this.state.inAsync || this.inModule) { + return this.parseAwait(node); + } + } else if (id.name === "async" && this.match(tt._function) && !this.canInsertSemicolon()) { + this.next(); + return this.parseFunction(node, false, false, true); + } else if (canBeArrow && id.name === "async" && this.match(tt.name)) { + const params = [this.parseIdentifier()]; + this.expect(tt.arrow); + // let foo = bar => {}; + return this.parseArrowExpression(node, params, true); + } + + if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { + return this.parseArrowExpression(node, [id]); + } + + return id; + + case tt._do: + if (this.hasPlugin("doExpressions")) { + const node = this.startNode(); + this.next(); + const oldInFunction = this.state.inFunction; + const oldLabels = this.state.labels; + this.state.labels = []; + this.state.inFunction = false; + node.body = this.parseBlock(false, true); + this.state.inFunction = oldInFunction; + this.state.labels = oldLabels; + return this.finishNode(node, "DoExpression"); + } + + case tt.regexp: + const value = this.state.value; + node = this.parseLiteral(value.value, "RegExpLiteral"); + node.pattern = value.pattern; + node.flags = value.flags; + return node; + + case tt.num: + return this.parseLiteral(this.state.value, "NumericLiteral"); + + case tt.string: + return this.parseLiteral(this.state.value, "StringLiteral"); + + case tt._null: + node = this.startNode(); + this.next(); + return this.finishNode(node, "NullLiteral"); + + case tt._true: case tt._false: + node = this.startNode(); + node.value = this.match(tt._true); + this.next(); + return this.finishNode(node, "BooleanLiteral"); + + case tt.parenL: + return this.parseParenAndDistinguishExpression(null, null, canBeArrow); + + case tt.bracketL: + node = this.startNode(); + this.next(); + node.elements = this.parseExprList(tt.bracketR, true, refShorthandDefaultPos); + this.toReferencedList(node.elements); + return this.finishNode(node, "ArrayExpression"); + + case tt.braceL: + return this.parseObj(false, refShorthandDefaultPos); + + case tt._function: + return this.parseFunctionExpression(); + + case tt.at: + this.parseDecorators(); + + case tt._class: + node = this.startNode(); + this.takeDecorators(node); + return this.parseClass(node, false); + + case tt._new: + return this.parseNew(); + + case tt.backQuote: + return this.parseTemplate(false); + + case tt.doubleColon: + node = this.startNode(); + this.next(); + node.object = null; + const callee = node.callee = this.parseNoCallExpr(); + if (callee.type === "MemberExpression") { + return this.finishNode(node, "BindExpression"); + } else { + this.raise(callee.start, "Binding should be performed on object property."); + } + + default: + this.unexpected(); + } + } + + parseFunctionExpression() { + const node = this.startNode(); + const meta = this.parseIdentifier(true); + if (this.state.inGenerator && this.eat(tt.dot) && this.hasPlugin("functionSent")) { + return this.parseMetaProperty(node, meta, "sent"); } else { - this.expect(tt.comma, refNeedsArrowPos.start || null); - if (this.match(tt.parenR)) { - optionalCommaStart = this.state.start; + return this.parseFunction(node, false); + } + } + + parseMetaProperty(node, meta, propertyName) { + node.meta = meta; + node.property = this.parseIdentifier(true); + + if (node.property.name !== propertyName) { + this.raise(node.property.start, `The only valid meta property for new is ${meta.name}.${propertyName}`); + } + + return this.finishNode(node, "MetaProperty"); + } + + parseLiteral(value, type, startPos, startLoc) { + startPos = startPos || this.state.start; + startLoc = startLoc || this.state.startLoc; + + const node = this.startNodeAt(startPos, startLoc); + this.addExtra(node, "rawValue", value); + this.addExtra(node, "raw", this.input.slice(startPos, this.state.end)); + node.value = value; + this.next(); + return this.finishNode(node, type); + } + + parseParenExpression() { + this.expect(tt.parenL); + const val = this.parseExpression(); + this.expect(tt.parenR); + return val; + } + + parseParenAndDistinguishExpression(startPos, startLoc, canBeArrow) { + startPos = startPos || this.state.start; + startLoc = startLoc || this.state.startLoc; + + let val; + this.expect(tt.parenL); + + const innerStartPos = this.state.start; + const innerStartLoc = this.state.startLoc; + const exprList = []; + const refShorthandDefaultPos = { start: 0 }; + const refNeedsArrowPos = { start: 0 }; + let first = true; + let spreadStart; + let optionalCommaStart; + + while (!this.match(tt.parenR)) { + if (first) { + first = false; + } else { + this.expect(tt.comma, refNeedsArrowPos.start || null); + if (this.match(tt.parenR)) { + optionalCommaStart = this.state.start; + break; + } + } + + if (this.match(tt.ellipsis)) { + const spreadNodeStartPos = this.state.start; + const spreadNodeStartLoc = this.state.startLoc; + spreadStart = this.state.start; + exprList.push(this.parseParenItem(this.parseRest(), spreadNodeStartPos, spreadNodeStartLoc)); break; + } else { + exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos)); } } - if (this.match(tt.ellipsis)) { - const spreadNodeStartPos = this.state.start; - const spreadNodeStartLoc = this.state.startLoc; - spreadStart = this.state.start; - exprList.push(this.parseParenItem(this.parseRest(), spreadNodeStartPos, spreadNodeStartLoc)); - break; + const innerEndPos = this.state.start; + const innerEndLoc = this.state.startLoc; + this.expect(tt.parenR); + + let arrowNode = this.startNodeAt(startPos, startLoc); + if (canBeArrow && this.shouldParseArrow() && (arrowNode = this.parseArrow(arrowNode))) { + for (const param of exprList) { + if (param.extra && param.extra.parenthesized) this.unexpected(param.extra.parenStart); + } + + return this.parseArrowExpression(arrowNode, exprList); + } + + if (!exprList.length) { + this.unexpected(this.state.lastTokStart); + } + if (optionalCommaStart) this.unexpected(optionalCommaStart); + if (spreadStart) this.unexpected(spreadStart); + if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start); + if (refNeedsArrowPos.start) this.unexpected(refNeedsArrowPos.start); + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc); + val.expressions = exprList; + this.toReferencedList(val.expressions); + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); } else { - exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos)); + val = exprList[0]; + } + + + this.addExtra(val, "parenthesized", true); + this.addExtra(val, "parenStart", startPos); + + return val; + } + + shouldParseArrow() { + return !this.canInsertSemicolon(); + } + + parseArrow(node) { + if (this.eat(tt.arrow)) { + return node; } } - const innerEndPos = this.state.start; - const innerEndLoc = this.state.startLoc; - this.expect(tt.parenR); - - let arrowNode = this.startNodeAt(startPos, startLoc); - if (canBeArrow && this.shouldParseArrow() && (arrowNode = this.parseArrow(arrowNode))) { - for (const param of exprList) { - if (param.extra && param.extra.parenthesized) this.unexpected(param.extra.parenStart); - } - - return this.parseArrowExpression(arrowNode, exprList); - } - - if (!exprList.length) { - this.unexpected(this.state.lastTokStart); - } - if (optionalCommaStart) this.unexpected(optionalCommaStart); - if (spreadStart) this.unexpected(spreadStart); - if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start); - if (refNeedsArrowPos.start) this.unexpected(refNeedsArrowPos.start); - - if (exprList.length > 1) { - val = this.startNodeAt(innerStartPos, innerStartLoc); - val.expressions = exprList; - this.toReferencedList(val.expressions); - this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); - } else { - val = exprList[0]; - } - - - this.addExtra(val, "parenthesized", true); - this.addExtra(val, "parenStart", startPos); - - return val; -}; - -pp.shouldParseArrow = function () { - return !this.canInsertSemicolon(); -}; - -pp.parseArrow = function (node) { - if (this.eat(tt.arrow)) { + parseParenItem(node) { return node; } -}; -pp.parseParenItem = function (node) { - return node; -}; + // New's precedence is slightly tricky. It must allow its argument + // to be a `[]` or dot subscript expression, but not a call — at + // least, not without wrapping it in parentheses. Thus, it uses the -// New's precedence is slightly tricky. It must allow its argument -// to be a `[]` or dot subscript expression, but not a call — at -// least, not without wrapping it in parentheses. Thus, it uses the + parseNew() { + const node = this.startNode(); + const meta = this.parseIdentifier(true); -pp.parseNew = function () { - const node = this.startNode(); - const meta = this.parseIdentifier(true); + if (this.eat(tt.dot)) { + const metaProp = this.parseMetaProperty(node, meta, "target"); - if (this.eat(tt.dot)) { - const metaProp = this.parseMetaProperty(node, meta, "target"); + if (!this.state.inFunction) { + this.raise(metaProp.property.start, "new.target can only be used in functions"); + } - if (!this.state.inFunction) { - this.raise(metaProp.property.start, "new.target can only be used in functions"); + return metaProp; } - return metaProp; - } + node.callee = this.parseNoCallExpr(); - node.callee = this.parseNoCallExpr(); - - if (this.eat(tt.parenL)) { - node.arguments = this.parseExprList(tt.parenR); - this.toReferencedList(node.arguments); - } else { - node.arguments = []; - } - - return this.finishNode(node, "NewExpression"); -}; - -// Parse template expression. - -pp.parseTemplateElement = function (isTagged) { - const elem = this.startNode(); - if (this.state.value === null) { - if (!isTagged) { - this.raise(this.state.invalidTemplateEscapePosition, "Invalid escape sequence in template"); + if (this.eat(tt.parenL)) { + node.arguments = this.parseExprList(tt.parenR); + this.toReferencedList(node.arguments); } else { - this.state.invalidTemplateEscapePosition = null; + node.arguments = []; } + + return this.finishNode(node, "NewExpression"); } - elem.value = { - raw: this.input.slice(this.state.start, this.state.end).replace(/\r\n?/g, "\n"), - cooked: this.state.value - }; - this.next(); - elem.tail = this.match(tt.backQuote); - return this.finishNode(elem, "TemplateElement"); -}; -pp.parseTemplate = function (isTagged) { - const node = this.startNode(); - this.next(); - node.expressions = []; - let curElt = this.parseTemplateElement(isTagged); - node.quasis = [curElt]; - while (!curElt.tail) { - this.expect(tt.dollarBraceL); - node.expressions.push(this.parseExpression()); - this.expect(tt.braceR); - node.quasis.push(curElt = this.parseTemplateElement(isTagged)); + // Parse template expression. + + parseTemplateElement(isTagged) { + const elem = this.startNode(); + if (this.state.value === null) { + if (!isTagged) { + this.raise(this.state.invalidTemplateEscapePosition, "Invalid escape sequence in template"); + } else { + this.state.invalidTemplateEscapePosition = null; + } + } + elem.value = { + raw: this.input.slice(this.state.start, this.state.end).replace(/\r\n?/g, "\n"), + cooked: this.state.value + }; + this.next(); + elem.tail = this.match(tt.backQuote); + return this.finishNode(elem, "TemplateElement"); } - this.next(); - return this.finishNode(node, "TemplateLiteral"); -}; -// Parse an object literal or binding pattern. - -pp.parseObj = function (isPattern, refShorthandDefaultPos) { - let decorators = []; - const propHash = Object.create(null); - let first = true; - const node = this.startNode(); - - node.properties = []; - this.next(); - - let firstRestLocation = null; - - while (!this.eat(tt.braceR)) { - if (first) { - first = false; - } else { - this.expect(tt.comma); - if (this.eat(tt.braceR)) break; + parseTemplate(isTagged) { + const node = this.startNode(); + this.next(); + node.expressions = []; + let curElt = this.parseTemplateElement(isTagged); + node.quasis = [curElt]; + while (!curElt.tail) { + this.expect(tt.dollarBraceL); + node.expressions.push(this.parseExpression()); + this.expect(tt.braceR); + node.quasis.push(curElt = this.parseTemplateElement(isTagged)); } + this.next(); + return this.finishNode(node, "TemplateLiteral"); + } - while (this.match(tt.at)) { - decorators.push(this.parseDecorator()); - } + // Parse an object literal or binding pattern. - let prop = this.startNode(), isGenerator = false, isAsync = false, startPos, startLoc; - if (decorators.length) { - prop.decorators = decorators; - decorators = []; - } + parseObj(isPattern, refShorthandDefaultPos) { + let decorators = []; + const propHash = Object.create(null); + let first = true; + const node = this.startNode(); - if (this.hasPlugin("objectRestSpread") && this.match(tt.ellipsis)) { - prop = this.parseSpread(isPattern ? { start: 0 } : undefined); - prop.type = isPattern ? "RestElement" : "SpreadElement"; - if (isPattern) this.toAssignable(prop.argument, true, "object pattern"); - node.properties.push(prop); - if (isPattern) { - const position = this.state.start; - if (firstRestLocation !== null) { - this.unexpected(firstRestLocation, "Cannot have multiple rest elements when destructuring"); - } else if (this.eat(tt.braceR)) { - break; - } else if (this.match(tt.comma) && this.lookahead().type === tt.braceR) { - this.unexpected(position, "A trailing comma is not permitted after the rest element"); + node.properties = []; + this.next(); + + let firstRestLocation = null; + + while (!this.eat(tt.braceR)) { + if (first) { + first = false; + } else { + this.expect(tt.comma); + if (this.eat(tt.braceR)) break; + } + + while (this.match(tt.at)) { + decorators.push(this.parseDecorator()); + } + + let prop = this.startNode(), isGenerator = false, isAsync = false, startPos, startLoc; + if (decorators.length) { + prop.decorators = decorators; + decorators = []; + } + + if (this.hasPlugin("objectRestSpread") && this.match(tt.ellipsis)) { + prop = this.parseSpread(isPattern ? { start: 0 } : undefined); + prop.type = isPattern ? "RestElement" : "SpreadElement"; + if (isPattern) this.toAssignable(prop.argument, true, "object pattern"); + node.properties.push(prop); + if (isPattern) { + const position = this.state.start; + if (firstRestLocation !== null) { + this.unexpected(firstRestLocation, "Cannot have multiple rest elements when destructuring"); + } else if (this.eat(tt.braceR)) { + break; + } else if (this.match(tt.comma) && this.lookahead().type === tt.braceR) { + this.unexpected(position, "A trailing comma is not permitted after the rest element"); + } else { + firstRestLocation = position; + continue; + } } else { - firstRestLocation = position; continue; } - } else { - continue; } - } - prop.method = false; - prop.shorthand = false; + prop.method = false; + prop.shorthand = false; - if (isPattern || refShorthandDefaultPos) { - startPos = this.state.start; - startLoc = this.state.startLoc; - } + if (isPattern || refShorthandDefaultPos) { + startPos = this.state.start; + startLoc = this.state.startLoc; + } - if (!isPattern) { - isGenerator = this.eat(tt.star); - } + if (!isPattern) { + isGenerator = this.eat(tt.star); + } - if (!isPattern && this.isContextual("async")) { - if (isGenerator) this.unexpected(); + if (!isPattern && this.isContextual("async")) { + if (isGenerator) this.unexpected(); - const asyncId = this.parseIdentifier(); - if (this.match(tt.colon) || this.match(tt.parenL) || this.match(tt.braceR) || this.match(tt.eq) || this.match(tt.comma)) { - prop.key = asyncId; - prop.computed = false; + const asyncId = this.parseIdentifier(); + if (this.match(tt.colon) || this.match(tt.parenL) || this.match(tt.braceR) || this.match(tt.eq) || this.match(tt.comma)) { + prop.key = asyncId; + prop.computed = false; + } else { + isAsync = true; + if (this.hasPlugin("asyncGenerators")) isGenerator = this.eat(tt.star); + this.parsePropertyName(prop); + } } else { - isAsync = true; - if (this.hasPlugin("asyncGenerators")) isGenerator = this.eat(tt.star); this.parsePropertyName(prop); } - } else { + + this.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos); + this.checkPropClash(prop, propHash); + + if (prop.shorthand) { + this.addExtra(prop, "shorthand", true); + } + + node.properties.push(prop); + } + + if (firstRestLocation !== null) { + this.unexpected(firstRestLocation, "The rest element has to be the last element when destructuring"); + } + + if (decorators.length) { + this.raise(this.state.start, "You have trailing decorators with no property"); + } + + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression"); + } + + isGetterOrSetterMethod(prop, isPattern) { + return !isPattern && + !prop.computed && + prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + ( + this.match(tt.string) || // get "string"() {} + this.match(tt.num) || // get 1() {} + this.match(tt.bracketL) || // get ["string"]() {} + this.match(tt.name) || // get foo() {} + this.state.type.keyword // get debugger() {} + ); + } + + // get methods aren't allowed to have any parameters + // set methods must have exactly 1 parameter + checkGetterSetterParamCount(method) { + const paramCount = method.kind === "get" ? 0 : 1; + if (method.params.length !== paramCount) { + const start = method.start; + if (method.kind === "get") { + this.raise(start, "getter should have no params"); + } else { + this.raise(start, "setter should have exactly one param"); + } + } + } + + parseObjectMethod(prop, isGenerator, isAsync, isPattern) { + if (isAsync || isGenerator || this.match(tt.parenL)) { + if (isPattern) this.unexpected(); + prop.kind = "method"; + prop.method = true; + this.parseMethod(prop, isGenerator, isAsync); + + return this.finishNode(prop, "ObjectMethod"); + } + + if (this.isGetterOrSetterMethod(prop, isPattern)) { + if (isGenerator || isAsync) this.unexpected(); + prop.kind = prop.key.name; this.parsePropertyName(prop); - } + this.parseMethod(prop); + this.checkGetterSetterParamCount(prop); - this.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos); - this.checkPropClash(prop, propHash); - - if (prop.shorthand) { - this.addExtra(prop, "shorthand", true); - } - - node.properties.push(prop); - } - - if (firstRestLocation !== null) { - this.unexpected(firstRestLocation, "The rest element has to be the last element when destructuring"); - } - - if (decorators.length) { - this.raise(this.state.start, "You have trailing decorators with no property"); - } - - return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression"); -}; - -pp.isGetterOrSetterMethod = function (prop, isPattern) { - return !isPattern && - !prop.computed && - prop.key.type === "Identifier" && - (prop.key.name === "get" || prop.key.name === "set") && - ( - this.match(tt.string) || // get "string"() {} - this.match(tt.num) || // get 1() {} - this.match(tt.bracketL) || // get ["string"]() {} - this.match(tt.name) || // get foo() {} - this.state.type.keyword // get debugger() {} - ); -}; - -// get methods aren't allowed to have any parameters -// set methods must have exactly 1 parameter -pp.checkGetterSetterParamCount = function (method) { - const paramCount = method.kind === "get" ? 0 : 1; - if (method.params.length !== paramCount) { - const start = method.start; - if (method.kind === "get") { - this.raise(start, "getter should have no params"); - } else { - this.raise(start, "setter should have exactly one param"); + return this.finishNode(prop, "ObjectMethod"); } } -}; -pp.parseObjectMethod = function (prop, isGenerator, isAsync, isPattern) { - if (isAsync || isGenerator || this.match(tt.parenL)) { - if (isPattern) this.unexpected(); - prop.kind = "method"; - prop.method = true; - this.parseMethod(prop, isGenerator, isAsync); + parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos) { + if (this.eat(tt.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos); - return this.finishNode(prop, "ObjectMethod"); - } + return this.finishNode(prop, "ObjectProperty"); + } - if (this.isGetterOrSetterMethod(prop, isPattern)) { - if (isGenerator || isAsync) this.unexpected(); - prop.kind = prop.key.name; - this.parsePropertyName(prop); - this.parseMethod(prop); - this.checkGetterSetterParamCount(prop); + if (!prop.computed && prop.key.type === "Identifier") { + this.checkReservedWord(prop.key.name, prop.key.start, true, true); - return this.finishNode(prop, "ObjectMethod"); - } -}; - -pp.parseObjectProperty = function (prop, startPos, startLoc, isPattern, refShorthandDefaultPos) { - if (this.eat(tt.colon)) { - prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos); - - return this.finishNode(prop, "ObjectProperty"); - } - - if (!prop.computed && prop.key.type === "Identifier") { - this.checkReservedWord(prop.key.name, prop.key.start, true, true); - - if (isPattern) { - prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); - } else if (this.match(tt.eq) && refShorthandDefaultPos) { - if (!refShorthandDefaultPos.start) { - refShorthandDefaultPos.start = this.state.start; + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); + } else if (this.match(tt.eq) && refShorthandDefaultPos) { + if (!refShorthandDefaultPos.start) { + refShorthandDefaultPos.start = this.state.start; + } + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); + } else { + prop.value = prop.key.__clone(); } - prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); + prop.shorthand = true; + + return this.finishNode(prop, "ObjectProperty"); + } + } + + parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos) { + const node = + this.parseObjectMethod(prop, isGenerator, isAsync, isPattern) || + this.parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos); + + if (!node) this.unexpected(); + + return node; + } + + parsePropertyName(prop) { + if (this.eat(tt.bracketL)) { + prop.computed = true; + prop.key = this.parseMaybeAssign(); + this.expect(tt.bracketR); } else { - prop.value = prop.key.__clone(); - } - prop.shorthand = true; - - return this.finishNode(prop, "ObjectProperty"); - } -}; - -pp.parseObjPropValue = function (prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos) { - const node = - this.parseObjectMethod(prop, isGenerator, isAsync, isPattern) || - this.parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos); - - if (!node) this.unexpected(); - - return node; -}; - -pp.parsePropertyName = function (prop) { - if (this.eat(tt.bracketL)) { - prop.computed = true; - prop.key = this.parseMaybeAssign(); - this.expect(tt.bracketR); - } else { - prop.computed = false; - const oldInPropertyName = this.state.inPropertyName; - this.state.inPropertyName = true; - prop.key = (this.match(tt.num) || this.match(tt.string)) ? this.parseExprAtom() : this.parseIdentifier(true); - this.state.inPropertyName = oldInPropertyName; - } - return prop.key; -}; - -// Initialize empty function node. - -pp.initFunction = function (node, isAsync) { - node.id = null; - node.generator = false; - node.expression = false; - node.async = !!isAsync; -}; - -// Parse object or class method. - -pp.parseMethod = function (node, isGenerator, isAsync) { - const oldInMethod = this.state.inMethod; - this.state.inMethod = node.kind || true; - this.initFunction(node, isAsync); - this.expect(tt.parenL); - node.params = this.parseBindingList(tt.parenR); - node.generator = !!isGenerator; - this.parseFunctionBody(node); - this.state.inMethod = oldInMethod; - return node; -}; - -// Parse arrow function expression with given parameters. - -pp.parseArrowExpression = function (node, params, isAsync) { - this.initFunction(node, isAsync); - node.params = this.toAssignableList(params, true, "arrow function parameters"); - this.parseFunctionBody(node, true); - return this.finishNode(node, "ArrowFunctionExpression"); -}; - -pp.isStrictBody = function (node, isExpression) { - if (!isExpression && node.body.directives.length) { - for (const directive of (node.body.directives: Array)) { - if (directive.value.value === "use strict") { - return true; - } + prop.computed = false; + const oldInPropertyName = this.state.inPropertyName; + this.state.inPropertyName = true; + prop.key = (this.match(tt.num) || this.match(tt.string)) ? this.parseExprAtom() : this.parseIdentifier(true); + this.state.inPropertyName = oldInPropertyName; } + return prop.key; } - return false; -}; + // Initialize empty function node. -// Parse function body and check parameters. -pp.parseFunctionBody = function (node, allowExpression) { - const isExpression = allowExpression && !this.match(tt.braceL); - - const oldInAsync = this.state.inAsync; - this.state.inAsync = node.async; - if (isExpression) { - node.body = this.parseMaybeAssign(); - node.expression = true; - } else { - // Start a new scope with regard to labels and the `inFunction` - // flag (restore them to their old value afterwards). - const oldInFunc = this.state.inFunction; - const oldInGen = this.state.inGenerator; - const oldLabels = this.state.labels; - this.state.inFunction = true; this.state.inGenerator = node.generator; this.state.labels = []; - node.body = this.parseBlock(true); + initFunction(node, isAsync) { + node.id = null; + node.generator = false; node.expression = false; - this.state.inFunction = oldInFunc; this.state.inGenerator = oldInGen; this.state.labels = oldLabels; - } - this.state.inAsync = oldInAsync; - - // If this is a strict mode function, verify that argument names - // are not repeated, and it does not try to bind the words `eval` - // or `arguments`. - const isStrict = this.isStrictBody(node, isExpression); - // Also check when allowExpression === true for arrow functions - const checkLVal = this.state.strict || allowExpression || isStrict; - - if (isStrict && node.id && node.id.type === "Identifier" && node.id.name === "yield") { - this.raise(node.id.start, "Binding yield in strict mode"); + node.async = !!isAsync; } - if (checkLVal) { - const nameHash = Object.create(null); - const oldStrict = this.state.strict; - if (isStrict) this.state.strict = true; - if (node.id) { - this.checkLVal(node.id, true, undefined, "function name"); - } - for (const param of (node.params: Array)) { - if (isStrict && param.type !== "Identifier") { - this.raise(param.start, "Non-simple parameter in strict mode"); + // Parse object or class method. + + parseMethod(node, isGenerator, isAsync) { + const oldInMethod = this.state.inMethod; + this.state.inMethod = node.kind || true; + this.initFunction(node, isAsync); + this.expect(tt.parenL); + node.params = this.parseBindingList(tt.parenR); + node.generator = !!isGenerator; + this.parseFunctionBody(node); + this.state.inMethod = oldInMethod; + return node; + } + + // Parse arrow function expression with given parameters. + + parseArrowExpression(node, params, isAsync) { + this.initFunction(node, isAsync); + node.params = this.toAssignableList(params, true, "arrow function parameters"); + this.parseFunctionBody(node, true); + return this.finishNode(node, "ArrowFunctionExpression"); + } + + isStrictBody(node, isExpression) { + if (!isExpression && node.body.directives.length) { + for (const directive of (node.body.directives: Array)) { + if (directive.value.value === "use strict") { + return true; + } } - this.checkLVal(param, true, nameHash, "function parameter list"); } - this.state.strict = oldStrict; + + return false; } -}; -// Parses a comma-separated list of expressions, and returns them as -// an array. `close` is the token type that ends the list, and -// `allowEmpty` can be turned on to allow subsequent commas with -// nothing in between them to be parsed as `null` (which is needed -// for array literals). + // Parse function body and check parameters. + parseFunctionBody(node, allowExpression) { + const isExpression = allowExpression && !this.match(tt.braceL); -pp.parseExprList = function (close, allowEmpty, refShorthandDefaultPos) { - const elts = []; - let first = true; - - while (!this.eat(close)) { - if (first) { - first = false; + const oldInAsync = this.state.inAsync; + this.state.inAsync = node.async; + if (isExpression) { + node.body = this.parseMaybeAssign(); + node.expression = true; } else { - this.expect(tt.comma); - if (this.eat(close)) break; + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + const oldInFunc = this.state.inFunction; + const oldInGen = this.state.inGenerator; + const oldLabels = this.state.labels; + this.state.inFunction = true; this.state.inGenerator = node.generator; this.state.labels = []; + node.body = this.parseBlock(true); + node.expression = false; + this.state.inFunction = oldInFunc; this.state.inGenerator = oldInGen; this.state.labels = oldLabels; + } + this.state.inAsync = oldInAsync; + + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + const isStrict = this.isStrictBody(node, isExpression); + // Also check when allowExpression === true for arrow functions + const checkLVal = this.state.strict || allowExpression || isStrict; + + if (isStrict && node.id && node.id.type === "Identifier" && node.id.name === "yield") { + this.raise(node.id.start, "Binding yield in strict mode"); } - elts.push(this.parseExprListItem(allowEmpty, refShorthandDefaultPos)); - } - return elts; -}; - -pp.parseExprListItem = function (allowEmpty, refShorthandDefaultPos, refNeedsArrowPos) { - let elt; - if (allowEmpty && this.match(tt.comma)) { - elt = null; - } else if (this.match(tt.ellipsis)) { - elt = this.parseSpread(refShorthandDefaultPos); - } else { - elt = this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos); - } - return elt; -}; - -// Parse the next token as an identifier. If `liberal` is true (used -// when parsing properties), it will also convert keywords into -// identifiers. - -pp.parseIdentifier = function (liberal) { - const node = this.startNode(); - if (!liberal) { - this.checkReservedWord(this.state.value, this.state.start, !!this.state.type.keyword, false); + if (checkLVal) { + const nameHash = Object.create(null); + const oldStrict = this.state.strict; + if (isStrict) this.state.strict = true; + if (node.id) { + this.checkLVal(node.id, true, undefined, "function name"); + } + for (const param of (node.params: Array)) { + if (isStrict && param.type !== "Identifier") { + this.raise(param.start, "Non-simple parameter in strict mode"); + } + this.checkLVal(param, true, nameHash, "function parameter list"); + } + this.state.strict = oldStrict; + } } - if (this.match(tt.name)) { - node.name = this.state.value; - } else if (this.state.type.keyword) { - node.name = this.state.type.keyword; - } else { - this.unexpected(); + // Parses a comma-separated list of expressions, and returns them as + // an array. `close` is the token type that ends the list, and + // `allowEmpty` can be turned on to allow subsequent commas with + // nothing in between them to be parsed as `null` (which is needed + // for array literals). + + parseExprList(close, allowEmpty, refShorthandDefaultPos) { + const elts = []; + let first = true; + + while (!this.eat(close)) { + if (first) { + first = false; + } else { + this.expect(tt.comma); + if (this.eat(close)) break; + } + + elts.push(this.parseExprListItem(allowEmpty, refShorthandDefaultPos)); + } + return elts; } - if (!liberal && node.name === "await" && this.state.inAsync) { - this.raise(node.start, "invalid use of await inside of an async function"); + parseExprListItem(allowEmpty, refShorthandDefaultPos, refNeedsArrowPos) { + let elt; + if (allowEmpty && this.match(tt.comma)) { + elt = null; + } else if (this.match(tt.ellipsis)) { + elt = this.parseSpread(refShorthandDefaultPos); + } else { + elt = this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos); + } + return elt; } - node.loc.identifierName = node.name; + // Parse the next token as an identifier. If `liberal` is true (used + // when parsing properties), it will also convert keywords into + // identifiers. - this.next(); - return this.finishNode(node, "Identifier"); -}; + parseIdentifier(liberal) { + const node = this.startNode(); + if (!liberal) { + this.checkReservedWord(this.state.value, this.state.start, !!this.state.type.keyword, false); + } -pp.checkReservedWord = function (word, startLoc, checkKeywords, isBinding) { - if (this.isReservedWord(word) || (checkKeywords && this.isKeyword(word))) { - this.raise(startLoc, word + " is a reserved word"); + if (this.match(tt.name)) { + node.name = this.state.value; + } else if (this.state.type.keyword) { + node.name = this.state.type.keyword; + } else { + this.unexpected(); + } + + if (!liberal && node.name === "await" && this.state.inAsync) { + this.raise(node.start, "invalid use of await inside of an async function"); + } + + node.loc.identifierName = node.name; + + this.next(); + return this.finishNode(node, "Identifier"); } - if (this.state.strict && (reservedWords.strict(word) || (isBinding && reservedWords.strictBind(word)))) { - this.raise(startLoc, word + " is a reserved word in strict mode"); - } -}; + checkReservedWord(word, startLoc, checkKeywords, isBinding) { + if (this.isReservedWord(word) || (checkKeywords && this.isKeyword(word))) { + this.raise(startLoc, word + " is a reserved word"); + } -// Parses await expression inside async function. - -pp.parseAwait = function (node) { - // istanbul ignore next: this condition is checked at the call site so won't be hit here - if (!this.state.inAsync) { - this.unexpected(); + if (this.state.strict && (reservedWords.strict(word) || (isBinding && reservedWords.strictBind(word)))) { + this.raise(startLoc, word + " is a reserved word in strict mode"); + } } - if (this.match(tt.star)) { - this.raise(node.start, "await* has been removed from the async functions proposal. Use Promise.all() instead."); - } - node.argument = this.parseMaybeUnary(); - return this.finishNode(node, "AwaitExpression"); -}; -// Parses yield expression inside generator. + // Parses await expression inside async function. -pp.parseYield = function () { - const node = this.startNode(); - this.next(); - if ( - this.match(tt.semi) || - this.canInsertSemicolon() || - (!this.match(tt.star) && !this.state.type.startsExpr) - ) { - node.delegate = false; - node.argument = null; - } else { - node.delegate = this.eat(tt.star); - node.argument = this.parseMaybeAssign(); + parseAwait(node) { + // istanbul ignore next: this condition is checked at the call site so won't be hit here + if (!this.state.inAsync) { + this.unexpected(); + } + if (this.match(tt.star)) { + this.raise(node.start, "await* has been removed from the async functions proposal. Use Promise.all() instead."); + } + node.argument = this.parseMaybeUnary(); + return this.finishNode(node, "AwaitExpression"); } - return this.finishNode(node, "YieldExpression"); -}; + + // Parses yield expression inside generator. + + parseYield() { + const node = this.startNode(); + this.next(); + if ( + this.match(tt.semi) || + this.canInsertSemicolon() || + (!this.match(tt.star) && !this.state.type.startsExpr) + ) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(tt.star); + node.argument = this.parseMaybeAssign(); + } + return this.finishNode(node, "YieldExpression"); + } +} diff --git a/src/parser/index.js b/src/parser/index.js index 9600040c5f..41ce90fde2 100644 --- a/src/parser/index.js +++ b/src/parser/index.js @@ -1,11 +1,14 @@ -import { reservedWords } from "../util/identifier"; +// @flow + +import type { Options } from "../options"; +import type { File } from "../types"; import { getOptions } from "../options"; -import Tokenizer from "../tokenizer"; +import StatementParser from "./statement"; export const plugins = {}; -export default class Parser extends Tokenizer { - constructor(options: Object, input: string) { +export default class Parser extends StatementParser { + constructor(options: Options, input: string) { options = getOptions(options); super(options, input); @@ -21,25 +24,7 @@ export default class Parser extends Tokenizer { } } - isReservedWord(word: string): boolean { - if (word === "await") { - return this.inModule; - } else { - return reservedWords[6](word); - } - } - - hasPlugin(name: string): boolean { - return !!this.plugins[name]; - } - - parse(): { - type: "File", - program: { - type: "Program", - body: Array - } - } { + parse(): File { const file = this.startNode(); const program = this.startNode(); this.nextToken(); diff --git a/src/parser/location.js b/src/parser/location.js index 2a408a5100..1562f52fb6 100644 --- a/src/parser/location.js +++ b/src/parser/location.js @@ -1,7 +1,5 @@ import { getLineInfo } from "../util/location"; -import Parser from "./index"; - -const pp = Parser.prototype; +import CommentsParser from "./comments"; // This function is used to raise exceptions on parse errors. It // takes an offset integer (into the current `input`) to indicate @@ -9,11 +7,13 @@ const pp = Parser.prototype; // of the error message, and then raises a `SyntaxError` with that // message. -pp.raise = function (pos, message) { - const loc = getLineInfo(this.input, pos); - message += ` (${loc.line}:${loc.column})`; - const err = new SyntaxError(message); - err.pos = pos; - err.loc = loc; - throw err; -}; +export default class LocationParser extends CommentsParser { + raise(pos, message) { + const loc = getLineInfo(this.input, pos); + message += ` (${loc.line}:${loc.column})`; + const err = new SyntaxError(message); + err.pos = pos; + err.loc = loc; + throw err; + } +} diff --git a/src/parser/lval.js b/src/parser/lval.js index 9f0f7566c7..b3d33baf3d 100644 --- a/src/parser/lval.js +++ b/src/parser/lval.js @@ -1,259 +1,260 @@ import { types as tt } from "../tokenizer/types"; -import Parser from "./index"; +import { NodeUtils } from "./node"; -const pp = Parser.prototype; +export default class LValParser extends NodeUtils { + // Convert existing expression atom to assignable pattern + // if possible. -// Convert existing expression atom to assignable pattern -// if possible. + toAssignable(node, isBinding, contextDescription) { + if (node) { + switch (node.type) { + case "Identifier": + case "ObjectPattern": + case "ArrayPattern": + case "AssignmentPattern": + break; -pp.toAssignable = function (node, isBinding, contextDescription) { - if (node) { - switch (node.type) { - case "Identifier": - case "ObjectPattern": - case "ArrayPattern": - case "AssignmentPattern": - break; - - case "ObjectExpression": - node.type = "ObjectPattern"; - for (const prop of (node.properties: Array)) { - if (prop.type === "ObjectMethod") { - if (prop.kind === "get" || prop.kind === "set") { - this.raise(prop.key.start, "Object pattern can't contain getter or setter"); + case "ObjectExpression": + node.type = "ObjectPattern"; + for (const prop of (node.properties: Array)) { + if (prop.type === "ObjectMethod") { + if (prop.kind === "get" || prop.kind === "set") { + this.raise(prop.key.start, "Object pattern can't contain getter or setter"); + } else { + this.raise(prop.key.start, "Object pattern can't contain methods"); + } } else { - this.raise(prop.key.start, "Object pattern can't contain methods"); + this.toAssignable(prop, isBinding, "object destructuring pattern"); } + } + break; + + case "ObjectProperty": + this.toAssignable(node.value, isBinding, contextDescription); + break; + + case "SpreadElement": + node.type = "RestElement"; + break; + + case "ArrayExpression": + node.type = "ArrayPattern"; + this.toAssignableList(node.elements, isBinding, contextDescription); + break; + + case "AssignmentExpression": + if (node.operator === "=") { + node.type = "AssignmentPattern"; + delete node.operator; } else { - this.toAssignable(prop, isBinding, "object destructuring pattern"); + this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); + } + break; + + case "MemberExpression": + if (!isBinding) break; + + default: { + const message = "Invalid left-hand side" + + (contextDescription ? " in " + contextDescription : /* istanbul ignore next */ "expression"); + this.raise(node.start, message); + } + } + } + return node; + } + + // Convert list of expression atoms to binding list. + + toAssignableList(exprList, isBinding, contextDescription) { + let end = exprList.length; + if (end) { + const last = exprList[end - 1]; + if (last && last.type === "RestElement") { + --end; + } else if (last && last.type === "SpreadElement") { + last.type = "RestElement"; + const arg = last.argument; + this.toAssignable(arg, isBinding, contextDescription); + if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") { + this.unexpected(arg.start); + } + --end; + } + } + for (let i = 0; i < end; i++) { + const elt = exprList[i]; + if (elt && elt.type === "SpreadElement") + this.raise(elt.start, "The rest element has to be the last element when destructuring"); + if (elt) this.toAssignable(elt, isBinding, contextDescription); + } + return exprList; + } + + // Convert list of expression atoms to a list of + + toReferencedList(exprList) { + return exprList; + } + + // Parses spread element. + + parseSpread(refShorthandDefaultPos) { + const node = this.startNode(); + this.next(); + node.argument = this.parseMaybeAssign(false, refShorthandDefaultPos); + return this.finishNode(node, "SpreadElement"); + } + + parseRest() { + const node = this.startNode(); + this.next(); + node.argument = this.parseBindingAtom(); + return this.finishNode(node, "RestElement"); + } + + shouldAllowYieldIdentifier() { + return this.match(tt._yield) && !this.state.strict && !this.state.inGenerator; + } + + parseBindingIdentifier() { + return this.parseIdentifier(this.shouldAllowYieldIdentifier()); + } + + // Parses lvalue (assignable) atom. + parseBindingAtom() { + switch (this.state.type) { + case tt._yield: + case tt.name: + return this.parseBindingIdentifier(); + + case tt.bracketL: + const node = this.startNode(); + this.next(); + node.elements = this.parseBindingList(tt.bracketR, true); + return this.finishNode(node, "ArrayPattern"); + + case tt.braceL: + return this.parseObj(true); + + default: + this.unexpected(); + } + } + + parseBindingList(close, allowEmpty) { + const elts = []; + let first = true; + while (!this.eat(close)) { + if (first) { + first = false; + } else { + this.expect(tt.comma); + } + if (allowEmpty && this.match(tt.comma)) { + elts.push(null); + } else if (this.eat(close)) { + break; + } else if (this.match(tt.ellipsis)) { + elts.push(this.parseAssignableListItemTypes(this.parseRest())); + this.expect(close); + break; + } else { + const decorators = []; + while (this.match(tt.at)) { + decorators.push(this.parseDecorator()); + } + const left = this.parseMaybeDefault(); + if (decorators.length) { + left.decorators = decorators; + } + this.parseAssignableListItemTypes(left); + elts.push(this.parseMaybeDefault(left.start, left.loc.start, left)); + } + } + return elts; + } + + parseAssignableListItemTypes(param) { + return param; + } + + // Parses assignment pattern around given atom if possible. + + parseMaybeDefault(startPos, startLoc, left) { + startLoc = startLoc || this.state.startLoc; + startPos = startPos || this.state.start; + left = left || this.parseBindingAtom(); + if (!this.eat(tt.eq)) return left; + + const node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.right = this.parseMaybeAssign(); + return this.finishNode(node, "AssignmentPattern"); + } + + // Verify that a node is an lval — something that can be assigned + // to. + + checkLVal(expr, isBinding, checkClashes, contextDescription) { + switch (expr.type) { + case "Identifier": + this.checkReservedWord(expr.name, expr.start, false, true); + + if (checkClashes) { + // we need to prefix this with an underscore for the cases where we have a key of + // `__proto__`. there's a bug in old V8 where the following wouldn't work: + // + // > var obj = Object.create(null); + // undefined + // > obj.__proto__ + // null + // > obj.__proto__ = true; + // true + // > obj.__proto__ + // null + const key = `_${expr.name}`; + + if (checkClashes[key]) { + this.raise(expr.start, "Argument name clash in strict mode"); + } else { + checkClashes[key] = true; } } break; - case "ObjectProperty": - this.toAssignable(node.value, isBinding, contextDescription); + case "MemberExpression": + if (isBinding) + this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression"); break; - case "SpreadElement": - node.type = "RestElement"; - break; - - case "ArrayExpression": - node.type = "ArrayPattern"; - this.toAssignableList(node.elements, isBinding, contextDescription); - break; - - case "AssignmentExpression": - if (node.operator === "=") { - node.type = "AssignmentPattern"; - delete node.operator; - } else { - this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); + case "ObjectPattern": + for (let prop of (expr.properties: Array)) { + if (prop.type === "ObjectProperty") prop = prop.value; + this.checkLVal(prop, isBinding, checkClashes, "object destructuring pattern"); } break; - case "MemberExpression": - if (!isBinding) break; + case "ArrayPattern": + for (const elem of (expr.elements: Array)) { + if (elem) this.checkLVal(elem, isBinding, checkClashes, "array destructuring pattern"); + } + break; + + case "AssignmentPattern": + this.checkLVal(expr.left, isBinding, checkClashes, "assignment pattern"); + break; + + case "RestElement": + this.checkLVal(expr.argument, isBinding, checkClashes, "rest element"); + break; default: { - const message = "Invalid left-hand side" + + const message = (isBinding ? /* istanbul ignore next */ "Binding invalid" : "Invalid") + + " left-hand side" + (contextDescription ? " in " + contextDescription : /* istanbul ignore next */ "expression"); - this.raise(node.start, message); + this.raise(expr.start, message); } } } - return node; -}; - -// Convert list of expression atoms to binding list. - -pp.toAssignableList = function (exprList, isBinding, contextDescription) { - let end = exprList.length; - if (end) { - const last = exprList[end - 1]; - if (last && last.type === "RestElement") { - --end; - } else if (last && last.type === "SpreadElement") { - last.type = "RestElement"; - const arg = last.argument; - this.toAssignable(arg, isBinding, contextDescription); - if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") { - this.unexpected(arg.start); - } - --end; - } - } - for (let i = 0; i < end; i++) { - const elt = exprList[i]; - if (elt && elt.type === "SpreadElement") - this.raise(elt.start, "The rest element has to be the last element when destructuring"); - if (elt) this.toAssignable(elt, isBinding, contextDescription); - } - return exprList; -}; - -// Convert list of expression atoms to a list of - -pp.toReferencedList = function (exprList) { - return exprList; -}; - -// Parses spread element. - -pp.parseSpread = function (refShorthandDefaultPos) { - const node = this.startNode(); - this.next(); - node.argument = this.parseMaybeAssign(false, refShorthandDefaultPos); - return this.finishNode(node, "SpreadElement"); -}; - -pp.parseRest = function () { - const node = this.startNode(); - this.next(); - node.argument = this.parseBindingAtom(); - return this.finishNode(node, "RestElement"); -}; - -pp.shouldAllowYieldIdentifier = function () { - return this.match(tt._yield) && !this.state.strict && !this.state.inGenerator; -}; - -pp.parseBindingIdentifier = function () { - return this.parseIdentifier(this.shouldAllowYieldIdentifier()); -}; - -// Parses lvalue (assignable) atom. -pp.parseBindingAtom = function () { - switch (this.state.type) { - case tt._yield: - case tt.name: - return this.parseBindingIdentifier(); - - case tt.bracketL: - const node = this.startNode(); - this.next(); - node.elements = this.parseBindingList(tt.bracketR, true); - return this.finishNode(node, "ArrayPattern"); - - case tt.braceL: - return this.parseObj(true); - - default: - this.unexpected(); - } -}; - -pp.parseBindingList = function (close, allowEmpty) { - const elts = []; - let first = true; - while (!this.eat(close)) { - if (first) { - first = false; - } else { - this.expect(tt.comma); - } - if (allowEmpty && this.match(tt.comma)) { - elts.push(null); - } else if (this.eat(close)) { - break; - } else if (this.match(tt.ellipsis)) { - elts.push(this.parseAssignableListItemTypes(this.parseRest())); - this.expect(close); - break; - } else { - const decorators = []; - while (this.match(tt.at)) { - decorators.push(this.parseDecorator()); - } - const left = this.parseMaybeDefault(); - if (decorators.length) { - left.decorators = decorators; - } - this.parseAssignableListItemTypes(left); - elts.push(this.parseMaybeDefault(left.start, left.loc.start, left)); - } - } - return elts; -}; - -pp.parseAssignableListItemTypes = function (param) { - return param; -}; - -// Parses assignment pattern around given atom if possible. - -pp.parseMaybeDefault = function (startPos, startLoc, left) { - startLoc = startLoc || this.state.startLoc; - startPos = startPos || this.state.start; - left = left || this.parseBindingAtom(); - if (!this.eat(tt.eq)) return left; - - const node = this.startNodeAt(startPos, startLoc); - node.left = left; - node.right = this.parseMaybeAssign(); - return this.finishNode(node, "AssignmentPattern"); -}; - -// Verify that a node is an lval — something that can be assigned -// to. - -pp.checkLVal = function (expr, isBinding, checkClashes, contextDescription) { - switch (expr.type) { - case "Identifier": - this.checkReservedWord(expr.name, expr.start, false, true); - - if (checkClashes) { - // we need to prefix this with an underscore for the cases where we have a key of - // `__proto__`. there's a bug in old V8 where the following wouldn't work: - // - // > var obj = Object.create(null); - // undefined - // > obj.__proto__ - // null - // > obj.__proto__ = true; - // true - // > obj.__proto__ - // null - const key = `_${expr.name}`; - - if (checkClashes[key]) { - this.raise(expr.start, "Argument name clash in strict mode"); - } else { - checkClashes[key] = true; - } - } - break; - - case "MemberExpression": - if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression"); - break; - - case "ObjectPattern": - for (let prop of (expr.properties: Array)) { - if (prop.type === "ObjectProperty") prop = prop.value; - this.checkLVal(prop, isBinding, checkClashes, "object destructuring pattern"); - } - break; - - case "ArrayPattern": - for (const elem of (expr.elements: Array)) { - if (elem) this.checkLVal(elem, isBinding, checkClashes, "array destructuring pattern"); - } - break; - - case "AssignmentPattern": - this.checkLVal(expr.left, isBinding, checkClashes, "assignment pattern"); - break; - - case "RestElement": - this.checkLVal(expr.argument, isBinding, checkClashes, "rest element"); - break; - - default: { - const message = (isBinding ? /* istanbul ignore next */ "Binding invalid" : "Invalid") + - " left-hand side" + - (contextDescription ? " in " + contextDescription : /* istanbul ignore next */ "expression"); - this.raise(expr.start, message); - } - } -}; +} diff --git a/src/parser/node.js b/src/parser/node.js index 364323ec7f..dafe10af9b 100644 --- a/src/parser/node.js +++ b/src/parser/node.js @@ -1,9 +1,9 @@ import Parser from "./index"; +import UtilParser from "./util"; import { SourceLocation, type Position } from "../util/location"; // Start an AST node, attaching a start offset. -const pp = Parser.prototype; const commentKeys = ["leadingComments", "trailingComments", "innerComments"]; class Node { @@ -34,43 +34,40 @@ class Node { } } -pp.startNode = function () { - return new Node(this, this.state.start, this.state.startLoc); -}; +export class NodeUtils extends UtilParser { + startNode() { + return new Node(this, this.state.start, this.state.startLoc); + } -pp.startNodeAt = function (pos, loc) { - return new Node(this, pos, loc); -}; + startNodeAt(pos, loc) { + return new Node(this, pos, loc); + } -function finishNodeAt(node, type, pos, loc) { - node.type = type; - node.end = pos; - node.loc.end = loc; - if (this.options.ranges) node.range[1] = pos; - this.processComment(node); - return node; + // Finish an AST node, adding `type` and `end` properties. + + finishNode(node, type) { + return this.finishNodeAt(node, type, this.state.lastTokEnd, this.state.lastTokEndLoc); + } + + // Finish node at given position + + finishNodeAt(node, type, pos, loc) { + node.type = type; + node.end = pos; + node.loc.end = loc; + if (this.options.ranges) node.range[1] = pos; + this.processComment(node); + return node; + } + + /** + * Reset the start location of node to the start location of locationNode + */ + resetStartLocationFromNode(node, locationNode) { + node.start = locationNode.start; + node.loc.start = locationNode.loc.start; + if (this.options.ranges) node.range[0] = locationNode.range[0]; + + return node; + } } - -// Finish an AST node, adding `type` and `end` properties. - -pp.finishNode = function (node, type) { - return finishNodeAt.call(this, node, type, this.state.lastTokEnd, this.state.lastTokEndLoc); -}; - -// Finish node at given position - -pp.finishNodeAt = function (node, type, pos, loc) { - return finishNodeAt.call(this, node, type, pos, loc); -}; - - -/** - * Reset the start location of node to the start location of locationNode - */ -pp.resetStartLocationFromNode = function (node, locationNode) { - node.start = locationNode.start; - node.loc.start = locationNode.loc.start; - if (this.options.ranges) node.range[0] = locationNode.range[0]; - - return node; -}; diff --git a/src/parser/statement.js b/src/parser/statement.js index f4bd38fb2f..376c685147 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -1,1105 +1,1106 @@ /* eslint max-len: 0 */ import { types as tt } from "../tokenizer/types"; -import Parser from "./index"; +import ExpressionParser from "./expression"; import { lineBreak } from "../util/whitespace"; -const pp = Parser.prototype; +// Reused empty array added for node fields that are always empty. -// ### Statement parsing - -// Parse a program. Initializes the parser, reads any number of -// statements, and wraps them in a Program node. Optionally takes a -// `program` argument. If present, the statements will be appended -// to its body instead of creating a new node. - -pp.parseTopLevel = function (file, program) { - program.sourceType = this.options.sourceType; - - this.parseBlockBody(program, true, true, tt.eof); - - file.program = this.finishNode(program, "Program"); - file.comments = this.state.comments; - file.tokens = this.state.tokens; - - return this.finishNode(file, "File"); -}; +const empty = []; const loopLabel = { kind: "loop" }, switchLabel = { kind: "switch" }; -// TODO +export default class StatementParser extends ExpressionParser { -pp.stmtToDirective = function (stmt) { - const expr = stmt.expression; + // ### Statement parsing - const directiveLiteral = this.startNodeAt(expr.start, expr.loc.start); - const directive = this.startNodeAt(stmt.start, stmt.loc.start); + // Parse a program. Initializes the parser, reads any number of + // statements, and wraps them in a Program node. Optionally takes a + // `program` argument. If present, the statements will be appended + // to its body instead of creating a new node. - const raw = this.input.slice(expr.start, expr.end); - const val = directiveLiteral.value = raw.slice(1, -1); // remove quotes + parseTopLevel(file, program) { + program.sourceType = this.options.sourceType; - this.addExtra(directiveLiteral, "raw", raw); - this.addExtra(directiveLiteral, "rawValue", val); + this.parseBlockBody(program, true, true, tt.eof); - directive.value = this.finishNodeAt(directiveLiteral, "DirectiveLiteral", expr.end, expr.loc.end); + file.program = this.finishNode(program, "Program"); + file.comments = this.state.comments; + file.tokens = this.state.tokens; - return this.finishNodeAt(directive, "Directive", stmt.end, stmt.loc.end); -}; - -// Parse a single statement. -// -// If expecting a statement and finding a slash operator, parse a -// regular expression literal. This is to handle cases like -// `if (foo) /blah/.exec(foo)`, where looking at the previous token -// does not help. - -pp.parseStatement = function (declaration, topLevel) { - if (this.match(tt.at)) { - this.parseDecorators(true); + return this.finishNode(file, "File"); } - const starttype = this.state.type; - const node = this.startNode(); + // TODO - // Most types of statements are recognized by the keyword they - // start with. Many are trivial to parse, some require a bit of - // complexity. + stmtToDirective(stmt) { + const expr = stmt.expression; - switch (starttype) { - case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword); - case tt._debugger: return this.parseDebuggerStatement(node); - case tt._do: return this.parseDoStatement(node); - case tt._for: return this.parseForStatement(node); - case tt._function: - if (!declaration) this.unexpected(); - return this.parseFunctionStatement(node); + const directiveLiteral = this.startNodeAt(expr.start, expr.loc.start); + const directive = this.startNodeAt(stmt.start, stmt.loc.start); - case tt._class: - if (!declaration) this.unexpected(); - return this.parseClass(node, true); + const raw = this.input.slice(expr.start, expr.end); + const val = directiveLiteral.value = raw.slice(1, -1); // remove quotes - case tt._if: return this.parseIfStatement(node); - case tt._return: return this.parseReturnStatement(node); - case tt._switch: return this.parseSwitchStatement(node); - case tt._throw: return this.parseThrowStatement(node); - case tt._try: return this.parseTryStatement(node); + this.addExtra(directiveLiteral, "raw", raw); + this.addExtra(directiveLiteral, "rawValue", val); - case tt._let: - case tt._const: - if (!declaration) this.unexpected(); // NOTE: falls through to _var + directive.value = this.finishNodeAt(directiveLiteral, "DirectiveLiteral", expr.end, expr.loc.end); - case tt._var: - return this.parseVarStatement(node, starttype); + return this.finishNodeAt(directive, "Directive", stmt.end, stmt.loc.end); + } - case tt._while: return this.parseWhileStatement(node); - case tt._with: return this.parseWithStatement(node); - case tt.braceL: return this.parseBlock(); - case tt.semi: return this.parseEmptyStatement(node); - case tt._export: - case tt._import: - if (this.hasPlugin("dynamicImport") && this.lookahead().type === tt.parenL) break; + // Parse a single statement. + // + // If expecting a statement and finding a slash operator, parse a + // regular expression literal. This is to handle cases like + // `if (foo) /blah/.exec(foo)`, where looking at the previous token + // does not help. - if (!this.options.allowImportExportEverywhere) { - if (!topLevel) { - this.raise(this.state.start, "'import' and 'export' may only appear at the top level"); + parseStatement(declaration, topLevel) { + if (this.match(tt.at)) { + this.parseDecorators(true); + } + + const starttype = this.state.type; + const node = this.startNode(); + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword); + case tt._debugger: return this.parseDebuggerStatement(node); + case tt._do: return this.parseDoStatement(node); + case tt._for: return this.parseForStatement(node); + case tt._function: + if (!declaration) this.unexpected(); + return this.parseFunctionStatement(node); + + case tt._class: + if (!declaration) this.unexpected(); + return this.parseClass(node, true); + + case tt._if: return this.parseIfStatement(node); + case tt._return: return this.parseReturnStatement(node); + case tt._switch: return this.parseSwitchStatement(node); + case tt._throw: return this.parseThrowStatement(node); + case tt._try: return this.parseTryStatement(node); + + case tt._let: + case tt._const: + if (!declaration) this.unexpected(); // NOTE: falls through to _var + + case tt._var: + return this.parseVarStatement(node, starttype); + + case tt._while: return this.parseWhileStatement(node); + case tt._with: return this.parseWithStatement(node); + case tt.braceL: return this.parseBlock(); + case tt.semi: return this.parseEmptyStatement(node); + case tt._export: + case tt._import: + if (this.hasPlugin("dynamicImport") && this.lookahead().type === tt.parenL) break; + + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) { + this.raise(this.state.start, "'import' and 'export' may only appear at the top level"); + } + + if (!this.inModule) { + this.raise(this.state.start, "'import' and 'export' may appear only with 'sourceType: module'"); + } } + return starttype === tt._import ? this.parseImport(node) : this.parseExport(node); - if (!this.inModule) { - this.raise(this.state.start, "'import' and 'export' may appear only with 'sourceType: module'"); + case tt.name: + if (this.state.value === "async") { + // peek ahead and see if next token is a function + const state = this.state.clone(); + this.next(); + if (this.match(tt._function) && !this.canInsertSemicolon()) { + this.expect(tt._function); + return this.parseFunction(node, true, false, true); + } else { + this.state = state; + } } - } - return starttype === tt._import ? this.parseImport(node) : this.parseExport(node); + } - case tt.name: - if (this.state.value === "async") { - // peek ahead and see if next token is a function - const state = this.state.clone(); - this.next(); - if (this.match(tt._function) && !this.canInsertSemicolon()) { - this.expect(tt._function); - return this.parseFunction(node, true, false, true); - } else { - this.state = state; - } - } - } + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + const maybeName = this.state.value; + const expr = this.parseExpression(); - // If the statement does not start with a statement keyword or a - // brace, it's an ExpressionStatement or LabeledStatement. We - // simply start parsing an expression, and afterwards, if the - // next token is a colon and the expression was a simple - // Identifier node, we switch to interpreting it as a label. - const maybeName = this.state.value; - const expr = this.parseExpression(); - - if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) { - return this.parseLabeledStatement(node, maybeName, expr); - } else { - return this.parseExpressionStatement(node, expr); - } -}; - -pp.takeDecorators = function (node) { - if (this.state.decorators.length) { - node.decorators = this.state.decorators; - this.state.decorators = []; - } -}; - -pp.parseDecorators = function (allowExport) { - while (this.match(tt.at)) { - const decorator = this.parseDecorator(); - this.state.decorators.push(decorator); - } - - if (allowExport && this.match(tt._export)) { - return; - } - - if (!this.match(tt._class)) { - this.raise(this.state.start, "Leading decorators must be attached to a class declaration"); - } -}; - -pp.parseDecorator = function () { - if (!this.hasPlugin("decorators")) { - this.unexpected(); - } - const node = this.startNode(); - this.next(); - node.expression = this.parseMaybeAssign(); - return this.finishNode(node, "Decorator"); -}; - -pp.parseBreakContinueStatement = function (node, keyword) { - const isBreak = keyword === "break"; - this.next(); - - if (this.isLineTerminator()) { - node.label = null; - } else if (!this.match(tt.name)) { - this.unexpected(); - } else { - node.label = this.parseIdentifier(); - this.semicolon(); - } - - // Verify that there is an actual destination to break or - // continue to. - let i; - for (i = 0; i < this.state.labels.length; ++i) { - const lab = this.state.labels[i]; - if (node.label == null || lab.name === node.label.name) { - if (lab.kind != null && (isBreak || lab.kind === "loop")) break; - if (node.label && isBreak) break; + if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) { + return this.parseLabeledStatement(node, maybeName, expr); + } else { + return this.parseExpressionStatement(node, expr); } } - if (i === this.state.labels.length) this.raise(node.start, "Unsyntactic " + keyword); - return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement"); -}; -pp.parseDebuggerStatement = function (node) { - this.next(); - this.semicolon(); - return this.finishNode(node, "DebuggerStatement"); -}; - -pp.parseDoStatement = function (node) { - this.next(); - this.state.labels.push(loopLabel); - node.body = this.parseStatement(false); - this.state.labels.pop(); - this.expect(tt._while); - node.test = this.parseParenExpression(); - this.eat(tt.semi); - return this.finishNode(node, "DoWhileStatement"); -}; - -// Disambiguating between a `for` and a `for`/`in` or `for`/`of` -// loop is non-trivial. Basically, we have to parse the init `var` -// statement or expression, disallowing the `in` operator (see -// the second parameter to `parseExpression`), and then check -// whether the next token is `in` or `of`. When there is no init -// part (semicolon immediately after the opening parenthesis), it -// is a regular `for` loop. - -pp.parseForStatement = function (node) { - this.next(); - this.state.labels.push(loopLabel); - - let forAwait = false; - if (this.hasPlugin("asyncGenerators") && this.state.inAsync && this.isContextual("await")) { - forAwait = true; - this.next(); + takeDecorators(node) { + if (this.state.decorators.length) { + node.decorators = this.state.decorators; + this.state.decorators = []; + } } - this.expect(tt.parenL); - if (this.match(tt.semi)) { - if (forAwait) { + parseDecorators(allowExport) { + while (this.match(tt.at)) { + const decorator = this.parseDecorator(); + this.state.decorators.push(decorator); + } + + if (allowExport && this.match(tt._export)) { + return; + } + + if (!this.match(tt._class)) { + this.raise(this.state.start, "Leading decorators must be attached to a class declaration"); + } + } + + parseDecorator() { + if (!this.hasPlugin("decorators")) { this.unexpected(); } - return this.parseFor(node, null); + const node = this.startNode(); + this.next(); + node.expression = this.parseMaybeAssign(); + return this.finishNode(node, "Decorator"); } - if (this.match(tt._var) || this.match(tt._let) || this.match(tt._const)) { - const init = this.startNode(); - const varKind = this.state.type; + parseBreakContinueStatement(node, keyword) { + const isBreak = keyword === "break"; this.next(); - this.parseVar(init, true, varKind); - this.finishNode(init, "VariableDeclaration"); - if (this.match(tt._in) || this.isContextual("of")) { - if (init.declarations.length === 1 && !init.declarations[0].init) { - return this.parseForIn(node, init, forAwait); + if (this.isLineTerminator()) { + node.label = null; + } else if (!this.match(tt.name)) { + this.unexpected(); + } else { + node.label = this.parseIdentifier(); + this.semicolon(); + } + + // Verify that there is an actual destination to break or + // continue to. + let i; + for (i = 0; i < this.state.labels.length; ++i) { + const lab = this.state.labels[i]; + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) break; + if (node.label && isBreak) break; } } + if (i === this.state.labels.length) this.raise(node.start, "Unsyntactic " + keyword); + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement"); + } + + parseDebuggerStatement(node) { + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement"); + } + + parseDoStatement(node) { + this.next(); + this.state.labels.push(loopLabel); + node.body = this.parseStatement(false); + this.state.labels.pop(); + this.expect(tt._while); + node.test = this.parseParenExpression(); + this.eat(tt.semi); + return this.finishNode(node, "DoWhileStatement"); + } + + // Disambiguating between a `for` and a `for`/`in` or `for`/`of` + // loop is non-trivial. Basically, we have to parse the init `var` + // statement or expression, disallowing the `in` operator (see + // the second parameter to `parseExpression`), and then check + // whether the next token is `in` or `of`. When there is no init + // part (semicolon immediately after the opening parenthesis), it + // is a regular `for` loop. + + parseForStatement(node) { + this.next(); + this.state.labels.push(loopLabel); + + let forAwait = false; + if (this.hasPlugin("asyncGenerators") && this.state.inAsync && this.isContextual("await")) { + forAwait = true; + this.next(); + } + this.expect(tt.parenL); + + if (this.match(tt.semi)) { + if (forAwait) { + this.unexpected(); + } + return this.parseFor(node, null); + } + + if (this.match(tt._var) || this.match(tt._let) || this.match(tt._const)) { + const init = this.startNode(); + const varKind = this.state.type; + this.next(); + this.parseVar(init, true, varKind); + this.finishNode(init, "VariableDeclaration"); + + if (this.match(tt._in) || this.isContextual("of")) { + if (init.declarations.length === 1 && !init.declarations[0].init) { + return this.parseForIn(node, init, forAwait); + } + } + if (forAwait) { + this.unexpected(); + } + return this.parseFor(node, init); + } + + const refShorthandDefaultPos = { start: 0 }; + const init = this.parseExpression(true, refShorthandDefaultPos); + if (this.match(tt._in) || this.isContextual("of")) { + const description = this.isContextual("of") ? "for-of statement" : "for-in statement"; + this.toAssignable(init, undefined, description); + this.checkLVal(init, undefined, undefined, description); + return this.parseForIn(node, init, forAwait); + } else if (refShorthandDefaultPos.start) { + this.unexpected(refShorthandDefaultPos.start); + } if (forAwait) { this.unexpected(); } return this.parseFor(node, init); } - const refShorthandDefaultPos = { start: 0 }; - const init = this.parseExpression(true, refShorthandDefaultPos); - if (this.match(tt._in) || this.isContextual("of")) { - const description = this.isContextual("of") ? "for-of statement" : "for-in statement"; - this.toAssignable(init, undefined, description); - this.checkLVal(init, undefined, undefined, description); - return this.parseForIn(node, init, forAwait); - } else if (refShorthandDefaultPos.start) { - this.unexpected(refShorthandDefaultPos.start); - } - if (forAwait) { - this.unexpected(); - } - return this.parseFor(node, init); -}; - -pp.parseFunctionStatement = function (node) { - this.next(); - return this.parseFunction(node, true); -}; - -pp.parseIfStatement = function (node) { - this.next(); - node.test = this.parseParenExpression(); - node.consequent = this.parseStatement(false); - node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null; - return this.finishNode(node, "IfStatement"); -}; - -pp.parseReturnStatement = function (node) { - if (!this.state.inFunction && !this.options.allowReturnOutsideFunction) { - this.raise(this.state.start, "'return' outside of function"); + parseFunctionStatement(node) { + this.next(); + return this.parseFunction(node, true); } - this.next(); + parseIfStatement(node) { + this.next(); + node.test = this.parseParenExpression(); + node.consequent = this.parseStatement(false); + node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null; + return this.finishNode(node, "IfStatement"); + } - // In `return` (and `break`/`continue`), the keywords with - // optional arguments, we eagerly look for a semicolon or the - // possibility to insert one. + parseReturnStatement(node) { + if (!this.state.inFunction && !this.options.allowReturnOutsideFunction) { + this.raise(this.state.start, "'return' outside of function"); + } - if (this.isLineTerminator()) { - node.argument = null; - } else { + this.next(); + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.isLineTerminator()) { + node.argument = null; + } else { + node.argument = this.parseExpression(); + this.semicolon(); + } + + return this.finishNode(node, "ReturnStatement"); + } + + parseSwitchStatement(node) { + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.expect(tt.braceL); + this.state.labels.push(switchLabel); + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + let cur; + for (let sawDefault; !this.match(tt.braceR); ) { + if (this.match(tt._case) || this.match(tt._default)) { + const isCase = this.match(tt._case); + if (cur) this.finishNode(cur, "SwitchCase"); + node.cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + if (isCase) { + cur.test = this.parseExpression(); + } else { + if (sawDefault) this.raise(this.state.lastTokStart, "Multiple default clauses"); + sawDefault = true; + cur.test = null; + } + this.expect(tt.colon); + } else { + if (cur) { + cur.consequent.push(this.parseStatement(true)); + } else { + this.unexpected(); + } + } + } + if (cur) this.finishNode(cur, "SwitchCase"); + this.next(); // Closing brace + this.state.labels.pop(); + return this.finishNode(node, "SwitchStatement"); + } + + parseThrowStatement(node) { + this.next(); + if (lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start))) + this.raise(this.state.lastTokEnd, "Illegal newline after throw"); node.argument = this.parseExpression(); this.semicolon(); + return this.finishNode(node, "ThrowStatement"); + } + + parseTryStatement(node) { + this.next(); + + node.block = this.parseBlock(); + node.handler = null; + + if (this.match(tt._catch)) { + const clause = this.startNode(); + this.next(); + + this.expect(tt.parenL); + clause.param = this.parseBindingAtom(); + this.checkLVal(clause.param, true, Object.create(null), "catch clause"); + this.expect(tt.parenR); + + clause.body = this.parseBlock(); + node.handler = this.finishNode(clause, "CatchClause"); + } + + node.guardedHandlers = empty; + node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null; + + if (!node.handler && !node.finalizer) { + this.raise(node.start, "Missing catch or finally clause"); + } + + return this.finishNode(node, "TryStatement"); + } + + parseVarStatement(node, kind) { + this.next(); + this.parseVar(node, false, kind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration"); + } + + parseWhileStatement(node) { + this.next(); + node.test = this.parseParenExpression(); + this.state.labels.push(loopLabel); + node.body = this.parseStatement(false); + this.state.labels.pop(); + return this.finishNode(node, "WhileStatement"); + } + + parseWithStatement(node) { + if (this.state.strict) this.raise(this.state.start, "'with' in strict mode"); + this.next(); + node.object = this.parseParenExpression(); + node.body = this.parseStatement(false); + return this.finishNode(node, "WithStatement"); + } + + parseEmptyStatement(node) { + this.next(); + return this.finishNode(node, "EmptyStatement"); + } + + parseLabeledStatement(node, maybeName, expr) { + for (const label of (this.state.labels: Array)) { + if (label.name === maybeName) { + this.raise(expr.start, `Label '${maybeName}' is already declared`); + } + } + + const kind = this.state.type.isLoop ? "loop" : this.match(tt._switch) ? "switch" : null; + for (let i = this.state.labels.length - 1; i >= 0; i--) { + const label = this.state.labels[i]; + if (label.statementStart === node.start) { + label.statementStart = this.state.start; + label.kind = kind; + } else { + break; + } + } + + this.state.labels.push({ name: maybeName, kind: kind, statementStart: this.state.start }); + node.body = this.parseStatement(true); + this.state.labels.pop(); + node.label = expr; + return this.finishNode(node, "LabeledStatement"); + } + + parseExpressionStatement(node, expr) { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement"); + } + + // Parse a semicolon-enclosed block of statements, handling `"use + // strict"` declarations when `allowStrict` is true (used for + // function bodies). + + parseBlock(allowDirectives?) { + const node = this.startNode(); + this.expect(tt.braceL); + this.parseBlockBody(node, allowDirectives, false, tt.braceR); + return this.finishNode(node, "BlockStatement"); + } + + isValidDirective(stmt) { + return stmt.type === "ExpressionStatement" && + stmt.expression.type === "StringLiteral" && + !stmt.expression.extra.parenthesized; + } + + parseBlockBody(node, allowDirectives, topLevel, end) { + node.body = []; + node.directives = []; + + let parsedNonDirective = false; + let oldStrict; + let octalPosition; + + while (!this.eat(end)) { + if (!parsedNonDirective && this.state.containsOctal && !octalPosition) { + octalPosition = this.state.octalPosition; + } + + const stmt = this.parseStatement(true, topLevel); + + if (allowDirectives && !parsedNonDirective && this.isValidDirective(stmt)) { + const directive = this.stmtToDirective(stmt); + node.directives.push(directive); + + if (oldStrict === undefined && directive.value.value === "use strict") { + oldStrict = this.state.strict; + this.setStrict(true); + + if (octalPosition) { + this.raise(octalPosition, "Octal literal in strict mode"); + } + } + + continue; + } + + parsedNonDirective = true; + node.body.push(stmt); + } + + if (oldStrict === false) { + this.setStrict(false); + } + } + + // Parse a regular `for` loop. The disambiguation code in + // `parseStatement` will already have parsed the init statement or + // expression. + + parseFor(node, init) { + node.init = init; + this.expect(tt.semi); + node.test = this.match(tt.semi) ? null : this.parseExpression(); + this.expect(tt.semi); + node.update = this.match(tt.parenR) ? null : this.parseExpression(); + this.expect(tt.parenR); + node.body = this.parseStatement(false); + this.state.labels.pop(); + return this.finishNode(node, "ForStatement"); + } + + // Parse a `for`/`in` and `for`/`of` loop, which are almost + // same from parser's perspective. + + parseForIn(node, init, forAwait) { + const type = this.match(tt._in) ? "ForInStatement" : "ForOfStatement"; + if (forAwait) { + this.eatContextual("of"); + } else { + this.next(); + } + node.await = !!forAwait; + node.left = init; + node.right = this.parseExpression(); + this.expect(tt.parenR); + node.body = this.parseStatement(false); + this.state.labels.pop(); + return this.finishNode(node, type); + } + + // Parse a list of variable declarations. + + parseVar(node, isFor, kind) { + node.declarations = []; + node.kind = kind.keyword; + for (;;) { + const decl = this.startNode(); + this.parseVarHead(decl); + if (this.eat(tt.eq)) { + decl.init = this.parseMaybeAssign(isFor); + } else if (kind === tt._const && !(this.match(tt._in) || this.isContextual("of"))) { + this.unexpected(); + } else if (decl.id.type !== "Identifier" && !(isFor && (this.match(tt._in) || this.isContextual("of")))) { + this.raise(this.state.lastTokEnd, "Complex binding patterns require an initialization value"); + } else { + decl.init = null; + } + node.declarations.push(this.finishNode(decl, "VariableDeclarator")); + if (!this.eat(tt.comma)) break; + } + return node; + } + + parseVarHead(decl) { + decl.id = this.parseBindingAtom(); + this.checkLVal(decl.id, true, undefined, "variable declaration"); + } + + // Parse a function declaration or literal (depending on the + // `isStatement` parameter). + + parseFunction(node, isStatement, allowExpressionBody, isAsync, optionalId) { + const oldInMethod = this.state.inMethod; + this.state.inMethod = false; + + this.initFunction(node, isAsync); + + if (this.match(tt.star)) { + if (node.async && !this.hasPlugin("asyncGenerators")) { + this.unexpected(); + } else { + node.generator = true; + this.next(); + } + } + + if (isStatement && !optionalId && !this.match(tt.name) && !this.match(tt._yield)) { + this.unexpected(); + } + + if (this.match(tt.name) || this.match(tt._yield)) { + node.id = this.parseBindingIdentifier(); + } + + this.parseFunctionParams(node); + this.parseFunctionBody(node, allowExpressionBody); + + this.state.inMethod = oldInMethod; + + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); + } + + parseFunctionParams(node) { + this.expect(tt.parenL); + node.params = this.parseBindingList(tt.parenR); + } + + // Parse a class declaration or literal (depending on the + // `isStatement` parameter). + + parseClass(node, isStatement, optionalId) { + this.next(); + this.takeDecorators(node); + this.parseClassId(node, isStatement, optionalId); + this.parseClassSuper(node); + this.parseClassBody(node); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression"); + } + + isClassProperty() { + return this.match(tt.eq) || this.match(tt.semi) || this.match(tt.braceR); + } + + isClassMethod() { + return this.match(tt.parenL); + } + + isNonstaticConstructor(method) { + return !method.computed && !method.static && ( + (method.key.name === "constructor") || // Identifier + (method.key.value === "constructor") // Literal + ); + } + + parseClassBody(node) { + // class bodies are implicitly strict + const oldStrict = this.state.strict; + this.state.strict = true; + + let hadConstructor = false; + let decorators = []; + const classBody = this.startNode(); + + classBody.body = []; + + this.expect(tt.braceL); + + while (!this.eat(tt.braceR)) { + if (this.eat(tt.semi)) { + if (decorators.length > 0) { + this.raise(this.state.lastTokEnd, "Decorators must not be followed by a semicolon"); + } + continue; + } + + if (this.match(tt.at)) { + decorators.push(this.parseDecorator()); + continue; + } + + const method = this.startNode(); + + // steal the decorators if there are any + if (decorators.length) { + method.decorators = decorators; + decorators = []; + } + + method.static = false; + if (this.match(tt.name) && this.state.value === "static") { + const key = this.parseIdentifier(true); // eats 'static' + if (this.isClassMethod()) { + // a method named 'static' + method.kind = "method"; + method.computed = false; + method.key = key; + this.parseClassMethod(classBody, method, false, false); + continue; + } else if (this.isClassProperty()) { + // a property named 'static' + method.computed = false; + method.key = key; + classBody.body.push(this.parseClassProperty(method)); + continue; + } + // otherwise something static + method.static = true; + } + + if (this.eat(tt.star)) { + // a generator + method.kind = "method"; + this.parsePropertyName(method); + if (this.isNonstaticConstructor(method)) { + this.raise(method.key.start, "Constructor can't be a generator"); + } + if (!method.computed && method.static && (method.key.name === "prototype" || method.key.value === "prototype")) { + this.raise(method.key.start, "Classes may not have static property named prototype"); + } + this.parseClassMethod(classBody, method, true, false); + } else { + const isSimple = this.match(tt.name); + const key = this.parsePropertyName(method); + if (!method.computed && method.static && (method.key.name === "prototype" || method.key.value === "prototype")) { + this.raise(method.key.start, "Classes may not have static property named prototype"); + } + if (this.isClassMethod()) { + // a normal method + if (this.isNonstaticConstructor(method)) { + if (hadConstructor) { + this.raise(key.start, "Duplicate constructor in the same class"); + } else if (method.decorators) { + this.raise(method.start, "You can't attach decorators to a class constructor"); + } + hadConstructor = true; + method.kind = "constructor"; + } else { + method.kind = "method"; + } + this.parseClassMethod(classBody, method, false, false); + } else if (this.isClassProperty()) { + // a normal property + if (this.isNonstaticConstructor(method)) { + this.raise(method.key.start, "Classes may not have a non-static field named 'constructor'"); + } + classBody.body.push(this.parseClassProperty(method)); + } else if (isSimple && key.name === "async" && !this.isLineTerminator()) { + // an async method + const isGenerator = this.hasPlugin("asyncGenerators") && this.eat(tt.star); + method.kind = "method"; + this.parsePropertyName(method); + if (this.isNonstaticConstructor(method)) { + this.raise(method.key.start, "Constructor can't be an async function"); + } + this.parseClassMethod(classBody, method, isGenerator, true); + } else if (isSimple && (key.name === "get" || key.name === "set") && !(this.isLineTerminator() && this.match(tt.star))) { // `get\n*` is an uninitialized property named 'get' followed by a generator. + // a getter or setter + method.kind = key.name; + this.parsePropertyName(method); + if (this.isNonstaticConstructor(method)) { + this.raise(method.key.start, "Constructor can't have get/set modifier"); + } + this.parseClassMethod(classBody, method, false, false); + this.checkGetterSetterParamCount(method); + } else if (this.isLineTerminator()) { + // an uninitialized class property (due to ASI, since we don't otherwise recognize the next token) + if (this.isNonstaticConstructor(method)) { + this.raise(method.key.start, "Classes may not have a non-static field named 'constructor'"); + } + classBody.body.push(this.parseClassProperty(method)); + } else { + this.unexpected(); + } + } + } + + if (decorators.length) { + this.raise(this.state.start, "You have trailing decorators with no method"); + } + + node.body = this.finishNode(classBody, "ClassBody"); + + this.state.strict = oldStrict; + } + + parseClassProperty(node) { + const noPluginMsg = "You can only use Class Properties when the 'classProperties' plugin is enabled."; + if (!node.typeAnnotation && !this.hasPlugin("classProperties")) { + this.raise(node.start, noPluginMsg); + } + + if (this.match(tt.eq)) { + if (!this.hasPlugin("classProperties")) this.raise(this.state.start, noPluginMsg); + this.next(); + node.value = this.parseMaybeAssign(); + } else { + node.value = null; + } + this.semicolon(); + return this.finishNode(node, "ClassProperty"); + } + + parseClassMethod(classBody, method, isGenerator, isAsync) { + this.parseMethod(method, isGenerator, isAsync); + classBody.body.push(this.finishNode(method, "ClassMethod")); + } + + parseClassId(node, isStatement, optionalId) { + if (this.match(tt.name)) { + node.id = this.parseIdentifier(); + } else { + if (optionalId || !isStatement) { + node.id = null; + } else { + this.unexpected(); + } + } + } + + parseClassSuper(node) { + node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null; + } + + // Parses module export declaration. + + parseExport(node) { + this.eat(tt._export); + + // export * from '...' + if (this.match(tt.star)) { + const specifier = this.startNode(); + this.next(); + if (this.hasPlugin("exportExtensions") && this.eatContextual("as")) { + specifier.exported = this.parseIdentifier(true); + node.specifiers = [this.finishNode(specifier, "ExportNamespaceSpecifier")]; + this.parseExportSpecifiersMaybe(node); + this.parseExportFrom(node, true); + } else { + this.parseExportFrom(node, true); + return this.finishNode(node, "ExportAllDeclaration"); + } + } else if (this.hasPlugin("exportExtensions") && this.isExportDefaultSpecifier()) { + const specifier = this.startNode(); + specifier.exported = this.parseIdentifier(true); + node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; + if (this.match(tt.comma) && this.lookahead().type === tt.star) { + this.expect(tt.comma); + const specifier = this.startNode(); + this.expect(tt.star); + this.expectContextual("as"); + specifier.exported = this.parseIdentifier(); + node.specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier")); + } else { + this.parseExportSpecifiersMaybe(node); + } + this.parseExportFrom(node, true); + } else if (this.eat(tt._default)) { // export default ... + let expr = this.startNode(); + let needsSemi = false; + if (this.eat(tt._function)) { + expr = this.parseFunction(expr, true, false, false, true); + } else if ( + this.isContextual("async") && + this.lookahead().type === tt._function + ) { // async function declaration + this.eatContextual("async"); + this.eat(tt._function); + expr = this.parseFunction(expr, true, false, true, true); + } else if (this.match(tt._class)) { + expr = this.parseClass(expr, true, true); + } else { + needsSemi = true; + expr = this.parseMaybeAssign(); + } + node.declaration = expr; + if (needsSemi) this.semicolon(); + this.checkExport(node, true, true); + return this.finishNode(node, "ExportDefaultDeclaration"); + } else if (this.shouldParseExportDeclaration()) { + node.specifiers = []; + node.source = null; + node.declaration = this.parseExportDeclaration(node); + } else { // export { x, y as z } [from '...'] + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(); + this.parseExportFrom(node); + } + this.checkExport(node, true); + return this.finishNode(node, "ExportNamedDeclaration"); + } + + parseExportDeclaration() { + return this.parseStatement(true); + } + + isExportDefaultSpecifier() { + if (this.match(tt.name)) { + return this.state.value !== "type" + && this.state.value !== "async" + && this.state.value !== "interface"; + } + + if (!this.match(tt._default)) { + return false; + } + + const lookahead = this.lookahead(); + return lookahead.type === tt.comma || (lookahead.type === tt.name && lookahead.value === "from"); + } + + parseExportSpecifiersMaybe(node) { + if (this.eat(tt.comma)) { + node.specifiers = node.specifiers.concat(this.parseExportSpecifiers()); + } + } + + parseExportFrom(node, expect?) { + if (this.eatContextual("from")) { + node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected(); + this.checkExport(node); + } else { + if (expect) { + this.unexpected(); + } else { + node.source = null; + } + } + + this.semicolon(); } - return this.finishNode(node, "ReturnStatement"); -}; - -pp.parseSwitchStatement = function (node) { - this.next(); - node.discriminant = this.parseParenExpression(); - node.cases = []; - this.expect(tt.braceL); - this.state.labels.push(switchLabel); - - // Statements under must be grouped (by label) in SwitchCase - // nodes. `cur` is used to keep the node that we are currently - // adding statements to. - - let cur; - for (let sawDefault; !this.match(tt.braceR); ) { - if (this.match(tt._case) || this.match(tt._default)) { - const isCase = this.match(tt._case); - if (cur) this.finishNode(cur, "SwitchCase"); - node.cases.push(cur = this.startNode()); - cur.consequent = []; - this.next(); - if (isCase) { - cur.test = this.parseExpression(); - } else { - if (sawDefault) this.raise(this.state.lastTokStart, "Multiple default clauses"); - sawDefault = true; - cur.test = null; - } - this.expect(tt.colon); - } else { - if (cur) { - cur.consequent.push(this.parseStatement(true)); - } else { - this.unexpected(); - } - } - } - if (cur) this.finishNode(cur, "SwitchCase"); - this.next(); // Closing brace - this.state.labels.pop(); - return this.finishNode(node, "SwitchStatement"); -}; - -pp.parseThrowStatement = function (node) { - this.next(); - if (lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start))) - this.raise(this.state.lastTokEnd, "Illegal newline after throw"); - node.argument = this.parseExpression(); - this.semicolon(); - return this.finishNode(node, "ThrowStatement"); -}; - -// Reused empty array added for node fields that are always empty. - -const empty = []; - -pp.parseTryStatement = function (node) { - this.next(); - - node.block = this.parseBlock(); - node.handler = null; - - if (this.match(tt._catch)) { - const clause = this.startNode(); - this.next(); - - this.expect(tt.parenL); - clause.param = this.parseBindingAtom(); - this.checkLVal(clause.param, true, Object.create(null), "catch clause"); - this.expect(tt.parenR); - - clause.body = this.parseBlock(); - node.handler = this.finishNode(clause, "CatchClause"); + shouldParseExportDeclaration(): boolean { + return this.state.type.keyword === "var" + || this.state.type.keyword === "const" + || this.state.type.keyword === "let" + || this.state.type.keyword === "function" + || this.state.type.keyword === "class" + || this.isContextual("async"); } - node.guardedHandlers = empty; - node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null; - - if (!node.handler && !node.finalizer) { - this.raise(node.start, "Missing catch or finally clause"); - } - - return this.finishNode(node, "TryStatement"); -}; - -pp.parseVarStatement = function (node, kind) { - this.next(); - this.parseVar(node, false, kind); - this.semicolon(); - return this.finishNode(node, "VariableDeclaration"); -}; - -pp.parseWhileStatement = function (node) { - this.next(); - node.test = this.parseParenExpression(); - this.state.labels.push(loopLabel); - node.body = this.parseStatement(false); - this.state.labels.pop(); - return this.finishNode(node, "WhileStatement"); -}; - -pp.parseWithStatement = function (node) { - if (this.state.strict) this.raise(this.state.start, "'with' in strict mode"); - this.next(); - node.object = this.parseParenExpression(); - node.body = this.parseStatement(false); - return this.finishNode(node, "WithStatement"); -}; - -pp.parseEmptyStatement = function (node) { - this.next(); - return this.finishNode(node, "EmptyStatement"); -}; - -pp.parseLabeledStatement = function (node, maybeName, expr) { - for (const label of (this.state.labels: Array)) { - if (label.name === maybeName) { - this.raise(expr.start, `Label '${maybeName}' is already declared`); - } - } - - const kind = this.state.type.isLoop ? "loop" : this.match(tt._switch) ? "switch" : null; - for (let i = this.state.labels.length - 1; i >= 0; i--) { - const label = this.state.labels[i]; - if (label.statementStart === node.start) { - label.statementStart = this.state.start; - label.kind = kind; - } else { - break; - } - } - - this.state.labels.push({ name: maybeName, kind: kind, statementStart: this.state.start }); - node.body = this.parseStatement(true); - this.state.labels.pop(); - node.label = expr; - return this.finishNode(node, "LabeledStatement"); -}; - -pp.parseExpressionStatement = function (node, expr) { - node.expression = expr; - this.semicolon(); - return this.finishNode(node, "ExpressionStatement"); -}; - -// Parse a semicolon-enclosed block of statements, handling `"use -// strict"` declarations when `allowStrict` is true (used for -// function bodies). - -pp.parseBlock = function (allowDirectives?) { - const node = this.startNode(); - this.expect(tt.braceL); - this.parseBlockBody(node, allowDirectives, false, tt.braceR); - return this.finishNode(node, "BlockStatement"); -}; - -pp.isValidDirective = function (stmt) { - return stmt.type === "ExpressionStatement" && - stmt.expression.type === "StringLiteral" && - !stmt.expression.extra.parenthesized; -}; - -pp.parseBlockBody = function (node, allowDirectives, topLevel, end) { - node.body = []; - node.directives = []; - - let parsedNonDirective = false; - let oldStrict; - let octalPosition; - - while (!this.eat(end)) { - if (!parsedNonDirective && this.state.containsOctal && !octalPosition) { - octalPosition = this.state.octalPosition; - } - - const stmt = this.parseStatement(true, topLevel); - - if (allowDirectives && !parsedNonDirective && this.isValidDirective(stmt)) { - const directive = this.stmtToDirective(stmt); - node.directives.push(directive); - - if (oldStrict === undefined && directive.value.value === "use strict") { - oldStrict = this.state.strict; - this.setStrict(true); - - if (octalPosition) { - this.raise(octalPosition, "Octal literal in strict mode"); + checkExport(node, checkNames, isDefault) { + if (checkNames) { + // Check for duplicate exports + if (isDefault) { + // Default exports + this.checkDuplicateExports(node, "default"); + } else if (node.specifiers && node.specifiers.length) { + // Named exports + for (const specifier of node.specifiers) { + this.checkDuplicateExports(specifier, specifier.exported.name); } - } - - continue; - } - - parsedNonDirective = true; - node.body.push(stmt); - } - - if (oldStrict === false) { - this.setStrict(false); - } -}; - -// Parse a regular `for` loop. The disambiguation code in -// `parseStatement` will already have parsed the init statement or -// expression. - -pp.parseFor = function (node, init) { - node.init = init; - this.expect(tt.semi); - node.test = this.match(tt.semi) ? null : this.parseExpression(); - this.expect(tt.semi); - node.update = this.match(tt.parenR) ? null : this.parseExpression(); - this.expect(tt.parenR); - node.body = this.parseStatement(false); - this.state.labels.pop(); - return this.finishNode(node, "ForStatement"); -}; - -// Parse a `for`/`in` and `for`/`of` loop, which are almost -// same from parser's perspective. - -pp.parseForIn = function (node, init, forAwait) { - const type = this.match(tt._in) ? "ForInStatement" : "ForOfStatement"; - if (forAwait) { - this.eatContextual("of"); - } else { - this.next(); - } - node.await = !!forAwait; - node.left = init; - node.right = this.parseExpression(); - this.expect(tt.parenR); - node.body = this.parseStatement(false); - this.state.labels.pop(); - return this.finishNode(node, type); -}; - -// Parse a list of variable declarations. - -pp.parseVar = function (node, isFor, kind) { - node.declarations = []; - node.kind = kind.keyword; - for (;;) { - const decl = this.startNode(); - this.parseVarHead(decl); - if (this.eat(tt.eq)) { - decl.init = this.parseMaybeAssign(isFor); - } else if (kind === tt._const && !(this.match(tt._in) || this.isContextual("of"))) { - this.unexpected(); - } else if (decl.id.type !== "Identifier" && !(isFor && (this.match(tt._in) || this.isContextual("of")))) { - this.raise(this.state.lastTokEnd, "Complex binding patterns require an initialization value"); - } else { - decl.init = null; - } - node.declarations.push(this.finishNode(decl, "VariableDeclarator")); - if (!this.eat(tt.comma)) break; - } - return node; -}; - -pp.parseVarHead = function (decl) { - decl.id = this.parseBindingAtom(); - this.checkLVal(decl.id, true, undefined, "variable declaration"); -}; - -// Parse a function declaration or literal (depending on the -// `isStatement` parameter). - -pp.parseFunction = function (node, isStatement, allowExpressionBody, isAsync, optionalId) { - const oldInMethod = this.state.inMethod; - this.state.inMethod = false; - - this.initFunction(node, isAsync); - - if (this.match(tt.star)) { - if (node.async && !this.hasPlugin("asyncGenerators")) { - this.unexpected(); - } else { - node.generator = true; - this.next(); - } - } - - if (isStatement && !optionalId && !this.match(tt.name) && !this.match(tt._yield)) { - this.unexpected(); - } - - if (this.match(tt.name) || this.match(tt._yield)) { - node.id = this.parseBindingIdentifier(); - } - - this.parseFunctionParams(node); - this.parseFunctionBody(node, allowExpressionBody); - - this.state.inMethod = oldInMethod; - - return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); -}; - -pp.parseFunctionParams = function (node) { - this.expect(tt.parenL); - node.params = this.parseBindingList(tt.parenR); -}; - -// Parse a class declaration or literal (depending on the -// `isStatement` parameter). - -pp.parseClass = function (node, isStatement, optionalId) { - this.next(); - this.takeDecorators(node); - this.parseClassId(node, isStatement, optionalId); - this.parseClassSuper(node); - this.parseClassBody(node); - return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression"); -}; - -pp.isClassProperty = function () { - return this.match(tt.eq) || this.match(tt.semi) || this.match(tt.braceR); -}; - -pp.isClassMethod = function () { - return this.match(tt.parenL); -}; - -pp.isNonstaticConstructor = function (method) { - return !method.computed && !method.static && ( - (method.key.name === "constructor") || // Identifier - (method.key.value === "constructor") // Literal - ); -}; - -pp.parseClassBody = function (node) { - // class bodies are implicitly strict - const oldStrict = this.state.strict; - this.state.strict = true; - - let hadConstructor = false; - let decorators = []; - const classBody = this.startNode(); - - classBody.body = []; - - this.expect(tt.braceL); - - while (!this.eat(tt.braceR)) { - if (this.eat(tt.semi)) { - if (decorators.length > 0) { - this.raise(this.state.lastTokEnd, "Decorators must not be followed by a semicolon"); - } - continue; - } - - if (this.match(tt.at)) { - decorators.push(this.parseDecorator()); - continue; - } - - const method = this.startNode(); - - // steal the decorators if there are any - if (decorators.length) { - method.decorators = decorators; - decorators = []; - } - - method.static = false; - if (this.match(tt.name) && this.state.value === "static") { - const key = this.parseIdentifier(true); // eats 'static' - if (this.isClassMethod()) { - // a method named 'static' - method.kind = "method"; - method.computed = false; - method.key = key; - this.parseClassMethod(classBody, method, false, false); - continue; - } else if (this.isClassProperty()) { - // a property named 'static' - method.computed = false; - method.key = key; - classBody.body.push(this.parseClassProperty(method)); - continue; - } - // otherwise something static - method.static = true; - } - - if (this.eat(tt.star)) { - // a generator - method.kind = "method"; - this.parsePropertyName(method); - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Constructor can't be a generator"); - } - if (!method.computed && method.static && (method.key.name === "prototype" || method.key.value === "prototype")) { - this.raise(method.key.start, "Classes may not have static property named prototype"); - } - this.parseClassMethod(classBody, method, true, false); - } else { - const isSimple = this.match(tt.name); - const key = this.parsePropertyName(method); - if (!method.computed && method.static && (method.key.name === "prototype" || method.key.value === "prototype")) { - this.raise(method.key.start, "Classes may not have static property named prototype"); - } - if (this.isClassMethod()) { - // a normal method - if (this.isNonstaticConstructor(method)) { - if (hadConstructor) { - this.raise(key.start, "Duplicate constructor in the same class"); - } else if (method.decorators) { - this.raise(method.start, "You can't attach decorators to a class constructor"); + } else if (node.declaration) { + // Exported declarations + if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") { + this.checkDuplicateExports(node, node.declaration.id.name); + } else if (node.declaration.type === "VariableDeclaration") { + for (const declaration of node.declaration.declarations) { + this.checkDeclaration(declaration.id); } - hadConstructor = true; - method.kind = "constructor"; - } else { - method.kind = "method"; } - this.parseClassMethod(classBody, method, false, false); - } else if (this.isClassProperty()) { - // a normal property - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Classes may not have a non-static field named 'constructor'"); + } + } + + if (this.state.decorators.length) { + const isClass = node.declaration && (node.declaration.type === "ClassDeclaration" || node.declaration.type === "ClassExpression"); + if (!node.declaration || !isClass) { + this.raise(node.start, "You can only use decorators on an export when exporting a class"); + } + this.takeDecorators(node.declaration); + } + } + + checkDeclaration(node) { + if (node.type === "ObjectPattern") { + for (const prop of node.properties) { + this.checkDeclaration(prop); + } + } else if (node.type === "ArrayPattern") { + for (const elem of node.elements) { + if (elem) { + this.checkDeclaration(elem); } - classBody.body.push(this.parseClassProperty(method)); - } else if (isSimple && key.name === "async" && !this.isLineTerminator()) { - // an async method - const isGenerator = this.hasPlugin("asyncGenerators") && this.eat(tt.star); - method.kind = "method"; - this.parsePropertyName(method); - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Constructor can't be an async function"); - } - this.parseClassMethod(classBody, method, isGenerator, true); - } else if (isSimple && (key.name === "get" || key.name === "set") && !(this.isLineTerminator() && this.match(tt.star))) { // `get\n*` is an uninitialized property named 'get' followed by a generator. - // a getter or setter - method.kind = key.name; - this.parsePropertyName(method); - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Constructor can't have get/set modifier"); - } - this.parseClassMethod(classBody, method, false, false); - this.checkGetterSetterParamCount(method); - } else if (this.isLineTerminator()) { - // an uninitialized class property (due to ASI, since we don't otherwise recognize the next token) - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Classes may not have a non-static field named 'constructor'"); - } - classBody.body.push(this.parseClassProperty(method)); + } + } else if (node.type === "ObjectProperty") { + this.checkDeclaration(node.value); + } else if (node.type === "RestElement") { + this.checkDeclaration(node.argument); + } else if (node.type === "Identifier") { + this.checkDuplicateExports(node, node.name); + } + } + + checkDuplicateExports(node, name) { + if (this.state.exportedIdentifiers.indexOf(name) > -1) { + this.raiseDuplicateExportError(node, name); + } + this.state.exportedIdentifiers.push(name); + } + + raiseDuplicateExportError(node, name) { + this.raise(node.start, name === "default" ? + "Only one default export allowed per module." : + `\`${name}\` has already been exported. Exported identifiers must be unique.` + ); + } + + // Parses a comma-separated list of module exports. + + parseExportSpecifiers() { + const nodes = []; + let first = true; + let needsFrom; + + // export { x, y as z } [from '...'] + this.expect(tt.braceL); + + while (!this.eat(tt.braceR)) { + if (first) { + first = false; } else { - this.unexpected(); + this.expect(tt.comma); + if (this.eat(tt.braceR)) break; } + + const isDefault = this.match(tt._default); + if (isDefault && !needsFrom) needsFrom = true; + + const node = this.startNode(); + node.local = this.parseIdentifier(isDefault); + node.exported = this.eatContextual("as") ? this.parseIdentifier(true) : node.local.__clone(); + nodes.push(this.finishNode(node, "ExportSpecifier")); } - } - if (decorators.length) { - this.raise(this.state.start, "You have trailing decorators with no method"); - } - - node.body = this.finishNode(classBody, "ClassBody"); - - this.state.strict = oldStrict; -}; - -pp.parseClassProperty = function (node) { - const noPluginMsg = "You can only use Class Properties when the 'classProperties' plugin is enabled."; - if (!node.typeAnnotation && !this.hasPlugin("classProperties")) { - this.raise(node.start, noPluginMsg); - } - - if (this.match(tt.eq)) { - if (!this.hasPlugin("classProperties")) this.raise(this.state.start, noPluginMsg); - this.next(); - node.value = this.parseMaybeAssign(); - } else { - node.value = null; - } - this.semicolon(); - return this.finishNode(node, "ClassProperty"); -}; - -pp.parseClassMethod = function (classBody, method, isGenerator, isAsync) { - this.parseMethod(method, isGenerator, isAsync); - classBody.body.push(this.finishNode(method, "ClassMethod")); -}; - -pp.parseClassId = function (node, isStatement, optionalId) { - if (this.match(tt.name)) { - node.id = this.parseIdentifier(); - } else { - if (optionalId || !isStatement) { - node.id = null; - } else { + // https://github.com/ember-cli/ember-cli/pull/3739 + if (needsFrom && !this.isContextual("from")) { this.unexpected(); } + + return nodes; } -}; -pp.parseClassSuper = function (node) { - node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null; -}; + // Parses import declaration. -// Parses module export declaration. + parseImport(node) { + this.eat(tt._import); -pp.parseExport = function (node) { - this.eat(tt._export); - - // export * from '...' - if (this.match(tt.star)) { - const specifier = this.startNode(); - this.next(); - if (this.hasPlugin("exportExtensions") && this.eatContextual("as")) { - specifier.exported = this.parseIdentifier(true); - node.specifiers = [this.finishNode(specifier, "ExportNamespaceSpecifier")]; - this.parseExportSpecifiersMaybe(node); - this.parseExportFrom(node, true); + // import '...' + if (this.match(tt.string)) { + node.specifiers = []; + node.source = this.parseExprAtom(); } else { - this.parseExportFrom(node, true); - return this.finishNode(node, "ExportAllDeclaration"); + node.specifiers = []; + this.parseImportSpecifiers(node); + this.expectContextual("from"); + node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected(); } - } else if (this.hasPlugin("exportExtensions") && this.isExportDefaultSpecifier()) { - const specifier = this.startNode(); - specifier.exported = this.parseIdentifier(true); - node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; - if (this.match(tt.comma) && this.lookahead().type === tt.star) { - this.expect(tt.comma); + this.semicolon(); + return this.finishNode(node, "ImportDeclaration"); + } + + // Parses a comma-separated list of module imports. + + parseImportSpecifiers(node) { + let first = true; + if (this.match(tt.name)) { + // import defaultObj, { x, y as z } from '...' + const startPos = this.state.start; + const startLoc = this.state.startLoc; + node.specifiers.push(this.parseImportSpecifierDefault(this.parseIdentifier(), startPos, startLoc)); + if (!this.eat(tt.comma)) return; + } + + if (this.match(tt.star)) { const specifier = this.startNode(); - this.expect(tt.star); + this.next(); this.expectContextual("as"); - specifier.exported = this.parseIdentifier(); - node.specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier")); - } else { - this.parseExportSpecifiersMaybe(node); + specifier.local = this.parseIdentifier(); + this.checkLVal(specifier.local, true, undefined, "import namespace specifier"); + node.specifiers.push(this.finishNode(specifier, "ImportNamespaceSpecifier")); + return; } - this.parseExportFrom(node, true); - } else if (this.eat(tt._default)) { // export default ... - let expr = this.startNode(); - let needsSemi = false; - if (this.eat(tt._function)) { - expr = this.parseFunction(expr, true, false, false, true); - } else if ( - this.isContextual("async") && - this.lookahead().type === tt._function - ) { // async function declaration - this.eatContextual("async"); - this.eat(tt._function); - expr = this.parseFunction(expr, true, false, true, true); - } else if (this.match(tt._class)) { - expr = this.parseClass(expr, true, true); - } else { - needsSemi = true; - expr = this.parseMaybeAssign(); - } - node.declaration = expr; - if (needsSemi) this.semicolon(); - this.checkExport(node, true, true); - return this.finishNode(node, "ExportDefaultDeclaration"); - } else if (this.shouldParseExportDeclaration()) { - node.specifiers = []; - node.source = null; - node.declaration = this.parseExportDeclaration(node); - } else { // export { x, y as z } [from '...'] - node.declaration = null; - node.specifiers = this.parseExportSpecifiers(); - this.parseExportFrom(node); - } - this.checkExport(node, true); - return this.finishNode(node, "ExportNamedDeclaration"); -}; -pp.parseExportDeclaration = function () { - return this.parseStatement(true); -}; - -pp.isExportDefaultSpecifier = function () { - if (this.match(tt.name)) { - return this.state.value !== "type" - && this.state.value !== "async" - && this.state.value !== "interface"; - } - - if (!this.match(tt._default)) { - return false; - } - - const lookahead = this.lookahead(); - return lookahead.type === tt.comma || (lookahead.type === tt.name && lookahead.value === "from"); -}; - -pp.parseExportSpecifiersMaybe = function (node) { - if (this.eat(tt.comma)) { - node.specifiers = node.specifiers.concat(this.parseExportSpecifiers()); - } -}; - -pp.parseExportFrom = function (node, expect?) { - if (this.eatContextual("from")) { - node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected(); - this.checkExport(node); - } else { - if (expect) { - this.unexpected(); - } else { - node.source = null; - } - } - - this.semicolon(); -}; - -pp.shouldParseExportDeclaration = function (): boolean { - return this.state.type.keyword === "var" - || this.state.type.keyword === "const" - || this.state.type.keyword === "let" - || this.state.type.keyword === "function" - || this.state.type.keyword === "class" - || this.isContextual("async"); -}; - -pp.checkExport = function (node, checkNames, isDefault) { - if (checkNames) { - // Check for duplicate exports - if (isDefault) { - // Default exports - this.checkDuplicateExports(node, "default"); - } else if (node.specifiers && node.specifiers.length) { - // Named exports - for (const specifier of node.specifiers) { - this.checkDuplicateExports(specifier, specifier.exported.name); - } - } else if (node.declaration) { - // Exported declarations - if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") { - this.checkDuplicateExports(node, node.declaration.id.name); - } else if (node.declaration.type === "VariableDeclaration") { - for (const declaration of node.declaration.declarations) { - this.checkDeclaration(declaration.id); + this.expect(tt.braceL); + while (!this.eat(tt.braceR)) { + if (first) { + first = false; + } else { + // Detect an attempt to deep destructure + if (this.eat(tt.colon)) { + this.unexpected(null, "ES2015 named imports do not destructure. Use another statement for destructuring after the import."); } + + this.expect(tt.comma); + if (this.eat(tt.braceR)) break; } + + this.parseImportSpecifier(node); } } - if (this.state.decorators.length) { - const isClass = node.declaration && (node.declaration.type === "ClassDeclaration" || node.declaration.type === "ClassExpression"); - if (!node.declaration || !isClass) { - this.raise(node.start, "You can only use decorators on an export when exporting a class"); - } - this.takeDecorators(node.declaration); - } -}; - -pp.checkDeclaration = function(node) { - if (node.type === "ObjectPattern") { - for (const prop of node.properties) { - this.checkDeclaration(prop); - } - } else if (node.type === "ArrayPattern") { - for (const elem of node.elements) { - if (elem) { - this.checkDeclaration(elem); - } - } - } else if (node.type === "ObjectProperty") { - this.checkDeclaration(node.value); - } else if (node.type === "RestElement") { - this.checkDeclaration(node.argument); - } else if (node.type === "Identifier") { - this.checkDuplicateExports(node, node.name); - } -}; - -pp.checkDuplicateExports = function(node, name) { - if (this.state.exportedIdentifiers.indexOf(name) > -1) { - this.raiseDuplicateExportError(node, name); - } - this.state.exportedIdentifiers.push(name); -}; - -pp.raiseDuplicateExportError = function(node, name) { - this.raise(node.start, name === "default" ? - "Only one default export allowed per module." : - `\`${name}\` has already been exported. Exported identifiers must be unique.` - ); -}; - -// Parses a comma-separated list of module exports. - -pp.parseExportSpecifiers = function () { - const nodes = []; - let first = true; - let needsFrom; - - // export { x, y as z } [from '...'] - this.expect(tt.braceL); - - while (!this.eat(tt.braceR)) { - if (first) { - first = false; - } else { - this.expect(tt.comma); - if (this.eat(tt.braceR)) break; - } - - const isDefault = this.match(tt._default); - if (isDefault && !needsFrom) needsFrom = true; - - const node = this.startNode(); - node.local = this.parseIdentifier(isDefault); - node.exported = this.eatContextual("as") ? this.parseIdentifier(true) : node.local.__clone(); - nodes.push(this.finishNode(node, "ExportSpecifier")); - } - - // https://github.com/ember-cli/ember-cli/pull/3739 - if (needsFrom && !this.isContextual("from")) { - this.unexpected(); - } - - return nodes; -}; - -// Parses import declaration. - -pp.parseImport = function (node) { - this.eat(tt._import); - - // import '...' - if (this.match(tt.string)) { - node.specifiers = []; - node.source = this.parseExprAtom(); - } else { - node.specifiers = []; - this.parseImportSpecifiers(node); - this.expectContextual("from"); - node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected(); - } - this.semicolon(); - return this.finishNode(node, "ImportDeclaration"); -}; - -// Parses a comma-separated list of module imports. - -pp.parseImportSpecifiers = function (node) { - let first = true; - if (this.match(tt.name)) { - // import defaultObj, { x, y as z } from '...' - const startPos = this.state.start; - const startLoc = this.state.startLoc; - node.specifiers.push(this.parseImportSpecifierDefault(this.parseIdentifier(), startPos, startLoc)); - if (!this.eat(tt.comma)) return; - } - - if (this.match(tt.star)) { + parseImportSpecifier(node) { const specifier = this.startNode(); - this.next(); - this.expectContextual("as"); - specifier.local = this.parseIdentifier(); - this.checkLVal(specifier.local, true, undefined, "import namespace specifier"); - node.specifiers.push(this.finishNode(specifier, "ImportNamespaceSpecifier")); - return; - } - - this.expect(tt.braceL); - while (!this.eat(tt.braceR)) { - if (first) { - first = false; + specifier.imported = this.parseIdentifier(true); + if (this.eatContextual("as")) { + specifier.local = this.parseIdentifier(); } else { - // Detect an attempt to deep destructure - if (this.eat(tt.colon)) { - this.unexpected(null, "ES2015 named imports do not destructure. Use another statement for destructuring after the import."); - } - - this.expect(tt.comma); - if (this.eat(tt.braceR)) break; + this.checkReservedWord(specifier.imported.name, specifier.start, true, true); + specifier.local = specifier.imported.__clone(); } - - this.parseImportSpecifier(node); + this.checkLVal(specifier.local, true, undefined, "import specifier"); + node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); } -}; -pp.parseImportSpecifier = function (node) { - const specifier = this.startNode(); - specifier.imported = this.parseIdentifier(true); - if (this.eatContextual("as")) { - specifier.local = this.parseIdentifier(); - } else { - this.checkReservedWord(specifier.imported.name, specifier.start, true, true); - specifier.local = specifier.imported.__clone(); + parseImportSpecifierDefault(id, startPos, startLoc) { + const node = this.startNodeAt(startPos, startLoc); + node.local = id; + this.checkLVal(node.local, true, undefined, "default import specifier"); + return this.finishNode(node, "ImportDefaultSpecifier"); } - this.checkLVal(specifier.local, true, undefined, "import specifier"); - node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); -}; - -pp.parseImportSpecifierDefault = function (id, startPos, startLoc) { - const node = this.startNodeAt(startPos, startLoc); - node.local = id; - this.checkLVal(node.local, true, undefined, "default import specifier"); - return this.finishNode(node, "ImportDefaultSpecifier"); -}; +} diff --git a/src/parser/util.js b/src/parser/util.js index 86724e67c6..532e3fe7a4 100644 --- a/src/parser/util.js +++ b/src/parser/util.js @@ -1,88 +1,88 @@ import { types as tt } from "../tokenizer/types"; -import Parser from "./index"; +import Tokenizer from "../tokenizer"; import { lineBreak } from "../util/whitespace"; -const pp = Parser.prototype; - // ## Parser utilities -// TODO +export default class UtilParser extends Tokenizer { + // TODO -pp.addExtra = function (node, key, val) { - if (!node) return; + addExtra(node, key, val) { + if (!node) return; - const extra = node.extra = node.extra || {}; - extra[key] = val; -}; - -// TODO - -pp.isRelational = function (op) { - return this.match(tt.relational) && this.state.value === op; -}; - -// TODO - -pp.expectRelational = function (op) { - if (this.isRelational(op)) { - this.next(); - } else { - this.unexpected(null, tt.relational); + const extra = node.extra = node.extra || {}; + extra[key] = val; } -}; -// Tests whether parsed token is a contextual keyword. + // TODO -pp.isContextual = function (name) { - return this.match(tt.name) && this.state.value === name; -}; - -// Consumes contextual keyword if possible. - -pp.eatContextual = function (name) { - return this.state.value === name && this.eat(tt.name); -}; - -// Asserts that following token is given contextual keyword. - -pp.expectContextual = function (name, message) { - if (!this.eatContextual(name)) this.unexpected(null, message); -}; - -// Test whether a semicolon can be inserted at the current position. - -pp.canInsertSemicolon = function () { - return this.match(tt.eof) || - this.match(tt.braceR) || - lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start)); -}; - -// TODO - -pp.isLineTerminator = function () { - return this.eat(tt.semi) || this.canInsertSemicolon(); -}; - -// Consume a semicolon, or, failing that, see if we are allowed to -// pretend that there is a semicolon at this position. - -pp.semicolon = function () { - if (!this.isLineTerminator()) this.unexpected(null, tt.semi); -}; - -// Expect a token of a given type. If found, consume it, otherwise, -// raise an unexpected token error at given pos. - -pp.expect = function (type, pos) { - return this.eat(type) || this.unexpected(pos, type); -}; - -// Raise an unexpected token error. Can take the expected token type -// instead of a message string. - -pp.unexpected = function (pos, messageOrType = "Unexpected token") { - if (messageOrType && typeof messageOrType === "object" && messageOrType.label) { - messageOrType = `Unexpected token, expected ${messageOrType.label}`; + isRelational(op) { + return this.match(tt.relational) && this.state.value === op; } - this.raise(pos != null ? pos : this.state.start, messageOrType); -}; + + // TODO + + expectRelational(op) { + if (this.isRelational(op)) { + this.next(); + } else { + this.unexpected(null, tt.relational); + } + } + + // Tests whether parsed token is a contextual keyword. + + isContextual(name) { + return this.match(tt.name) && this.state.value === name; + } + + // Consumes contextual keyword if possible. + + eatContextual(name) { + return this.state.value === name && this.eat(tt.name); + } + + // Asserts that following token is given contextual keyword. + + expectContextual(name, message) { + if (!this.eatContextual(name)) this.unexpected(null, message); + } + + // Test whether a semicolon can be inserted at the current position. + + canInsertSemicolon() { + return this.match(tt.eof) || + this.match(tt.braceR) || + lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start)); + } + + // TODO + + isLineTerminator() { + return this.eat(tt.semi) || this.canInsertSemicolon(); + } + + // Consume a semicolon, or, failing that, see if we are allowed to + // pretend that there is a semicolon at this position. + + semicolon() { + if (!this.isLineTerminator()) this.unexpected(null, tt.semi); + } + + // Expect a token of a given type. If found, consume it, otherwise, + // raise an unexpected token error at given pos. + + expect(type, pos) { + return this.eat(type) || this.unexpected(pos, type); + } + + // Raise an unexpected token error. Can take the expected token type + // instead of a message string. + + unexpected(pos, messageOrType = "Unexpected token") { + if (messageOrType && typeof messageOrType === "object" && messageOrType.label) { + messageOrType = `Unexpected token, expected ${messageOrType.label}`; + } + this.raise(pos != null ? pos : this.state.start, messageOrType); + } +} diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index 74f03f3088..2303175c18 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -8,6 +8,7 @@ import type { Position } from "../util/location"; import { isIdentifierStart, isIdentifierChar, isKeyword } from "../util/identifier"; import { types as tt, keywords as keywordTypes } from "./types"; import { type TokContext, types as ct } from "./context"; +import LocationParser from "../parser/location"; import { SourceLocation } from "../util/location"; import { lineBreak, lineBreakG, isNewLine, nonASCIIwhitespace } from "../util/whitespace"; import State from "./state"; @@ -43,14 +44,8 @@ function codePointToString(code: number): string { } } -export default class Tokenizer { +export default class Tokenizer extends LocationParser { // Forward-declarations - // location.js - +raise: (pos: number, message: string) => empty; - // comments.js (TODO: Better type for the parameter) - +addComment: (comment: Object) => void; - // parser/index.js - +hasPlugin: (name: string) => boolean; // parser/util.js +unexpected: (pos?: ?number, messageOrType?: string | TokenType) => empty; @@ -59,6 +54,7 @@ export default class Tokenizer { input: string; constructor(options: Options, input: string) { + super(); this.state = new State; this.state.init(options, input); } From 68967bf5157163c3dccc611e851965abd34a3a64 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Sun, 23 Apr 2017 17:45:19 -0500 Subject: [PATCH 16/73] Remove jsx context when parsing arrow functions (#475) --- src/plugins/flow.js | 14 +- test/fixtures/flow/type-generics/1/actual.js | 1 + .../flow/type-generics/1/expected.json | 346 ++++++++++++++++++ test/fixtures/flow/type-generics/2/actual.js | 2 + .../flow/type-generics/2/expected.json | 340 +++++++++++++++++ 5 files changed, 695 insertions(+), 8 deletions(-) create mode 100644 test/fixtures/flow/type-generics/1/actual.js create mode 100644 test/fixtures/flow/type-generics/1/expected.json create mode 100644 test/fixtures/flow/type-generics/2/actual.js create mode 100644 test/fixtures/flow/type-generics/2/expected.json diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 0dcf624fe9..869ba2fc0d 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -1,7 +1,6 @@ /* eslint max-len: 0 */ import { types as tt } from "../tokenizer/types"; -import { types as ct } from "../tokenizer/context"; const primitiveTypes = [ "any", @@ -1437,6 +1436,12 @@ export default (superClass) => class extends superClass { } catch (err) { if (err instanceof SyntaxError) { this.state = state; + + // Remove `tc.j_expr` and `tc.j_oTag` from context added + // by parsing `jsxTagStart` to stop the JSX plugin from + // messing with the tokens + this.state.context.length -= 2; + jsxError = err; } else { // istanbul ignore next: no such error is expected @@ -1446,9 +1451,6 @@ export default (superClass) => class extends superClass { } if (jsxError != null || this.isRelational("<")) { - // Need to push something onto the context to stop - // the JSX plugin from messing with the tokens - this.state.context.push(ct.parenExpression); let arrowExpression; let typeParameters; try { @@ -1458,13 +1460,9 @@ export default (superClass) => class extends superClass { arrowExpression.typeParameters = typeParameters; this.resetStartLocationFromNode(arrowExpression, typeParameters); } catch (err) { - this.state.context.pop(); - throw jsxError || err; } - this.state.context.pop(); - if (arrowExpression.type === "ArrowFunctionExpression") { return arrowExpression; } else if (jsxError != null) { diff --git a/test/fixtures/flow/type-generics/1/actual.js b/test/fixtures/flow/type-generics/1/actual.js new file mode 100644 index 0000000000..f27ba81379 --- /dev/null +++ b/test/fixtures/flow/type-generics/1/actual.js @@ -0,0 +1 @@ +const functionReturningIdentityAsAField = () => ({ id: (value: T): T => value }); diff --git a/test/fixtures/flow/type-generics/1/expected.json b/test/fixtures/flow/type-generics/1/expected.json new file mode 100644 index 0000000000..40dcb01fe0 --- /dev/null +++ b/test/fixtures/flow/type-generics/1/expected.json @@ -0,0 +1,346 @@ +{ + "type": "File", + "start": 0, + "end": 84, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 84 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 84, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 84 + } + }, + "sourceType": "module", + "body": [ + { + "type": "VariableDeclaration", + "start": 0, + "end": 84, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 84 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 6, + "end": 83, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 83 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 39, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 39 + }, + "identifierName": "functionReturningIdentityAsAField" + }, + "name": "functionReturningIdentityAsAField" + }, + "init": { + "type": "ArrowFunctionExpression", + "start": 42, + "end": 83, + "loc": { + "start": { + "line": 1, + "column": 42 + }, + "end": { + "line": 1, + "column": 83 + } + }, + "id": null, + "generator": false, + "expression": true, + "async": false, + "params": [], + "body": { + "type": "ObjectExpression", + "start": 49, + "end": 82, + "loc": { + "start": { + "line": 1, + "column": 49 + }, + "end": { + "line": 1, + "column": 82 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 51, + "end": 80, + "loc": { + "start": { + "line": 1, + "column": 51 + }, + "end": { + "line": 1, + "column": 80 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 51, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 51 + }, + "end": { + "line": 1, + "column": 53 + }, + "identifierName": "id" + }, + "name": "id" + }, + "value": { + "type": "ArrowFunctionExpression", + "start": 55, + "end": 80, + "loc": { + "start": { + "line": 1, + "column": 55 + }, + "end": { + "line": 1, + "column": 80 + } + }, + "predicate": null, + "returnType": { + "type": "TypeAnnotation", + "start": 68, + "end": 71, + "loc": { + "start": { + "line": 1, + "column": 68 + }, + "end": { + "line": 1, + "column": 71 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 70, + "end": 71, + "loc": { + "start": { + "line": 1, + "column": 70 + }, + "end": { + "line": 1, + "column": 71 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 70, + "end": 71, + "loc": { + "start": { + "line": 1, + "column": 70 + }, + "end": { + "line": 1, + "column": 71 + }, + "identifierName": "T" + }, + "name": "T" + } + } + }, + "id": null, + "generator": false, + "expression": true, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 59, + "end": 67, + "loc": { + "start": { + "line": 1, + "column": 59 + }, + "end": { + "line": 1, + "column": 67 + }, + "identifierName": "value" + }, + "name": "value", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 64, + "end": 67, + "loc": { + "start": { + "line": 1, + "column": 64 + }, + "end": { + "line": 1, + "column": 67 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 66, + "end": 67, + "loc": { + "start": { + "line": 1, + "column": 66 + }, + "end": { + "line": 1, + "column": 67 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 66, + "end": 67, + "loc": { + "start": { + "line": 1, + "column": 66 + }, + "end": { + "line": 1, + "column": 67 + }, + "identifierName": "T" + }, + "name": "T" + } + } + } + } + ], + "body": { + "type": "Identifier", + "start": 75, + "end": 80, + "loc": { + "start": { + "line": 1, + "column": 75 + }, + "end": { + "line": 1, + "column": 80 + }, + "identifierName": "value" + }, + "name": "value" + }, + "typeParameters": { + "type": "TypeParameterDeclaration", + "start": 55, + "end": 58, + "loc": { + "start": { + "line": 1, + "column": 55 + }, + "end": { + "line": 1, + "column": 58 + } + }, + "params": [ + { + "type": "TypeParameter", + "start": 56, + "end": 57, + "loc": { + "start": { + "line": 1, + "column": 56 + }, + "end": { + "line": 1, + "column": 57 + } + }, + "name": "T", + "variance": null + } + ] + } + } + } + ], + "extra": { + "parenthesized": true, + "parenStart": 48 + } + } + } + } + ], + "kind": "const" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/type-generics/2/actual.js b/test/fixtures/flow/type-generics/2/actual.js new file mode 100644 index 0000000000..e3a4739249 --- /dev/null +++ b/test/fixtures/flow/type-generics/2/actual.js @@ -0,0 +1,2 @@ +const identity = (t: T): T => t; +const a = 1; diff --git a/test/fixtures/flow/type-generics/2/expected.json b/test/fixtures/flow/type-generics/2/expected.json new file mode 100644 index 0000000000..07043bb8c9 --- /dev/null +++ b/test/fixtures/flow/type-generics/2/expected.json @@ -0,0 +1,340 @@ +{ + "type": "File", + "start": 0, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "sourceType": "module", + "body": [ + { + "type": "VariableDeclaration", + "start": 0, + "end": 35, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 35 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 6, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 34 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 14 + }, + "identifierName": "identity" + }, + "name": "identity" + }, + "init": { + "type": "ArrowFunctionExpression", + "start": 17, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 34 + } + }, + "predicate": null, + "returnType": { + "type": "TypeAnnotation", + "start": 26, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 29 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 28, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 29 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 28, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 29 + }, + "identifierName": "T" + }, + "name": "T" + } + } + }, + "id": null, + "generator": false, + "expression": true, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 21, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 25 + }, + "identifierName": "t" + }, + "name": "t", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 22, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 1, + "column": 25 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 24, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 25 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 24, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 25 + }, + "identifierName": "T" + }, + "name": "T" + } + } + } + } + ], + "body": { + "type": "Identifier", + "start": 33, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 1, + "column": 34 + }, + "identifierName": "t" + }, + "name": "t" + }, + "typeParameters": { + "type": "TypeParameterDeclaration", + "start": 17, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "params": [ + { + "type": "TypeParameter", + "start": 18, + "end": 19, + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 19 + } + }, + "name": "T", + "variance": null + } + ] + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 36, + "end": 48, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 42, + "end": 47, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "id": { + "type": "Identifier", + "start": 42, + "end": 43, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 7 + }, + "identifierName": "a" + }, + "name": "a" + }, + "init": { + "type": "NumericLiteral", + "start": 46, + "end": 47, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + } + ], + "kind": "const" + } + ], + "directives": [] + } +} \ No newline at end of file From 34acecca2e72dbbeb3b0964114cf0b76a5e038dc Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 25 Apr 2017 13:07:01 -0700 Subject: [PATCH 17/73] Type-check CommentsParser and LocationParser (#484) --- .flowconfig | 1 + src/parser/base.js | 7 +++++++ src/parser/comments.js | 13 +++++++------ src/parser/location.js | 7 +++++-- src/tokenizer/index.js | 2 -- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/.flowconfig b/.flowconfig index ec70beff84..3dccffe4e4 100644 --- a/.flowconfig +++ b/.flowconfig @@ -11,3 +11,4 @@ strip_root=true suppress_comment= \\(.\\|\n\\)*\\$FlowFixMe suppress_comment= \\(.\\|\n\\)*\\$FlowIssue +suppress_comment= \\(.\\|\n\\)*\\$FlowIgnore diff --git a/src/parser/base.js b/src/parser/base.js index fa1fc13539..3795b71668 100644 --- a/src/parser/base.js +++ b/src/parser/base.js @@ -3,6 +3,8 @@ import type { Options } from "../options"; import { reservedWords } from "../util/identifier"; +import type State from "../tokenizer/state"; + export default class BaseParser { // Properties set by constructor in index.js options: Options; @@ -10,6 +12,11 @@ export default class BaseParser { plugins: { [key: string]: boolean }; filename: ?string; + // Initialized by Tokenizer + state: State; + input: string; + + isReservedWord(word: string): boolean { if (word === "await") { return this.inModule; diff --git a/src/parser/comments.js b/src/parser/comments.js index a634491848..c39f91e44a 100644 --- a/src/parser/comments.js +++ b/src/parser/comments.js @@ -1,5 +1,7 @@ /* eslint max-len: 0 */ +// @flow + /** * Based on the comment attachment algorithm used in espree and estraverse. * @@ -25,19 +27,20 @@ */ import BaseParser from "./base"; +import type { Comment, Node } from "../types"; function last(stack) { return stack[stack.length - 1]; } export default class CommentsParser extends BaseParser { - addComment(comment) { + addComment(comment: Comment): void { if (this.filename) comment.loc.filename = this.filename; this.state.trailingComments.push(comment); this.state.leadingComments.push(comment); } - processComment(node) { + processComment(node: Node): void { if (node.type === "Program" && node.body.length > 0) return; const stack = this.state.commentStack; @@ -127,10 +130,8 @@ export default class CommentsParser extends BaseParser { // that comes after the node. Keep in mind that this could // result in an empty array, and if so, the array must be // deleted. - node.leadingComments = this.state.leadingComments.slice(0, i); - if ((node.leadingComments: Array).length === 0) { - node.leadingComments = null; - } + const leadingComments = this.state.leadingComments.slice(0, i); + node.leadingComments = leadingComments.length === 0 ? null : leadingComments; // Similarly, trailing comments are attached later. The variable // must be reset to null if there are no trailing comments. diff --git a/src/parser/location.js b/src/parser/location.js index 1562f52fb6..aed2760d62 100644 --- a/src/parser/location.js +++ b/src/parser/location.js @@ -1,3 +1,5 @@ +// @flow + import { getLineInfo } from "../util/location"; import CommentsParser from "./comments"; @@ -8,10 +10,11 @@ import CommentsParser from "./comments"; // message. export default class LocationParser extends CommentsParser { - raise(pos, message) { + raise(pos: number, message: string): empty { const loc = getLineInfo(this.input, pos); message += ` (${loc.line}:${loc.column})`; - const err = new SyntaxError(message); + // $FlowIgnore + const err: SyntaxError & { pos: number, loc: Position } = new SyntaxError(message); err.pos = pos; err.loc = loc; throw err; diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index 2303175c18..fde3448c0d 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -49,9 +49,7 @@ export default class Tokenizer extends LocationParser { // parser/util.js +unexpected: (pos?: ?number, messageOrType?: string | TokenType) => empty; - state: State; isLookahead: boolean; - input: string; constructor(options: Options, input: string) { super(); From 3199ceecdbc04b5c50e102155bd9f2baf251b16b Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 25 Apr 2017 14:54:47 -0700 Subject: [PATCH 18/73] Type-check node.js (#486) --- src/parser/node.js | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/parser/node.js b/src/parser/node.js index dafe10af9b..cc8f514366 100644 --- a/src/parser/node.js +++ b/src/parser/node.js @@ -1,13 +1,16 @@ +// @flow + import Parser from "./index"; import UtilParser from "./util"; import { SourceLocation, type Position } from "../util/location"; +import type { Comment, Node as NodeType, NodeBase } from "../types"; // Start an AST node, attaching a start offset. const commentKeys = ["leadingComments", "trailingComments", "innerComments"]; -class Node { - constructor(parser?: Parser, pos?: number, loc?: Position) { +class Node implements NodeBase { + constructor(parser: Parser, pos: number, loc: Position) { this.type = ""; this.start = pos; this.end = 0; @@ -17,15 +20,22 @@ class Node { } type: string; - start: ?number; + start: number; end: number; loc: SourceLocation; + range: [number, number]; + leadingComments: ?Array; + trailingComments: ?Array; + innerComments: ?Array; + extra: { [key: string]: any }; - __clone(): Node { - const node2 = new Node; + __clone(): this { + // $FlowIgnore + const node2: any = new Node; for (const key in this) { // Do not clone comments that are already attached to the node if (commentKeys.indexOf(key) < 0) { + // $FlowIgnore node2[key] = this[key]; } } @@ -35,23 +45,25 @@ class Node { } export class NodeUtils extends UtilParser { - startNode() { + startNode(): T { + // $FlowIgnore return new Node(this, this.state.start, this.state.startLoc); } - startNodeAt(pos, loc) { + startNodeAt(pos: number, loc: Position): T { + // $FlowIgnore return new Node(this, pos, loc); } // Finish an AST node, adding `type` and `end` properties. - finishNode(node, type) { + finishNode(node: T, type: string): T { return this.finishNodeAt(node, type, this.state.lastTokEnd, this.state.lastTokEndLoc); } // Finish node at given position - finishNodeAt(node, type, pos, loc) { + finishNodeAt(node: T, type: string, pos: number, loc: Position): T { node.type = type; node.end = pos; node.loc.end = loc; @@ -63,11 +75,9 @@ export class NodeUtils extends UtilParser { /** * Reset the start location of node to the start location of locationNode */ - resetStartLocationFromNode(node, locationNode) { + resetStartLocationFromNode(node: NodeBase, locationNode: NodeBase): void { node.start = locationNode.start; node.loc.start = locationNode.loc.start; if (this.options.ranges) node.range[0] = locationNode.range[0]; - - return node; } } From 7627c5a2be47f2fd38f9df32f62d26577f40e732 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 25 Apr 2017 15:01:55 -0700 Subject: [PATCH 19/73] Type-check UtilParser (#485) --- src/parser/util.js | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/parser/util.js b/src/parser/util.js index 532e3fe7a4..891a193c25 100644 --- a/src/parser/util.js +++ b/src/parser/util.js @@ -1,5 +1,8 @@ -import { types as tt } from "../tokenizer/types"; +// @flow + +import { types as tt, type TokenType } from "../tokenizer/types"; import Tokenizer from "../tokenizer"; +import type { Node } from "../types"; import { lineBreak } from "../util/whitespace"; // ## Parser utilities @@ -7,7 +10,7 @@ import { lineBreak } from "../util/whitespace"; export default class UtilParser extends Tokenizer { // TODO - addExtra(node, key, val) { + addExtra(node: Node, key: string, val: any): void { if (!node) return; const extra = node.extra = node.extra || {}; @@ -16,13 +19,13 @@ export default class UtilParser extends Tokenizer { // TODO - isRelational(op) { + isRelational(op: "<" | ">"): boolean { return this.match(tt.relational) && this.state.value === op; } // TODO - expectRelational(op) { + expectRelational(op: "<" | ">"): void { if (this.isRelational(op)) { this.next(); } else { @@ -32,25 +35,25 @@ export default class UtilParser extends Tokenizer { // Tests whether parsed token is a contextual keyword. - isContextual(name) { + isContextual(name: string): boolean { return this.match(tt.name) && this.state.value === name; } // Consumes contextual keyword if possible. - eatContextual(name) { + eatContextual(name: string): boolean { return this.state.value === name && this.eat(tt.name); } // Asserts that following token is given contextual keyword. - expectContextual(name, message) { + expectContextual(name: string, message?: string): void { if (!this.eatContextual(name)) this.unexpected(null, message); } // Test whether a semicolon can be inserted at the current position. - canInsertSemicolon() { + canInsertSemicolon(): boolean { return this.match(tt.eof) || this.match(tt.braceR) || lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start)); @@ -58,31 +61,31 @@ export default class UtilParser extends Tokenizer { // TODO - isLineTerminator() { + isLineTerminator(): boolean { return this.eat(tt.semi) || this.canInsertSemicolon(); } // Consume a semicolon, or, failing that, see if we are allowed to // pretend that there is a semicolon at this position. - semicolon() { + semicolon(): void { if (!this.isLineTerminator()) this.unexpected(null, tt.semi); } // Expect a token of a given type. If found, consume it, otherwise, // raise an unexpected token error at given pos. - expect(type, pos) { - return this.eat(type) || this.unexpected(pos, type); + expect(type: TokenType, pos?: ?number): void { + this.eat(type) || this.unexpected(pos, type); } // Raise an unexpected token error. Can take the expected token type // instead of a message string. - unexpected(pos, messageOrType = "Unexpected token") { + unexpected(pos: ?number, messageOrType: string | TokenType = "Unexpected token"): empty { if (messageOrType && typeof messageOrType === "object" && messageOrType.label) { messageOrType = `Unexpected token, expected ${messageOrType.label}`; } - this.raise(pos != null ? pos : this.state.start, messageOrType); + throw this.raise(pos != null ? pos : this.state.start, messageOrType); } } From 47cade874c1add7b3f35a0939dbf26f7abd77f6b Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 26 Apr 2017 14:18:17 -0700 Subject: [PATCH 20/73] Type-check options.js and index.js (#490) --- src/index.js | 15 ++++++++++----- src/options.js | 30 +++++++++++++++++------------- src/parser/index.js | 4 ++-- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/index.js b/src/index.js index a797b55f15..09a5c40cbe 100755 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,6 @@ +// @flow + +import type { Options } from "./options"; import Parser, { plugins } from "./parser"; import "./parser/util"; import "./parser/statement"; @@ -11,6 +14,8 @@ import { types as tokTypes } from "./tokenizer/types"; import "./tokenizer"; import "./tokenizer/context"; +import type { Expression, File } from "./types"; + import estreePlugin from "./plugins/estree"; import flowPlugin from "./plugins/flow"; import jsxPlugin from "./plugins/jsx"; @@ -18,11 +23,11 @@ plugins.estree = estreePlugin; plugins.flow = flowPlugin; plugins.jsx = jsxPlugin; -export function parse(input, options) { +export function parse(input: string, options?: Options): File { return getParser(options, input).parse(); } -export function parseExpression(input, options) { +export function parseExpression(input: string, options?: Options): Expression { const parser = getParser(options, input); if (parser.options.strictMode) { parser.state.strict = true; @@ -33,15 +38,15 @@ export function parseExpression(input, options) { export { tokTypes }; -function getParser(options, input) { +function getParser(options: ?Options, input: string): Parser { const cls = options && options.plugins ? getParserClass(options.plugins) : Parser; return new cls(options, input); } -const parserClassCache = {}; +const parserClassCache: { [key: string]: Class } = {}; /** Get a Parser class with plugins applied. */ -function getParserClass(pluginsFromOptions) { +function getParserClass(pluginsFromOptions: $ReadOnlyArray): Class { // Filter out just the plugins that have an actual mixin associated with them. let pluginList = pluginsFromOptions.filter((p) => p === "estree" || p === "flow" || p === "jsx"); diff --git a/src/options.js b/src/options.js index ad75996fce..72d65ed0df 100755 --- a/src/options.js +++ b/src/options.js @@ -1,17 +1,21 @@ +// @flow + // A second optional argument can be given to further configure // the parser process. These options are recognized: -export const defaultOptions: { - sourceType: string, - sourceFilename: any, - startLine: number, - allowReturnOutsideFunction: boolean, - allowImportExportEverywhere: boolean, - allowSuperOutsideMethod: boolean, - plugins: Array, - strictMode: any, - ranges: boolean, -} = { +export type Options = { + sourceType: "script" | "module"; + sourceFilename?: string; + startLine: number; + allowReturnOutsideFunction: boolean; + allowImportExportEverywhere: boolean; + allowSuperOutsideMethod: boolean; + plugins: $ReadOnlyArray; + strictMode: ?boolean; + ranges: boolean; +}; + +export const defaultOptions: Options = { // Source type ("script" or "module") for different semantics sourceType: "script", // Source filename. @@ -44,8 +48,8 @@ export const defaultOptions: { // Interpret and default an options object -export function getOptions(opts?: Object): Object { - const options = {}; +export function getOptions(opts: ?Options): Options { + const options: any = {}; for (const key in defaultOptions) { options[key] = opts && key in opts ? opts[key] : defaultOptions[key]; } diff --git a/src/parser/index.js b/src/parser/index.js index 41ce90fde2..7a66b89a54 100644 --- a/src/parser/index.js +++ b/src/parser/index.js @@ -5,10 +5,10 @@ import type { File } from "../types"; import { getOptions } from "../options"; import StatementParser from "./statement"; -export const plugins = {}; +export const plugins: { [name: string]: (superClass: Class) => Class } = {}; export default class Parser extends StatementParser { - constructor(options: Options, input: string) { + constructor(options: ?Options, input: string) { options = getOptions(options); super(options, input); From e1a06544bccda0e899965ae5db67decc4ea4d76e Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 27 Apr 2017 07:23:13 -0700 Subject: [PATCH 21/73] Type-check utils (#491) * Type-check utils * Improve test coverage --- src/tokenizer/index.js | 1 + src/util/identifier.js | 17 ++++++++++------- src/util/location.js | 18 +++++++++++++++++- src/util/whitespace.js | 2 ++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index fde3448c0d..34f75fa490 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -809,6 +809,7 @@ export default class Tokenizer extends LocationParser { ++this.state.pos; const esc = this.readCodePoint(true); + // $FlowFixMe (thinks esc may be null, but throwOnInvalid is true) if (!(first ? isIdentifierStart : isIdentifierChar)(esc, true)) { this.raise(escStart, "Invalid Unicode escape"); } diff --git a/src/util/identifier.js b/src/util/identifier.js index d8a9c83c49..3fc6ab2cde 100644 --- a/src/util/identifier.js +++ b/src/util/identifier.js @@ -1,5 +1,7 @@ /* eslint max-len: 0 */ +// @flow + // This is a trick taken from Esprima. It turns out that, on // non-Chrome browsers, to check whether a string is in a set, a // predicate containing a big ugly `switch` statement is faster than @@ -9,17 +11,17 @@ // // It starts by sorting the words by length. -function makePredicate(words) { - words = words.split(" "); +function makePredicate(words: string): (str: string) => boolean { + const wordsArr = words.split(" "); return function (str) { - return words.indexOf(str) >= 0; + return wordsArr.indexOf(str) >= 0; }; } // Reserved word lists for various dialects of the language export const reservedWords = { - 6: makePredicate("enum await"), + "6": makePredicate("enum await"), strict: makePredicate("implements interface let package private protected public static yield"), strictBind: makePredicate("eval arguments") }; @@ -57,7 +59,7 @@ const astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,1 // This has a complexity linear to the value of the code. The // assumption is that looking up astral identifier characters is // rare. -function isInAstralSet(code, set) { +function isInAstralSet(code: number, set: $ReadOnlyArray): boolean { let pos = 0x10000; for (let i = 0; i < set.length; i += 2) { pos += set[i]; @@ -66,11 +68,12 @@ function isInAstralSet(code, set) { pos += set[i + 1]; if (pos >= code) return true; } + return false; } // Test whether a given character code starts an identifier. -export function isIdentifierStart(code) { +export function isIdentifierStart(code: number): boolean { if (code < 65) return code === 36; if (code < 91) return true; if (code < 97) return code === 95; @@ -81,7 +84,7 @@ export function isIdentifierStart(code) { // Test whether a given character is part of an identifier. -export function isIdentifierChar(code) { +export function isIdentifierChar(code: number): boolean { if (code < 48) return code === 36; if (code < 58) return true; if (code < 65) return false; diff --git a/src/util/location.js b/src/util/location.js index fb53aab1c5..aaa4ae531c 100644 --- a/src/util/location.js +++ b/src/util/location.js @@ -1,9 +1,18 @@ +// @flow + import { lineBreakG } from "./whitespace"; +export type Pos = { + start: number; +} + // These are used when `options.locations` is on, for the // `startLoc` and `endLoc` properties. export class Position { + line: number; + column: number; + constructor(line: number, col: number) { this.line = line; this.column = col; @@ -11,8 +20,13 @@ export class Position { } export class SourceLocation { + start: Position; + end: Position; + filename: string; + constructor(start: Position, end?: Position) { this.start = start; + // $FlowIgnore (may start as null, but initialized later) this.end = end; } } @@ -23,7 +37,7 @@ export class SourceLocation { // offset. `input` should be the code string that the offset refers // into. -export function getLineInfo(input, offset) { +export function getLineInfo(input: string, offset: number): Position { for (let line = 1, cur = 0; ;) { lineBreakG.lastIndex = cur; const match = lineBreakG.exec(input); @@ -34,4 +48,6 @@ export function getLineInfo(input, offset) { return new Position(line, offset - cur); } } + // istanbul ignore next + throw new Error("Unreachable"); } diff --git a/src/util/whitespace.js b/src/util/whitespace.js index e345a4cf5e..0588213ecd 100644 --- a/src/util/whitespace.js +++ b/src/util/whitespace.js @@ -1,3 +1,5 @@ +// @flow + // Matches a whole line break (where CRLF is considered a single // line break). Used to count lines. From d8ff63181e23ec2e8fbef38da6b5c733217ff23a Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 27 Apr 2017 07:37:08 -0700 Subject: [PATCH 22/73] Type-check LValParser (#487) --- src/parser/lval.js | 57 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/src/parser/lval.js b/src/parser/lval.js index b3d33baf3d..811c37038a 100644 --- a/src/parser/lval.js +++ b/src/parser/lval.js @@ -1,11 +1,28 @@ -import { types as tt } from "../tokenizer/types"; +// @flow + +import { types as tt, type TokenType } from "../tokenizer/types"; +import type { Decorator, Expression, Identifier, Node, ObjectExpression, ObjectPattern, Pattern, RestElement, + SpreadElement } from "../types"; +import type { Pos, Position } from "../util/location"; import { NodeUtils } from "./node"; export default class LValParser extends NodeUtils { + // Forward-declaration: defined in expression.js + +checkReservedWord: (word: string, startLoc: number, checkKeywords: boolean, isBinding: boolean) => void; + +parseIdentifier: (liberal?: boolean) => Identifier; + +parseMaybeAssign: ( + noIn?: ?boolean, + refShorthandDefaultPos?: ?Pos, + afterLeftParse?: Function, + refNeedsArrowPos?: ?Pos) => Expression; + +parseObj: (isPattern: boolean, refShorthandDefaultPos?: ?Pos) => T; + // Forward-declaration: defined in statement.js + +parseDecorator: () => Decorator; + // Convert existing expression atom to assignable pattern // if possible. - toAssignable(node, isBinding, contextDescription) { + toAssignable(node: Node, isBinding: ?boolean, contextDescription: string): Node { if (node) { switch (node.type) { case "Identifier": @@ -16,7 +33,7 @@ export default class LValParser extends NodeUtils { case "ObjectExpression": node.type = "ObjectPattern"; - for (const prop of (node.properties: Array)) { + for (const prop of node.properties) { if (prop.type === "ObjectMethod") { if (prop.kind === "get" || prop.kind === "set") { this.raise(prop.key.start, "Object pattern can't contain getter or setter"); @@ -66,7 +83,8 @@ export default class LValParser extends NodeUtils { // Convert list of expression atoms to binding list. - toAssignableList(exprList, isBinding, contextDescription) { + toAssignableList( + exprList: Expression[], isBinding: ?boolean, contextDescription: string): $ReadOnlyArray { let end = exprList.length; if (end) { const last = exprList[end - 1]; @@ -93,36 +111,36 @@ export default class LValParser extends NodeUtils { // Convert list of expression atoms to a list of - toReferencedList(exprList) { + toReferencedList(exprList: $ReadOnlyArray): $ReadOnlyArray { return exprList; } // Parses spread element. - parseSpread(refShorthandDefaultPos) { + parseSpread(refShorthandDefaultPos: ?Pos): T { const node = this.startNode(); this.next(); node.argument = this.parseMaybeAssign(false, refShorthandDefaultPos); return this.finishNode(node, "SpreadElement"); } - parseRest() { + parseRest(): RestElement { const node = this.startNode(); this.next(); node.argument = this.parseBindingAtom(); return this.finishNode(node, "RestElement"); } - shouldAllowYieldIdentifier() { + shouldAllowYieldIdentifier(): boolean { return this.match(tt._yield) && !this.state.strict && !this.state.inGenerator; } - parseBindingIdentifier() { + parseBindingIdentifier(): Identifier { return this.parseIdentifier(this.shouldAllowYieldIdentifier()); } // Parses lvalue (assignable) atom. - parseBindingAtom() { + parseBindingAtom(): Pattern { switch (this.state.type) { case tt._yield: case tt.name: @@ -138,11 +156,11 @@ export default class LValParser extends NodeUtils { return this.parseObj(true); default: - this.unexpected(); + throw this.unexpected(); } } - parseBindingList(close, allowEmpty) { + parseBindingList(close: TokenType, allowEmpty?: boolean): $ReadOnlyArray { const elts = []; let first = true; while (!this.eat(close)) { @@ -152,6 +170,7 @@ export default class LValParser extends NodeUtils { this.expect(tt.comma); } if (allowEmpty && this.match(tt.comma)) { + // $FlowFixMe This method returns `$ReadOnlyArray` if `allowEmpty` is set. elts.push(null); } else if (this.eat(close)) { break; @@ -175,13 +194,13 @@ export default class LValParser extends NodeUtils { return elts; } - parseAssignableListItemTypes(param) { + parseAssignableListItemTypes(param: Pattern): Pattern { return param; } // Parses assignment pattern around given atom if possible. - parseMaybeDefault(startPos, startLoc, left) { + parseMaybeDefault(startPos?: ?number, startLoc?: ?Position, left?: ?Pattern): Pattern { startLoc = startLoc || this.state.startLoc; startPos = startPos || this.state.start; left = left || this.parseBindingAtom(); @@ -196,7 +215,11 @@ export default class LValParser extends NodeUtils { // Verify that a node is an lval — something that can be assigned // to. - checkLVal(expr, isBinding, checkClashes, contextDescription) { + checkLVal( + expr: Expression, + isBinding: ?boolean, + checkClashes: ?{ [key: string]: boolean }, + contextDescription: string): void { switch (expr.type) { case "Identifier": this.checkReservedWord(expr.name, expr.start, false, true); @@ -229,14 +252,14 @@ export default class LValParser extends NodeUtils { break; case "ObjectPattern": - for (let prop of (expr.properties: Array)) { + for (let prop of expr.properties) { if (prop.type === "ObjectProperty") prop = prop.value; this.checkLVal(prop, isBinding, checkClashes, "object destructuring pattern"); } break; case "ArrayPattern": - for (const elem of (expr.elements: Array)) { + for (const elem of expr.elements) { if (elem) this.checkLVal(elem, isBinding, checkClashes, "array destructuring pattern"); } break; From cd5bfb786aaabf0c25d4d178c99c8e4588ac0881 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 27 Apr 2017 07:40:51 -0700 Subject: [PATCH 23/73] Type-check estree plugin (#494) --- src/plugins/estree.js | 56 ++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/src/plugins/estree.js b/src/plugins/estree.js index 3d9f9477a7..e4b7041774 100644 --- a/src/plugins/estree.js +++ b/src/plugins/estree.js @@ -1,14 +1,18 @@ -import { types as tt } from "../tokenizer/types"; +// @flow -function isSimpleProperty(node) { - return node && +import { types as tt } from "../tokenizer/types"; +import type Parser from "../parser"; +import * as N from "../types"; + +function isSimpleProperty(node: N.Node): boolean { + return node != null && node.type === "Property" && node.kind === "init" && node.method === false; } -export default (superClass) => class extends superClass { - estreeParseRegExpLiteral({ pattern, flags }) { +export default (superClass: Class): Class => class extends superClass { + estreeParseRegExpLiteral({ pattern, flags }: N.RegExpLiteral): N.Node { let regex = null; try { regex = new RegExp(pattern, flags); @@ -22,11 +26,11 @@ export default (superClass) => class extends superClass { return node; } - estreeParseLiteral(value) { + estreeParseLiteral(value: any): N.Node { return this.parseLiteral(value, "Literal"); } - directiveToStmt(directive) { + directiveToStmt(directive: N.Directive): N.ExpressionStatement { const directiveLiteral = directive.value; const stmt = this.startNodeAt(directive.start, directive.loc.start); @@ -46,15 +50,16 @@ export default (superClass) => class extends superClass { // Overrides // ================================== - checkDeclaration(node) { + checkDeclaration(node: N.Pattern): void { if (isSimpleProperty(node)) { + // $FlowFixMe this.checkDeclaration(node.value); } else { super.checkDeclaration(node); } } - checkGetterSetterParamCount(prop) { + checkGetterSetterParamCount(prop: N.ObjectMethod): void { const paramCount = prop.kind === "get" ? 0 : 1; if (prop.value.params.length !== paramCount) { const start = prop.start; @@ -66,7 +71,8 @@ export default (superClass) => class extends superClass { } } - checkLVal(expr, isBinding, checkClashes, ...args) { + checkLVal( + expr: N.Expression, isBinding: ?boolean, checkClashes: ?{ [key: string]: boolean }, ...args): void { switch (expr.type) { case "ObjectPattern": expr.properties.forEach((prop) => { @@ -83,7 +89,7 @@ export default (superClass) => class extends superClass { } } - checkPropClash(prop, propHash) { + checkPropClash(prop: N.ObjectMember, propHash: { [key: string]: boolean }): void { if (prop.computed || !isSimpleProperty(prop)) return; const key = prop.key; @@ -96,9 +102,9 @@ export default (superClass) => class extends superClass { } } - isStrictBody(node, isExpression) { + isStrictBody(node: { body: N.BlockStatement }, isExpression?: boolean): boolean { if (!isExpression && node.body.body.length > 0) { - for (const directive of (node.body.body: Array)) { + for (const directive of node.body.body) { if (directive.type === "ExpressionStatement" && directive.expression.type === "Literal") { if (directive.expression.value === "use strict") return true; } else { @@ -111,19 +117,18 @@ export default (superClass) => class extends superClass { return false; } - isValidDirective(stmt) { + isValidDirective(stmt: N.Statement): boolean { return stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && typeof stmt.expression.value === "string" && (!stmt.expression.extra || !stmt.expression.extra.parenthesized); } - parseBlockBody(node, ...args) { + parseBlockBody(node: N.BlockStatementLike, ...args): void { super.parseBlockBody(node, ...args); - node.directives.reverse().forEach((directive) => { - node.body.unshift(this.directiveToStmt(directive)); - }); + const directiveStatements = node.directives.map((d) => this.directiveToStmt(d)); + node.body = directiveStatements.concat(node.body); delete node.directives; } @@ -134,7 +139,7 @@ export default (superClass) => class extends superClass { body[body.length - 1].type = "MethodDefinition"; } - parseExprAtom(...args) { + parseExprAtom(...args): N.Expression { switch (this.state.type) { case tt.regexp: return this.estreeParseRegExpLiteral(this.state.value); @@ -157,7 +162,7 @@ export default (superClass) => class extends superClass { } } - parseLiteral(...args) { + parseLiteral(...args): T { const node = super.parseLiteral(...args); node.raw = node.extra.raw; delete node.extra; @@ -165,17 +170,18 @@ export default (superClass) => class extends superClass { return node; } - parseMethod(node, ...args) { + parseMethod(node: N.MethodLike, ...args): N.MethodLike { let funcNode = this.startNode(); funcNode.kind = node.kind; // provide kind, so super method correctly sets state funcNode = super.parseMethod(funcNode, ...args); delete funcNode.kind; + // $FlowIgnore node.value = this.finishNode(funcNode, "FunctionExpression"); return node; } - parseObjectMethod(...args) { + parseObjectMethod(...args): ?N.ObjectMethod { const node = super.parseObjectMethod(...args); if (node) { @@ -186,7 +192,7 @@ export default (superClass) => class extends superClass { return node; } - parseObjectProperty(...args) { + parseObjectProperty(...args): ?N.ObjectProperty { const node = super.parseObjectProperty(...args); if (node) { @@ -197,14 +203,14 @@ export default (superClass) => class extends superClass { return node; } - toAssignable(node, isBinding, ...args) { + toAssignable(node: N.Node, isBinding: ?boolean, ...args): N.Node { if (isSimpleProperty(node)) { this.toAssignable(node.value, isBinding, ...args); return node; } else if (node.type === "ObjectExpression") { node.type = "ObjectPattern"; - for (const prop of (node.properties: Array)) { + for (const prop of node.properties) { if (prop.kind === "get" || prop.kind === "set") { this.raise(prop.key.start, "Object pattern can't contain getter or setter"); } else if (prop.method) { From 8288f7d9e45c254158509cb23e231a3525d74197 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 27 Apr 2017 07:53:17 -0700 Subject: [PATCH 24/73] Type-check tokenizer/types.js (#493) --- src/parser/util.js | 2 +- src/tokenizer/context.js | 2 ++ src/tokenizer/types.js | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/parser/util.js b/src/parser/util.js index 891a193c25..89ec41154e 100644 --- a/src/parser/util.js +++ b/src/parser/util.js @@ -83,7 +83,7 @@ export default class UtilParser extends Tokenizer { // instead of a message string. unexpected(pos: ?number, messageOrType: string | TokenType = "Unexpected token"): empty { - if (messageOrType && typeof messageOrType === "object" && messageOrType.label) { + if (typeof messageOrType !== "string") { messageOrType = `Unexpected token, expected ${messageOrType.label}`; } throw this.raise(pos != null ? pos : this.state.start, messageOrType); diff --git a/src/tokenizer/context.js b/src/tokenizer/context.js index 81db0499c3..7b7b97b6d7 100644 --- a/src/tokenizer/context.js +++ b/src/tokenizer/context.js @@ -1,3 +1,5 @@ +// @flow + // The algorithm used to determine whether a regexp can appear at a // given point in the program is loosely based on sweet.js' approach. // See https://github.com/mozilla/sweet.js/wiki/design diff --git a/src/tokenizer/types.js b/src/tokenizer/types.js index 1d78aabb40..e6552249e6 100644 --- a/src/tokenizer/types.js +++ b/src/tokenizer/types.js @@ -1,3 +1,5 @@ +// @flow + // ## Token types // The assignment of fine-grained, information-carrying type objects @@ -23,8 +25,33 @@ const isAssign = true; const prefix = true; const postfix = true; +type TokenOptions = { + keyword?: string; + + beforeExpr?: boolean; + startsExpr?: boolean; + rightAssociative?: boolean; + isLoop?: boolean; + isAssign?: boolean; + prefix?: boolean; + postfix?: boolean; + binop?: ?number; +}; + export class TokenType { - constructor(label, conf = {}) { + label: string; + keyword: ?string; + beforeExpr: boolean; + startsExpr: boolean; + rightAssociative: boolean; + isLoop: boolean; + isAssign: boolean; + prefix: boolean; + postfix: boolean; + binop: ?number; + updateContext: ?((prevType: TokenType) => void); + + constructor(label: string, conf: TokenOptions = {}) { this.label = label; this.keyword = conf.keyword; this.beforeExpr = !!conf.beforeExpr; @@ -40,7 +67,7 @@ export class TokenType { } class KeywordTokenType extends TokenType { - constructor(name, options = {}) { + constructor(name: string, options: TokenOptions = {}) { options.keyword = name; super(name, options); @@ -48,12 +75,12 @@ class KeywordTokenType extends TokenType { } export class BinopTokenType extends TokenType { - constructor(name, prec) { + constructor(name: string, prec: number) { super(name, { beforeExpr, binop: prec }); } } -export const types = { +export const types: { [name: string]: TokenType } = { num: new TokenType("num", { startsExpr }), regexp: new TokenType("regexp", { startsExpr }), string: new TokenType("string", { startsExpr }), From cccee0060621373c6c5d54d335eed5fa469ec5e7 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 27 Apr 2017 07:58:33 -0700 Subject: [PATCH 25/73] Type-check JSX plugin (#496) * Type-check JSX plugin * Improve test coverage --- src/plugins/jsx/index.js | 60 +++++++++++++++++++++++----------------- src/plugins/jsx/xhtml.js | 5 +++- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/plugins/jsx/index.js b/src/plugins/jsx/index.js index c309d2c965..0d8e6b91a5 100644 --- a/src/plugins/jsx/index.js +++ b/src/plugins/jsx/index.js @@ -1,7 +1,12 @@ +// @flow + import XHTMLEntities from "./xhtml"; +import type Parser from "../../parser"; import { TokenType, types as tt } from "../../tokenizer/types"; import { TokContext, types as tc } from "../../tokenizer/context"; +import * as N from "../../types"; import { isIdentifierChar, isIdentifierStart } from "../../util/identifier"; +import type { Pos, Position } from "../../util/location"; import { isNewLine } from "../../util/whitespace"; const HEX_NUMBER = /^[\da-fA-F]+$/; @@ -34,7 +39,7 @@ tt.jsxTagEnd.updateContext = function(prevType) { // Transforms JSX element name to string. -function getQualifiedJSXName(object) { +function getQualifiedJSXName(object: N.JSXIdentifier | N.JSXNamespacedName | N.JSXMemberExpression): string { if (object.type === "JSXIdentifier") { return object.name; } @@ -46,12 +51,15 @@ function getQualifiedJSXName(object) { if (object.type === "JSXMemberExpression") { return getQualifiedJSXName(object.object) + "." + getQualifiedJSXName(object.property); } + + // istanbul ignore next + throw new Error("Node had unexpected type: " + object.type); } -export default (superClass) => class extends superClass { +export default (superClass: Class): Class => class extends superClass { // Reads inline JSX contents token. - jsxReadToken() { + jsxReadToken(): void { let out = ""; let chunkStart = this.state.pos; for (;;) { @@ -92,7 +100,7 @@ export default (superClass) => class extends superClass { } } - jsxReadNewLine(normalizeCRLF) { + jsxReadNewLine(normalizeCRLF: boolean): string { const ch = this.input.charCodeAt(this.state.pos); let out; ++this.state.pos; @@ -108,7 +116,7 @@ export default (superClass) => class extends superClass { return out; } - jsxReadString(quote) { + jsxReadString(quote: number): void { let out = ""; let chunkStart = ++this.state.pos; for (;;) { @@ -134,7 +142,7 @@ export default (superClass) => class extends superClass { return this.finishToken(tt.string, out); } - jsxReadEntity() { + jsxReadEntity(): string { let str = ""; let count = 0; let entity; @@ -176,7 +184,7 @@ export default (superClass) => class extends superClass { // Also assumes that first character was already checked // by isIdentifierStart in readToken. - jsxReadWord() { + jsxReadWord(): void { let ch; const start = this.state.pos; do { @@ -187,7 +195,7 @@ export default (superClass) => class extends superClass { // Parse next token as JSX identifier - jsxParseIdentifier() { + jsxParseIdentifier(): N.JSXIdentifier { const node = this.startNode(); if (this.match(tt.jsxName)) { node.name = this.state.value; @@ -202,7 +210,7 @@ export default (superClass) => class extends superClass { // Parse namespaced identifier. - jsxParseNamespacedName() { + jsxParseNamespacedName(): N.JSXNamespacedName { const startPos = this.state.start; const startLoc = this.state.startLoc; const name = this.jsxParseIdentifier(); @@ -217,7 +225,7 @@ export default (superClass) => class extends superClass { // Parses element name in any form - namespaced, member // or single identifier. - jsxParseElementName() { + jsxParseElementName(): N.JSXNamespacedName | N.JSXMemberExpression { const startPos = this.state.start; const startLoc = this.state.startLoc; let node = this.jsxParseNamespacedName(); @@ -232,13 +240,13 @@ export default (superClass) => class extends superClass { // Parses any type of JSX attribute value. - jsxParseAttributeValue() { + jsxParseAttributeValue(): N.Expression { let node; switch (this.state.type) { case tt.braceL: node = this.jsxParseExpressionContainer(); if (node.expression.type === "JSXEmptyExpression") { - this.raise(node.start, "JSX attributes must only be assigned a non-empty expression"); + throw this.raise(node.start, "JSX attributes must only be assigned a non-empty expression"); } else { return node; } @@ -248,7 +256,7 @@ export default (superClass) => class extends superClass { return this.parseExprAtom(); default: - this.raise(this.state.start, "JSX value should be either an expression or a quoted JSX text"); + throw this.raise(this.state.start, "JSX value should be either an expression or a quoted JSX text"); } } @@ -256,14 +264,14 @@ export default (superClass) => class extends superClass { // and so it should start at the end of last read token (left brace) and finish // at the beginning of the next one (right brace). - jsxParseEmptyExpression() { + jsxParseEmptyExpression(): N.JSXEmptyExpression { const node = this.startNodeAt(this.state.lastTokEnd, this.state.lastTokEndLoc); return this.finishNodeAt(node, "JSXEmptyExpression", this.state.start, this.state.startLoc); } // Parse JSX spread child - jsxParseSpreadChild() { + jsxParseSpreadChild(): N.JSXSpreadChild { const node = this.startNode(); this.expect(tt.braceL); this.expect(tt.ellipsis); @@ -276,7 +284,7 @@ export default (superClass) => class extends superClass { // Parses JSX expression enclosed into curly brackets. - jsxParseExpressionContainer() { + jsxParseExpressionContainer(): N.JSXExpressionContainer { const node = this.startNode(); this.next(); if (this.match(tt.braceR)) { @@ -290,7 +298,7 @@ export default (superClass) => class extends superClass { // Parses following JSX attribute name-value pair. - jsxParseAttribute() { + jsxParseAttribute(): N.JSXAttribute { const node = this.startNode(); if (this.eat(tt.braceL)) { this.expect(tt.ellipsis); @@ -305,7 +313,7 @@ export default (superClass) => class extends superClass { // Parses JSX opening tag starting after "<". - jsxParseOpeningElementAt(startPos, startLoc) { + jsxParseOpeningElementAt(startPos: number, startLoc: Position): N.JSXOpeningElement { const node = this.startNodeAt(startPos, startLoc); node.attributes = []; node.name = this.jsxParseElementName(); @@ -319,7 +327,7 @@ export default (superClass) => class extends superClass { // Parses JSX closing tag starting after " class extends superClass { // Parses entire JSX element, including it"s opening tag // (starting after "<"), attributes, contents and closing tag. - jsxParseElementAt(startPos, startLoc) { + jsxParseElementAt(startPos: number, startLoc: Position): N.JSXElement { const node = this.startNodeAt(startPos, startLoc); const children = []; const openingElement = this.jsxParseOpeningElementAt(startPos, startLoc); @@ -363,12 +371,14 @@ export default (superClass) => class extends superClass { // istanbul ignore next - should never happen default: - this.unexpected(); + throw this.unexpected(); } } + // $FlowIgnore if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) { this.raise( + // $FlowIgnore closingElement.start, "Expected corresponding JSX closing tag for <" + getQualifiedJSXName(openingElement.name) + ">" ); @@ -386,7 +396,7 @@ export default (superClass) => class extends superClass { // Parses entire JSX element from current position. - jsxParseElement() { + jsxParseElement(): N.JSXElement { const startPos = this.state.start; const startLoc = this.state.startLoc; this.next(); @@ -397,7 +407,7 @@ export default (superClass) => class extends superClass { // Overrides // ================================== - parseExprAtom(refShortHandDefaultPos) { + parseExprAtom(refShortHandDefaultPos: ?Pos): N.Expression { if (this.match(tt.jsxText)) { return this.parseLiteral(this.state.value, "JSXText"); } else if (this.match(tt.jsxTagStart)) { @@ -407,7 +417,7 @@ export default (superClass) => class extends superClass { } } - readToken(code) { + readToken(code: number): void { if (this.state.inPropertyName) return super.readToken(code); const context = this.curContext(); @@ -439,7 +449,7 @@ export default (superClass) => class extends superClass { return super.readToken(code); } - updateContext(prevType) { + updateContext(prevType: TokenType): void { if (this.match(tt.braceL)) { const curContext = this.curContext(); if (curContext === tc.j_oTag) { diff --git a/src/plugins/jsx/xhtml.js b/src/plugins/jsx/xhtml.js index 232f8b1b1a..022c4e94ac 100644 --- a/src/plugins/jsx/xhtml.js +++ b/src/plugins/jsx/xhtml.js @@ -1,4 +1,6 @@ -export default { +// @flow + +const entities: { [name: string]: string } = { quot: "\u0022", amp: "&", apos: "\u0027", @@ -253,3 +255,4 @@ export default { hearts: "\u2665", diams: "\u2666" }; +export default entities; From 5ae165d4899d7b364aa48ed56b13ea1ce26fddf7 Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Thu, 27 Apr 2017 11:16:48 -0400 Subject: [PATCH 26/73] update changelog [skip ci] --- CHANGELOG.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 161458e9c7..b7a486500a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,78 @@ _Note: Gaps between patch versions are faulty, broken or test releases._ See the [Babel Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) for the pre-6.8.0 version Changelog. -## 7.0.0-beta.4 (2017-03-01) +## v6.17.0 (2017-04-20) + +### :bug: Bug Fix + * Cherry-pick #418 to 6.x ([#476](https://github.com/babel/babylon/pull/476)) (Sebastian McKenzie) + * Add support for invalid escapes in tagged templates ([#274](https://github.com/babel/babylon/pull/274)) (Kevin Gibbons) + * Throw error if new.target is used outside of a function ([#402](https://github.com/babel/babylon/pull/402)) (Brian Ng) + * Fix parsing of class properties ([#351](https://github.com/babel/babylon/pull/351)) (Kevin Gibbons) + * Fix parsing yield with dynamicImport ([#383](https://github.com/babel/babylon/pull/383)) (Brian Ng) + * Ensure consistent start args for parseParenItem ([#386](https://github.com/babel/babylon/pull/386)) (Brian Ng) + +## 7.0.0-beta.8 (2017-04-04) + +### New Feature +* Add support for flow type spread (#418) (Conrad Buck) +* Allow statics in flow interfaces (#427) (Brian Ng) + +### Bug Fix +* Fix predicate attachment to match flow parser (#428) (Brian Ng) +* Add extra.raw back to JSXText and JSXAttribute (#344) (Alex Rattray) +* Fix rest parameters with array and objects (#424) (Brian Ng) +* Fix number parser (#433) (Alex Kuzmenko) + +### Docs +* Fix CONTRIBUTING.md [skip ci] (#432) (Alex Kuzmenko) + +### Internal +* Use babel-register script when running babel smoke tests (#442) (Brian Ng) + +## 7.0.0-beta.7 (2017-03-22) + +### Spec Compliancy +* Remove babylon plugin for template revision since it's stage-4 (#426) (Henry Zhu) + +### Bug Fix + +* Fix push-pop logic in flow (#405) (Daniel Tschinder) + +## 7.0.0-beta.6 (2017-03-21) + +### New Feature +* Add support for invalid escapes in tagged templates (#274) (Kevin Gibbons) + +### Polish +* Improves error message when super is called outside of constructor (#408) (Arshabh Kumar Agarwal) + +### Docs + +* [7.0] Moved value field in spec from ObjectMember to ObjectProperty as ObjectMethod's don't have it (#415) [skip ci] (James Browning) + +## 7.0.0-beta.5 (2017-03-21) + +### Bug Fix +* Throw error if new.target is used outside of a function (#402) (Brian Ng) +* Fix parsing of class properties (#351) (Kevin Gibbons) + +### Other + * Test runner: Detect extra property in 'actual' but not in 'expected'. (#407) (Andy) + * Optimize travis builds (#419) (Daniel Tschinder) + * Update codecov to 2.0 (#412) (Daniel Tschinder) + * Fix spec for ClassMethod: It doesn't have a function, it *is* a function. (#406) [skip ci] (Andy) + * Changed Non-existent RestPattern to RestElement which is what is actually parsed (#409) [skip ci] (James Browning) + * Upgrade flow to 0.41 (Daniel Tschinder) + * Fix watch command (#403) (Brian Ng) + * Update yarn lock (Daniel Tschinder) + * Fix watch command (#403) (Brian Ng) + * chore(package): update flow-bin to version 0.41.0 (#395) (greenkeeper[bot]) + * Add estree test for correct order of directives (Daniel Tschinder) + * Add DoExpression to spec (#364) (Alex Kuzmenko) + * Mention cloning of repository in CONTRIBUTING.md (#391) [skip ci] (Sumedh Nimkarde) + * Explain how to run only one test (#389) [skip ci] (Aaron Ang) + + ## 7.0.0-beta.4 (2017-03-01) * Don't consume async when checking for async func decl (#377) (Brian Ng) * add `ranges` option [skip ci] (Henry Zhu) From e81b5f8af273e92667696c51a870c64c4a163b18 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 27 Apr 2017 09:04:06 -0700 Subject: [PATCH 27/73] Type-check flow plugin (#495) * Type-check flow plugin * Fix typo --- src/plugins/flow.js | 206 +++++++++++++++++++++++--------------------- src/types.js | 3 + 2 files changed, 113 insertions(+), 96 deletions(-) diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 869ba2fc0d..cad3c4b645 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -1,6 +1,11 @@ /* eslint max-len: 0 */ -import { types as tt } from "../tokenizer/types"; +// @flow + +import type Parser from "../parser"; +import { types as tt, type TokenType } from "../tokenizer/types"; +import * as N from "../types"; +import type { Pos, Position } from "../util/location"; const primitiveTypes = [ "any", @@ -14,7 +19,7 @@ const primitiveTypes = [ "null" ]; -function isEsModuleType(bodyElement) { +function isEsModuleType(bodyElement: N.Node): boolean { return bodyElement.type === "DeclareExportAllDeclaration" || ( bodyElement.type === "DeclareExportDeclaration" && @@ -32,8 +37,8 @@ const exportSuggestions = { interface: "export interface", }; -export default (superClass) => class extends superClass { - flowParseTypeInitialiser(tok) { +export default (superClass: Class): Class => class extends superClass { + flowParseTypeInitialiser(tok?: TokenType): N.FlowType { const oldInType = this.state.inType; this.state.inType = true; this.expect(tok || tt.colon); @@ -43,7 +48,7 @@ export default (superClass) => class extends superClass { return type; } - flowParsePredicate() { + flowParsePredicate() : N.FlowType { const node = this.startNode(); const moduloLoc = this.state.startLoc; const moduloPos = this.state.start; @@ -63,7 +68,7 @@ export default (superClass) => class extends superClass { } } - flowParseTypeAndPredicateInitialiser() { + flowParseTypeAndPredicateInitialiser(): [?N.FlowType, ?N.FlowPredicate] { const oldInType = this.state.inType; this.state.inType = true; this.expect(tt.colon); @@ -82,13 +87,13 @@ export default (superClass) => class extends superClass { return [type, predicate]; } - flowParseDeclareClass(node) { + flowParseDeclareClass(node: N.FlowDeclareClass): N.FlowDeclareClass { this.next(); this.flowParseInterfaceish(node); return this.finishNode(node, "DeclareClass"); } - flowParseDeclareFunction(node) { + flowParseDeclareFunction(node: N.FlowDeclareFunction): N.FlowDeclareFunction { this.next(); const id = node.id = this.parseIdentifier(); @@ -108,6 +113,7 @@ export default (superClass) => class extends superClass { typeNode.rest = tmp.rest; this.expect(tt.parenR); + // $FlowFixMe (destructuring not supported yet) [typeNode.returnType, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation"); @@ -120,7 +126,7 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "DeclareFunction"); } - flowParseDeclare(node, insideModule) { + flowParseDeclare(node: N.FlowDeclare, insideModule?: boolean): N.FlowDeclare { if (this.match(tt._class)) { return this.flowParseDeclareClass(node); } else if (this.match(tt._function)) { @@ -141,18 +147,18 @@ export default (superClass) => class extends superClass { } else if (this.match(tt._export)) { return this.flowParseDeclareExportDeclaration(node, insideModule); } else { - this.unexpected(); + throw this.unexpected(); } } - flowParseDeclareVariable(node) { + flowParseDeclareVariable(node: N.FlowDeclareVariable): N.FlowDeclareVariable { this.next(); node.id = this.flowParseTypeAnnotatableIdentifier(); this.semicolon(); return this.finishNode(node, "DeclareVariable"); } - flowParseDeclareModule(node) { + flowParseDeclareModule(node: N.FlowDeclareModule): N.FlowDeclareModule { this.next(); if (this.match(tt.string)) { @@ -205,7 +211,7 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "DeclareModule"); } - flowParseDeclareExportDeclaration(node, insideModule) { + flowParseDeclareExportDeclaration(node: N.FlowDeclareExportDeclaration, insideModule: ?boolean): N.FlowDeclareExportDeclaration { this.expect(tt._export); if (this.eat(tt._default)) { @@ -252,21 +258,24 @@ export default (superClass) => class extends superClass { node = this.parseExport(node); if (node.type === "ExportNamedDeclaration") { // flow does not support the ExportNamedDeclaration + // $FlowIgnore node.type = "ExportDeclaration"; + // $FlowFixMe node.default = false; delete node.exportKind; } + // $FlowIgnore node.type = "Declare" + node.type; return node; } } - this.unexpected(); + throw this.unexpected(); } - flowParseDeclareModuleExports(node) { + flowParseDeclareModuleExports(node: N.FlowDeclareModuleExports): N.FlowDeclareModuleExports { this.expectContextual("module"); this.expect(tt.dot); this.expectContextual("exports"); @@ -276,13 +285,13 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "DeclareModuleExports"); } - flowParseDeclareTypeAlias(node) { + flowParseDeclareTypeAlias(node: N.FlowDeclareTypeAlias): N.FlowDeclareTypeAlias { this.next(); this.flowParseTypeAlias(node); return this.finishNode(node, "DeclareTypeAlias"); } - flowParseDeclareInterface(node) { + flowParseDeclareInterface(node: N.FlowDeclareInterface): N.FlowDeclareInterface { this.next(); this.flowParseInterfaceish(node); return this.finishNode(node, "DeclareInterface"); @@ -290,7 +299,7 @@ export default (superClass) => class extends superClass { // Interfaces - flowParseInterfaceish(node) { + flowParseInterfaceish(node: N.FlowDeclare): void { node.id = this.parseIdentifier(); if (this.isRelational("<")) { @@ -318,7 +327,7 @@ export default (superClass) => class extends superClass { node.body = this.flowParseObjectType(true, false, false); } - flowParseInterfaceExtends() { + flowParseInterfaceExtends(): N.FlowInterfaceExtends { const node = this.startNode(); node.id = this.flowParseQualifiedTypeIdentifier(); @@ -331,12 +340,12 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "InterfaceExtends"); } - flowParseInterface(node) { + flowParseInterface(node: N.FlowInterface): N.FlowInterface { this.flowParseInterfaceish(node); return this.finishNode(node, "InterfaceDeclaration"); } - flowParseRestrictedIdentifier(liberal) { + flowParseRestrictedIdentifier(liberal?: boolean): N.Identifier { if (primitiveTypes.indexOf(this.state.value) > -1) { this.raise(this.state.start, `Cannot overwrite primitive type ${this.state.value}`); } @@ -346,7 +355,7 @@ export default (superClass) => class extends superClass { // Type aliases - flowParseTypeAlias(node) { + flowParseTypeAlias(node: N.FlowTypeAlias): N.FlowTypeAlias { node.id = this.flowParseRestrictedIdentifier(); if (this.isRelational("<")) { @@ -363,7 +372,7 @@ export default (superClass) => class extends superClass { // Type annotations - flowParseTypeParameter() { + flowParseTypeParameter(): N.FlowTypeParameter { const node = this.startNode(); const variance = this.flowParseVariance(); @@ -381,7 +390,7 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "TypeParameter"); } - flowParseTypeParameterDeclaration() { + flowParseTypeParameterDeclaration(): N.FlowTypeParameterDeclaration { const oldInType = this.state.inType; const node = this.startNode(); node.params = []; @@ -408,7 +417,7 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "TypeParameterDeclaration"); } - flowParseTypeParameterInstantiation() { + flowParseTypeParameterInstantiation(): N.FlowTypeParameterInstantiation { const node = this.startNode(); const oldInType = this.state.inType; node.params = []; @@ -429,11 +438,11 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "TypeParameterInstantiation"); } - flowParseObjectPropertyKey() { + flowParseObjectPropertyKey(): N.Expression { return (this.match(tt.num) || this.match(tt.string)) ? this.parseExprAtom() : this.parseIdentifier(true); } - flowParseObjectTypeIndexer(node, isStatic, variance) { + flowParseObjectTypeIndexer(node: N.FlowObjectTypeIndexer, isStatic: boolean, variance: ?N.FlowVariance): N.FlowObjectTypeIndexer { node.static = isStatic; this.expect(tt.bracketL); @@ -451,7 +460,7 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "ObjectTypeIndexer"); } - flowParseObjectTypeMethodish(node) { + flowParseObjectTypeMethodish(node: N.FlowFunctionTypeAnnotation): N.FlowFunctionTypeAnnotation { node.params = []; node.rest = null; node.typeParameters = null; @@ -477,14 +486,14 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "FunctionTypeAnnotation"); } - flowParseObjectTypeCallProperty(node, isStatic) { + flowParseObjectTypeCallProperty(node: N.FlowObjectTypeCallProperty, isStatic: boolean): N.FlowObjectTypeCallProperty { const valueNode = this.startNode(); node.static = isStatic; node.value = this.flowParseObjectTypeMethodish(valueNode); return this.finishNode(node, "ObjectTypeCallProperty"); } - flowParseObjectType(allowStatic, allowExact, allowSpread) { + flowParseObjectType(allowStatic: boolean, allowExact: boolean, allowSpread: boolean): N.FlowObjectTypeAnnotation { const oldInType = this.state.inType; this.state.inType = true; @@ -555,7 +564,13 @@ export default (superClass) => class extends superClass { return out; } - flowParseObjectTypeProperty(node, isStatic, variance, kind, allowSpread) { + flowParseObjectTypeProperty( + node: N.FlowObjectTypeProperty | N.FlowObjectTypeSpreadProperty, + isStatic: boolean, + variance: ?N.FlowVariance, + kind: string, + allowSpread: boolean, + ): N.FlowObjectTypeProperty | N.FlowObjectTypeSpreadProperty { if (this.match(tt.ellipsis)) { if (!allowSpread) { this.unexpected( @@ -602,7 +617,7 @@ export default (superClass) => class extends superClass { // This is similar to checkGetterSetterParamCount, but as // babylon uses non estree properties we cannot reuse it here - flowCheckGetterSetterParamCount(property) { + flowCheckGetterSetterParamCount(property: N.FlowObjectTypeProperty | N.FlowObjectTypeSpreadProperty): void { const paramCount = property.kind === "get" ? 0 : 1; if (property.value.params.length !== paramCount) { const start = property.start; @@ -614,14 +629,14 @@ export default (superClass) => class extends superClass { } } - flowObjectTypeSemicolon() { + flowObjectTypeSemicolon(): void { if (!this.eat(tt.semi) && !this.eat(tt.comma) && !this.match(tt.braceR) && !this.match(tt.braceBarR)) { this.unexpected(); } } - flowParseQualifiedTypeIdentifier(startPos, startLoc, id) { + flowParseQualifiedTypeIdentifier(startPos?: number, startLoc?: Position, id?: N.Identifier): N.FlowQualifiedTypeIdentifier { startPos = startPos || this.state.start; startLoc = startLoc || this.state.startLoc; let node = id || this.parseIdentifier(); @@ -636,7 +651,7 @@ export default (superClass) => class extends superClass { return node; } - flowParseGenericType(startPos, startLoc, id) { + flowParseGenericType(startPos: number, startLoc: Position, id: N.Identifier): N.FlowGenericTypeAnnotation { const node = this.startNodeAt(startPos, startLoc); node.typeParameters = null; @@ -649,14 +664,14 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "GenericTypeAnnotation"); } - flowParseTypeofType() { + flowParseTypeofType(): N.FlowTypeofTypeAnnotation { const node = this.startNode(); this.expect(tt._typeof); node.argument = this.flowParsePrimaryType(); return this.finishNode(node, "TypeofTypeAnnotation"); } - flowParseTupleType() { + flowParseTupleType(): N.FlowTupleTypeAnnotation { const node = this.startNode(); node.types = []; this.expect(tt.bracketL); @@ -670,7 +685,7 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "TupleTypeAnnotation"); } - flowParseFunctionTypeParam() { + flowParseFunctionTypeParam(): N.FlowFunctionTypeParam { let name = null; let optional = false; let typeAnnotation = null; @@ -692,7 +707,7 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "FunctionTypeParam"); } - reinterpretTypeAsFunctionTypeParam(type) { + reinterpretTypeAsFunctionTypeParam(type: N.FlowType): N.FlowFunctionTypeParam { const node = this.startNodeAt(type.start, type.loc); node.name = null; node.optional = false; @@ -700,21 +715,21 @@ export default (superClass) => class extends superClass { return this.finishNode(node, "FunctionTypeParam"); } - flowParseFunctionTypeParams(params = []) { - const ret = { params, rest: null }; + flowParseFunctionTypeParams(params: N.FlowFunctionTypeParam[] = []): { params: N.FlowFunctionTypeParam[], rest: ?N.FlowFunctionTypeParam } { + let rest: ?N.FlowFunctionTypeParam = null; while (!this.match(tt.parenR) && !this.match(tt.ellipsis)) { - ret.params.push(this.flowParseFunctionTypeParam()); + params.push(this.flowParseFunctionTypeParam()); if (!this.match(tt.parenR)) { this.expect(tt.comma); } } if (this.eat(tt.ellipsis)) { - ret.rest = this.flowParseFunctionTypeParam(); + rest = this.flowParseFunctionTypeParam(); } - return ret; + return { params, rest }; } - flowIdentToTypeAnnotation(startPos, startLoc, node, id) { + flowIdentToTypeAnnotation(startPos: number, startLoc: Position, node: N.FlowTypeAnnotation, id: N.Identifier): N.FlowTypeAnnotation { switch (id.name) { case "any": return this.finishNode(node, "AnyTypeAnnotation"); @@ -746,7 +761,7 @@ export default (superClass) => class extends superClass { // The parsing of types roughly parallels the parsing of expressions, and // primary types are kind of like primary expressions...they're the // primitives with which other types are constructed. - flowParsePrimaryType() { + flowParsePrimaryType(): N.FlowTypeAnnotation { const startPos = this.state.start; const startLoc = this.state.startLoc; const node = this.startNode(); @@ -876,10 +891,10 @@ export default (superClass) => class extends superClass { } } - this.unexpected(); + throw this.unexpected(); } - flowParsePostfixType() { + flowParsePostfixType(): N.FlowTypeAnnotation { const startPos = this.state.start, startLoc = this.state.startLoc; let type = this.flowParsePrimaryType(); while (!this.canInsertSemicolon() && this.match(tt.bracketL)) { @@ -892,7 +907,7 @@ export default (superClass) => class extends superClass { return type; } - flowParsePrefixType() { + flowParsePrefixType(): N.FlowTypeAnnotation { const node = this.startNode(); if (this.eat(tt.question)) { node.typeAnnotation = this.flowParsePrefixType(); @@ -902,9 +917,10 @@ export default (superClass) => class extends superClass { } } - flowParseAnonFunctionWithoutParens() { + flowParseAnonFunctionWithoutParens(): N.FlowTypeAnnotation { const param = this.flowParsePrefixType(); if (!this.state.noAnonFunctionType && this.eat(tt.arrow)) { + // TODO: This should be a type error. Passing in a SourceLocation, and it expects a Position. const node = this.startNodeAt(param.start, param.loc); node.params = [this.reinterpretTypeAsFunctionTypeParam(param)]; node.rest = null; @@ -915,7 +931,7 @@ export default (superClass) => class extends superClass { return param; } - flowParseIntersectionType() { + flowParseIntersectionType(): N.FlowTypeAnnotation { const node = this.startNode(); this.eat(tt.bitwiseAND); const type = this.flowParseAnonFunctionWithoutParens(); @@ -926,7 +942,7 @@ export default (superClass) => class extends superClass { return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation"); } - flowParseUnionType() { + flowParseUnionType(): N.FlowTypeAnnotation { const node = this.startNode(); this.eat(tt.bitwiseOR); const type = this.flowParseIntersectionType(); @@ -937,7 +953,7 @@ export default (superClass) => class extends superClass { return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation"); } - flowParseType() { + flowParseType(): N.FlowTypeAnnotation { const oldInType = this.state.inType; this.state.inType = true; const type = this.flowParseUnionType(); @@ -945,13 +961,13 @@ export default (superClass) => class extends superClass { return type; } - flowParseTypeAnnotation() { + flowParseTypeAnnotation(): N.FlowTypeAnnotation { const node = this.startNode(); node.typeAnnotation = this.flowParseTypeInitialiser(); return this.finishNode(node, "TypeAnnotation"); } - flowParseTypeAnnotatableIdentifier() { + flowParseTypeAnnotatableIdentifier(): N.Identifier { const ident = this.flowParseRestrictedIdentifier(); if (this.match(tt.colon)) { ident.typeAnnotation = this.flowParseTypeAnnotation(); @@ -960,7 +976,7 @@ export default (superClass) => class extends superClass { return ident; } - typeCastToParameter(node) { + typeCastToParameter(node: N.Node): N.Node { node.expression.typeAnnotation = node.typeAnnotation; return this.finishNodeAt( @@ -971,7 +987,7 @@ export default (superClass) => class extends superClass { ); } - flowParseVariance() { + flowParseVariance(): ?N.FlowVariance { let variance = null; if (this.match(tt.plusMin)) { variance = this.startNode(); @@ -991,11 +1007,12 @@ export default (superClass) => class extends superClass { // ================================== // plain function return types: function name(): string {} - parseFunctionBody(node, allowExpression) { + parseFunctionBody(node: N.Function, allowExpression?: boolean): void { if (this.match(tt.colon) && !allowExpression) { // if allowExpression is true then we're parsing an arrow function and if // there's a return type then it's been handled elsewhere const typeNode = this.startNode(); + // $FlowFixMe (destructuring not yet supported) [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); node.returnType = typeNode.typeAnnotation @@ -1007,7 +1024,7 @@ export default (superClass) => class extends superClass { } // interfaces - parseStatement(declaration, topLevel) { + parseStatement(declaration: boolean, topLevel?: boolean): N.Statement { // strict mode handling of `interface` since it's a reserved word if (this.state.strict && this.match(tt.name) && this.state.value === "interface") { const node = this.startNode(); @@ -1019,7 +1036,7 @@ export default (superClass) => class extends superClass { } // declares, interfaces and type aliases - parseExpressionStatement(node, expr) { + parseExpressionStatement(node: N.ExpressionStatement, expr: N.Expression): N.ExpressionStatement { if (expr.type === "Identifier") { if (expr.name === "declare") { if (this.match(tt._class) || this.match(tt.name) || this.match(tt._function) || this.match(tt._var) || this.match(tt._export)) { @@ -1038,13 +1055,13 @@ export default (superClass) => class extends superClass { } // export type - shouldParseExportDeclaration() { + shouldParseExportDeclaration(): boolean { return this.isContextual("type") || this.isContextual("interface") || super.shouldParseExportDeclaration(); } - parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos) { + parseConditional(expr: N.Expression, noIn: ?boolean, startPos: number, startLoc: Position, refNeedsArrowPos?: Pos): N.Expression { // only do the expensive clone if there is a question mark // and if we come from inside parens if (refNeedsArrowPos && this.match(tt.question)) { @@ -1066,7 +1083,7 @@ export default (superClass) => class extends superClass { return super.parseConditional(expr, noIn, startPos, startLoc); } - parseParenItem(node, startPos, startLoc) { + parseParenItem(node: N.Expression, startPos: number, startLoc: Position): N.Expression { node = super.parseParenItem(node, startPos, startLoc); if (this.eat(tt.question)) { node.optional = true; @@ -1083,7 +1100,7 @@ export default (superClass) => class extends superClass { return node; } - parseExport(node) { + parseExport(node: N.ExportNamedDeclaration): N.ExportNamedDeclaration { node = super.parseExport(node); if (node.type === "ExportNamedDeclaration") { node.exportKind = node.exportKind || "value"; @@ -1091,7 +1108,7 @@ export default (superClass) => class extends superClass { return node; } - parseExportDeclaration(node) { + parseExportDeclaration(node: N.ExportNamedDeclaration): ?N.Declaration { if (this.isContextual("type")) { node.exportKind = "type"; @@ -1117,7 +1134,7 @@ export default (superClass) => class extends superClass { } } - parseClassId(node, ...args) { + parseClassId(node: N.Class, ...args) { super.parseClassId(node, ...args); if (this.isRelational("<")) { node.typeParameters = this.flowParseTypeParameterDeclaration(); @@ -1126,7 +1143,7 @@ export default (superClass) => class extends superClass { // don't consider `void` to be a keyword as then it'll use the void token type // and set startExpr - isKeyword(name) { + isKeyword(name: string): boolean { if (this.state.inType && name === "void") { return false; } else { @@ -1135,7 +1152,7 @@ export default (superClass) => class extends superClass { } // ensure that inside flow types, we bypass the jsx parser plugin - readToken(code) { + readToken(code: number): void { if (this.state.inType && (code === 62 || code === 60)) { return this.finishOp(tt.relational, 1); } else { @@ -1143,12 +1160,7 @@ export default (superClass) => class extends superClass { } } - // don't lex any token as a jsx one inside a flow type - jsx_readToken() { - if (!this.state.inType) return super.jsx_readToken(); - } - - toAssignable(node, isBinding, contextDescription) { + toAssignable(node: N.Node, isBinding: ?boolean, contextDescription: string): N.Node { if (node.type === "TypeCastExpression") { return super.toAssignable(this.typeCastToParameter(node), isBinding, contextDescription); } else { @@ -1157,7 +1169,7 @@ export default (superClass) => class extends superClass { } // turn type casts that we found in function parameter head into type annotated params - toAssignableList(exprList, isBinding, contextDescription) { + toAssignableList(exprList: N.Expression[], isBinding: ?boolean, contextDescription: string): $ReadOnlyArray { for (let i = 0; i < exprList.length; i++) { const expr = exprList[i]; if (expr && expr.type === "TypeCastExpression") { @@ -1169,7 +1181,7 @@ export default (superClass) => class extends superClass { // this is a list of nodes, from something like a call expression, we need to filter the // type casts that we've found that are illegal in this context - toReferencedList(exprList) { + toReferencedList(exprList: $ReadOnlyArray): $ReadOnlyArray { for (let i = 0; i < exprList.length; i++) { const expr = exprList[i]; if (expr && expr._exprListItem && expr.type === "TypeCastExpression") { @@ -1182,7 +1194,7 @@ export default (superClass) => class extends superClass { // parse an item inside a expression list eg. `(NODE, NODE)` where NODE represents // the position where this function is called - parseExprListItem(...args) { + parseExprListItem(...args): ?N.Expression { const container = this.startNode(); const node = super.parseExprListItem(...args); if (this.match(tt.colon)) { @@ -1195,14 +1207,14 @@ export default (superClass) => class extends superClass { } } - checkLVal(node, ...args) { + checkLVal(node: N.Expression, ...args): void { if (node.type !== "TypeCastExpression") { return super.checkLVal(node, ...args); } } // parse class property type annotations - parseClassProperty(node) { + parseClassProperty(node: N.ClassProperty): N.ClassProperty { if (this.match(tt.colon)) { node.typeAnnotation = this.flowParseTypeAnnotation(); } @@ -1210,17 +1222,17 @@ export default (superClass) => class extends superClass { } // determine whether or not we're currently in the position where a class method would appear - isClassMethod() { + isClassMethod(): boolean { return this.isRelational("<") || super.isClassMethod(); } // determine whether or not we're currently in the position where a class property would appear - isClassProperty() { + isClassProperty(): boolean { return this.match(tt.colon) || super.isClassProperty(); } // parse type parameters for class methods - parseClassMethod(classBody, method, ...args) { + parseClassMethod(classBody: N.ClassBody, method: N.ClassMethod, ...args): void { if (method.variance) { this.unexpected(method.variance.start); } @@ -1233,7 +1245,7 @@ export default (superClass) => class extends superClass { } // parse a the super class type parameters and implements - parseClassSuper(node, isStatement) { + parseClassSuper(node: N.Class, isStatement?: boolean): void { super.parseClassSuper(node, isStatement); if (node.superClass && this.isRelational("<")) { node.superTypeParameters = this.flowParseTypeParameterInstantiation(); @@ -1254,7 +1266,7 @@ export default (superClass) => class extends superClass { } } - parsePropertyName(node) { + parsePropertyName(node: N.ObjectMember): N.Identifier { const variance = this.flowParseVariance(); const key = super.parsePropertyName(node); node.variance = variance; @@ -1262,7 +1274,7 @@ export default (superClass) => class extends superClass { } // parse type parameters for object method shorthand - parseObjPropValue(prop, ...args) { + parseObjPropValue(prop: N.ObjectMember, ...args): void { if (prop.variance) { this.unexpected(prop.variance.start); } @@ -1280,11 +1292,12 @@ export default (superClass) => class extends superClass { // add typeParameters if we found them if (typeParameters) { + // $FlowFixMe (trying to set '.typeParameters' on an expression) (prop.value || prop).typeParameters = typeParameters; } } - parseAssignableListItemTypes(param) { + parseAssignableListItemTypes(param: N.Pattern): N.Pattern { if (this.eat(tt.question)) { param.optional = true; } @@ -1295,7 +1308,7 @@ export default (superClass) => class extends superClass { return param; } - parseMaybeDefault(...args) { + parseMaybeDefault(...args): N.Pattern { const node = super.parseMaybeDefault(...args); if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) { @@ -1306,7 +1319,7 @@ export default (superClass) => class extends superClass { } // parse typeof and type imports - parseImportSpecifiers(node) { + parseImportSpecifiers(node: N.ImportDeclaration): void { node.importKind = "value"; let kind = null; @@ -1327,7 +1340,7 @@ export default (superClass) => class extends superClass { } // parse import-type/typeof shorthand - parseImportSpecifier(node) { + parseImportSpecifier(node: N.ImportDeclaration): void { const specifier = this.startNode(); const firstIdentLoc = this.state.start; const firstIdent = this.parseIdentifier(true); @@ -1384,7 +1397,7 @@ export default (superClass) => class extends superClass { } // parse function type parameters - function foo() {} - parseFunctionParams(node) { + parseFunctionParams(node: N.NormalFunction): void { if (this.isRelational("<")) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } @@ -1392,7 +1405,7 @@ export default (superClass) => class extends superClass { } // parse flow type annotations on variable declarator heads - let foo: string = bar - parseVarHead(decl) { + parseVarHead(decl: N.VariableDeclarator): void { super.parseVarHead(decl); if (this.match(tt.colon)) { decl.id.typeAnnotation = this.flowParseTypeAnnotation(); @@ -1401,7 +1414,7 @@ export default (superClass) => class extends superClass { } // parse the return type of an async arrow function - let foo = (async (): number => {}); - parseAsyncArrowFromCallExpression(node, call) { + parseAsyncArrowFromCallExpression(node: N.ArrowFunctionExpression, call: N.CallExpression): N.ArrowFunctionExpression { if (this.match(tt.colon)) { const oldNoAnonFunctionType = this.state.noAnonFunctionType; this.state.noAnonFunctionType = true; @@ -1413,7 +1426,7 @@ export default (superClass) => class extends superClass { } // todo description - shouldParseAsyncArrow() { + shouldParseAsyncArrow(): boolean { return this.match(tt.colon) || super.shouldParseAsyncArrow(); } @@ -1427,7 +1440,7 @@ export default (superClass) => class extends superClass { // parse the rest, make sure the rest is an arrow function, and go from // there // 3. This is neither. Just call the super method - parseMaybeAssign(...args) { + parseMaybeAssign(...args): N.Expression { let jsxError = null; if (tt.jsxTagStart && this.match(tt.jsxTagStart)) { const state = this.state.clone(); @@ -1479,7 +1492,7 @@ export default (superClass) => class extends superClass { } // handle return types for arrow functions - parseArrow(node) { + parseArrow(node: N.ArrowFunctionExpression): ?N.ArrowFunctionExpression { if (this.match(tt.colon)) { const state = this.state.clone(); try { @@ -1487,6 +1500,7 @@ export default (superClass) => class extends superClass { this.state.noAnonFunctionType = true; const typeNode = this.startNode(); + // $FlowFixMe (destructuring not supported yet) [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); this.state.noAnonFunctionType = oldNoAnonFunctionType; @@ -1511,7 +1525,7 @@ export default (superClass) => class extends superClass { return super.parseArrow(node); } - shouldParseArrow() { + shouldParseArrow(): boolean { return this.match(tt.colon) || super.shouldParseArrow(); } }; diff --git a/src/types.js b/src/types.js index d7d4f388f5..b42f72a154 100644 --- a/src/types.js +++ b/src/types.js @@ -489,6 +489,7 @@ export type TemplateElement = NodeBase & { export type PatternBase = HasDecorators & { // Flow only: + optional?: true; typeAnnotation?: ?FlowTypeAnnotation; }; @@ -679,6 +680,7 @@ export type FlowType = Node; export type FlowPredicate = Node; export type FlowDeclare = Node; export type FlowDeclareClass = Node; +export type FlowDeclareExportDeclaration = Node; export type FlowDeclareFunction = Node; export type FlowDeclareVariable = Node; export type FlowDeclareModule = Node; @@ -694,6 +696,7 @@ export type FlowTypeParameterInstantiation = Node; export type FlowObjectTypeIndexer = Node; export type FlowFunctionTypeAnnotation = Node; export type FlowObjectTypeProperty = Node; +export type FlowObjectTypeSpreadProperty = Node; export type FlowObjectTypeCallProperty = Node; export type FlowObjectTypeAnnotation = Node; export type FlowQualifiedTypeIdentifier = Node; From 3a6b77f374763c0e7a348583f0f15f46854e5062 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 2 May 2017 11:37:58 -0700 Subject: [PATCH 28/73] Don't add 'await' property to ForInStatement (#504) --- src/parser/statement.js | 4 +++- test/fixtures/core/uncategorised/246/expected.json | 1 - test/fixtures/core/uncategorised/247/expected.json | 1 - test/fixtures/core/uncategorised/532/expected.json | 1 - test/fixtures/es2015/uncategorised/310/expected.json | 1 - test/fixtures/es2015/uncategorised/323/expected.json | 1 - .../esprima/es2015-object-pattern/empty-for-lex/expected.json | 1 - .../esprima/statement-iteration/const_forin/expected.json | 1 - .../esprima/statement-iteration/migrated_0017/expected.json | 1 - .../esprima/statement-iteration/migrated_0018/expected.json | 1 - .../esprima/statement-iteration/migrated_0020/expected.json | 1 - .../esprima/statement-iteration/migrated_0024/expected.json | 1 - .../esprima/statement-iteration/migrated_0025/expected.json | 1 - .../esprima/statement-iteration/migrated_0026/expected.json | 1 - 14 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/parser/statement.js b/src/parser/statement.js index 376c685147..53cbaacb77 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -535,7 +535,9 @@ export default class StatementParser extends ExpressionParser { } else { this.next(); } - node.await = !!forAwait; + if (type === "ForOfStatement") { + node.await = !!forAwait; + } node.left = init; node.right = this.parseExpression(); this.expect(tt.parenR); diff --git a/test/fixtures/core/uncategorised/246/expected.json b/test/fixtures/core/uncategorised/246/expected.json index 9c7cdebe0f..b49d510db1 100644 --- a/test/fixtures/core/uncategorised/246/expected.json +++ b/test/fixtures/core/uncategorised/246/expected.json @@ -42,7 +42,6 @@ "column": 26 } }, - "await": false, "left": { "type": "Identifier", "start": 4, diff --git a/test/fixtures/core/uncategorised/247/expected.json b/test/fixtures/core/uncategorised/247/expected.json index 4a3a0ecfda..59067a9ff1 100644 --- a/test/fixtures/core/uncategorised/247/expected.json +++ b/test/fixtures/core/uncategorised/247/expected.json @@ -42,7 +42,6 @@ "column": 31 } }, - "await": false, "left": { "type": "VariableDeclaration", "start": 5, diff --git a/test/fixtures/core/uncategorised/532/expected.json b/test/fixtures/core/uncategorised/532/expected.json index c86ced2dd6..20311af984 100644 --- a/test/fixtures/core/uncategorised/532/expected.json +++ b/test/fixtures/core/uncategorised/532/expected.json @@ -42,7 +42,6 @@ "column": 31 } }, - "await": false, "left": { "type": "VariableDeclaration", "start": 5, diff --git a/test/fixtures/es2015/uncategorised/310/expected.json b/test/fixtures/es2015/uncategorised/310/expected.json index facb5febd6..2e3b4faf28 100644 --- a/test/fixtures/es2015/uncategorised/310/expected.json +++ b/test/fixtures/es2015/uncategorised/310/expected.json @@ -42,7 +42,6 @@ "column": 21 } }, - "await": false, "left": { "type": "ObjectPattern", "start": 5, diff --git a/test/fixtures/es2015/uncategorised/323/expected.json b/test/fixtures/es2015/uncategorised/323/expected.json index 158a4615bd..b76d82ee86 100644 --- a/test/fixtures/es2015/uncategorised/323/expected.json +++ b/test/fixtures/es2015/uncategorised/323/expected.json @@ -42,7 +42,6 @@ "column": 33 } }, - "await": false, "left": { "type": "VariableDeclaration", "start": 5, diff --git a/test/fixtures/esprima/es2015-object-pattern/empty-for-lex/expected.json b/test/fixtures/esprima/es2015-object-pattern/empty-for-lex/expected.json index 69927b7511..85430cc73f 100644 --- a/test/fixtures/esprima/es2015-object-pattern/empty-for-lex/expected.json +++ b/test/fixtures/esprima/es2015-object-pattern/empty-for-lex/expected.json @@ -42,7 +42,6 @@ "column": 18 } }, - "await": false, "left": { "type": "VariableDeclaration", "start": 5, diff --git a/test/fixtures/esprima/statement-iteration/const_forin/expected.json b/test/fixtures/esprima/statement-iteration/const_forin/expected.json index aea7786f71..094cbea3c2 100644 --- a/test/fixtures/esprima/statement-iteration/const_forin/expected.json +++ b/test/fixtures/esprima/statement-iteration/const_forin/expected.json @@ -42,7 +42,6 @@ "column": 33 } }, - "await": false, "left": { "type": "VariableDeclaration", "start": 5, diff --git a/test/fixtures/esprima/statement-iteration/migrated_0017/expected.json b/test/fixtures/esprima/statement-iteration/migrated_0017/expected.json index 9c7cdebe0f..b49d510db1 100644 --- a/test/fixtures/esprima/statement-iteration/migrated_0017/expected.json +++ b/test/fixtures/esprima/statement-iteration/migrated_0017/expected.json @@ -42,7 +42,6 @@ "column": 26 } }, - "await": false, "left": { "type": "Identifier", "start": 4, diff --git a/test/fixtures/esprima/statement-iteration/migrated_0018/expected.json b/test/fixtures/esprima/statement-iteration/migrated_0018/expected.json index 4a3a0ecfda..59067a9ff1 100644 --- a/test/fixtures/esprima/statement-iteration/migrated_0018/expected.json +++ b/test/fixtures/esprima/statement-iteration/migrated_0018/expected.json @@ -42,7 +42,6 @@ "column": 31 } }, - "await": false, "left": { "type": "VariableDeclaration", "start": 5, diff --git a/test/fixtures/esprima/statement-iteration/migrated_0020/expected.json b/test/fixtures/esprima/statement-iteration/migrated_0020/expected.json index c86ced2dd6..20311af984 100644 --- a/test/fixtures/esprima/statement-iteration/migrated_0020/expected.json +++ b/test/fixtures/esprima/statement-iteration/migrated_0020/expected.json @@ -42,7 +42,6 @@ "column": 31 } }, - "await": false, "left": { "type": "VariableDeclaration", "start": 5, diff --git a/test/fixtures/esprima/statement-iteration/migrated_0024/expected.json b/test/fixtures/esprima/statement-iteration/migrated_0024/expected.json index 9bb6c3e3fc..739ce79307 100644 --- a/test/fixtures/esprima/statement-iteration/migrated_0024/expected.json +++ b/test/fixtures/esprima/statement-iteration/migrated_0024/expected.json @@ -42,7 +42,6 @@ "column": 21 } }, - "await": false, "left": { "type": "MemberExpression", "start": 5, diff --git a/test/fixtures/esprima/statement-iteration/migrated_0025/expected.json b/test/fixtures/esprima/statement-iteration/migrated_0025/expected.json index a50e44182a..190164f5b4 100644 --- a/test/fixtures/esprima/statement-iteration/migrated_0025/expected.json +++ b/test/fixtures/esprima/statement-iteration/migrated_0025/expected.json @@ -42,7 +42,6 @@ "column": 24 } }, - "await": false, "left": { "type": "MemberExpression", "start": 5, diff --git a/test/fixtures/esprima/statement-iteration/migrated_0026/expected.json b/test/fixtures/esprima/statement-iteration/migrated_0026/expected.json index dc3c4e3104..9cbe245b30 100644 --- a/test/fixtures/esprima/statement-iteration/migrated_0026/expected.json +++ b/test/fixtures/esprima/statement-iteration/migrated_0026/expected.json @@ -42,7 +42,6 @@ "column": 16 } }, - "await": false, "left": { "type": "MemberExpression", "start": 5, From 9660f06b25a4210ba0deade3854f9f9433814463 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 2 May 2017 11:39:21 -0700 Subject: [PATCH 29/73] Don't add 'shorthand' property to ObjectMethod (#506) --- src/parser/expression.js | 3 +- .../basic/shebang-object/expected.json | 2 +- .../core/uncategorised/22/expected.json | 2 +- .../core/uncategorised/23/expected.json | 2 +- .../core/uncategorised/24/expected.json | 2 +- .../core/uncategorised/25/expected.json | 2 +- .../core/uncategorised/26/expected.json | 2 +- .../core/uncategorised/27/expected.json | 2 +- .../core/uncategorised/275/expected.json | 2 +- .../core/uncategorised/28/expected.json | 4 +- .../core/uncategorised/29/expected.json | 1 - .../core/uncategorised/30/expected.json | 1 - .../core/uncategorised/31/expected.json | 1 - .../core/uncategorised/32/expected.json | 1 - .../core/uncategorised/33/expected.json | 1 - .../core/uncategorised/335/expected.json | 2 +- .../core/uncategorised/338/expected.json | 2 +- .../core/uncategorised/34/expected.json | 1 - .../core/uncategorised/35/expected.json | 1 - .../core/uncategorised/36/expected.json | 1 - .../core/uncategorised/37/expected.json | 1 - .../core/uncategorised/38/expected.json | 1 - .../core/uncategorised/39/expected.json | 1 - .../core/uncategorised/40/expected.json | 1 - .../core/uncategorised/41/expected.json | 1 - .../core/uncategorised/42/expected.json | 1 - .../core/uncategorised/43/expected.json | 1 - .../core/uncategorised/44/expected.json | 2 +- .../core/uncategorised/45/expected.json | 2 +- .../core/uncategorised/546/expected.json | 2 +- .../core/uncategorised/549/expected.json | 2 +- .../with-object/expected.json | 2 +- .../object-rest-spread/expected.json | 2 +- .../call-expression/expected.json | 2 +- .../expected.json | 52 +++++++++---------- .../es2015/regression/186/expected.json | 4 +- .../es2015/uncategorised/103/expected.json | 1 - .../es2015/uncategorised/141/expected.json | 2 +- .../es2015/uncategorised/142/expected.json | 2 +- .../es2015/uncategorised/143/expected.json | 2 +- .../es2015/uncategorised/144/expected.json | 4 +- .../es2015/uncategorised/145/expected.json | 2 - .../es2015/uncategorised/146/expected.json | 1 - .../es2015/uncategorised/147/expected.json | 4 +- .../es2015/uncategorised/148/expected.json | 2 +- .../es2015/uncategorised/149/expected.json | 1 - .../es2015/uncategorised/153/expected.json | 4 +- .../es2015/uncategorised/154/expected.json | 4 +- .../es2015/uncategorised/155/expected.json | 6 +-- .../es2015/uncategorised/156/expected.json | 5 +- .../es2015/uncategorised/157/expected.json | 4 +- .../es2015/uncategorised/158/expected.json | 4 +- .../es2015/uncategorised/161/expected.json | 2 +- .../es2015/uncategorised/162/expected.json | 1 - .../es2015/uncategorised/165/expected.json | 4 +- .../es2015/uncategorised/166/expected.json | 2 +- .../es2015/uncategorised/168/expected.json | 8 +-- .../es2015/uncategorised/170/expected.json | 4 +- .../es2015/uncategorised/172/expected.json | 8 +-- .../es2015/uncategorised/173/expected.json | 1 - .../es2015/uncategorised/174/expected.json | 1 - .../es2015/uncategorised/175/expected.json | 9 ++-- .../es2015/uncategorised/178/expected.json | 2 +- .../es2015/uncategorised/179/expected.json | 2 +- .../es2015/uncategorised/182/expected.json | 2 +- .../es2015/uncategorised/183/expected.json | 4 +- .../es2015/uncategorised/186/expected.json | 4 +- .../es2015/uncategorised/190/expected.json | 4 +- .../es2015/uncategorised/26/expected.json | 4 +- .../es2015/uncategorised/279/expected.json | 2 +- .../es2015/uncategorised/303/expected.json | 2 +- .../es2015/uncategorised/304/expected.json | 2 +- .../es2015/uncategorised/305/expected.json | 2 +- .../es2015/uncategorised/307/expected.json | 2 +- .../es2015/uncategorised/308/expected.json | 2 +- .../es2015/uncategorised/309/expected.json | 4 +- .../es2015/uncategorised/310/expected.json | 2 +- .../es2015/uncategorised/313/expected.json | 2 +- .../es2015/uncategorised/321/expected.json | 2 +- .../es2015/uncategorised/33/expected.json | 2 +- .../es2015/uncategorised/350/expected.json | 4 +- .../es2015/uncategorised/351/expected.json | 3 +- .../es2015/uncategorised/352/expected.json | 3 +- .../es2015/uncategorised/355/expected.json | 2 +- .../es2015/uncategorised/360/expected.json | 2 +- .../es2015/uncategorised/362/expected.json | 2 +- .../es2015/uncategorised/393/expected.json | 2 +- .../es2015/uncategorised/52/expected.json | 1 - .../es2015/uncategorised/53/expected.json | 1 - .../es2015/uncategorised/54/expected.json | 1 - .../es2015/uncategorised/55/expected.json | 1 - .../es2015/uncategorised/56/expected.json | 1 - .../es2015/uncategorised/61/expected.json | 4 +- .../es2015/uncategorised/63/expected.json | 2 +- .../es2015/uncategorised/65/expected.json | 2 +- .../es2015/uncategorised/67/expected.json | 2 +- .../es2015/uncategorised/69/expected.json | 2 +- .../es2015/uncategorised/70/expected.json | 2 +- .../es2015/uncategorised/71/expected.json | 2 +- .../es2017/async-functions/15/expected.json | 3 +- .../es2017/async-functions/23/expected.json | 2 +- .../es2017/async-functions/24/expected.json | 1 - .../es2017/async-functions/27/expected.json | 2 +- .../es2017/async-functions/28/expected.json | 2 +- .../es2017/async-functions/29/expected.json | 2 +- .../es2017/async-functions/30/expected.json | 2 +- .../es2017/async-functions/31/expected.json | 2 +- .../es2017/async-functions/32/expected.json | 2 +- .../es2017/async-functions/33/expected.json | 2 +- .../es2017/async-functions/34/expected.json | 2 +- .../es2017/async-functions/37/expected.json | 2 +- .../es2017/async-functions/38/expected.json | 2 +- .../es2017/async-functions/7/expected.json | 2 +- .../es2017/async-functions/8/expected.json | 2 +- .../patterned-catch/expected.json | 8 +-- .../with-object-pattern/expected.json | 2 +- .../migrated_0005/expected.json | 2 +- .../migrated_0002/expected.json | 2 +- .../nested-cover-grammar/expected.json | 2 +- .../nested-cover-grammar/expected.json | 2 +- .../object-pattern-assignment/expected.json | 14 ++--- .../export-default-object/expected.json | 2 +- .../for-of-object-pattern-const/expected.json | 4 +- .../for-of-object-pattern/expected.json | 4 +- .../expected.json | 1 - .../expected.json | 1 - .../expected.json | 1 - .../expected.json | 1 - .../expected.json | 1 - .../generator-method-with-yield/expected.json | 1 - .../generator-method/expected.json | 1 - .../migrated_0000/expected.json | 1 - .../migrated_0001/expected.json | 1 - .../migrated_0002/expected.json | 1 - .../migrated_0003/expected.json | 1 - .../migrated_0004/expected.json | 1 - .../expected.json | 4 +- .../proto-identifier-getter/expected.json | 3 +- .../proto-identifier-method/expected.json | 3 +- .../proto-identifier-setter/expected.json | 3 +- .../proto-literal-getter-setter/expected.json | 4 +- .../proto-literal-getter/expected.json | 3 +- .../proto-literal-method/expected.json | 3 +- .../proto-literal-setter/expected.json | 3 +- .../migrated_0000/expected.json | 4 +- .../elision/expected.json | 2 +- .../nested/expected.json | 2 +- .../properties/expected.json | 10 ++-- .../object-method/expected.json | 2 +- .../object-shorthand-method/expected.json | 1 - .../yield-binding-element/expected.json | 2 +- .../yield-binding-property/expected.json | 2 +- .../yield-generator-method/expected.json | 1 - .../expected.json | 2 +- .../es2015-yield/yield-method/expected.json | 1 - .../expected.json | 2 +- .../expected.json | 2 +- .../yield-strict-method/expected.json | 1 - .../arrow-rest-parameter-object/expected.json | 2 +- .../invalid-setter-rest/expected.json | 1 - .../object-method/expected.json | 2 +- .../object-shorthand-method/expected.json | 1 - .../rest-parameter-object/expected.json | 2 +- .../migrated_0002/expected.json | 2 +- .../estree/object-method/basic/expected.json | 1 - .../object-property/basic/expected.json | 2 +- .../object-default-params/expected.json | 2 +- .../object-method/expected.json | 1 - .../class-method-parameter/expected.json | 2 +- .../expected.json | 2 +- .../expected.json | 2 +- .../expected.json | 2 +- .../object-method-parameter/expected.json | 3 +- .../object-rest-spread/10/expected.json | 4 +- .../object-rest-spread/16/expected.json | 4 +- .../object-rest-spread/17/expected.json | 4 +- .../object-rest-spread/2/expected.json | 2 +- .../object-rest-spread/3/expected.json | 2 +- .../object-rest-spread/5/expected.json | 2 +- .../object-rest-spread/6/expected.json | 6 +-- .../uncategorised/39/expected.json | 2 +- .../uncategorised/49/expected.json | 2 +- .../flow/regression/issue-264/expected.json | 2 +- .../flow/type-annotations/107/expected.json | 2 +- .../flow/type-annotations/108/expected.json | 24 ++++----- .../flow/type-annotations/20/expected.json | 1 - .../flow/type-annotations/21/expected.json | 1 - .../flow/type-annotations/22/expected.json | 1 - .../flow/type-annotations/23/expected.json | 1 - .../flow/type-annotations/24/expected.json | 1 - .../flow/type-annotations/25/expected.json | 1 - .../flow/type-annotations/26/expected.json | 1 - .../flow/type-annotations/60/expected.json | 4 +- .../flow/type-annotations/61/expected.json | 4 +- .../flow/type-annotations/63/expected.json | 2 +- .../flow/type-annotations/97/expected.json | 2 +- .../flow/type-generics/1/expected.json | 2 +- .../expected.json | 1 - .../object-reserved-word/expected.json | 4 -- test/fixtures/flow/typecasts/2/expected.json | 4 +- test/fixtures/jsx/regression/3/expected.json | 2 +- .../expected.json | 6 +-- .../expected.json | 2 +- .../expected.json | 2 +- .../expected.json | 2 +- .../expected.json | 6 +-- .../expected.json | 6 +-- .../expected.json | 6 +-- .../expected.json | 12 ++--- .../expected.json | 6 +-- .../expected.json | 2 +- .../expected.json | 2 +- .../expected.json | 2 +- .../expected.json | 4 +- .../expected.json | 2 +- 215 files changed, 264 insertions(+), 340 deletions(-) diff --git a/src/parser/expression.js b/src/parser/expression.js index 168e595415..9afb11da4c 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -772,7 +772,6 @@ export default class ExpressionParser extends LValParser { } prop.method = false; - prop.shorthand = false; if (isPattern || refShorthandDefaultPos) { startPos = this.state.start; @@ -870,6 +869,8 @@ export default class ExpressionParser extends LValParser { } parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos) { + prop.shorthand = false; + if (this.eat(tt.colon)) { prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos); diff --git a/test/fixtures/comments/basic/shebang-object/expected.json b/test/fixtures/comments/basic/shebang-object/expected.json index 1d5ab8aced..ba246f1e89 100644 --- a/test/fixtures/comments/basic/shebang-object/expected.json +++ b/test/fixtures/comments/basic/shebang-object/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -107,6 +106,7 @@ "name": "spawn", "leadingComments": null }, + "shorthand": true, "value": { "type": "Identifier", "start": 33, diff --git a/test/fixtures/core/uncategorised/22/expected.json b/test/fixtures/core/uncategorised/22/expected.json index bc44d62df8..8a57b4b290 100644 --- a/test/fixtures/core/uncategorised/22/expected.json +++ b/test/fixtures/core/uncategorised/22/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "answer" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 14, diff --git a/test/fixtures/core/uncategorised/23/expected.json b/test/fixtures/core/uncategorised/23/expected.json index 8373348ba7..36656a5a0c 100644 --- a/test/fixtures/core/uncategorised/23/expected.json +++ b/test/fixtures/core/uncategorised/23/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "if" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 10, diff --git a/test/fixtures/core/uncategorised/24/expected.json b/test/fixtures/core/uncategorised/24/expected.json index 723c8db2a5..bf9211c537 100644 --- a/test/fixtures/core/uncategorised/24/expected.json +++ b/test/fixtures/core/uncategorised/24/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "true" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 12, diff --git a/test/fixtures/core/uncategorised/25/expected.json b/test/fixtures/core/uncategorised/25/expected.json index 1245b12ad3..72b5293e2e 100644 --- a/test/fixtures/core/uncategorised/25/expected.json +++ b/test/fixtures/core/uncategorised/25/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "false" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 13, diff --git a/test/fixtures/core/uncategorised/26/expected.json b/test/fixtures/core/uncategorised/26/expected.json index 17acbb207e..b3d2471ea3 100644 --- a/test/fixtures/core/uncategorised/26/expected.json +++ b/test/fixtures/core/uncategorised/26/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "null" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 12, diff --git a/test/fixtures/core/uncategorised/27/expected.json b/test/fixtures/core/uncategorised/27/expected.json index df92c26e13..390c389545 100644 --- a/test/fixtures/core/uncategorised/27/expected.json +++ b/test/fixtures/core/uncategorised/27/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "StringLiteral", @@ -126,6 +125,7 @@ }, "value": "answer" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 16, diff --git a/test/fixtures/core/uncategorised/275/expected.json b/test/fixtures/core/uncategorised/275/expected.json index e0ef904785..9c4a377caa 100644 --- a/test/fixtures/core/uncategorised/275/expected.json +++ b/test/fixtures/core/uncategorised/275/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "message" }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 17, diff --git a/test/fixtures/core/uncategorised/28/expected.json b/test/fixtures/core/uncategorised/28/expected.json index c3ee0acf14..96b5b5d4b5 100644 --- a/test/fixtures/core/uncategorised/28/expected.json +++ b/test/fixtures/core/uncategorised/28/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 9, @@ -159,7 +159,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -178,6 +177,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 15, diff --git a/test/fixtures/core/uncategorised/29/expected.json b/test/fixtures/core/uncategorised/29/expected.json index 057f1cf08d..f586ae626b 100644 --- a/test/fixtures/core/uncategorised/29/expected.json +++ b/test/fixtures/core/uncategorised/29/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/core/uncategorised/30/expected.json b/test/fixtures/core/uncategorised/30/expected.json index b2a8bf8168..e925ad0daf 100644 --- a/test/fixtures/core/uncategorised/30/expected.json +++ b/test/fixtures/core/uncategorised/30/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/core/uncategorised/31/expected.json b/test/fixtures/core/uncategorised/31/expected.json index 5b18965177..c5b5923ef9 100644 --- a/test/fixtures/core/uncategorised/31/expected.json +++ b/test/fixtures/core/uncategorised/31/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/core/uncategorised/32/expected.json b/test/fixtures/core/uncategorised/32/expected.json index 5ed0dee78e..338f19fb67 100644 --- a/test/fixtures/core/uncategorised/32/expected.json +++ b/test/fixtures/core/uncategorised/32/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/core/uncategorised/33/expected.json b/test/fixtures/core/uncategorised/33/expected.json index a0a3fa12fd..316ceff9fd 100644 --- a/test/fixtures/core/uncategorised/33/expected.json +++ b/test/fixtures/core/uncategorised/33/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/core/uncategorised/335/expected.json b/test/fixtures/core/uncategorised/335/expected.json index 7ecc877cd8..ebb58af9d2 100644 --- a/test/fixtures/core/uncategorised/335/expected.json +++ b/test/fixtures/core/uncategorised/335/expected.json @@ -100,7 +100,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -119,6 +118,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "ArrayExpression", "start": 5, diff --git a/test/fixtures/core/uncategorised/338/expected.json b/test/fixtures/core/uncategorised/338/expected.json index fe0875e9a4..625cf5776e 100644 --- a/test/fixtures/core/uncategorised/338/expected.json +++ b/test/fixtures/core/uncategorised/338/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "NumericLiteral", @@ -94,6 +93,7 @@ }, "value": 1 }, + "shorthand": false, "value": { "type": "BinaryExpression", "start": 5, diff --git a/test/fixtures/core/uncategorised/34/expected.json b/test/fixtures/core/uncategorised/34/expected.json index 5ccdf34d1e..ec8a378624 100644 --- a/test/fixtures/core/uncategorised/34/expected.json +++ b/test/fixtures/core/uncategorised/34/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/core/uncategorised/35/expected.json b/test/fixtures/core/uncategorised/35/expected.json index 36830ddf37..0a96220824 100644 --- a/test/fixtures/core/uncategorised/35/expected.json +++ b/test/fixtures/core/uncategorised/35/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "StringLiteral", diff --git a/test/fixtures/core/uncategorised/36/expected.json b/test/fixtures/core/uncategorised/36/expected.json index dfbd42e884..de643d969a 100644 --- a/test/fixtures/core/uncategorised/36/expected.json +++ b/test/fixtures/core/uncategorised/36/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "NumericLiteral", diff --git a/test/fixtures/core/uncategorised/37/expected.json b/test/fixtures/core/uncategorised/37/expected.json index 821787cfd7..43b7edb9d1 100644 --- a/test/fixtures/core/uncategorised/37/expected.json +++ b/test/fixtures/core/uncategorised/37/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/core/uncategorised/38/expected.json b/test/fixtures/core/uncategorised/38/expected.json index 8b525fb80c..e7c0af7521 100644 --- a/test/fixtures/core/uncategorised/38/expected.json +++ b/test/fixtures/core/uncategorised/38/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/core/uncategorised/39/expected.json b/test/fixtures/core/uncategorised/39/expected.json index 6d693c7fb0..bb18e63d32 100644 --- a/test/fixtures/core/uncategorised/39/expected.json +++ b/test/fixtures/core/uncategorised/39/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/core/uncategorised/40/expected.json b/test/fixtures/core/uncategorised/40/expected.json index 226cdce5f6..e14dc5c87f 100644 --- a/test/fixtures/core/uncategorised/40/expected.json +++ b/test/fixtures/core/uncategorised/40/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/core/uncategorised/41/expected.json b/test/fixtures/core/uncategorised/41/expected.json index 6fb466dce4..20b7295274 100644 --- a/test/fixtures/core/uncategorised/41/expected.json +++ b/test/fixtures/core/uncategorised/41/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/core/uncategorised/42/expected.json b/test/fixtures/core/uncategorised/42/expected.json index c0d601a0c6..3156d2e2ff 100644 --- a/test/fixtures/core/uncategorised/42/expected.json +++ b/test/fixtures/core/uncategorised/42/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "StringLiteral", diff --git a/test/fixtures/core/uncategorised/43/expected.json b/test/fixtures/core/uncategorised/43/expected.json index ef2d3f1eb7..5dcdec165e 100644 --- a/test/fixtures/core/uncategorised/43/expected.json +++ b/test/fixtures/core/uncategorised/43/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "NumericLiteral", diff --git a/test/fixtures/core/uncategorised/44/expected.json b/test/fixtures/core/uncategorised/44/expected.json index da5e30670e..b77f8b4535 100644 --- a/test/fixtures/core/uncategorised/44/expected.json +++ b/test/fixtures/core/uncategorised/44/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "get" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 11, diff --git a/test/fixtures/core/uncategorised/45/expected.json b/test/fixtures/core/uncategorised/45/expected.json index 36c20d4050..904dcf5112 100644 --- a/test/fixtures/core/uncategorised/45/expected.json +++ b/test/fixtures/core/uncategorised/45/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "set" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 11, diff --git a/test/fixtures/core/uncategorised/546/expected.json b/test/fixtures/core/uncategorised/546/expected.json index 9f7364ea93..de77ab2b95 100644 --- a/test/fixtures/core/uncategorised/546/expected.json +++ b/test/fixtures/core/uncategorised/546/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "public" }, + "shorthand": true, "value": { "type": "Identifier", "start": 8, diff --git a/test/fixtures/core/uncategorised/549/expected.json b/test/fixtures/core/uncategorised/549/expected.json index b604724403..088ba6a7ad 100644 --- a/test/fixtures/core/uncategorised/549/expected.json +++ b/test/fixtures/core/uncategorised/549/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "arguments" }, + "shorthand": true, "value": { "type": "Identifier", "start": 8, diff --git a/test/fixtures/es2015/array-rest-spread/with-object/expected.json b/test/fixtures/es2015/array-rest-spread/with-object/expected.json index bf10b699ac..b278aa92ef 100644 --- a/test/fixtures/es2015/array-rest-spread/with-object/expected.json +++ b/test/fixtures/es2015/array-rest-spread/with-object/expected.json @@ -116,7 +116,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -135,6 +134,7 @@ }, "name": "length" }, + "shorthand": true, "value": { "type": "Identifier", "start": 9, diff --git a/test/fixtures/es2015/arrow-functions/object-rest-spread/expected.json b/test/fixtures/es2015/arrow-functions/object-rest-spread/expected.json index 718795d103..0357f6b22e 100644 --- a/test/fixtures/es2015/arrow-functions/object-rest-spread/expected.json +++ b/test/fixtures/es2015/arrow-functions/object-rest-spread/expected.json @@ -123,7 +123,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -142,6 +141,7 @@ }, "name": "title" }, + "shorthand": true, "value": { "type": "Identifier", "start": 14, diff --git a/test/fixtures/es2015/computed-properties/call-expression/expected.json b/test/fixtures/es2015/computed-properties/call-expression/expected.json index 876a6855b0..779c7b6849 100644 --- a/test/fixtures/es2015/computed-properties/call-expression/expected.json +++ b/test/fixtures/es2015/computed-properties/call-expression/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "CallExpression", @@ -139,6 +138,7 @@ }, "arguments": [] }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 23, diff --git a/test/fixtures/es2015/modules/duplicate-named-export-destructuring/expected.json b/test/fixtures/es2015/modules/duplicate-named-export-destructuring/expected.json index 7b3fa80cce..e8a01c593c 100644 --- a/test/fixtures/es2015/modules/duplicate-named-export-destructuring/expected.json +++ b/test/fixtures/es2015/modules/duplicate-named-export-destructuring/expected.json @@ -103,7 +103,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -122,6 +121,7 @@ }, "name": "foo" }, + "shorthand": true, "value": { "type": "Identifier", "start": 15, @@ -242,7 +242,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -261,6 +260,7 @@ }, "name": "foo" }, + "shorthand": false, "value": { "type": "Identifier", "start": 48, @@ -378,7 +378,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -397,6 +396,7 @@ }, "name": "foo" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 82, @@ -427,7 +427,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -446,6 +445,7 @@ }, "name": "baz" }, + "shorthand": true, "value": { "type": "Identifier", "start": 84, @@ -569,7 +569,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -588,6 +587,7 @@ }, "name": "foo" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 119, @@ -618,7 +618,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -637,6 +636,7 @@ }, "name": "baz" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 127, @@ -667,7 +667,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -686,6 +685,7 @@ }, "name": "qux" }, + "shorthand": true, "value": { "type": "Identifier", "start": 129, @@ -812,7 +812,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -831,6 +830,7 @@ }, "name": "foo" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 166, @@ -861,7 +861,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -880,6 +879,7 @@ }, "name": "baz" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 174, @@ -910,7 +910,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -929,6 +928,7 @@ }, "name": "qux2" }, + "shorthand": true, "value": { "type": "Identifier", "start": 176, @@ -971,7 +971,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -990,6 +989,7 @@ }, "name": "foo3" }, + "shorthand": true, "value": { "type": "Identifier", "start": 186, @@ -1344,7 +1344,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1363,6 +1362,7 @@ }, "name": "foo" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 277, @@ -1430,7 +1430,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1449,6 +1448,7 @@ }, "name": "foo2" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 295, @@ -1585,7 +1585,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1604,6 +1603,7 @@ }, "name": "foo" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 332, @@ -1634,7 +1634,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1653,6 +1652,7 @@ }, "name": "baz" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 339, @@ -1683,7 +1683,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -1702,6 +1701,7 @@ }, "name": "qux3" }, + "shorthand": true, "value": { "type": "Identifier", "start": 341, @@ -1744,7 +1744,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1763,6 +1762,7 @@ }, "name": "foo2" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 357, @@ -1793,7 +1793,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1812,6 +1811,7 @@ }, "name": "baz2" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 365, @@ -1949,7 +1949,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1968,6 +1967,7 @@ }, "name": "foo" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 402, @@ -1998,7 +1998,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -2017,6 +2016,7 @@ }, "name": "baz" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 409, @@ -2047,7 +2047,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -2066,6 +2065,7 @@ }, "name": "qux5" }, + "shorthand": true, "value": { "type": "Identifier", "start": 411, @@ -2108,7 +2108,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -2127,6 +2126,7 @@ }, "name": "foo2" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 427, @@ -2157,7 +2157,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -2176,6 +2175,7 @@ }, "name": "baz2" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 435, @@ -2221,7 +2221,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -2240,6 +2239,7 @@ }, "name": "qux6" }, + "shorthand": true, "value": { "type": "Identifier", "start": 437, @@ -2368,7 +2368,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -2387,6 +2386,7 @@ }, "name": "Foo" }, + "shorthand": true, "value": { "type": "Identifier", "start": 469, @@ -2507,7 +2507,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -2526,6 +2525,7 @@ }, "name": "foo" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 502, diff --git a/test/fixtures/es2015/regression/186/expected.json b/test/fixtures/es2015/regression/186/expected.json index 080e9bbb8d..49b6d1aab0 100644 --- a/test/fixtures/es2015/regression/186/expected.json +++ b/test/fixtures/es2015/regression/186/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": true, "key": { "type": "Identifier", "start": 11, @@ -123,6 +122,7 @@ "name": "async" }, "computed": false, + "shorthand": true, "value": { "type": "Identifier", "start": 11, @@ -159,7 +159,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -178,6 +177,7 @@ }, "name": "bar" }, + "shorthand": true, "value": { "type": "Identifier", "start": 18, diff --git a/test/fixtures/es2015/uncategorised/103/expected.json b/test/fixtures/es2015/uncategorised/103/expected.json index fc3feab5f7..23040e20d4 100644 --- a/test/fixtures/es2015/uncategorised/103/expected.json +++ b/test/fixtures/es2015/uncategorised/103/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/es2015/uncategorised/141/expected.json b/test/fixtures/es2015/uncategorised/141/expected.json index eddaee3cad..fd69ba0ca6 100644 --- a/test/fixtures/es2015/uncategorised/141/expected.json +++ b/test/fixtures/es2015/uncategorised/141/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 7, diff --git a/test/fixtures/es2015/uncategorised/142/expected.json b/test/fixtures/es2015/uncategorised/142/expected.json index 15b8f684ff..15acdfd1ee 100644 --- a/test/fixtures/es2015/uncategorised/142/expected.json +++ b/test/fixtures/es2015/uncategorised/142/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "BinaryExpression", @@ -130,6 +129,7 @@ "value": "y" } }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 15, diff --git a/test/fixtures/es2015/uncategorised/143/expected.json b/test/fixtures/es2015/uncategorised/143/expected.json index aaa1c78fe5..6852b7e74c 100644 --- a/test/fixtures/es2015/uncategorised/143/expected.json +++ b/test/fixtures/es2015/uncategorised/143/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "FunctionExpression", "start": 7, diff --git a/test/fixtures/es2015/uncategorised/144/expected.json b/test/fixtures/es2015/uncategorised/144/expected.json index 3e8c0bd2cf..c484ee3622 100644 --- a/test/fixtures/es2015/uncategorised/144/expected.json +++ b/test/fixtures/es2015/uncategorised/144/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 7, @@ -127,7 +127,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -146,6 +145,7 @@ }, "name": "y" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 14, diff --git a/test/fixtures/es2015/uncategorised/145/expected.json b/test/fixtures/es2015/uncategorised/145/expected.json index 39d0f02fc4..b57ffb2797 100644 --- a/test/fixtures/es2015/uncategorised/145/expected.json +++ b/test/fixtures/es2015/uncategorised/145/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "Identifier", @@ -130,7 +129,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "Identifier", diff --git a/test/fixtures/es2015/uncategorised/146/expected.json b/test/fixtures/es2015/uncategorised/146/expected.json index 7c8df52528..5aab5e9622 100644 --- a/test/fixtures/es2015/uncategorised/146/expected.json +++ b/test/fixtures/es2015/uncategorised/146/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": true, "key": { "type": "Identifier", diff --git a/test/fixtures/es2015/uncategorised/147/expected.json b/test/fixtures/es2015/uncategorised/147/expected.json index 3605b59b78..9b0cfcecac 100644 --- a/test/fixtures/es2015/uncategorised/147/expected.json +++ b/test/fixtures/es2015/uncategorised/147/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "Identifier", "start": 10, @@ -156,7 +156,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -175,6 +174,7 @@ }, "name": "y" }, + "shorthand": true, "value": { "type": "Identifier", "start": 16, diff --git a/test/fixtures/es2015/uncategorised/148/expected.json b/test/fixtures/es2015/uncategorised/148/expected.json index dfea488504..35aa9b82e9 100644 --- a/test/fixtures/es2015/uncategorised/148/expected.json +++ b/test/fixtures/es2015/uncategorised/148/expected.json @@ -93,7 +93,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "Identifier", @@ -112,6 +111,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "Identifier", "start": 17, diff --git a/test/fixtures/es2015/uncategorised/149/expected.json b/test/fixtures/es2015/uncategorised/149/expected.json index 531feae88a..1bb1bd74da 100644 --- a/test/fixtures/es2015/uncategorised/149/expected.json +++ b/test/fixtures/es2015/uncategorised/149/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": true, "key": { "type": "Identifier", diff --git a/test/fixtures/es2015/uncategorised/153/expected.json b/test/fixtures/es2015/uncategorised/153/expected.json index 2876aa00ee..a371840ab6 100644 --- a/test/fixtures/es2015/uncategorised/153/expected.json +++ b/test/fixtures/es2015/uncategorised/153/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 12, @@ -179,7 +179,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -198,6 +197,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 21, diff --git a/test/fixtures/es2015/uncategorised/154/expected.json b/test/fixtures/es2015/uncategorised/154/expected.json index 47be23ad0b..5138fc882b 100644 --- a/test/fixtures/es2015/uncategorised/154/expected.json +++ b/test/fixtures/es2015/uncategorised/154/expected.json @@ -137,7 +137,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -156,6 +155,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 14, @@ -209,7 +209,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -228,6 +227,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 23, diff --git a/test/fixtures/es2015/uncategorised/155/expected.json b/test/fixtures/es2015/uncategorised/155/expected.json index 40fd9771cf..a35b2d27f2 100644 --- a/test/fixtures/es2015/uncategorised/155/expected.json +++ b/test/fixtures/es2015/uncategorised/155/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "f" }, + "shorthand": false, "value": { "type": "FunctionExpression", "start": 5, @@ -154,7 +154,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -173,6 +172,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 15, @@ -226,7 +226,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -245,6 +244,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 24, diff --git a/test/fixtures/es2015/uncategorised/156/expected.json b/test/fixtures/es2015/uncategorised/156/expected.json index 287d7e8771..f023b81a28 100644 --- a/test/fixtures/es2015/uncategorised/156/expected.json +++ b/test/fixtures/es2015/uncategorised/156/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -141,7 +140,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -160,6 +158,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 5, @@ -213,7 +212,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -232,6 +230,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 14, diff --git a/test/fixtures/es2015/uncategorised/157/expected.json b/test/fixtures/es2015/uncategorised/157/expected.json index 6075b1827f..2964c59783 100644 --- a/test/fixtures/es2015/uncategorised/157/expected.json +++ b/test/fixtures/es2015/uncategorised/157/expected.json @@ -156,7 +156,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -175,6 +174,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 11, @@ -228,7 +228,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -247,6 +246,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 20, diff --git a/test/fixtures/es2015/uncategorised/158/expected.json b/test/fixtures/es2015/uncategorised/158/expected.json index 88d65a30fb..a94e42c1d7 100644 --- a/test/fixtures/es2015/uncategorised/158/expected.json +++ b/test/fixtures/es2015/uncategorised/158/expected.json @@ -105,7 +105,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -124,6 +123,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 3, @@ -177,7 +177,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -196,6 +195,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 12, diff --git a/test/fixtures/es2015/uncategorised/161/expected.json b/test/fixtures/es2015/uncategorised/161/expected.json index 9d6157c40e..ef6bf56941 100644 --- a/test/fixtures/es2015/uncategorised/161/expected.json +++ b/test/fixtures/es2015/uncategorised/161/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "f" }, + "shorthand": false, "value": { "type": "FunctionExpression", "start": 9, diff --git a/test/fixtures/es2015/uncategorised/162/expected.json b/test/fixtures/es2015/uncategorised/162/expected.json index 7d167b78cf..11d3f9a875 100644 --- a/test/fixtures/es2015/uncategorised/162/expected.json +++ b/test/fixtures/es2015/uncategorised/162/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/es2015/uncategorised/165/expected.json b/test/fixtures/es2015/uncategorised/165/expected.json index f6be853aa4..c48f8c98ce 100644 --- a/test/fixtures/es2015/uncategorised/165/expected.json +++ b/test/fixtures/es2015/uncategorised/165/expected.json @@ -93,7 +93,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -112,6 +111,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 13, @@ -148,7 +148,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -167,6 +166,7 @@ }, "name": "b" }, + "shorthand": true, "value": { "type": "Identifier", "start": 16, diff --git a/test/fixtures/es2015/uncategorised/166/expected.json b/test/fixtures/es2015/uncategorised/166/expected.json index 4d1f380f71..5327aa282f 100644 --- a/test/fixtures/es2015/uncategorised/166/expected.json +++ b/test/fixtures/es2015/uncategorised/166/expected.json @@ -110,7 +110,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -129,6 +128,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 16, diff --git a/test/fixtures/es2015/uncategorised/168/expected.json b/test/fixtures/es2015/uncategorised/168/expected.json index 009f02d6c5..3fb28437fb 100644 --- a/test/fixtures/es2015/uncategorised/168/expected.json +++ b/test/fixtures/es2015/uncategorised/168/expected.json @@ -93,7 +93,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -112,6 +111,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 16, @@ -142,7 +142,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -161,6 +160,7 @@ }, "name": "w" }, + "shorthand": true, "value": { "type": "Identifier", "start": 18, @@ -197,7 +197,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -216,6 +215,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 21, @@ -255,7 +255,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -274,6 +273,7 @@ }, "name": "b" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 29, diff --git a/test/fixtures/es2015/uncategorised/170/expected.json b/test/fixtures/es2015/uncategorised/170/expected.json index 4053df70fa..6449d5ba66 100644 --- a/test/fixtures/es2015/uncategorised/170/expected.json +++ b/test/fixtures/es2015/uncategorised/170/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 14, @@ -162,7 +162,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -181,6 +180,7 @@ }, "name": "b" }, + "shorthand": true, "value": { "type": "Identifier", "start": 17, diff --git a/test/fixtures/es2015/uncategorised/172/expected.json b/test/fixtures/es2015/uncategorised/172/expected.json index 3f75c7c880..8e42ea2ca2 100644 --- a/test/fixtures/es2015/uncategorised/172/expected.json +++ b/test/fixtures/es2015/uncategorised/172/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 17, @@ -156,7 +156,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -175,6 +174,7 @@ }, "name": "w" }, + "shorthand": true, "value": { "type": "Identifier", "start": 19, @@ -211,7 +211,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -230,6 +229,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 22, @@ -269,7 +269,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -288,6 +287,7 @@ }, "name": "b" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 30, diff --git a/test/fixtures/es2015/uncategorised/173/expected.json b/test/fixtures/es2015/uncategorised/173/expected.json index 8cbad3c24a..f7c8cd58cb 100644 --- a/test/fixtures/es2015/uncategorised/173/expected.json +++ b/test/fixtures/es2015/uncategorised/173/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/es2015/uncategorised/174/expected.json b/test/fixtures/es2015/uncategorised/174/expected.json index f430150fa0..17308d92ca 100644 --- a/test/fixtures/es2015/uncategorised/174/expected.json +++ b/test/fixtures/es2015/uncategorised/174/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/es2015/uncategorised/175/expected.json b/test/fixtures/es2015/uncategorised/175/expected.json index 04aba9b49f..45eb4b22ff 100644 --- a/test/fixtures/es2015/uncategorised/175/expected.json +++ b/test/fixtures/es2015/uncategorised/175/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -127,7 +126,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -146,6 +144,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 10, @@ -176,7 +175,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -195,6 +193,7 @@ }, "name": "w" }, + "shorthand": true, "value": { "type": "Identifier", "start": 12, @@ -231,7 +230,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -250,6 +248,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 15, @@ -289,7 +288,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -308,6 +306,7 @@ }, "name": "b" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 23, diff --git a/test/fixtures/es2015/uncategorised/178/expected.json b/test/fixtures/es2015/uncategorised/178/expected.json index 1019f36221..ab295e9001 100644 --- a/test/fixtures/es2015/uncategorised/178/expected.json +++ b/test/fixtures/es2015/uncategorised/178/expected.json @@ -91,7 +91,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -110,6 +109,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 3, diff --git a/test/fixtures/es2015/uncategorised/179/expected.json b/test/fixtures/es2015/uncategorised/179/expected.json index 1483adeab3..db8d1a1658 100644 --- a/test/fixtures/es2015/uncategorised/179/expected.json +++ b/test/fixtures/es2015/uncategorised/179/expected.json @@ -91,7 +91,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -110,6 +109,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 3, diff --git a/test/fixtures/es2015/uncategorised/182/expected.json b/test/fixtures/es2015/uncategorised/182/expected.json index 403a007d36..6d952744d2 100644 --- a/test/fixtures/es2015/uncategorised/182/expected.json +++ b/test/fixtures/es2015/uncategorised/182/expected.json @@ -91,7 +91,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -110,6 +109,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 6, diff --git a/test/fixtures/es2015/uncategorised/183/expected.json b/test/fixtures/es2015/uncategorised/183/expected.json index e6a04cd66b..3acabbe14d 100644 --- a/test/fixtures/es2015/uncategorised/183/expected.json +++ b/test/fixtures/es2015/uncategorised/183/expected.json @@ -91,7 +91,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -110,6 +109,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "Identifier", "start": 6, @@ -143,7 +143,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -162,6 +161,7 @@ }, "name": "c" }, + "shorthand": true, "value": { "type": "Identifier", "start": 9, diff --git a/test/fixtures/es2015/uncategorised/186/expected.json b/test/fixtures/es2015/uncategorised/186/expected.json index 6164999ca8..b8a5b0f64f 100644 --- a/test/fixtures/es2015/uncategorised/186/expected.json +++ b/test/fixtures/es2015/uncategorised/186/expected.json @@ -102,7 +102,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -121,6 +120,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 3, @@ -157,7 +157,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -176,6 +175,7 @@ }, "name": "b" }, + "shorthand": true, "value": { "type": "Identifier", "start": 6, diff --git a/test/fixtures/es2015/uncategorised/190/expected.json b/test/fixtures/es2015/uncategorised/190/expected.json index 2968812946..ac1a13b3c2 100644 --- a/test/fixtures/es2015/uncategorised/190/expected.json +++ b/test/fixtures/es2015/uncategorised/190/expected.json @@ -102,7 +102,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -121,6 +120,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 7, @@ -157,7 +157,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -176,6 +175,7 @@ }, "name": "b" }, + "shorthand": true, "value": { "type": "Identifier", "start": 10, diff --git a/test/fixtures/es2015/uncategorised/26/expected.json b/test/fixtures/es2015/uncategorised/26/expected.json index b4c0e8bc2d..f5757a32bf 100644 --- a/test/fixtures/es2015/uncategorised/26/expected.json +++ b/test/fixtures/es2015/uncategorised/26/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "ObjectExpression", "start": 12, @@ -136,7 +136,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -155,6 +154,7 @@ }, "name": "y" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 16, diff --git a/test/fixtures/es2015/uncategorised/279/expected.json b/test/fixtures/es2015/uncategorised/279/expected.json index e2a39dc8b2..5703482a9a 100644 --- a/test/fixtures/es2015/uncategorised/279/expected.json +++ b/test/fixtures/es2015/uncategorised/279/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 16, diff --git a/test/fixtures/es2015/uncategorised/303/expected.json b/test/fixtures/es2015/uncategorised/303/expected.json index 935f87201b..668070027b 100644 --- a/test/fixtures/es2015/uncategorised/303/expected.json +++ b/test/fixtures/es2015/uncategorised/303/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "get" }, + "shorthand": true, "value": { "type": "Identifier", "start": 5, diff --git a/test/fixtures/es2015/uncategorised/304/expected.json b/test/fixtures/es2015/uncategorised/304/expected.json index 28602311f9..1f0a81aa3a 100644 --- a/test/fixtures/es2015/uncategorised/304/expected.json +++ b/test/fixtures/es2015/uncategorised/304/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "propName" }, + "shorthand": false, "value": { "type": "AssignmentPattern", "start": 15, diff --git a/test/fixtures/es2015/uncategorised/305/expected.json b/test/fixtures/es2015/uncategorised/305/expected.json index 2da5b72f13..65a3330a86 100644 --- a/test/fixtures/es2015/uncategorised/305/expected.json +++ b/test/fixtures/es2015/uncategorised/305/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "propName" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 5, diff --git a/test/fixtures/es2015/uncategorised/307/expected.json b/test/fixtures/es2015/uncategorised/307/expected.json index b4df0a2a30..26e8370e1b 100644 --- a/test/fixtures/es2015/uncategorised/307/expected.json +++ b/test/fixtures/es2015/uncategorised/307/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 2, diff --git a/test/fixtures/es2015/uncategorised/308/expected.json b/test/fixtures/es2015/uncategorised/308/expected.json index a983e9498e..b7295cf418 100644 --- a/test/fixtures/es2015/uncategorised/308/expected.json +++ b/test/fixtures/es2015/uncategorised/308/expected.json @@ -91,7 +91,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -110,6 +109,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 2, diff --git a/test/fixtures/es2015/uncategorised/309/expected.json b/test/fixtures/es2015/uncategorised/309/expected.json index adf09ef4d3..195565514b 100644 --- a/test/fixtures/es2015/uncategorised/309/expected.json +++ b/test/fixtures/es2015/uncategorised/309/expected.json @@ -119,7 +119,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -138,6 +137,7 @@ }, "name": "b" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 8, @@ -168,7 +168,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -187,6 +186,7 @@ }, "name": "c" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 9, diff --git a/test/fixtures/es2015/uncategorised/310/expected.json b/test/fixtures/es2015/uncategorised/310/expected.json index 2e3b4faf28..59105c1b3f 100644 --- a/test/fixtures/es2015/uncategorised/310/expected.json +++ b/test/fixtures/es2015/uncategorised/310/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 6, diff --git a/test/fixtures/es2015/uncategorised/313/expected.json b/test/fixtures/es2015/uncategorised/313/expected.json index 67a25aed7f..6c8963e87e 100644 --- a/test/fixtures/es2015/uncategorised/313/expected.json +++ b/test/fixtures/es2015/uncategorised/313/expected.json @@ -103,7 +103,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -122,6 +121,7 @@ }, "name": "message" }, + "shorthand": true, "value": { "type": "Identifier", "start": 15, diff --git a/test/fixtures/es2015/uncategorised/321/expected.json b/test/fixtures/es2015/uncategorised/321/expected.json index 0aed7ab433..2a3b5211e8 100644 --- a/test/fixtures/es2015/uncategorised/321/expected.json +++ b/test/fixtures/es2015/uncategorised/321/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 5, diff --git a/test/fixtures/es2015/uncategorised/33/expected.json b/test/fixtures/es2015/uncategorised/33/expected.json index 0931f56cf1..e493220b5c 100644 --- a/test/fixtures/es2015/uncategorised/33/expected.json +++ b/test/fixtures/es2015/uncategorised/33/expected.json @@ -109,7 +109,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -128,6 +127,7 @@ }, "name": "property" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 18, diff --git a/test/fixtures/es2015/uncategorised/350/expected.json b/test/fixtures/es2015/uncategorised/350/expected.json index e0f955220c..6c8ba6c0c7 100644 --- a/test/fixtures/es2015/uncategorised/350/expected.json +++ b/test/fixtures/es2015/uncategorised/350/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "StringLiteral", @@ -94,6 +93,7 @@ }, "value": "__proto__" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 18, @@ -130,7 +130,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -149,6 +148,7 @@ }, "name": "__proto__" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 32, diff --git a/test/fixtures/es2015/uncategorised/351/expected.json b/test/fixtures/es2015/uncategorised/351/expected.json index 2c0aacecab..40fd874fe3 100644 --- a/test/fixtures/es2015/uncategorised/351/expected.json +++ b/test/fixtures/es2015/uncategorised/351/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -166,7 +165,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -185,6 +183,7 @@ }, "name": "__proto__" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 40, diff --git a/test/fixtures/es2015/uncategorised/352/expected.json b/test/fixtures/es2015/uncategorised/352/expected.json index 8fc9a7d3a2..9430a3ea5b 100644 --- a/test/fixtures/es2015/uncategorised/352/expected.json +++ b/test/fixtures/es2015/uncategorised/352/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -166,7 +165,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -185,6 +183,7 @@ }, "name": "__proto__" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 44, diff --git a/test/fixtures/es2015/uncategorised/355/expected.json b/test/fixtures/es2015/uncategorised/355/expected.json index f916983e29..0081764853 100644 --- a/test/fixtures/es2015/uncategorised/355/expected.json +++ b/test/fixtures/es2015/uncategorised/355/expected.json @@ -93,7 +93,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -112,6 +111,7 @@ }, "name": "set" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 13, diff --git a/test/fixtures/es2015/uncategorised/360/expected.json b/test/fixtures/es2015/uncategorised/360/expected.json index 7afc6719a9..cfee130b5b 100644 --- a/test/fixtures/es2015/uncategorised/360/expected.json +++ b/test/fixtures/es2015/uncategorised/360/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "await" }, + "shorthand": true, "value": { "type": "Identifier", "start": 8, diff --git a/test/fixtures/es2015/uncategorised/362/expected.json b/test/fixtures/es2015/uncategorised/362/expected.json index 03eb6643e3..2f746e5bd4 100644 --- a/test/fixtures/es2015/uncategorised/362/expected.json +++ b/test/fixtures/es2015/uncategorised/362/expected.json @@ -93,7 +93,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -112,6 +111,7 @@ }, "name": "await" }, + "shorthand": true, "value": { "type": "Identifier", "start": 15, diff --git a/test/fixtures/es2015/uncategorised/393/expected.json b/test/fixtures/es2015/uncategorised/393/expected.json index 8a7f651b62..519d3d0d90 100644 --- a/test/fixtures/es2015/uncategorised/393/expected.json +++ b/test/fixtures/es2015/uncategorised/393/expected.json @@ -91,7 +91,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -110,6 +109,7 @@ }, "name": "set" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 2, diff --git a/test/fixtures/es2015/uncategorised/52/expected.json b/test/fixtures/es2015/uncategorised/52/expected.json index ce0016fdc3..9415c4be2b 100644 --- a/test/fixtures/es2015/uncategorised/52/expected.json +++ b/test/fixtures/es2015/uncategorised/52/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/es2015/uncategorised/53/expected.json b/test/fixtures/es2015/uncategorised/53/expected.json index 403f65e101..d5e9eb555e 100644 --- a/test/fixtures/es2015/uncategorised/53/expected.json +++ b/test/fixtures/es2015/uncategorised/53/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/es2015/uncategorised/54/expected.json b/test/fixtures/es2015/uncategorised/54/expected.json index cc11812169..879d54f7ee 100644 --- a/test/fixtures/es2015/uncategorised/54/expected.json +++ b/test/fixtures/es2015/uncategorised/54/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "StringLiteral", diff --git a/test/fixtures/es2015/uncategorised/55/expected.json b/test/fixtures/es2015/uncategorised/55/expected.json index a8769bfc25..a1a2904802 100644 --- a/test/fixtures/es2015/uncategorised/55/expected.json +++ b/test/fixtures/es2015/uncategorised/55/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/es2015/uncategorised/56/expected.json b/test/fixtures/es2015/uncategorised/56/expected.json index 98450690a7..947e572d5e 100644 --- a/test/fixtures/es2015/uncategorised/56/expected.json +++ b/test/fixtures/es2015/uncategorised/56/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/es2015/uncategorised/61/expected.json b/test/fixtures/es2015/uncategorised/61/expected.json index 17d1d997d4..620e423e0a 100644 --- a/test/fixtures/es2015/uncategorised/61/expected.json +++ b/test/fixtures/es2015/uncategorised/61/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "y" }, + "shorthand": true, "value": { "type": "Identifier", "start": 6, @@ -159,7 +159,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -178,6 +177,7 @@ }, "name": "z" }, + "shorthand": true, "value": { "type": "Identifier", "start": 9, diff --git a/test/fixtures/es2015/uncategorised/63/expected.json b/test/fixtures/es2015/uncategorised/63/expected.json index b52b7efed4..32c1f441a1 100644 --- a/test/fixtures/es2015/uncategorised/63/expected.json +++ b/test/fixtures/es2015/uncategorised/63/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 7, diff --git a/test/fixtures/es2015/uncategorised/65/expected.json b/test/fixtures/es2015/uncategorised/65/expected.json index 8f76a24663..1903ed8773 100644 --- a/test/fixtures/es2015/uncategorised/65/expected.json +++ b/test/fixtures/es2015/uncategorised/65/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 5, diff --git a/test/fixtures/es2015/uncategorised/67/expected.json b/test/fixtures/es2015/uncategorised/67/expected.json index f166d30898..553cd0a7b1 100644 --- a/test/fixtures/es2015/uncategorised/67/expected.json +++ b/test/fixtures/es2015/uncategorised/67/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 5, diff --git a/test/fixtures/es2015/uncategorised/69/expected.json b/test/fixtures/es2015/uncategorised/69/expected.json index d4b8dda2a4..87c594fbad 100644 --- a/test/fixtures/es2015/uncategorised/69/expected.json +++ b/test/fixtures/es2015/uncategorised/69/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "Identifier", "start": 9, diff --git a/test/fixtures/es2015/uncategorised/70/expected.json b/test/fixtures/es2015/uncategorised/70/expected.json index 6ae7f4bf7f..f19653b31b 100644 --- a/test/fixtures/es2015/uncategorised/70/expected.json +++ b/test/fixtures/es2015/uncategorised/70/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "Identifier", "start": 7, diff --git a/test/fixtures/es2015/uncategorised/71/expected.json b/test/fixtures/es2015/uncategorised/71/expected.json index 2175291efc..62072bc52e 100644 --- a/test/fixtures/es2015/uncategorised/71/expected.json +++ b/test/fixtures/es2015/uncategorised/71/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "Identifier", "start": 7, diff --git a/test/fixtures/es2017/async-functions/15/expected.json b/test/fixtures/es2017/async-functions/15/expected.json index fe07c7f6de..6e44684aa0 100644 --- a/test/fixtures/es2017/async-functions/15/expected.json +++ b/test/fixtures/es2017/async-functions/15/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 13, @@ -159,7 +159,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/es2017/async-functions/23/expected.json b/test/fixtures/es2017/async-functions/23/expected.json index 3890646e01..f645821c7e 100644 --- a/test/fixtures/es2017/async-functions/23/expected.json +++ b/test/fixtures/es2017/async-functions/23/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "key": { "type": "Identifier", "start": 12, @@ -123,6 +122,7 @@ "name": "async" }, "computed": false, + "shorthand": false, "value": { "type": "StringLiteral", "start": 19, diff --git a/test/fixtures/es2017/async-functions/24/expected.json b/test/fixtures/es2017/async-functions/24/expected.json index bdd29cecde..9f0d18451f 100644 --- a/test/fixtures/es2017/async-functions/24/expected.json +++ b/test/fixtures/es2017/async-functions/24/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "key": { "type": "Identifier", "start": 12, diff --git a/test/fixtures/es2017/async-functions/27/expected.json b/test/fixtures/es2017/async-functions/27/expected.json index 1e70bd9615..c22d0e642a 100644 --- a/test/fixtures/es2017/async-functions/27/expected.json +++ b/test/fixtures/es2017/async-functions/27/expected.json @@ -123,7 +123,6 @@ } }, "method": false, - "shorthand": true, "key": { "type": "Identifier", "start": 15, @@ -142,6 +141,7 @@ "name": "async" }, "computed": false, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 15, diff --git a/test/fixtures/es2017/async-functions/28/expected.json b/test/fixtures/es2017/async-functions/28/expected.json index d90f600a88..5542a1f7d0 100644 --- a/test/fixtures/es2017/async-functions/28/expected.json +++ b/test/fixtures/es2017/async-functions/28/expected.json @@ -123,7 +123,6 @@ } }, "method": false, - "shorthand": false, "key": { "type": "Identifier", "start": 15, @@ -142,6 +141,7 @@ "name": "async" }, "computed": false, + "shorthand": false, "value": { "type": "Identifier", "start": 22, diff --git a/test/fixtures/es2017/async-functions/29/expected.json b/test/fixtures/es2017/async-functions/29/expected.json index 2b1b294507..993df81280 100644 --- a/test/fixtures/es2017/async-functions/29/expected.json +++ b/test/fixtures/es2017/async-functions/29/expected.json @@ -123,7 +123,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -142,6 +141,7 @@ }, "name": "async" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 23, diff --git a/test/fixtures/es2017/async-functions/30/expected.json b/test/fixtures/es2017/async-functions/30/expected.json index 1aea157ede..0bb8a17387 100644 --- a/test/fixtures/es2017/async-functions/30/expected.json +++ b/test/fixtures/es2017/async-functions/30/expected.json @@ -123,7 +123,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -142,6 +141,7 @@ }, "name": "async" }, + "shorthand": false, "value": { "type": "Identifier", "start": 30, diff --git a/test/fixtures/es2017/async-functions/31/expected.json b/test/fixtures/es2017/async-functions/31/expected.json index b4f0aea8b8..1284053864 100644 --- a/test/fixtures/es2017/async-functions/31/expected.json +++ b/test/fixtures/es2017/async-functions/31/expected.json @@ -123,7 +123,6 @@ } }, "method": false, - "shorthand": false, "key": { "type": "Identifier", "start": 21, @@ -142,6 +141,7 @@ "name": "async" }, "computed": false, + "shorthand": false, "value": { "type": "Identifier", "start": 28, diff --git a/test/fixtures/es2017/async-functions/32/expected.json b/test/fixtures/es2017/async-functions/32/expected.json index 7cdfabffe3..7bdc1b1cbc 100644 --- a/test/fixtures/es2017/async-functions/32/expected.json +++ b/test/fixtures/es2017/async-functions/32/expected.json @@ -123,7 +123,6 @@ } }, "method": false, - "shorthand": true, "key": { "type": "Identifier", "start": 21, @@ -142,6 +141,7 @@ "name": "async" }, "computed": false, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 21, diff --git a/test/fixtures/es2017/async-functions/33/expected.json b/test/fixtures/es2017/async-functions/33/expected.json index a12a5ebf50..26698d24e6 100644 --- a/test/fixtures/es2017/async-functions/33/expected.json +++ b/test/fixtures/es2017/async-functions/33/expected.json @@ -123,7 +123,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -142,6 +141,7 @@ }, "name": "async" }, + "shorthand": false, "value": { "type": "Identifier", "start": 36, diff --git a/test/fixtures/es2017/async-functions/34/expected.json b/test/fixtures/es2017/async-functions/34/expected.json index ba2325893d..fe65e72356 100644 --- a/test/fixtures/es2017/async-functions/34/expected.json +++ b/test/fixtures/es2017/async-functions/34/expected.json @@ -123,7 +123,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -142,6 +141,7 @@ }, "name": "async" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 29, diff --git a/test/fixtures/es2017/async-functions/37/expected.json b/test/fixtures/es2017/async-functions/37/expected.json index 38c3a3e6f3..9904051f7a 100644 --- a/test/fixtures/es2017/async-functions/37/expected.json +++ b/test/fixtures/es2017/async-functions/37/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "async" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 8, diff --git a/test/fixtures/es2017/async-functions/38/expected.json b/test/fixtures/es2017/async-functions/38/expected.json index 8980e6eb41..ac62e0ad35 100644 --- a/test/fixtures/es2017/async-functions/38/expected.json +++ b/test/fixtures/es2017/async-functions/38/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "async" }, + "shorthand": false, "value": { "type": "Identifier", "start": 15, diff --git a/test/fixtures/es2017/async-functions/7/expected.json b/test/fixtures/es2017/async-functions/7/expected.json index a896663d5d..f4392f7f53 100644 --- a/test/fixtures/es2017/async-functions/7/expected.json +++ b/test/fixtures/es2017/async-functions/7/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": true, "key": { "type": "Identifier", "start": 6, @@ -123,6 +122,7 @@ "name": "async" }, "computed": false, + "shorthand": true, "value": { "type": "Identifier", "start": 6, diff --git a/test/fixtures/es2017/async-functions/8/expected.json b/test/fixtures/es2017/async-functions/8/expected.json index b1aba60ea4..7f51e9a3eb 100644 --- a/test/fixtures/es2017/async-functions/8/expected.json +++ b/test/fixtures/es2017/async-functions/8/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "async" }, + "shorthand": true, "value": { "type": "Identifier", "start": 7, diff --git a/test/fixtures/esprima/es2015-array-pattern/patterned-catch/expected.json b/test/fixtures/esprima/es2015-array-pattern/patterned-catch/expected.json index c9f2745187..7dfea8e34d 100644 --- a/test/fixtures/esprima/es2015-array-pattern/patterned-catch/expected.json +++ b/test/fixtures/esprima/es2015-array-pattern/patterned-catch/expected.json @@ -152,7 +152,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -171,6 +170,7 @@ }, "name": "c" }, + "shorthand": true, "value": { "type": "Identifier", "start": 21, @@ -207,7 +207,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -226,6 +225,7 @@ }, "name": "d" }, + "shorthand": false, "value": { "type": "AssignmentPattern", "start": 26, @@ -294,7 +294,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "Identifier", @@ -313,6 +312,7 @@ }, "name": "f" }, + "shorthand": false, "value": { "type": "AssignmentPattern", "start": 35, @@ -381,7 +381,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -400,6 +399,7 @@ }, "name": "h" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 40, diff --git a/test/fixtures/esprima/es2015-array-pattern/with-object-pattern/expected.json b/test/fixtures/esprima/es2015-array-pattern/with-object-pattern/expected.json index 7b5862ff98..dea5d68b0e 100644 --- a/test/fixtures/esprima/es2015-array-pattern/with-object-pattern/expected.json +++ b/test/fixtures/esprima/es2015-array-pattern/with-object-pattern/expected.json @@ -102,7 +102,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -121,6 +120,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 6, diff --git a/test/fixtures/esprima/es2015-arrow-function/migrated_0005/expected.json b/test/fixtures/esprima/es2015-arrow-function/migrated_0005/expected.json index 0931f56cf1..e493220b5c 100644 --- a/test/fixtures/esprima/es2015-arrow-function/migrated_0005/expected.json +++ b/test/fixtures/esprima/es2015-arrow-function/migrated_0005/expected.json @@ -109,7 +109,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -128,6 +127,7 @@ }, "name": "property" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 18, diff --git a/test/fixtures/esprima/es2015-default-parameter-value/migrated_0002/expected.json b/test/fixtures/esprima/es2015-default-parameter-value/migrated_0002/expected.json index 9d6157c40e..ef6bf56941 100644 --- a/test/fixtures/esprima/es2015-default-parameter-value/migrated_0002/expected.json +++ b/test/fixtures/esprima/es2015-default-parameter-value/migrated_0002/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "f" }, + "shorthand": false, "value": { "type": "FunctionExpression", "start": 9, diff --git a/test/fixtures/esprima/es2015-destructuring-assignment-array-pattern/nested-cover-grammar/expected.json b/test/fixtures/esprima/es2015-destructuring-assignment-array-pattern/nested-cover-grammar/expected.json index fc37f6abce..df55dfe4df 100644 --- a/test/fixtures/esprima/es2015-destructuring-assignment-array-pattern/nested-cover-grammar/expected.json +++ b/test/fixtures/esprima/es2015-destructuring-assignment-array-pattern/nested-cover-grammar/expected.json @@ -102,7 +102,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -121,6 +120,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 2, diff --git a/test/fixtures/esprima/es2015-destructuring-assignment-object-pattern/nested-cover-grammar/expected.json b/test/fixtures/esprima/es2015-destructuring-assignment-object-pattern/nested-cover-grammar/expected.json index 327467fdf6..ffcd88b46a 100644 --- a/test/fixtures/esprima/es2015-destructuring-assignment-object-pattern/nested-cover-grammar/expected.json +++ b/test/fixtures/esprima/es2015-destructuring-assignment-object-pattern/nested-cover-grammar/expected.json @@ -387,7 +387,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -406,6 +405,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 21, diff --git a/test/fixtures/esprima/es2015-destructuring-assignment-object-pattern/object-pattern-assignment/expected.json b/test/fixtures/esprima/es2015-destructuring-assignment-object-pattern/object-pattern-assignment/expected.json index 7bd635bfb1..14b57f257c 100644 --- a/test/fixtures/esprima/es2015-destructuring-assignment-object-pattern/object-pattern-assignment/expected.json +++ b/test/fixtures/esprima/es2015-destructuring-assignment-object-pattern/object-pattern-assignment/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 7, @@ -142,7 +142,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -161,6 +160,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "Identifier", "start": 16, @@ -194,7 +194,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -213,6 +212,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "AssignmentPattern", "start": 25, @@ -278,7 +278,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "Identifier", @@ -297,6 +296,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 38, @@ -327,7 +327,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -346,6 +345,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 39, @@ -385,7 +385,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -404,6 +403,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "MemberExpression", "start": 49, @@ -486,7 +486,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -505,6 +504,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "MemberExpression", "start": 71, diff --git a/test/fixtures/esprima/es2015-export-declaration/export-default-object/expected.json b/test/fixtures/esprima/es2015-export-declaration/export-default-object/expected.json index f9028639b0..e9316ee54f 100644 --- a/test/fixtures/esprima/es2015-export-declaration/export-default-object/expected.json +++ b/test/fixtures/esprima/es2015-export-declaration/export-default-object/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "foo" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 22, diff --git a/test/fixtures/esprima/es2015-for-of/for-of-object-pattern-const/expected.json b/test/fixtures/esprima/es2015-for-of/for-of-object-pattern-const/expected.json index 2f0291d7fa..f39a7f0e1d 100644 --- a/test/fixtures/esprima/es2015-for-of/for-of-object-pattern-const/expected.json +++ b/test/fixtures/esprima/es2015-for-of/for-of-object-pattern-const/expected.json @@ -102,7 +102,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -121,6 +120,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 12, @@ -157,7 +157,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -176,6 +175,7 @@ }, "name": "y" }, + "shorthand": true, "value": { "type": "Identifier", "start": 15, diff --git a/test/fixtures/esprima/es2015-for-of/for-of-object-pattern/expected.json b/test/fixtures/esprima/es2015-for-of/for-of-object-pattern/expected.json index a9ec1dc8a2..b0e0c85061 100644 --- a/test/fixtures/esprima/es2015-for-of/for-of-object-pattern/expected.json +++ b/test/fixtures/esprima/es2015-for-of/for-of-object-pattern/expected.json @@ -73,7 +73,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -92,6 +91,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 6, @@ -128,7 +128,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -147,6 +146,7 @@ }, "name": "y" }, + "shorthand": true, "value": { "type": "Identifier", "start": 9, diff --git a/test/fixtures/esprima/es2015-generator/generator-method-with-computed-name/expected.json b/test/fixtures/esprima/es2015-generator/generator-method-with-computed-name/expected.json index 820bf5831b..66422a0b0a 100644 --- a/test/fixtures/esprima/es2015-generator/generator-method-with-computed-name/expected.json +++ b/test/fixtures/esprima/es2015-generator/generator-method-with-computed-name/expected.json @@ -120,7 +120,6 @@ } }, "method": true, - "shorthand": false, "computed": true, "key": { "type": "YieldExpression", diff --git a/test/fixtures/esprima/es2015-generator/generator-method-with-params/expected.json b/test/fixtures/esprima/es2015-generator/generator-method-with-params/expected.json index 74705225ac..a45b9ad7f9 100644 --- a/test/fixtures/esprima/es2015-generator/generator-method-with-params/expected.json +++ b/test/fixtures/esprima/es2015-generator/generator-method-with-params/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-generator/generator-method-with-yield-delegate/expected.json b/test/fixtures/esprima/es2015-generator/generator-method-with-yield-delegate/expected.json index e002528905..2180fdc787 100644 --- a/test/fixtures/esprima/es2015-generator/generator-method-with-yield-delegate/expected.json +++ b/test/fixtures/esprima/es2015-generator/generator-method-with-yield-delegate/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-generator/generator-method-with-yield-expression/expected.json b/test/fixtures/esprima/es2015-generator/generator-method-with-yield-expression/expected.json index bbadbbe669..93a78ef520 100644 --- a/test/fixtures/esprima/es2015-generator/generator-method-with-yield-expression/expected.json +++ b/test/fixtures/esprima/es2015-generator/generator-method-with-yield-expression/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-generator/generator-method-with-yield-line-terminator/expected.json b/test/fixtures/esprima/es2015-generator/generator-method-with-yield-line-terminator/expected.json index d700b2546d..8d7abdba4a 100644 --- a/test/fixtures/esprima/es2015-generator/generator-method-with-yield-line-terminator/expected.json +++ b/test/fixtures/esprima/es2015-generator/generator-method-with-yield-line-terminator/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-generator/generator-method-with-yield/expected.json b/test/fixtures/esprima/es2015-generator/generator-method-with-yield/expected.json index addc5c802c..f4a5aa5272 100644 --- a/test/fixtures/esprima/es2015-generator/generator-method-with-yield/expected.json +++ b/test/fixtures/esprima/es2015-generator/generator-method-with-yield/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-generator/generator-method/expected.json b/test/fixtures/esprima/es2015-generator/generator-method/expected.json index 9b2aa0b7c9..808a6a8397 100644 --- a/test/fixtures/esprima/es2015-generator/generator-method/expected.json +++ b/test/fixtures/esprima/es2015-generator/generator-method/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-method-definition/migrated_0000/expected.json b/test/fixtures/esprima/es2015-method-definition/migrated_0000/expected.json index ce0016fdc3..9415c4be2b 100644 --- a/test/fixtures/esprima/es2015-method-definition/migrated_0000/expected.json +++ b/test/fixtures/esprima/es2015-method-definition/migrated_0000/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-method-definition/migrated_0001/expected.json b/test/fixtures/esprima/es2015-method-definition/migrated_0001/expected.json index 403f65e101..d5e9eb555e 100644 --- a/test/fixtures/esprima/es2015-method-definition/migrated_0001/expected.json +++ b/test/fixtures/esprima/es2015-method-definition/migrated_0001/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-method-definition/migrated_0002/expected.json b/test/fixtures/esprima/es2015-method-definition/migrated_0002/expected.json index cc11812169..879d54f7ee 100644 --- a/test/fixtures/esprima/es2015-method-definition/migrated_0002/expected.json +++ b/test/fixtures/esprima/es2015-method-definition/migrated_0002/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "StringLiteral", diff --git a/test/fixtures/esprima/es2015-method-definition/migrated_0003/expected.json b/test/fixtures/esprima/es2015-method-definition/migrated_0003/expected.json index a8769bfc25..a1a2904802 100644 --- a/test/fixtures/esprima/es2015-method-definition/migrated_0003/expected.json +++ b/test/fixtures/esprima/es2015-method-definition/migrated_0003/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-method-definition/migrated_0004/expected.json b/test/fixtures/esprima/es2015-method-definition/migrated_0004/expected.json index 98450690a7..947e572d5e 100644 --- a/test/fixtures/esprima/es2015-method-definition/migrated_0004/expected.json +++ b/test/fixtures/esprima/es2015-method-definition/migrated_0004/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-getter-setter/expected.json b/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-getter-setter/expected.json index 194bb1af4a..dbb75d94ab 100644 --- a/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-getter-setter/expected.json +++ b/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-getter-setter/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "__proto__" }, + "shorthand": false, "value": { "type": "NullLiteral", "start": 14, @@ -122,7 +122,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -180,7 +179,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-getter/expected.json b/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-getter/expected.json index 0cce78e2c4..cbfcf5f82e 100644 --- a/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-getter/expected.json +++ b/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-getter/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "__proto__" }, + "shorthand": false, "value": { "type": "NullLiteral", "start": 14, @@ -122,7 +122,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-method/expected.json b/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-method/expected.json index afab4b37f8..df65cc7cd9 100644 --- a/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-method/expected.json +++ b/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-method/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "__proto__" }, + "shorthand": false, "value": { "type": "NullLiteral", "start": 14, @@ -122,7 +122,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-setter/expected.json b/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-setter/expected.json index 920dce0155..0186c1bc41 100644 --- a/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-setter/expected.json +++ b/test/fixtures/esprima/es2015-object-initialiser/proto-identifier-setter/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "__proto__" }, + "shorthand": false, "value": { "type": "NullLiteral", "start": 14, @@ -122,7 +122,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-object-initialiser/proto-literal-getter-setter/expected.json b/test/fixtures/esprima/es2015-object-initialiser/proto-literal-getter-setter/expected.json index 82b235c2bb..e0fb06eef1 100644 --- a/test/fixtures/esprima/es2015-object-initialiser/proto-literal-getter-setter/expected.json +++ b/test/fixtures/esprima/es2015-object-initialiser/proto-literal-getter-setter/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "StringLiteral", @@ -94,6 +93,7 @@ }, "value": "__proto__" }, + "shorthand": false, "value": { "type": "NullLiteral", "start": 16, @@ -125,7 +125,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -183,7 +182,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-object-initialiser/proto-literal-getter/expected.json b/test/fixtures/esprima/es2015-object-initialiser/proto-literal-getter/expected.json index d5af9e236d..895e87a678 100644 --- a/test/fixtures/esprima/es2015-object-initialiser/proto-literal-getter/expected.json +++ b/test/fixtures/esprima/es2015-object-initialiser/proto-literal-getter/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "StringLiteral", @@ -94,6 +93,7 @@ }, "value": "__proto__" }, + "shorthand": false, "value": { "type": "NullLiteral", "start": 16, @@ -125,7 +125,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-object-initialiser/proto-literal-method/expected.json b/test/fixtures/esprima/es2015-object-initialiser/proto-literal-method/expected.json index b77f23777c..bb7f43d8a5 100644 --- a/test/fixtures/esprima/es2015-object-initialiser/proto-literal-method/expected.json +++ b/test/fixtures/esprima/es2015-object-initialiser/proto-literal-method/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "StringLiteral", @@ -94,6 +93,7 @@ }, "value": "__proto__" }, + "shorthand": false, "value": { "type": "NullLiteral", "start": 16, @@ -125,7 +125,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-object-initialiser/proto-literal-setter/expected.json b/test/fixtures/esprima/es2015-object-initialiser/proto-literal-setter/expected.json index 7efe87207c..3d984cf804 100644 --- a/test/fixtures/esprima/es2015-object-initialiser/proto-literal-setter/expected.json +++ b/test/fixtures/esprima/es2015-object-initialiser/proto-literal-setter/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "StringLiteral", @@ -94,6 +93,7 @@ }, "value": "__proto__" }, + "shorthand": false, "value": { "type": "NullLiteral", "start": 16, @@ -125,7 +125,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-object-literal-property-value-shorthand/migrated_0000/expected.json b/test/fixtures/esprima/es2015-object-literal-property-value-shorthand/migrated_0000/expected.json index 17d1d997d4..620e423e0a 100644 --- a/test/fixtures/esprima/es2015-object-literal-property-value-shorthand/migrated_0000/expected.json +++ b/test/fixtures/esprima/es2015-object-literal-property-value-shorthand/migrated_0000/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "y" }, + "shorthand": true, "value": { "type": "Identifier", "start": 6, @@ -159,7 +159,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -178,6 +177,7 @@ }, "name": "z" }, + "shorthand": true, "value": { "type": "Identifier", "start": 9, diff --git a/test/fixtures/esprima/es2015-object-pattern/elision/expected.json b/test/fixtures/esprima/es2015-object-pattern/elision/expected.json index 567e7248c2..6dcfe66427 100644 --- a/test/fixtures/esprima/es2015-object-pattern/elision/expected.json +++ b/test/fixtures/esprima/es2015-object-pattern/elision/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 5, diff --git a/test/fixtures/esprima/es2015-object-pattern/nested/expected.json b/test/fixtures/esprima/es2015-object-pattern/nested/expected.json index e4bc4272b8..5e1855da28 100644 --- a/test/fixtures/esprima/es2015-object-pattern/nested/expected.json +++ b/test/fixtures/esprima/es2015-object-pattern/nested/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 7, diff --git a/test/fixtures/esprima/es2015-object-pattern/properties/expected.json b/test/fixtures/esprima/es2015-object-pattern/properties/expected.json index 4fff32b6b5..8dde30d848 100644 --- a/test/fixtures/esprima/es2015-object-pattern/properties/expected.json +++ b/test/fixtures/esprima/es2015-object-pattern/properties/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 5, @@ -142,7 +142,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -161,6 +160,7 @@ }, "name": "b" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 7, @@ -232,7 +232,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -251,6 +250,7 @@ }, "name": "c" }, + "shorthand": false, "value": { "type": "Identifier", "start": 13, @@ -284,7 +284,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -303,6 +302,7 @@ }, "name": "e" }, + "shorthand": false, "value": { "type": "AssignmentPattern", "start": 17, @@ -371,7 +371,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "Identifier", @@ -390,6 +389,7 @@ }, "name": "g" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 25, diff --git a/test/fixtures/esprima/es2015-rest-parameter/object-method/expected.json b/test/fixtures/esprima/es2015-rest-parameter/object-method/expected.json index 44a231cab5..220cb767a5 100644 --- a/test/fixtures/esprima/es2015-rest-parameter/object-method/expected.json +++ b/test/fixtures/esprima/es2015-rest-parameter/object-method/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "f" }, + "shorthand": false, "value": { "type": "FunctionExpression", "start": 9, diff --git a/test/fixtures/esprima/es2015-rest-parameter/object-shorthand-method/expected.json b/test/fixtures/esprima/es2015-rest-parameter/object-shorthand-method/expected.json index 2d6b8d4961..158fdcac2a 100644 --- a/test/fixtures/esprima/es2015-rest-parameter/object-shorthand-method/expected.json +++ b/test/fixtures/esprima/es2015-rest-parameter/object-shorthand-method/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-yield/yield-binding-element/expected.json b/test/fixtures/esprima/es2015-yield/yield-binding-element/expected.json index 3cf2edca58..21e8a75108 100644 --- a/test/fixtures/esprima/es2015-yield/yield-binding-element/expected.json +++ b/test/fixtures/esprima/es2015-yield/yield-binding-element/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "Identifier", "start": 9, diff --git a/test/fixtures/esprima/es2015-yield/yield-binding-property/expected.json b/test/fixtures/esprima/es2015-yield/yield-binding-property/expected.json index 0799aa00f4..185e1b80fc 100644 --- a/test/fixtures/esprima/es2015-yield/yield-binding-property/expected.json +++ b/test/fixtures/esprima/es2015-yield/yield-binding-property/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "yield" }, + "shorthand": false, "value": { "type": "Identifier", "start": 13, diff --git a/test/fixtures/esprima/es2015-yield/yield-generator-method/expected.json b/test/fixtures/esprima/es2015-yield/yield-generator-method/expected.json index 9625fd5709..79c30e517e 100644 --- a/test/fixtures/esprima/es2015-yield/yield-generator-method/expected.json +++ b/test/fixtures/esprima/es2015-yield/yield-generator-method/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-yield/yield-generator-parameter-object-pattern/expected.json b/test/fixtures/esprima/es2015-yield/yield-generator-parameter-object-pattern/expected.json index ac7d7b8b51..4ede8e5d8e 100644 --- a/test/fixtures/esprima/es2015-yield/yield-generator-parameter-object-pattern/expected.json +++ b/test/fixtures/esprima/es2015-yield/yield-generator-parameter-object-pattern/expected.json @@ -93,7 +93,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -112,6 +111,7 @@ }, "name": "yield" }, + "shorthand": false, "value": { "type": "Identifier", "start": 20, diff --git a/test/fixtures/esprima/es2015-yield/yield-method/expected.json b/test/fixtures/esprima/es2015-yield/yield-method/expected.json index b10ddb8590..0e9ebaaa33 100644 --- a/test/fixtures/esprima/es2015-yield/yield-method/expected.json +++ b/test/fixtures/esprima/es2015-yield/yield-method/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/es2015-yield/yield-parameter-object-pattern/expected.json b/test/fixtures/esprima/es2015-yield/yield-parameter-object-pattern/expected.json index b5c586eeee..e16e19c653 100644 --- a/test/fixtures/esprima/es2015-yield/yield-parameter-object-pattern/expected.json +++ b/test/fixtures/esprima/es2015-yield/yield-parameter-object-pattern/expected.json @@ -93,7 +93,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -112,6 +111,7 @@ }, "name": "yield" }, + "shorthand": false, "value": { "type": "Identifier", "start": 19, diff --git a/test/fixtures/esprima/es2015-yield/yield-strict-binding-property/expected.json b/test/fixtures/esprima/es2015-yield/yield-strict-binding-property/expected.json index d88ed08060..0a5773facc 100644 --- a/test/fixtures/esprima/es2015-yield/yield-strict-binding-property/expected.json +++ b/test/fixtures/esprima/es2015-yield/yield-strict-binding-property/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "yield" }, + "shorthand": false, "value": { "type": "Identifier", "start": 27, diff --git a/test/fixtures/esprima/es2015-yield/yield-strict-method/expected.json b/test/fixtures/esprima/es2015-yield/yield-strict-method/expected.json index bf006185f0..e3f77abfeb 100644 --- a/test/fixtures/esprima/es2015-yield/yield-strict-method/expected.json +++ b/test/fixtures/esprima/es2015-yield/yield-strict-method/expected.json @@ -72,7 +72,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/rest-parameter/arrow-rest-parameter-object/expected.json b/test/fixtures/esprima/rest-parameter/arrow-rest-parameter-object/expected.json index ea2b1244f6..3ab154002e 100644 --- a/test/fixtures/esprima/rest-parameter/arrow-rest-parameter-object/expected.json +++ b/test/fixtures/esprima/rest-parameter/arrow-rest-parameter-object/expected.json @@ -122,7 +122,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -141,6 +140,7 @@ }, "name": "b" }, + "shorthand": true, "value": { "type": "Identifier", "start": 8, diff --git a/test/fixtures/esprima/rest-parameter/invalid-setter-rest/expected.json b/test/fixtures/esprima/rest-parameter/invalid-setter-rest/expected.json index 06e1f71eea..7ca9b46fe2 100644 --- a/test/fixtures/esprima/rest-parameter/invalid-setter-rest/expected.json +++ b/test/fixtures/esprima/rest-parameter/invalid-setter-rest/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/rest-parameter/object-method/expected.json b/test/fixtures/esprima/rest-parameter/object-method/expected.json index 44a231cab5..220cb767a5 100644 --- a/test/fixtures/esprima/rest-parameter/object-method/expected.json +++ b/test/fixtures/esprima/rest-parameter/object-method/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "f" }, + "shorthand": false, "value": { "type": "FunctionExpression", "start": 9, diff --git a/test/fixtures/esprima/rest-parameter/object-shorthand-method/expected.json b/test/fixtures/esprima/rest-parameter/object-shorthand-method/expected.json index 2d6b8d4961..158fdcac2a 100644 --- a/test/fixtures/esprima/rest-parameter/object-shorthand-method/expected.json +++ b/test/fixtures/esprima/rest-parameter/object-shorthand-method/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/esprima/rest-parameter/rest-parameter-object/expected.json b/test/fixtures/esprima/rest-parameter/rest-parameter-object/expected.json index 2d0c8bee41..42ce27cb2a 100644 --- a/test/fixtures/esprima/rest-parameter/rest-parameter-object/expected.json +++ b/test/fixtures/esprima/rest-parameter/rest-parameter-object/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 15, diff --git a/test/fixtures/esprima/statement-throw/migrated_0002/expected.json b/test/fixtures/esprima/statement-throw/migrated_0002/expected.json index e0ef904785..9c4a377caa 100644 --- a/test/fixtures/esprima/statement-throw/migrated_0002/expected.json +++ b/test/fixtures/esprima/statement-throw/migrated_0002/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "message" }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 17, diff --git a/test/fixtures/estree/object-method/basic/expected.json b/test/fixtures/estree/object-method/basic/expected.json index 03f4b2182c..b432d8ad2d 100644 --- a/test/fixtures/estree/object-method/basic/expected.json +++ b/test/fixtures/estree/object-method/basic/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/estree/object-property/basic/expected.json b/test/fixtures/estree/object-property/basic/expected.json index 650d82af47..c2051e303a 100644 --- a/test/fixtures/estree/object-property/basic/expected.json +++ b/test/fixtures/estree/object-property/basic/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "foo" }, + "shorthand": false, "value": { "type": "Literal", "start": 17, diff --git a/test/fixtures/experimental/async-functions/object-default-params/expected.json b/test/fixtures/experimental/async-functions/object-default-params/expected.json index cc01a02977..300d135dc2 100644 --- a/test/fixtures/experimental/async-functions/object-default-params/expected.json +++ b/test/fixtures/experimental/async-functions/object-default-params/expected.json @@ -123,7 +123,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -142,6 +141,7 @@ }, "name": "bar" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 18, diff --git a/test/fixtures/experimental/async-generators/object-method/expected.json b/test/fixtures/experimental/async-generators/object-method/expected.json index 79413a2d47..24a82e11c9 100644 --- a/test/fixtures/experimental/async-generators/object-method/expected.json +++ b/test/fixtures/experimental/async-generators/object-method/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/experimental/decorators/class-method-parameter/expected.json b/test/fixtures/experimental/decorators/class-method-parameter/expected.json index 4a401fa758..4fa42e9a70 100644 --- a/test/fixtures/experimental/decorators/class-method-parameter/expected.json +++ b/test/fixtures/experimental/decorators/class-method-parameter/expected.json @@ -274,7 +274,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -293,6 +292,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 46, diff --git a/test/fixtures/experimental/decorators/export-default-declaration-function-declaration-parameter/expected.json b/test/fixtures/experimental/decorators/export-default-declaration-function-declaration-parameter/expected.json index a936f5fee4..e52e8cbb64 100644 --- a/test/fixtures/experimental/decorators/export-default-declaration-function-declaration-parameter/expected.json +++ b/test/fixtures/experimental/decorators/export-default-declaration-function-declaration-parameter/expected.json @@ -237,7 +237,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -256,6 +255,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 49, diff --git a/test/fixtures/experimental/decorators/function-declaration-parameter/expected.json b/test/fixtures/experimental/decorators/function-declaration-parameter/expected.json index 2949fbdb5c..2c9ec156dd 100644 --- a/test/fixtures/experimental/decorators/function-declaration-parameter/expected.json +++ b/test/fixtures/experimental/decorators/function-declaration-parameter/expected.json @@ -223,7 +223,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -242,6 +241,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 34, diff --git a/test/fixtures/experimental/decorators/function-expression-parameter/expected.json b/test/fixtures/experimental/decorators/function-expression-parameter/expected.json index 652a728e04..32b529a664 100644 --- a/test/fixtures/experimental/decorators/function-expression-parameter/expected.json +++ b/test/fixtures/experimental/decorators/function-expression-parameter/expected.json @@ -253,7 +253,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -272,6 +271,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 43, diff --git a/test/fixtures/experimental/decorators/object-method-parameter/expected.json b/test/fixtures/experimental/decorators/object-method-parameter/expected.json index 5a22cd58ee..d0ec8b5295 100644 --- a/test/fixtures/experimental/decorators/object-method-parameter/expected.json +++ b/test/fixtures/experimental/decorators/object-method-parameter/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -289,7 +288,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -308,6 +306,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 41, diff --git a/test/fixtures/experimental/object-rest-spread/10/expected.json b/test/fixtures/experimental/object-rest-spread/10/expected.json index bce210e65b..169e1ee02d 100644 --- a/test/fixtures/experimental/object-rest-spread/10/expected.json +++ b/test/fixtures/experimental/object-rest-spread/10/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 6, @@ -142,7 +142,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -161,6 +160,7 @@ }, "name": "y" }, + "shorthand": true, "value": { "type": "Identifier", "start": 9, diff --git a/test/fixtures/experimental/object-rest-spread/16/expected.json b/test/fixtures/experimental/object-rest-spread/16/expected.json index cd68bed7a3..317f0a9f5d 100644 --- a/test/fixtures/experimental/object-rest-spread/16/expected.json +++ b/test/fixtures/experimental/object-rest-spread/16/expected.json @@ -116,7 +116,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -135,6 +134,7 @@ }, "name": "z" }, + "shorthand": true, "value": { "type": "Identifier", "start": 9, @@ -191,7 +191,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -210,6 +209,7 @@ }, "name": "z" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 20, diff --git a/test/fixtures/experimental/object-rest-spread/17/expected.json b/test/fixtures/experimental/object-rest-spread/17/expected.json index c6d9695d8b..a37ac1e771 100644 --- a/test/fixtures/experimental/object-rest-spread/17/expected.json +++ b/test/fixtures/experimental/object-rest-spread/17/expected.json @@ -116,7 +116,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -135,6 +134,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 11, @@ -226,7 +226,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -245,6 +244,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 28, diff --git a/test/fixtures/experimental/object-rest-spread/2/expected.json b/test/fixtures/experimental/object-rest-spread/2/expected.json index 77ad59f8cb..f03eed64e8 100644 --- a/test/fixtures/experimental/object-rest-spread/2/expected.json +++ b/test/fixtures/experimental/object-rest-spread/2/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 5, diff --git a/test/fixtures/experimental/object-rest-spread/3/expected.json b/test/fixtures/experimental/object-rest-spread/3/expected.json index bb0cd7a162..4de6807268 100644 --- a/test/fixtures/experimental/object-rest-spread/3/expected.json +++ b/test/fixtures/experimental/object-rest-spread/3/expected.json @@ -91,7 +91,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -110,6 +109,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 11, diff --git a/test/fixtures/experimental/object-rest-spread/5/expected.json b/test/fixtures/experimental/object-rest-spread/5/expected.json index efbc0e3f05..edfb47e37b 100644 --- a/test/fixtures/experimental/object-rest-spread/5/expected.json +++ b/test/fixtures/experimental/object-rest-spread/5/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -123,6 +122,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 5, diff --git a/test/fixtures/experimental/object-rest-spread/6/expected.json b/test/fixtures/experimental/object-rest-spread/6/expected.json index 0584ebbbe7..b6b781d209 100644 --- a/test/fixtures/experimental/object-rest-spread/6/expected.json +++ b/test/fixtures/experimental/object-rest-spread/6/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 2, @@ -159,7 +159,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -178,6 +177,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 11, @@ -246,7 +246,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -265,6 +264,7 @@ }, "name": "c" }, + "shorthand": true, "value": { "type": "Identifier", "start": 20, diff --git a/test/fixtures/experimental/uncategorised/39/expected.json b/test/fixtures/experimental/uncategorised/39/expected.json index 29893aa8b2..3988cde402 100644 --- a/test/fixtures/experimental/uncategorised/39/expected.json +++ b/test/fixtures/experimental/uncategorised/39/expected.json @@ -153,7 +153,6 @@ } ], "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -172,6 +171,7 @@ }, "name": "foo" }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 17, diff --git a/test/fixtures/experimental/uncategorised/49/expected.json b/test/fixtures/experimental/uncategorised/49/expected.json index a339588287..a222166ebe 100644 --- a/test/fixtures/experimental/uncategorised/49/expected.json +++ b/test/fixtures/experimental/uncategorised/49/expected.json @@ -138,7 +138,6 @@ } ], "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -157,6 +156,7 @@ }, "name": "bar" }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 22, diff --git a/test/fixtures/flow/regression/issue-264/expected.json b/test/fixtures/flow/regression/issue-264/expected.json index ca0f1791c7..ae189190fc 100644 --- a/test/fixtures/flow/regression/issue-264/expected.json +++ b/test/fixtures/flow/regression/issue-264/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": true, "key": { "type": "BinaryExpression", @@ -159,6 +158,7 @@ "value": 17 } }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 30, diff --git a/test/fixtures/flow/type-annotations/107/expected.json b/test/fixtures/flow/type-annotations/107/expected.json index 9f972ee738..c077e69e8d 100644 --- a/test/fixtures/flow/type-annotations/107/expected.json +++ b/test/fixtures/flow/type-annotations/107/expected.json @@ -137,7 +137,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -156,6 +155,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 11, diff --git a/test/fixtures/flow/type-annotations/108/expected.json b/test/fixtures/flow/type-annotations/108/expected.json index 54aad24d12..9e8df837d4 100644 --- a/test/fixtures/flow/type-annotations/108/expected.json +++ b/test/fixtures/flow/type-annotations/108/expected.json @@ -241,7 +241,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -260,6 +259,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 42, @@ -296,7 +296,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -315,6 +314,7 @@ }, "name": "y" }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 48, @@ -555,7 +555,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -574,6 +573,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 100, @@ -610,7 +610,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -629,6 +628,7 @@ }, "name": "y" }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 106, @@ -1076,7 +1076,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1095,6 +1094,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "ObjectExpression", "start": 196, @@ -1125,7 +1125,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1144,6 +1143,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 201, @@ -1180,7 +1180,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1199,6 +1198,7 @@ }, "name": "y" }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 207, @@ -1238,7 +1238,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1257,6 +1256,7 @@ }, "name": "b" }, + "shorthand": false, "value": { "type": "BooleanLiteral", "start": 219, @@ -1600,7 +1600,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1619,6 +1618,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "ObjectExpression", "start": 289, @@ -1649,7 +1649,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1668,6 +1667,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 294, @@ -1704,7 +1704,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1723,6 +1722,7 @@ }, "name": "y" }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 300, @@ -1762,7 +1762,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -1781,6 +1780,7 @@ }, "name": "b" }, + "shorthand": false, "value": { "type": "BooleanLiteral", "start": 312, diff --git a/test/fixtures/flow/type-annotations/20/expected.json b/test/fixtures/flow/type-annotations/20/expected.json index cf418c1dd4..9290cd973c 100644 --- a/test/fixtures/flow/type-annotations/20/expected.json +++ b/test/fixtures/flow/type-annotations/20/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/flow/type-annotations/21/expected.json b/test/fixtures/flow/type-annotations/21/expected.json index c5d4df45b5..ea57e98499 100644 --- a/test/fixtures/flow/type-annotations/21/expected.json +++ b/test/fixtures/flow/type-annotations/21/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/flow/type-annotations/22/expected.json b/test/fixtures/flow/type-annotations/22/expected.json index 3cbd6273d8..e9eb17db9d 100644 --- a/test/fixtures/flow/type-annotations/22/expected.json +++ b/test/fixtures/flow/type-annotations/22/expected.json @@ -104,7 +104,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/flow/type-annotations/23/expected.json b/test/fixtures/flow/type-annotations/23/expected.json index 05b77ef383..590ac53b43 100644 --- a/test/fixtures/flow/type-annotations/23/expected.json +++ b/test/fixtures/flow/type-annotations/23/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/flow/type-annotations/24/expected.json b/test/fixtures/flow/type-annotations/24/expected.json index ffb6d1e92c..b42844e0b6 100644 --- a/test/fixtures/flow/type-annotations/24/expected.json +++ b/test/fixtures/flow/type-annotations/24/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/flow/type-annotations/25/expected.json b/test/fixtures/flow/type-annotations/25/expected.json index cdf03fcf78..b3c441c97f 100644 --- a/test/fixtures/flow/type-annotations/25/expected.json +++ b/test/fixtures/flow/type-annotations/25/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/flow/type-annotations/26/expected.json b/test/fixtures/flow/type-annotations/26/expected.json index 9a5cf1d754..920a06a06b 100644 --- a/test/fixtures/flow/type-annotations/26/expected.json +++ b/test/fixtures/flow/type-annotations/26/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "NumericLiteral", diff --git a/test/fixtures/flow/type-annotations/60/expected.json b/test/fixtures/flow/type-annotations/60/expected.json index 7bcec9cc23..8dfba881ef 100644 --- a/test/fixtures/flow/type-annotations/60/expected.json +++ b/test/fixtures/flow/type-annotations/60/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 5, @@ -245,7 +245,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -264,6 +263,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 30, diff --git a/test/fixtures/flow/type-annotations/61/expected.json b/test/fixtures/flow/type-annotations/61/expected.json index d67405b5b2..37f870ae0d 100644 --- a/test/fixtures/flow/type-annotations/61/expected.json +++ b/test/fixtures/flow/type-annotations/61/expected.json @@ -87,7 +87,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -106,6 +105,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 5, @@ -245,7 +245,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -264,6 +263,7 @@ }, "name": "x" }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 29, diff --git a/test/fixtures/flow/type-annotations/63/expected.json b/test/fixtures/flow/type-annotations/63/expected.json index 9317604671..7b384938b2 100644 --- a/test/fixtures/flow/type-annotations/63/expected.json +++ b/test/fixtures/flow/type-annotations/63/expected.json @@ -93,7 +93,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -112,6 +111,7 @@ }, "name": "x" }, + "shorthand": true, "value": { "type": "Identifier", "start": 14, diff --git a/test/fixtures/flow/type-annotations/97/expected.json b/test/fixtures/flow/type-annotations/97/expected.json index 6021547089..a65d8fd551 100644 --- a/test/fixtures/flow/type-annotations/97/expected.json +++ b/test/fixtures/flow/type-annotations/97/expected.json @@ -72,7 +72,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -91,6 +90,7 @@ }, "name": "f" }, + "shorthand": false, "value": { "type": "FunctionExpression", "start": 5, diff --git a/test/fixtures/flow/type-generics/1/expected.json b/test/fixtures/flow/type-generics/1/expected.json index 40dcb01fe0..0efdcd9066 100644 --- a/test/fixtures/flow/type-generics/1/expected.json +++ b/test/fixtures/flow/type-generics/1/expected.json @@ -123,7 +123,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -142,6 +141,7 @@ }, "name": "id" }, + "shorthand": false, "value": { "type": "ArrowFunctionExpression", "start": 55, diff --git a/test/fixtures/flow/type-parameter-declaration/object-method-type-param-jsx/expected.json b/test/fixtures/flow/type-parameter-declaration/object-method-type-param-jsx/expected.json index 07d8e1ebe8..cd52fb7e74 100644 --- a/test/fixtures/flow/type-parameter-declaration/object-method-type-param-jsx/expected.json +++ b/test/fixtures/flow/type-parameter-declaration/object-method-type-param-jsx/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/flow/type-parameter-declaration/object-reserved-word/expected.json b/test/fixtures/flow/type-parameter-declaration/object-reserved-word/expected.json index c89615b382..934c0fddb3 100644 --- a/test/fixtures/flow/type-parameter-declaration/object-reserved-word/expected.json +++ b/test/fixtures/flow/type-parameter-declaration/object-reserved-word/expected.json @@ -104,7 +104,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -196,7 +195,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -288,7 +286,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -380,7 +377,6 @@ } }, "method": true, - "shorthand": false, "computed": false, "key": { "type": "Identifier", diff --git a/test/fixtures/flow/typecasts/2/expected.json b/test/fixtures/flow/typecasts/2/expected.json index e41a4f7b34..ac27cb40c4 100644 --- a/test/fixtures/flow/typecasts/2/expected.json +++ b/test/fixtures/flow/typecasts/2/expected.json @@ -86,7 +86,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -105,6 +104,7 @@ }, "name": "xxx" }, + "shorthand": false, "value": { "type": "NumericLiteral", "start": 7, @@ -141,7 +141,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -160,6 +159,7 @@ }, "name": "yyy" }, + "shorthand": false, "value": { "type": "StringLiteral", "start": 15, diff --git a/test/fixtures/jsx/regression/3/expected.json b/test/fixtures/jsx/regression/3/expected.json index e952ae4a2b..d314d03df0 100644 --- a/test/fixtures/jsx/regression/3/expected.json +++ b/test/fixtures/jsx/regression/3/expected.json @@ -165,7 +165,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -184,6 +183,7 @@ }, "name": "a" }, + "shorthand": true, "value": { "type": "Identifier", "start": 8, diff --git a/test/fixtures/test262/rest-parameter/array-pattern-multi-element-with-object/expected.json b/test/fixtures/test262/rest-parameter/array-pattern-multi-element-with-object/expected.json index 1159886da3..e46cd87e8d 100644 --- a/test/fixtures/test262/rest-parameter/array-pattern-multi-element-with-object/expected.json +++ b/test/fixtures/test262/rest-parameter/array-pattern-multi-element-with-object/expected.json @@ -122,7 +122,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -141,6 +140,7 @@ }, "name": "p" }, + "shorthand": false, "value": { "type": "Identifier", "start": 40, @@ -191,7 +191,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -210,6 +209,7 @@ }, "name": "r" }, + "shorthand": true, "value": { "type": "Identifier", "start": 45, @@ -263,7 +263,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -282,6 +281,7 @@ }, "name": "s" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 50, diff --git a/test/fixtures/test262/rest-parameter/array-pattern-single-element-with-object/expected.json b/test/fixtures/test262/rest-parameter/array-pattern-single-element-with-object/expected.json index 2731def325..ad6ee909e9 100644 --- a/test/fixtures/test262/rest-parameter/array-pattern-single-element-with-object/expected.json +++ b/test/fixtures/test262/rest-parameter/array-pattern-single-element-with-object/expected.json @@ -122,7 +122,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -141,6 +140,7 @@ }, "name": "p" }, + "shorthand": false, "value": { "type": "Identifier", "start": 41, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-empty-with-array/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-empty-with-array/expected.json index ce6d9fc36e..d16c7b6b46 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-empty-with-array/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-empty-with-array/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "p" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 31, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-empty-with-object/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-empty-with-object/expected.json index 732c68014c..4977ba0df5 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-empty-with-object/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-empty-with-object/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "p" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 32, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-array/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-array/expected.json index b455a94709..4b32aef8fb 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-array/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-array/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "p" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 38, @@ -176,7 +176,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -195,6 +194,7 @@ }, "name": "b" }, + "shorthand": true, "value": { "type": "Identifier", "start": 43, @@ -231,7 +231,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -250,6 +249,7 @@ }, "name": "q" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 49, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-initializer/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-initializer/expected.json index f497d59bd3..00fb663d0e 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-initializer/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-initializer/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "AssignmentPattern", "start": 44, @@ -194,7 +194,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -213,6 +212,7 @@ }, "name": "b" }, + "shorthand": false, "value": { "type": "Identifier", "start": 54, @@ -246,7 +246,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -265,6 +264,7 @@ }, "name": "c" }, + "shorthand": false, "value": { "type": "AssignmentPattern", "start": 60, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-leading/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-leading/expected.json index 52d43f0153..fd80d529d9 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-leading/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-leading/expected.json @@ -141,7 +141,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -160,6 +159,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "Identifier", "start": 46, @@ -193,7 +193,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -212,6 +211,7 @@ }, "name": "b" }, + "shorthand": false, "value": { "type": "Identifier", "start": 52, @@ -245,7 +245,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -264,6 +263,7 @@ }, "name": "c" }, + "shorthand": false, "value": { "type": "Identifier", "start": 58, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-object/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-object/expected.json index 6c5d7cf14f..0a51e17c59 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-object/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-multi-element-with-object/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 39, @@ -156,7 +156,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -175,6 +174,7 @@ }, "name": "p" }, + "shorthand": false, "value": { "type": "Identifier", "start": 43, @@ -211,7 +211,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -230,6 +229,7 @@ }, "name": "b" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 50, @@ -260,7 +260,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -279,6 +278,7 @@ }, "name": "r" }, + "shorthand": true, "value": { "type": "Identifier", "start": 51, @@ -318,7 +318,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -337,6 +336,7 @@ }, "name": "c" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 58, @@ -367,7 +367,6 @@ } }, "method": false, - "shorthand": true, "computed": false, "key": { "type": "Identifier", @@ -386,6 +385,7 @@ }, "name": "s" }, + "shorthand": true, "value": { "type": "AssignmentPattern", "start": 59, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-multi-element/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-multi-element/expected.json index b95a4b6234..e79b67a273 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-multi-element/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-multi-element/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "Identifier", "start": 29, @@ -159,7 +159,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -178,6 +177,7 @@ }, "name": "b" }, + "shorthand": false, "value": { "type": "Identifier", "start": 35, @@ -211,7 +211,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -230,6 +229,7 @@ }, "name": "c" }, + "shorthand": false, "value": { "type": "Identifier", "start": 41, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-array/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-array/expected.json index e9c4c2859a..f3e9810813 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-array/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-array/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "p" }, + "shorthand": false, "value": { "type": "ArrayPattern", "start": 39, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-initializer/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-initializer/expected.json index 9faf97f761..ff62b03d63 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-initializer/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-initializer/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "AssignmentPattern", "start": 45, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-leading/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-leading/expected.json index dc7c07c735..554a4ebf3d 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-leading/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-leading/expected.json @@ -124,7 +124,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -143,6 +142,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "Identifier", "start": 44, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-object/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-object/expected.json index 35be5a85ee..92b741d8a9 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-object/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-single-element-with-object/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "p" }, + "shorthand": false, "value": { "type": "ObjectPattern", "start": 40, @@ -156,7 +156,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -175,6 +174,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "Identifier", "start": 44, diff --git a/test/fixtures/test262/rest-parameter/object-pattern-single-element/expected.json b/test/fixtures/test262/rest-parameter/object-pattern-single-element/expected.json index f7e75584e0..3685c479ca 100644 --- a/test/fixtures/test262/rest-parameter/object-pattern-single-element/expected.json +++ b/test/fixtures/test262/rest-parameter/object-pattern-single-element/expected.json @@ -107,7 +107,6 @@ } }, "method": false, - "shorthand": false, "computed": false, "key": { "type": "Identifier", @@ -126,6 +125,7 @@ }, "name": "a" }, + "shorthand": false, "value": { "type": "Identifier", "start": 30, From d33c82781aaa4e79aed7dcb7cb5746ef7ba962f2 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Tue, 2 May 2017 13:41:10 -0500 Subject: [PATCH 30/73] Allow super in class properties (#499) --- src/parser/expression.js | 6 +- src/parser/statement.js | 8 +- src/tokenizer/state.js | 2 + .../class-properties/super/actual.js | 3 + .../class-properties/super/expected.json | 272 ++++++++++++++++++ .../class-properties/super/options.json | 3 + 6 files changed, 291 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/experimental/class-properties/super/actual.js create mode 100644 test/fixtures/experimental/class-properties/super/expected.json create mode 100644 test/fixtures/experimental/class-properties/super/options.json diff --git a/src/parser/expression.js b/src/parser/expression.js index 9afb11da4c..dac08cec24 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -381,7 +381,11 @@ export default class ExpressionParser extends LValParser { switch (this.state.type) { case tt._super: - if (!this.state.inMethod && !this.options.allowSuperOutsideMethod) { + if ( + !this.state.inMethod && + !this.state.inClassProperty && + !this.options.allowSuperOutsideMethod + ) { this.raise(this.state.start, "'super' outside of function or class"); } diff --git a/src/parser/statement.js b/src/parser/statement.js index 53cbaacb77..9979f6a388 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -772,19 +772,23 @@ export default class StatementParser extends ExpressionParser { } parseClassProperty(node) { + const hasPlugin = this.hasPlugin("classProperties"); const noPluginMsg = "You can only use Class Properties when the 'classProperties' plugin is enabled."; - if (!node.typeAnnotation && !this.hasPlugin("classProperties")) { + if (!node.typeAnnotation && !hasPlugin) { this.raise(node.start, noPluginMsg); } + this.state.inClassProperty = true; + if (this.match(tt.eq)) { - if (!this.hasPlugin("classProperties")) this.raise(this.state.start, noPluginMsg); + if (!hasPlugin) this.raise(this.state.start, noPluginMsg); this.next(); node.value = this.parseMaybeAssign(); } else { node.value = null; } this.semicolon(); + this.state.inClassProperty = false; return this.finishNode(node, "ClassProperty"); } diff --git a/src/tokenizer/state.js b/src/tokenizer/state.js index 2e35b3ac4f..1bbfbda23d 100644 --- a/src/tokenizer/state.js +++ b/src/tokenizer/state.js @@ -18,6 +18,7 @@ export default class State { this.inAsync = this.inPropertyName = this.inType = + this.inClassProperty = this.noAnonFunctionType = false; @@ -73,6 +74,7 @@ export default class State { inAsync: boolean; inType: boolean; inPropertyName: boolean; + inClassProperty: boolean; // Labels in scope. labels: Array; diff --git a/test/fixtures/experimental/class-properties/super/actual.js b/test/fixtures/experimental/class-properties/super/actual.js new file mode 100644 index 0000000000..9c760b0bb1 --- /dev/null +++ b/test/fixtures/experimental/class-properties/super/actual.js @@ -0,0 +1,3 @@ +class Fails extends class { c(){} } { + c = super.c(); +} diff --git a/test/fixtures/experimental/class-properties/super/expected.json b/test/fixtures/experimental/class-properties/super/expected.json new file mode 100644 index 0000000000..3460702b3b --- /dev/null +++ b/test/fixtures/experimental/class-properties/super/expected.json @@ -0,0 +1,272 @@ +{ + "type": "File", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "Fails" + }, + "name": "Fails" + }, + "superClass": { + "type": "ClassExpression", + "start": 20, + "end": 35, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 35 + } + }, + "id": null, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 26, + "end": 35, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 35 + } + }, + "body": [ + { + "type": "ClassMethod", + "start": 28, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 28, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 29 + }, + "identifierName": "c" + }, + "name": "c" + }, + "kind": "method", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 31, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "body": [], + "directives": [] + } + } + ] + } + }, + "body": { + "type": "ClassBody", + "start": 36, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 36 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "ClassProperty", + "start": 40, + "end": 54, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 16 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 40, + "end": 41, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 3 + }, + "identifierName": "c" + }, + "name": "c" + }, + "value": { + "type": "CallExpression", + "start": 44, + "end": 53, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 15 + } + }, + "callee": { + "type": "MemberExpression", + "start": 44, + "end": 51, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 13 + } + }, + "object": { + "type": "Super", + "start": 44, + "end": 49, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 11 + } + } + }, + "property": { + "type": "Identifier", + "start": 50, + "end": 51, + "loc": { + "start": { + "line": 2, + "column": 12 + }, + "end": { + "line": 2, + "column": 13 + }, + "identifierName": "c" + }, + "name": "c" + }, + "computed": false + }, + "arguments": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/class-properties/super/options.json b/test/fixtures/experimental/class-properties/super/options.json new file mode 100644 index 0000000000..9c27576d4a --- /dev/null +++ b/test/fixtures/experimental/class-properties/super/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties"] +} From 0e12f565daf6c83ef2aeea87fbf0e1d9cfa0775a Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Wed, 3 May 2017 16:56:22 +0200 Subject: [PATCH 31/73] Document babylon plugin system (#507) [skip ci] * docs: document babylon plugin system * [skip ci] * [skip ci] * [skip ci] it's -> its * [skip ci] --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 3aaf8acf43..f3764fed44 100644 --- a/README.md +++ b/README.md @@ -135,3 +135,22 @@ require("babylon").parse("code", { - `functionSent` - `dynamicImport` +### FAQ + +#### Will Babylon support a plugin system? + +Previous issues: [babel/babel#1351](https://github.com/babel/babel/issues/1351), [#500](https://github.com/babel/babylon/issues/500). + +We currently aren't willing to commit to supporting the API for plugins or the resulting ecosystem (there is already enough work maintaining Babel's own plugin system). It's not clear how to make that API effective, and it would limit out ability to refactor and optimize the codebase. + +Our current recommendation for those that want to create their own custom syntax is for users to fork Babylon. + +To consume your custom parser, you can add to your `.babelrc` via its npm package name or require it if using JavaScript, + +```json +{ + "parserOpts": { + "parser": "custom-fork-of-babylon-on-npm-here" + } +} +``` From 9d1f8193206fcd7c709dbede2ebeed8d3f99b2be Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Wed, 10 May 2017 09:18:08 -0500 Subject: [PATCH 32/73] Allow flow class field to be named constructor (#510) --- src/plugins/flow.js | 4 + .../actual.js | 3 + .../expected.json | 169 +++++++++++++ .../options.json | 3 + .../actual.js | 5 + .../expected.json | 222 ++++++++++++++++++ .../options.json | 3 + 7 files changed, 409 insertions(+) create mode 100644 test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/actual.js create mode 100644 test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/expected.json create mode 100644 test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/options.json create mode 100644 test/fixtures/flow/classes/constructor-with-class-prop-plugin/actual.js create mode 100644 test/fixtures/flow/classes/constructor-with-class-prop-plugin/expected.json create mode 100644 test/fixtures/flow/classes/constructor-with-class-prop-plugin/options.json diff --git a/src/plugins/flow.js b/src/plugins/flow.js index cad3c4b645..f3a1b739a7 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -1231,6 +1231,10 @@ export default (superClass: Class): Class => class extends super return this.match(tt.colon) || super.isClassProperty(); } + isNonstaticConstructor(method: N.ClassMethod): boolean { + return !this.match(tt.colon) && super.isNonstaticConstructor(method); + } + // parse type parameters for class methods parseClassMethod(classBody: N.ClassBody, method: N.ClassMethod, ...args): void { if (method.variance) { diff --git a/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/actual.js b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/actual.js new file mode 100644 index 0000000000..1db4f60888 --- /dev/null +++ b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/actual.js @@ -0,0 +1,3 @@ +class Foo { + constructor: () => this; +} diff --git a/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/expected.json b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/expected.json new file mode 100644 index 0000000000..721399cff9 --- /dev/null +++ b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/expected.json @@ -0,0 +1,169 @@ +{ + "type": "File", + "start": 0, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "sourceType": "module", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 10, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "ClassProperty", + "start": 14, + "end": 38, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 26 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 14, + "end": 25, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 13 + }, + "identifierName": "constructor" + }, + "name": "constructor" + }, + "variance": null, + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 25, + "end": 37, + "loc": { + "start": { + "line": 2, + "column": 13 + }, + "end": { + "line": 2, + "column": 25 + } + }, + "typeAnnotation": { + "type": "FunctionTypeAnnotation", + "start": 27, + "end": 37, + "loc": { + "start": { + "line": 2, + "column": 15 + }, + "end": { + "line": 2, + "column": 25 + } + }, + "params": [], + "rest": null, + "returnType": { + "type": "ThisTypeAnnotation", + "start": 33, + "end": 37, + "loc": { + "start": { + "line": 2, + "column": 21 + }, + "end": { + "line": 2, + "column": 25 + } + }, + "value": true + }, + "typeParameters": null + } + }, + "value": null + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/options.json b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/options.json new file mode 100644 index 0000000000..3c8f72c900 --- /dev/null +++ b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["jsx", "flow", "classProperties"] +} diff --git a/test/fixtures/flow/classes/constructor-with-class-prop-plugin/actual.js b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/actual.js new file mode 100644 index 0000000000..90c635b7b7 --- /dev/null +++ b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/actual.js @@ -0,0 +1,5 @@ +class A { + constructor(): Object { + return {}; + } +} diff --git a/test/fixtures/flow/classes/constructor-with-class-prop-plugin/expected.json b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/expected.json new file mode 100644 index 0000000000..661a2f5828 --- /dev/null +++ b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/expected.json @@ -0,0 +1,222 @@ +{ + "type": "File", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "sourceType": "module", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + }, + "identifierName": "A" + }, + "name": "A" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 8, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "body": [ + { + "type": "ClassMethod", + "start": 12, + "end": 54, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 12, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 13 + }, + "identifierName": "constructor" + }, + "name": "constructor" + }, + "kind": "constructor", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "predicate": null, + "returnType": { + "type": "TypeAnnotation", + "start": 25, + "end": 33, + "loc": { + "start": { + "line": 2, + "column": 15 + }, + "end": { + "line": 2, + "column": 23 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 27, + "end": 33, + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 23 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 27, + "end": 33, + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 23 + }, + "identifierName": "Object" + }, + "name": "Object" + } + } + }, + "body": { + "type": "BlockStatement", + "start": 34, + "end": 54, + "loc": { + "start": { + "line": 2, + "column": 24 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 40, + "end": 50, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 14 + } + }, + "argument": { + "type": "ObjectExpression", + "start": 47, + "end": 49, + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "properties": [] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/classes/constructor-with-class-prop-plugin/options.json b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/options.json new file mode 100644 index 0000000000..3c8f72c900 --- /dev/null +++ b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["jsx", "flow", "classProperties"] +} From 63412e54f406664116165ee48b25f067402f8fa8 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Wed, 10 May 2017 09:18:08 -0500 Subject: [PATCH 33/73] Allow flow class field to be named constructor (#510) --- src/plugins/flow.js | 6 + .../actual.js | 3 + .../expected.json | 169 +++++++++++++ .../options.json | 3 + .../actual.js | 5 + .../expected.json | 222 ++++++++++++++++++ .../options.json | 3 + 7 files changed, 411 insertions(+) create mode 100644 test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/actual.js create mode 100644 test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/expected.json create mode 100644 test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/options.json create mode 100644 test/fixtures/flow/classes/constructor-with-class-prop-plugin/actual.js create mode 100644 test/fixtures/flow/classes/constructor-with-class-prop-plugin/expected.json create mode 100644 test/fixtures/flow/classes/constructor-with-class-prop-plugin/options.json diff --git a/src/plugins/flow.js b/src/plugins/flow.js index ab6003aa2a..996f492993 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -1139,6 +1139,12 @@ export default function (instance) { }; }); + instance.extend("isNonstaticConstructor", function(inner) { + return function (method) { + return !this.match(tt.colon) && inner.call(this, method); + }; + }); + // parse type parameters for class methods instance.extend("parseClassMethod", function (inner) { return function (classBody, method, ...args) { diff --git a/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/actual.js b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/actual.js new file mode 100644 index 0000000000..1db4f60888 --- /dev/null +++ b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/actual.js @@ -0,0 +1,3 @@ +class Foo { + constructor: () => this; +} diff --git a/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/expected.json b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/expected.json new file mode 100644 index 0000000000..721399cff9 --- /dev/null +++ b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/expected.json @@ -0,0 +1,169 @@ +{ + "type": "File", + "start": 0, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "sourceType": "module", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 10, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "ClassProperty", + "start": 14, + "end": 38, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 26 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 14, + "end": 25, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 13 + }, + "identifierName": "constructor" + }, + "name": "constructor" + }, + "variance": null, + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 25, + "end": 37, + "loc": { + "start": { + "line": 2, + "column": 13 + }, + "end": { + "line": 2, + "column": 25 + } + }, + "typeAnnotation": { + "type": "FunctionTypeAnnotation", + "start": 27, + "end": 37, + "loc": { + "start": { + "line": 2, + "column": 15 + }, + "end": { + "line": 2, + "column": 25 + } + }, + "params": [], + "rest": null, + "returnType": { + "type": "ThisTypeAnnotation", + "start": 33, + "end": 37, + "loc": { + "start": { + "line": 2, + "column": 21 + }, + "end": { + "line": 2, + "column": 25 + } + }, + "value": true + }, + "typeParameters": null + } + }, + "value": null + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/options.json b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/options.json new file mode 100644 index 0000000000..3c8f72c900 --- /dev/null +++ b/test/fixtures/flow/classes/constructor-override-with-class-prop-plugin/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["jsx", "flow", "classProperties"] +} diff --git a/test/fixtures/flow/classes/constructor-with-class-prop-plugin/actual.js b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/actual.js new file mode 100644 index 0000000000..90c635b7b7 --- /dev/null +++ b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/actual.js @@ -0,0 +1,5 @@ +class A { + constructor(): Object { + return {}; + } +} diff --git a/test/fixtures/flow/classes/constructor-with-class-prop-plugin/expected.json b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/expected.json new file mode 100644 index 0000000000..1424dbc6ba --- /dev/null +++ b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/expected.json @@ -0,0 +1,222 @@ +{ + "type": "File", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "sourceType": "module", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + }, + "identifierName": "A" + }, + "name": "A" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 8, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "body": [ + { + "type": "ClassMethod", + "start": 12, + "end": 54, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 12, + "end": 23, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 13 + }, + "identifierName": "constructor" + }, + "name": "constructor" + }, + "kind": "constructor", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "returnType": { + "type": "TypeAnnotation", + "start": 25, + "end": 33, + "loc": { + "start": { + "line": 2, + "column": 15 + }, + "end": { + "line": 2, + "column": 23 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 27, + "end": 33, + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 23 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 27, + "end": 33, + "loc": { + "start": { + "line": 2, + "column": 17 + }, + "end": { + "line": 2, + "column": 23 + }, + "identifierName": "Object" + }, + "name": "Object" + } + }, + "predicate": null + }, + "body": { + "type": "BlockStatement", + "start": 34, + "end": 54, + "loc": { + "start": { + "line": 2, + "column": 24 + }, + "end": { + "line": 4, + "column": 3 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 40, + "end": 50, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 14 + } + }, + "argument": { + "type": "ObjectExpression", + "start": 47, + "end": 49, + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "properties": [] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/classes/constructor-with-class-prop-plugin/options.json b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/options.json new file mode 100644 index 0000000000..3c8f72c900 --- /dev/null +++ b/test/fixtures/flow/classes/constructor-with-class-prop-plugin/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["jsx", "flow", "classProperties"] +} From 4a29ccdd1aa84df293c3b334d6ee1c578ccba425 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Tue, 2 May 2017 13:41:10 -0500 Subject: [PATCH 34/73] Allow super in class properties (#499) --- src/parser/expression.js | 6 +- src/parser/statement.js | 2 + src/tokenizer/state.js | 2 + .../class-properties/super/actual.js | 3 + .../class-properties/super/expected.json | 272 ++++++++++++++++++ .../class-properties/super/options.json | 3 + 6 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/experimental/class-properties/super/actual.js create mode 100644 test/fixtures/experimental/class-properties/super/expected.json create mode 100644 test/fixtures/experimental/class-properties/super/options.json diff --git a/src/parser/expression.js b/src/parser/expression.js index 775d658f32..d92b9db2f8 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -382,7 +382,11 @@ pp.parseExprAtom = function (refShorthandDefaultPos) { switch (this.state.type) { case tt._super: - if (!this.state.inMethod && !this.options.allowSuperOutsideMethod) { + if ( + !this.state.inMethod && + !this.state.inClassProperty && + !this.options.allowSuperOutsideMethod + ) { this.raise(this.state.start, "'super' outside of function or class"); } diff --git a/src/parser/statement.js b/src/parser/statement.js index 03fc2aaac3..488a554b94 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -783,6 +783,7 @@ pp.parseClassBody = function (node) { }; pp.parseClassProperty = function (node) { + this.state.inClassProperty = true; if (this.match(tt.eq)) { if (!this.hasPlugin("classProperties")) this.unexpected(); this.next(); @@ -791,6 +792,7 @@ pp.parseClassProperty = function (node) { node.value = null; } this.semicolon(); + this.state.inClassProperty = false; return this.finishNode(node, "ClassProperty"); }; diff --git a/src/tokenizer/state.js b/src/tokenizer/state.js index 2e35b3ac4f..1bbfbda23d 100644 --- a/src/tokenizer/state.js +++ b/src/tokenizer/state.js @@ -18,6 +18,7 @@ export default class State { this.inAsync = this.inPropertyName = this.inType = + this.inClassProperty = this.noAnonFunctionType = false; @@ -73,6 +74,7 @@ export default class State { inAsync: boolean; inType: boolean; inPropertyName: boolean; + inClassProperty: boolean; // Labels in scope. labels: Array; diff --git a/test/fixtures/experimental/class-properties/super/actual.js b/test/fixtures/experimental/class-properties/super/actual.js new file mode 100644 index 0000000000..9c760b0bb1 --- /dev/null +++ b/test/fixtures/experimental/class-properties/super/actual.js @@ -0,0 +1,3 @@ +class Fails extends class { c(){} } { + c = super.c(); +} diff --git a/test/fixtures/experimental/class-properties/super/expected.json b/test/fixtures/experimental/class-properties/super/expected.json new file mode 100644 index 0000000000..3460702b3b --- /dev/null +++ b/test/fixtures/experimental/class-properties/super/expected.json @@ -0,0 +1,272 @@ +{ + "type": "File", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "Fails" + }, + "name": "Fails" + }, + "superClass": { + "type": "ClassExpression", + "start": 20, + "end": 35, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 35 + } + }, + "id": null, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 26, + "end": 35, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 35 + } + }, + "body": [ + { + "type": "ClassMethod", + "start": 28, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 28, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 29 + }, + "identifierName": "c" + }, + "name": "c" + }, + "kind": "method", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 31, + "end": 33, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 33 + } + }, + "body": [], + "directives": [] + } + } + ] + } + }, + "body": { + "type": "ClassBody", + "start": 36, + "end": 56, + "loc": { + "start": { + "line": 1, + "column": 36 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "ClassProperty", + "start": 40, + "end": 54, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 16 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 40, + "end": 41, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 3 + }, + "identifierName": "c" + }, + "name": "c" + }, + "value": { + "type": "CallExpression", + "start": 44, + "end": 53, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 15 + } + }, + "callee": { + "type": "MemberExpression", + "start": 44, + "end": 51, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 13 + } + }, + "object": { + "type": "Super", + "start": 44, + "end": 49, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 11 + } + } + }, + "property": { + "type": "Identifier", + "start": 50, + "end": 51, + "loc": { + "start": { + "line": 2, + "column": 12 + }, + "end": { + "line": 2, + "column": 13 + }, + "identifierName": "c" + }, + "name": "c" + }, + "computed": false + }, + "arguments": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/class-properties/super/options.json b/test/fixtures/experimental/class-properties/super/options.json new file mode 100644 index 0000000000..9c27576d4a --- /dev/null +++ b/test/fixtures/experimental/class-properties/super/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties"] +} From 67db275c94f97da3362f05f35404383c1531f0b2 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Sun, 23 Apr 2017 17:45:19 -0500 Subject: [PATCH 35/73] Remove jsx context when parsing arrow functions (#475) --- src/plugins/flow.js | 11 +- test/fixtures/flow/type-generics/1/actual.js | 1 + .../flow/type-generics/1/expected.json | 346 ++++++++++++++++++ test/fixtures/flow/type-generics/2/actual.js | 2 + .../flow/type-generics/2/expected.json | 340 +++++++++++++++++ 5 files changed, 695 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/flow/type-generics/1/actual.js create mode 100644 test/fixtures/flow/type-generics/1/expected.json create mode 100644 test/fixtures/flow/type-generics/2/actual.js create mode 100644 test/fixtures/flow/type-generics/2/expected.json diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 996f492993..8b63c97207 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -1,7 +1,6 @@ /* eslint max-len: 0 */ import { types as tt } from "../tokenizer/types"; -import { types as ct } from "../tokenizer/context"; import Parser from "../parser"; const primitiveTypes = [ @@ -1392,6 +1391,12 @@ export default function (instance) { } catch (err) { if (err instanceof SyntaxError) { this.state = state; + + // Remove `tc.j_expr` and `tc.j_oTag` from context added + // by parsing `jsxTagStart` to stop the JSX plugin from + // messing with the tokens + this.state.context.length -= 2; + jsxError = err; } else { // istanbul ignore next: no such error is expected @@ -1400,9 +1405,6 @@ export default function (instance) { } } - // Need to push something onto the context to stop - // the JSX plugin from messing with the tokens - this.state.context.push(ct.parenExpression); if (jsxError != null || this.isRelational("<")) { let arrowExpression; let typeParameters; @@ -1428,7 +1430,6 @@ export default function (instance) { ); } } - this.state.context.pop(); return inner.apply(this, args); }; diff --git a/test/fixtures/flow/type-generics/1/actual.js b/test/fixtures/flow/type-generics/1/actual.js new file mode 100644 index 0000000000..f27ba81379 --- /dev/null +++ b/test/fixtures/flow/type-generics/1/actual.js @@ -0,0 +1 @@ +const functionReturningIdentityAsAField = () => ({ id: (value: T): T => value }); diff --git a/test/fixtures/flow/type-generics/1/expected.json b/test/fixtures/flow/type-generics/1/expected.json new file mode 100644 index 0000000000..48f4ddd650 --- /dev/null +++ b/test/fixtures/flow/type-generics/1/expected.json @@ -0,0 +1,346 @@ +{ + "type": "File", + "start": 0, + "end": 84, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 84 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 84, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 84 + } + }, + "sourceType": "module", + "body": [ + { + "type": "VariableDeclaration", + "start": 0, + "end": 84, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 84 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 6, + "end": 83, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 83 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 39, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 39 + }, + "identifierName": "functionReturningIdentityAsAField" + }, + "name": "functionReturningIdentityAsAField" + }, + "init": { + "type": "ArrowFunctionExpression", + "start": 42, + "end": 83, + "loc": { + "start": { + "line": 1, + "column": 42 + }, + "end": { + "line": 1, + "column": 83 + } + }, + "id": null, + "generator": false, + "expression": true, + "async": false, + "params": [], + "body": { + "type": "ObjectExpression", + "start": 49, + "end": 82, + "loc": { + "start": { + "line": 1, + "column": 49 + }, + "end": { + "line": 1, + "column": 82 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 51, + "end": 80, + "loc": { + "start": { + "line": 1, + "column": 51 + }, + "end": { + "line": 1, + "column": 80 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 51, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 51 + }, + "end": { + "line": 1, + "column": 53 + }, + "identifierName": "id" + }, + "name": "id" + }, + "value": { + "type": "ArrowFunctionExpression", + "start": 55, + "end": 80, + "loc": { + "start": { + "line": 1, + "column": 55 + }, + "end": { + "line": 1, + "column": 80 + } + }, + "returnType": { + "type": "TypeAnnotation", + "start": 68, + "end": 71, + "loc": { + "start": { + "line": 1, + "column": 68 + }, + "end": { + "line": 1, + "column": 71 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 70, + "end": 71, + "loc": { + "start": { + "line": 1, + "column": 70 + }, + "end": { + "line": 1, + "column": 71 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 70, + "end": 71, + "loc": { + "start": { + "line": 1, + "column": 70 + }, + "end": { + "line": 1, + "column": 71 + }, + "identifierName": "T" + }, + "name": "T" + } + }, + "predicate": null + }, + "id": null, + "generator": false, + "expression": true, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 59, + "end": 67, + "loc": { + "start": { + "line": 1, + "column": 59 + }, + "end": { + "line": 1, + "column": 67 + }, + "identifierName": "value" + }, + "name": "value", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 64, + "end": 67, + "loc": { + "start": { + "line": 1, + "column": 64 + }, + "end": { + "line": 1, + "column": 67 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 66, + "end": 67, + "loc": { + "start": { + "line": 1, + "column": 66 + }, + "end": { + "line": 1, + "column": 67 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 66, + "end": 67, + "loc": { + "start": { + "line": 1, + "column": 66 + }, + "end": { + "line": 1, + "column": 67 + }, + "identifierName": "T" + }, + "name": "T" + } + } + } + } + ], + "body": { + "type": "Identifier", + "start": 75, + "end": 80, + "loc": { + "start": { + "line": 1, + "column": 75 + }, + "end": { + "line": 1, + "column": 80 + }, + "identifierName": "value" + }, + "name": "value" + }, + "typeParameters": { + "type": "TypeParameterDeclaration", + "start": 55, + "end": 58, + "loc": { + "start": { + "line": 1, + "column": 55 + }, + "end": { + "line": 1, + "column": 58 + } + }, + "params": [ + { + "type": "TypeParameter", + "start": 56, + "end": 57, + "loc": { + "start": { + "line": 1, + "column": 56 + }, + "end": { + "line": 1, + "column": 57 + } + }, + "name": "T", + "variance": null + } + ] + } + } + } + ], + "extra": { + "parenthesized": true, + "parenStart": 48 + } + } + } + } + ], + "kind": "const" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/flow/type-generics/2/actual.js b/test/fixtures/flow/type-generics/2/actual.js new file mode 100644 index 0000000000..e3a4739249 --- /dev/null +++ b/test/fixtures/flow/type-generics/2/actual.js @@ -0,0 +1,2 @@ +const identity = (t: T): T => t; +const a = 1; diff --git a/test/fixtures/flow/type-generics/2/expected.json b/test/fixtures/flow/type-generics/2/expected.json new file mode 100644 index 0000000000..6f8bda5539 --- /dev/null +++ b/test/fixtures/flow/type-generics/2/expected.json @@ -0,0 +1,340 @@ +{ + "type": "File", + "start": 0, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "sourceType": "module", + "body": [ + { + "type": "VariableDeclaration", + "start": 0, + "end": 35, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 35 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 6, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 34 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 14 + }, + "identifierName": "identity" + }, + "name": "identity" + }, + "init": { + "type": "ArrowFunctionExpression", + "start": 17, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 34 + } + }, + "returnType": { + "type": "TypeAnnotation", + "start": 26, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 29 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 28, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 29 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 28, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 28 + }, + "end": { + "line": 1, + "column": 29 + }, + "identifierName": "T" + }, + "name": "T" + } + }, + "predicate": null + }, + "id": null, + "generator": false, + "expression": true, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 21, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 25 + }, + "identifierName": "t" + }, + "name": "t", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 22, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 1, + "column": 25 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 24, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 25 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 24, + "end": 25, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 25 + }, + "identifierName": "T" + }, + "name": "T" + } + } + } + } + ], + "body": { + "type": "Identifier", + "start": 33, + "end": 34, + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 1, + "column": 34 + }, + "identifierName": "t" + }, + "name": "t" + }, + "typeParameters": { + "type": "TypeParameterDeclaration", + "start": 17, + "end": 20, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 20 + } + }, + "params": [ + { + "type": "TypeParameter", + "start": 18, + "end": 19, + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 19 + } + }, + "name": "T", + "variance": null + } + ] + } + } + } + ], + "kind": "const" + }, + { + "type": "VariableDeclaration", + "start": 36, + "end": 48, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 42, + "end": 47, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "id": { + "type": "Identifier", + "start": 42, + "end": 43, + "loc": { + "start": { + "line": 2, + "column": 6 + }, + "end": { + "line": 2, + "column": 7 + }, + "identifierName": "a" + }, + "name": "a" + }, + "init": { + "type": "NumericLiteral", + "start": 46, + "end": 47, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + } + ], + "kind": "const" + } + ], + "directives": [] + } +} \ No newline at end of file From 7c56c24bb0ddf8e710dbfe145dcbca5508550faf Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Fri, 21 Apr 2017 09:25:34 -0500 Subject: [PATCH 36/73] Ensure non pattern shorthand props are checked for reserved words (#479) --- src/parser/expression.js | 3 ++- test/fixtures/es2015/shorthand/1/actual.js | 1 + test/fixtures/es2015/shorthand/1/options.json | 3 +++ test/fixtures/es2015/shorthand/2/actual.js | 1 + test/fixtures/es2015/shorthand/2/options.json | 3 +++ 5 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/es2015/shorthand/1/actual.js create mode 100644 test/fixtures/es2015/shorthand/1/options.json create mode 100644 test/fixtures/es2015/shorthand/2/actual.js create mode 100644 test/fixtures/es2015/shorthand/2/options.json diff --git a/src/parser/expression.js b/src/parser/expression.js index d92b9db2f8..7048f01c56 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -884,8 +884,9 @@ pp.parseObjectProperty = function (prop, startPos, startLoc, isPattern, refShort } if (!prop.computed && prop.key.type === "Identifier") { + this.checkReservedWord(prop.key.name, prop.key.start, true, true); + if (isPattern) { - this.checkReservedWord(prop.key.name, prop.key.start, true, true); prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); } else if (this.match(tt.eq) && refShorthandDefaultPos) { if (!refShorthandDefaultPos.start) { diff --git a/test/fixtures/es2015/shorthand/1/actual.js b/test/fixtures/es2015/shorthand/1/actual.js new file mode 100644 index 0000000000..5ce7c9deac --- /dev/null +++ b/test/fixtures/es2015/shorthand/1/actual.js @@ -0,0 +1 @@ +var x = ({ const }); diff --git a/test/fixtures/es2015/shorthand/1/options.json b/test/fixtures/es2015/shorthand/1/options.json new file mode 100644 index 0000000000..a618f5e2ef --- /dev/null +++ b/test/fixtures/es2015/shorthand/1/options.json @@ -0,0 +1,3 @@ +{ + "throws": "const is a reserved word (1:11)" +} diff --git a/test/fixtures/es2015/shorthand/2/actual.js b/test/fixtures/es2015/shorthand/2/actual.js new file mode 100644 index 0000000000..fabf36837d --- /dev/null +++ b/test/fixtures/es2015/shorthand/2/actual.js @@ -0,0 +1 @@ +({ get, this, if }); diff --git a/test/fixtures/es2015/shorthand/2/options.json b/test/fixtures/es2015/shorthand/2/options.json new file mode 100644 index 0000000000..7691eb820f --- /dev/null +++ b/test/fixtures/es2015/shorthand/2/options.json @@ -0,0 +1,3 @@ +{ + "throws": "this is a reserved word (1:8)" +} From 406c3dabc025f5ca89fa3ac1c81200853aa4b3b4 Mon Sep 17 00:00:00 2001 From: Alex Kuzmenko Date: Mon, 3 Apr 2017 23:25:29 +0300 Subject: [PATCH 37/73] Fix number parser (#433) Fixed number parser #2 Added one more test --- src/tokenizer/index.js | 8 ++- .../core/uncategorised/355/expected.json | 69 +++++++++++++++++++ .../core/uncategorised/355/options.json | 3 - .../core/uncategorised/356/expected.json | 69 +++++++++++++++++++ .../core/uncategorised/356/options.json | 3 - .../fixtures/core/uncategorised/550/actual.js | 2 + .../core/uncategorised/550/options.json | 3 + .../fixtures/core/uncategorised/551/actual.js | 1 + .../core/uncategorised/551/expected.json | 69 +++++++++++++++++++ .../fixtures/core/uncategorised/552/actual.js | 2 + .../core/uncategorised/552/options.json | 3 + .../fixtures/core/uncategorised/553/actual.js | 1 + .../core/uncategorised/553/expected.json | 69 +++++++++++++++++++ 13 files changed, 293 insertions(+), 9 deletions(-) create mode 100644 test/fixtures/core/uncategorised/355/expected.json delete mode 100644 test/fixtures/core/uncategorised/355/options.json create mode 100644 test/fixtures/core/uncategorised/356/expected.json delete mode 100644 test/fixtures/core/uncategorised/356/options.json create mode 100644 test/fixtures/core/uncategorised/550/actual.js create mode 100644 test/fixtures/core/uncategorised/550/options.json create mode 100644 test/fixtures/core/uncategorised/551/actual.js create mode 100644 test/fixtures/core/uncategorised/551/expected.json create mode 100644 test/fixtures/core/uncategorised/552/actual.js create mode 100644 test/fixtures/core/uncategorised/552/options.json create mode 100644 test/fixtures/core/uncategorised/553/actual.js create mode 100644 test/fixtures/core/uncategorised/553/expected.json diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index a058ba91a5..076b636381 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -564,7 +564,7 @@ export default class Tokenizer { readNumber(startsWithDot) { const start = this.state.pos; - const octal = this.input.charCodeAt(this.state.pos) === 48; + const firstIsZero = this.input.charCodeAt(start) === 48; // '0' let isFloat = false; if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number"); @@ -587,10 +587,12 @@ export default class Tokenizer { let val; if (isFloat) { val = parseFloat(str); - } else if (!octal || str.length === 1) { + } else if (!firstIsZero || str.length === 1) { val = parseInt(str, 10); - } else if (/[89]/.test(str) || this.state.strict) { + } else if (this.state.strict) { this.raise(start, "Invalid number"); + } else if (/[89]/.test(str)) { + val = parseInt(str, 10); } else { val = parseInt(str, 8); } diff --git a/test/fixtures/core/uncategorised/355/expected.json b/test/fixtures/core/uncategorised/355/expected.json new file mode 100644 index 0000000000..08de8c762b --- /dev/null +++ b/test/fixtures/core/uncategorised/355/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "extra": { + "rawValue": 9, + "raw": "09" + }, + "value": 9 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/355/options.json b/test/fixtures/core/uncategorised/355/options.json deleted file mode 100644 index cf3086295c..0000000000 --- a/test/fixtures/core/uncategorised/355/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Invalid number (1:0)" -} \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/356/expected.json b/test/fixtures/core/uncategorised/356/expected.json new file mode 100644 index 0000000000..6d04954399 --- /dev/null +++ b/test/fixtures/core/uncategorised/356/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "extra": { + "rawValue": 18, + "raw": "018" + }, + "value": 18 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/356/options.json b/test/fixtures/core/uncategorised/356/options.json deleted file mode 100644 index cf3086295c..0000000000 --- a/test/fixtures/core/uncategorised/356/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Invalid number (1:0)" -} \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/550/actual.js b/test/fixtures/core/uncategorised/550/actual.js new file mode 100644 index 0000000000..64dcf36896 --- /dev/null +++ b/test/fixtures/core/uncategorised/550/actual.js @@ -0,0 +1,2 @@ +'use strict'; +const a = 07; diff --git a/test/fixtures/core/uncategorised/550/options.json b/test/fixtures/core/uncategorised/550/options.json new file mode 100644 index 0000000000..f635fb88c5 --- /dev/null +++ b/test/fixtures/core/uncategorised/550/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Invalid number (2:10)" +} diff --git a/test/fixtures/core/uncategorised/551/actual.js b/test/fixtures/core/uncategorised/551/actual.js new file mode 100644 index 0000000000..524f32795d --- /dev/null +++ b/test/fixtures/core/uncategorised/551/actual.js @@ -0,0 +1 @@ +0111 \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/551/expected.json b/test/fixtures/core/uncategorised/551/expected.json new file mode 100644 index 0000000000..07311dd1eb --- /dev/null +++ b/test/fixtures/core/uncategorised/551/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "extra": { + "rawValue": 73, + "raw": "0111" + }, + "value": 73 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/552/actual.js b/test/fixtures/core/uncategorised/552/actual.js new file mode 100644 index 0000000000..63f4544f72 --- /dev/null +++ b/test/fixtures/core/uncategorised/552/actual.js @@ -0,0 +1,2 @@ +'use strict'; +const a = 08; diff --git a/test/fixtures/core/uncategorised/552/options.json b/test/fixtures/core/uncategorised/552/options.json new file mode 100644 index 0000000000..f635fb88c5 --- /dev/null +++ b/test/fixtures/core/uncategorised/552/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Invalid number (2:10)" +} diff --git a/test/fixtures/core/uncategorised/553/actual.js b/test/fixtures/core/uncategorised/553/actual.js new file mode 100644 index 0000000000..6b07531279 --- /dev/null +++ b/test/fixtures/core/uncategorised/553/actual.js @@ -0,0 +1 @@ +0274134317073 \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/553/expected.json b/test/fixtures/core/uncategorised/553/expected.json new file mode 100644 index 0000000000..756da7f491 --- /dev/null +++ b/test/fixtures/core/uncategorised/553/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "extra": { + "rawValue": 25257156155, + "raw": "0274134317073" + }, + "value": 25257156155 + } + } + ], + "directives": [] + } +} \ No newline at end of file From b98f463aa759979bbed1dd7704e66c7616e89d07 Mon Sep 17 00:00:00 2001 From: Alex Kuzmenko Date: Fri, 21 Apr 2017 16:22:50 +0300 Subject: [PATCH 38/73] Fixed invalid number literal parsing (#473) * Fixed invalid number literal parsing * Don't ignore period or E characters after octal numbers cherry-pick fix from acorn * Fix tests --- src/tokenizer/index.js | 12 ++++++++---- test/fixtures/core/uncategorised/554/actual.js | 1 + test/fixtures/core/uncategorised/554/options.json | 3 +++ 3 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/core/uncategorised/554/actual.js create mode 100644 test/fixtures/core/uncategorised/554/options.json diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index 076b636381..4031b008b1 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -564,30 +564,34 @@ export default class Tokenizer { readNumber(startsWithDot) { const start = this.state.pos; - const firstIsZero = this.input.charCodeAt(start) === 48; // '0' + let octal = this.input.charCodeAt(start) === 48; // '0' let isFloat = false; if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number"); + if (octal && this.state.pos == start + 1) octal = false; // number === 0 + let next = this.input.charCodeAt(this.state.pos); - if (next === 46) { // '.' + if (next === 46 && !octal) { // '.' ++this.state.pos; this.readInt(10); isFloat = true; next = this.input.charCodeAt(this.state.pos); } - if (next === 69 || next === 101) { // 'eE' + + if ((next === 69 || next === 101) && !octal) { // 'eE' next = this.input.charCodeAt(++this.state.pos); if (next === 43 || next === 45) ++this.state.pos; // '+-' if (this.readInt(10) === null) this.raise(start, "Invalid number"); isFloat = true; } + if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.state.pos, "Identifier directly after number"); const str = this.input.slice(start, this.state.pos); let val; if (isFloat) { val = parseFloat(str); - } else if (!firstIsZero || str.length === 1) { + } else if (!octal || str.length === 1) { val = parseInt(str, 10); } else if (this.state.strict) { this.raise(start, "Invalid number"); diff --git a/test/fixtures/core/uncategorised/554/actual.js b/test/fixtures/core/uncategorised/554/actual.js new file mode 100644 index 0000000000..204735a64f --- /dev/null +++ b/test/fixtures/core/uncategorised/554/actual.js @@ -0,0 +1 @@ +var a = 0123.; \ No newline at end of file diff --git a/test/fixtures/core/uncategorised/554/options.json b/test/fixtures/core/uncategorised/554/options.json new file mode 100644 index 0000000000..e247a786c1 --- /dev/null +++ b/test/fixtures/core/uncategorised/554/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token (1:13)" +} From 1077a7304ea923510e37744a2fba99fad2ae0d11 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Mon, 10 Apr 2017 10:48:51 -0500 Subject: [PATCH 39/73] Fix typo in flow spread operator error [skip ci] --- src/plugins/flow.js | 2 +- test/fixtures/flow/type-annotations/137/options.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 8b63c97207..eac336b2d2 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -451,7 +451,7 @@ pp.flowParseObjectType = function (allowStatic, allowExact, allowSpread) { if (!allowSpread) { this.unexpected( null, - "Spread operator cannnot appear in class or interface definitions" + "Spread operator cannot appear in class or interface definitions" ); } if (variance) { diff --git a/test/fixtures/flow/type-annotations/137/options.json b/test/fixtures/flow/type-annotations/137/options.json index 79756f8c33..786acad32a 100644 --- a/test/fixtures/flow/type-annotations/137/options.json +++ b/test/fixtures/flow/type-annotations/137/options.json @@ -1,3 +1,3 @@ { - "throws": "Spread operator cannnot appear in class or interface definitions (2:1)" + "throws": "Spread operator cannot appear in class or interface definitions (2:1)" } From 934a3a78b6e7115679be98d7bd27d9e5b236b8f4 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder Date: Wed, 10 May 2017 18:25:13 +0200 Subject: [PATCH 40/73] Update changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dda35be878..e64c141cac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,16 @@ _Note: Gaps between patch versions are faulty, broken or test releases._ See the [Babel Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) for the pre-6.8.0 version Changelog. +## 6.17.1 (2017-05-10) + + * Fix typo in flow spread operator error (Brian Ng) + * Fixed invalid number literal parsing ([#473](https://github.com/babel/babylon/pull/473)) (Alex Kuzmenko) + * Fix number parser ([#433](https://github.com/babel/babylon/pull/433)) (Alex Kuzmenko) + * Ensure non pattern shorthand props are checked for reserved words ([#479](https://github.com/babel/babylon/pull/479)) (Brian Ng) + * Remove jsx context when parsing arrow functions ([#475](https://github.com/babel/babylon/pull/475)) (Brian Ng) + * Allow super in class properties ([#499](https://github.com/babel/babylon/pull/499)) (Brian Ng) + * Allow flow class field to be named constructor ([#510](https://github.com/babel/babylon/pull/510)) (Brian Ng) + ## 6.17.0 (2017-04-20) * Cherry-pick #418 to 6.x ([#476](https://github.com/babel/babylon/pull/476)) (Sebastian McKenzie) From 28985e7acc4de4e68fde74311ddc47175fccfa22 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder Date: Wed, 10 May 2017 18:25:58 +0200 Subject: [PATCH 41/73] 6.17.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a7adfa725b..dab549eb7b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "babylon", - "version": "6.17.0", + "version": "6.17.1", "description": "A JavaScript parser", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", From 7f9eb50b2c689e83697d4d8ff48f12f7b3a02d35 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder Date: Wed, 10 May 2017 18:40:12 +0200 Subject: [PATCH 42/73] Fix changelog --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd907247d6..1e2bbac604 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -145,8 +145,6 @@ Need to modify Babel for this AST node change, so moving to 7.0. [react-native](https://github.com/facebook/react-native/issues/12542) broke with this so we reverted. -======= ->>>>>>> 6.x ## 6.16.0 (2017-02-23) ### :rocket: New Feature From 4e776bf00be93fcea0985cd4583820835e95c8dd Mon Sep 17 00:00:00 2001 From: Alex Rattray Date: Wed, 10 May 2017 12:26:38 -0700 Subject: [PATCH 43/73] Better error message for anonymous class declarations (#509) --- src/parser/statement.js | 2 +- test/fixtures/es2015/uncategorised/263/options.json | 4 ++-- .../esprima/invalid-syntax/migrated_0261/options.json | 4 ++-- .../esprima/invalid-syntax/migrated_0262/options.json | 4 ++-- .../esprima/invalid-syntax/migrated_0263/options.json | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/parser/statement.js b/src/parser/statement.js index 9979f6a388..74a2a277dd 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -804,7 +804,7 @@ export default class StatementParser extends ExpressionParser { if (optionalId || !isStatement) { node.id = null; } else { - this.unexpected(); + this.unexpected(null, "A class name is required"); } } } diff --git a/test/fixtures/es2015/uncategorised/263/options.json b/test/fixtures/es2015/uncategorised/263/options.json index 515b971673..2b34d4c1e1 100644 --- a/test/fixtures/es2015/uncategorised/263/options.json +++ b/test/fixtures/es2015/uncategorised/263/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected token (1:6)" -} \ No newline at end of file + "throws": "A class name is required (1:6)" +} diff --git a/test/fixtures/esprima/invalid-syntax/migrated_0261/options.json b/test/fixtures/esprima/invalid-syntax/migrated_0261/options.json index 0ab445fe47..ffd3a3ed26 100644 --- a/test/fixtures/esprima/invalid-syntax/migrated_0261/options.json +++ b/test/fixtures/esprima/invalid-syntax/migrated_0261/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected token (1:5)" -} \ No newline at end of file + "throws": "A class name is required (1:5)" +} diff --git a/test/fixtures/esprima/invalid-syntax/migrated_0262/options.json b/test/fixtures/esprima/invalid-syntax/migrated_0262/options.json index 0ab445fe47..ffd3a3ed26 100644 --- a/test/fixtures/esprima/invalid-syntax/migrated_0262/options.json +++ b/test/fixtures/esprima/invalid-syntax/migrated_0262/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected token (1:5)" -} \ No newline at end of file + "throws": "A class name is required (1:5)" +} diff --git a/test/fixtures/esprima/invalid-syntax/migrated_0263/options.json b/test/fixtures/esprima/invalid-syntax/migrated_0263/options.json index 0ab445fe47..ffd3a3ed26 100644 --- a/test/fixtures/esprima/invalid-syntax/migrated_0263/options.json +++ b/test/fixtures/esprima/invalid-syntax/migrated_0263/options.json @@ -1,3 +1,3 @@ { - "throws": "Unexpected token (1:5)" -} \ No newline at end of file + "throws": "A class name is required (1:5)" +} From 1f113fd650a3924c48b41e8f6e135c9e066f4044 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 10 May 2017 12:29:05 -0700 Subject: [PATCH 44/73] Fix FunctionDeclaration spec: Id may be null (#503) * Fix FunctionDeclaration spec: Id may be null * Use OptFunctionDeclaration and OptFunctionExpression --- ast/spec.md | 18 +++++++++++++----- src/types.js | 16 +++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/ast/spec.md b/ast/spec.md index 0ff1c87c51..07c6a6482d 100644 --- a/ast/spec.md +++ b/ast/spec.md @@ -144,13 +144,13 @@ interface Position { ### Babylon 7 Flow: Node renamed from `ExistentialTypeParam` to `ExistsTypeAnnotation` [#322](https://github.com/babel/babylon/pull/322) - + Flow: Node renamed from `NumericLiteralTypeAnnotation` to `NumberLiteralTypeAnnotation` [babel/babylon#332](https://github.com/babel/babylon/pull/332) - + Flow: Node `Variance` which replaces the string value of the `variance` field on several nodes [babel/babylon#333](https://github.com/babel/babylon/pull/333) Flow: `ObjectTypeIndexer` location info matches Flow's better [babel/babylon#228](https://github.com/babel/babylon/pull/228) - + Node `ForAwaitStatement` has been removed [#349](https://github.com/babel/babylon/pull/349) in favor of modifying `ForOfStatement` `RestProperty` and `SpreadProperty` have been dropped in favor of `RestElement` and `SpreadElement`. @@ -514,7 +514,7 @@ interface FunctionDeclaration <: Function, Declaration { } ``` -A function declaration. Note that unlike in the parent interface `Function`, the `id` cannot be `null`. +A function declaration. Note that unlike in the parent interface `Function`, the `id` cannot be `null`, except when this is the child of an `ExportDefaultDeclaration`. ## VariableDeclaration @@ -1166,9 +1166,17 @@ An exported variable binding, e.g., `{foo}` in `export {foo}` or `{bar as foo}` ### ExportDefaultDeclaration ```js +interface OptFunctionDeclaration <: FunctionDeclaration { + id: Identifier | null; +} + +interface OptClasDeclaration <: ClassDeclaration { + id: Identifier | null; +} + interface ExportDefaultDeclaration <: ModuleDeclaration { type: "ExportDefaultDeclaration"; - declaration: Declaration | Expression; + declaration: OptFunctionDeclaration | OptClassDeclaration | Expression; } ``` diff --git a/src/types.js b/src/types.js index b42f72a154..e76d738994 100644 --- a/src/types.js +++ b/src/types.js @@ -266,11 +266,14 @@ export type ForOfStatement = ForInOfBase & { // Declarations -export type FunctionDeclaration = FunctionBase & DeclarationBase & HasDecorators & { +export type OptFunctionDeclaration = FunctionBase & DeclarationBase & HasDecorators & { type: "FunctionDeclaration"; - id: Identifier; }; +export type FunctionDeclaration = OptFunctionDeclaration & { + id: Identifier; +} + export type VariableDeclaration = DeclarationBase & HasDecorators & { type: "VariableDeclaration"; declarations: $ReadOnlyArray; @@ -581,13 +584,16 @@ export type ClassProperty = ClassMemberBase & { readonly?: true; }; -export type ClassDeclaration = ClassBase & DeclarationBase & HasDecorators & { +export type OptClassDeclaration = ClassBase & DeclarationBase & HasDecorators & { type: "ClassDeclaration"; - id: Identifier; // TypeScript only abstract?: ?true; }; +export type ClassDeclaration = OptClassDeclaration & { + id: Identifier; +}; + export type ClassExpression = ClassBase & { type: "ClassExpression" }; export type MetaProperty = NodeBase & { @@ -653,7 +659,7 @@ export type ExportSpecifier = NodeBase & { export type ExportDefaultDeclaration = NodeBase & { type: "ExportDefaultDeclaration"; - declaration: Declaration | Expression; + declaration: OptFunctionDeclaration | OptClassDeclaration | Expression; }; export type ExportAllDeclaration = NodeBase & { From 8862c9623761a43a705cb3cb766824f1aeb2532d Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Wed, 10 May 2017 21:50:30 +0200 Subject: [PATCH 45/73] =?UTF-8?q?Update=20flow-bin=20to=20the=20latest=20v?= =?UTF-8?q?ersion=20=F0=9F=9A=80=20(#497)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(package): update flow-bin to version 0.45.0 https://greenkeeper.io/ * Update yarn.lock --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 3280a72a9a..8389e7e451 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "eslint": "^3.7.1", "eslint-config-babel": "^6.0.0", "eslint-plugin-flowtype": "^2.20.0", - "flow-bin": "^0.44.0", + "flow-bin": "^0.46.0", "nyc": "^10.0.0", "rimraf": "^2.5.4", "rollup": "^0.41.0", diff --git a/yarn.lock b/yarn.lock index f9d3433784..a5dc687ace 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1994,9 +1994,9 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -flow-bin@^0.44.0: - version "0.44.2" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.44.2.tgz#3893c7db5de043ed82674f327a04b1309db208b5" +flow-bin@^0.46.0: + version "0.46.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.46.0.tgz#06ad7fe19dddb1042264438064a2a32fee12b872" fn-name@^2.0.0: version "2.0.1" From 1773ca74578b44200ff754534299a7fd1962adbd Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 10 May 2017 12:55:09 -0700 Subject: [PATCH 46/73] Type-check State (#492) --- src/parser/comments.js | 2 +- src/tokenizer/index.js | 1 + src/tokenizer/state.js | 42 +++++++++++++++++++++++++++++------------- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/parser/comments.js b/src/parser/comments.js index c39f91e44a..96e339389b 100644 --- a/src/parser/comments.js +++ b/src/parser/comments.js @@ -29,7 +29,7 @@ import BaseParser from "./base"; import type { Comment, Node } from "../types"; -function last(stack) { +function last(stack: $ReadOnlyArray): T { return stack[stack.length - 1]; } diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index 34f75fa490..42273d664c 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -626,6 +626,7 @@ export default class Tokenizer extends LocationParser { code = this.readHexChar(this.input.indexOf("}", this.state.pos) - this.state.pos, throwOnInvalid); ++this.state.pos; if (code === null) { + // $FlowFixMe (is this always non-null?) --this.state.invalidTemplateEscapePosition; // to point to the '\'' instead of the 'u' } else if (code > 0x10FFFF) { if (throwOnInvalid) { diff --git a/src/tokenizer/state.js b/src/tokenizer/state.js index 1bbfbda23d..3200c4e646 100644 --- a/src/tokenizer/state.js +++ b/src/tokenizer/state.js @@ -1,11 +1,17 @@ +// @flow + +import type { Options } from "../options"; +import * as N from "../types"; + import type { TokContext } from "./context"; +import type { Token } from "./index"; import type { TokenType } from "./types"; import { Position } from "../util/location"; import { types as ct } from "./context"; import { types as tt } from "./types"; export default class State { - init(options: Object, input: string) { + init(options: Options, input: string): void { this.strict = options.strictMode === false ? false : options.sourceType === "module"; this.input = input; @@ -70,28 +76,34 @@ export default class State { // Flags to track whether we are in a function, a generator. inFunction: boolean; inGenerator: boolean; - inMethod: boolean; + inMethod: boolean | N.MethodKind; inAsync: boolean; inType: boolean; + noAnonFunctionType: boolean; inPropertyName: boolean; inClassProperty: boolean; // Labels in scope. - labels: Array; + labels: Array<{ kind: ?("loop" | "switch"), statementStart?: number }>; // Leading decorators. - decorators: Array; + decorators: Array; // Token store. - tokens: Array; + tokens: Array; // Comment store. - comments: Array; + comments: Array; // Comment attachment store - trailingComments: Array; - leadingComments: Array; - commentStack: Array; + trailingComments: Array; + leadingComments: Array; + commentStack: Array<{ + start: number; + leadingComments: ?Array; + trailingComments: ?Array; + }>; + commentPreviousNode: N.Node; // The current position of the tokenizer in the input. pos: number; @@ -115,8 +127,8 @@ export default class State { endLoc: Position; // Position information for the previous token - lastTokEndLoc: ?Position; - lastTokStartLoc: ?Position; + lastTokEndLoc: Position; + lastTokStartLoc: Position; lastTokStart: number; lastTokEnd: number; @@ -139,19 +151,23 @@ export default class State { // `export default foo;` and `export { foo as default };`. exportedIdentifiers: Array; - curPosition() { + invalidTemplateEscapePosition: ?number; + + curPosition(): Position { return new Position(this.curLine, this.pos - this.lineStart); } - clone(skipArrays?) { + clone(skipArrays?: boolean): State { const state = new State; for (const key in this) { + // $FlowIgnore let val = this[key]; if ((!skipArrays || key === "context") && Array.isArray(val)) { val = val.slice(); } + // $FlowIgnore state[key] = val; } return state; From d605a9a4de61a21e00468ca3d84df52275a2f07b Mon Sep 17 00:00:00 2001 From: Daniel Tschinder Date: Thu, 11 May 2017 00:04:43 +0200 Subject: [PATCH 47/73] Fix flow errors (#517) --- src/tokenizer/state.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tokenizer/state.js b/src/tokenizer/state.js index 3200c4e646..8fe08ac001 100644 --- a/src/tokenizer/state.js +++ b/src/tokenizer/state.js @@ -48,6 +48,7 @@ export default class State { this.start = this.end = this.pos; this.startLoc = this.endLoc = this.curPosition(); + // $FlowIgnore this.lastTokEndLoc = this.lastTokStartLoc = null; this.lastTokStart = this.lastTokEnd = this.pos; @@ -60,8 +61,6 @@ export default class State { this.invalidTemplateEscapePosition = null; this.exportedIdentifiers = []; - - return this; } // TODO From f6020aecbf6f716241e755d7358018454ae11332 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder Date: Thu, 11 May 2017 00:45:08 +0200 Subject: [PATCH 48/73] Convert argument of SpreadElement correctly to assignable (#518) --- src/parser/lval.js | 8 +- .../es2015/destructuring/nested/actual.js | 1 + .../es2015/destructuring/nested/expected.json | 300 ++++++++++++++++++ .../es2015/destructuring/nested/options.json | 3 + 4 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/es2015/destructuring/nested/actual.js create mode 100644 test/fixtures/es2015/destructuring/nested/expected.json create mode 100644 test/fixtures/es2015/destructuring/nested/options.json diff --git a/src/parser/lval.js b/src/parser/lval.js index 811c37038a..8576198b61 100644 --- a/src/parser/lval.js +++ b/src/parser/lval.js @@ -52,6 +52,8 @@ export default class LValParser extends NodeUtils { case "SpreadElement": node.type = "RestElement"; + const arg = node.argument; + this.toAssignable(arg, isBinding, contextDescription); break; case "ArrayExpression": @@ -94,7 +96,11 @@ export default class LValParser extends NodeUtils { last.type = "RestElement"; const arg = last.argument; this.toAssignable(arg, isBinding, contextDescription); - if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") { + if ( + arg.type !== "Identifier" && + arg.type !== "MemberExpression" && + arg.type !== "ArrayPattern" + ) { this.unexpected(arg.start); } --end; diff --git a/test/fixtures/es2015/destructuring/nested/actual.js b/test/fixtures/es2015/destructuring/nested/actual.js new file mode 100644 index 0000000000..aa9fada3b4 --- /dev/null +++ b/test/fixtures/es2015/destructuring/nested/actual.js @@ -0,0 +1 @@ +({ x, ...{ y, z } } = o) diff --git a/test/fixtures/es2015/destructuring/nested/expected.json b/test/fixtures/es2015/destructuring/nested/expected.json new file mode 100644 index 0000000000..a1ab80ecf3 --- /dev/null +++ b/test/fixtures/es2015/destructuring/nested/expected.json @@ -0,0 +1,300 @@ +{ + "type": "File", + "start": 0, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 1, + "end": 23, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 23 + } + }, + "operator": "=", + "left": { + "type": "ObjectPattern", + "start": 1, + "end": 19, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 19 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 3, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "method": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 3, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 4 + }, + "identifierName": "x" + }, + "name": "x" + }, + "shorthand": true, + "value": { + "type": "Identifier", + "start": 3, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 4 + }, + "identifierName": "x" + }, + "name": "x" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "RestElement", + "start": 6, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 17 + } + }, + "argument": { + "type": "ObjectPattern", + "start": 9, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 17 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 11, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "method": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 11, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + }, + "identifierName": "y" + }, + "name": "y" + }, + "shorthand": true, + "value": { + "type": "Identifier", + "start": 11, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + }, + "identifierName": "y" + }, + "name": "y" + }, + "extra": { + "shorthand": true + } + }, + { + "type": "ObjectProperty", + "start": 14, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "method": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 14, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 15 + }, + "identifierName": "z" + }, + "name": "z" + }, + "shorthand": true, + "value": { + "type": "Identifier", + "start": 14, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 15 + }, + "identifierName": "z" + }, + "name": "z" + }, + "extra": { + "shorthand": true + } + } + ] + } + } + ] + }, + "right": { + "type": "Identifier", + "start": 22, + "end": 23, + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 1, + "column": 23 + }, + "identifierName": "o" + }, + "name": "o" + }, + "extra": { + "parenthesized": true, + "parenStart": 0 + } + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/es2015/destructuring/nested/options.json b/test/fixtures/es2015/destructuring/nested/options.json new file mode 100644 index 0000000000..527f225b5b --- /dev/null +++ b/test/fixtures/es2015/destructuring/nested/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["objectRestSpread"] +} From 7a8b64c0d38e615903b484aa1b3e99ebbd21ddbe Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 11 May 2017 07:28:12 -0700 Subject: [PATCH 49/73] Type-check StatementParser (#489) --- src/parser/statement.js | 143 +++++++++++++++++++++------------------- src/types.js | 2 +- 2 files changed, 76 insertions(+), 69 deletions(-) diff --git a/src/parser/statement.js b/src/parser/statement.js index 74a2a277dd..153b614ce0 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -1,7 +1,11 @@ /* eslint max-len: 0 */ -import { types as tt } from "../tokenizer/types"; +// @flow + +import * as N from "../types"; +import { types as tt, TokenType } from "../tokenizer/types"; import ExpressionParser from "./expression"; +import type { Position } from "../util/location"; import { lineBreak } from "../util/whitespace"; // Reused empty array added for node fields that are always empty. @@ -19,7 +23,7 @@ export default class StatementParser extends ExpressionParser { // `program` argument. If present, the statements will be appended // to its body instead of creating a new node. - parseTopLevel(file, program) { + parseTopLevel(file: N.File, program: N.Program): N.File { program.sourceType = this.options.sourceType; this.parseBlockBody(program, true, true, tt.eof); @@ -33,7 +37,7 @@ export default class StatementParser extends ExpressionParser { // TODO - stmtToDirective(stmt) { + stmtToDirective(stmt: N.Statement): N.Directive { const expr = stmt.expression; const directiveLiteral = this.startNodeAt(expr.start, expr.loc.start); @@ -57,7 +61,7 @@ export default class StatementParser extends ExpressionParser { // `if (foo) /blah/.exec(foo)`, where looking at the previous token // does not help. - parseStatement(declaration, topLevel) { + parseStatement(declaration: boolean, topLevel?: boolean): N.Statement { if (this.match(tt.at)) { this.parseDecorators(true); } @@ -143,14 +147,14 @@ export default class StatementParser extends ExpressionParser { } } - takeDecorators(node) { + takeDecorators(node: N.HasDecorators): void { if (this.state.decorators.length) { node.decorators = this.state.decorators; this.state.decorators = []; } } - parseDecorators(allowExport) { + parseDecorators(allowExport?: boolean): void { while (this.match(tt.at)) { const decorator = this.parseDecorator(); this.state.decorators.push(decorator); @@ -165,7 +169,7 @@ export default class StatementParser extends ExpressionParser { } } - parseDecorator() { + parseDecorator(): N.Decorator { if (!this.hasPlugin("decorators")) { this.unexpected(); } @@ -175,7 +179,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "Decorator"); } - parseBreakContinueStatement(node, keyword) { + parseBreakContinueStatement(node: N.BreakStatement | N.ContinueStatement, keyword: string): N.BreakStatement | N.ContinueStatement { const isBreak = keyword === "break"; this.next(); @@ -202,13 +206,13 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement"); } - parseDebuggerStatement(node) { + parseDebuggerStatement(node: N.DebuggerStatement): N.DebuggerStatement { this.next(); this.semicolon(); return this.finishNode(node, "DebuggerStatement"); } - parseDoStatement(node) { + parseDoStatement(node: N.DoWhileStatement): N.DoWhileStatement { this.next(); this.state.labels.push(loopLabel); node.body = this.parseStatement(false); @@ -227,7 +231,7 @@ export default class StatementParser extends ExpressionParser { // part (semicolon immediately after the opening parenthesis), it // is a regular `for` loop. - parseForStatement(node) { + parseForStatement(node: N.Node): N.ForLike { this.next(); this.state.labels.push(loopLabel); @@ -279,12 +283,12 @@ export default class StatementParser extends ExpressionParser { return this.parseFor(node, init); } - parseFunctionStatement(node) { + parseFunctionStatement(node: N.FunctionDeclaration): N.FunctionDeclaration { this.next(); return this.parseFunction(node, true); } - parseIfStatement(node) { + parseIfStatement(node: N.IfStatement): N.IfStatement { this.next(); node.test = this.parseParenExpression(); node.consequent = this.parseStatement(false); @@ -292,7 +296,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "IfStatement"); } - parseReturnStatement(node) { + parseReturnStatement(node: N.ReturnStatement): N.ReturnStatement { if (!this.state.inFunction && !this.options.allowReturnOutsideFunction) { this.raise(this.state.start, "'return' outside of function"); } @@ -313,10 +317,10 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "ReturnStatement"); } - parseSwitchStatement(node) { + parseSwitchStatement(node: N.SwitchStatement): N.SwitchStatement { this.next(); node.discriminant = this.parseParenExpression(); - node.cases = []; + const cases = node.cases = []; this.expect(tt.braceL); this.state.labels.push(switchLabel); @@ -329,7 +333,7 @@ export default class StatementParser extends ExpressionParser { if (this.match(tt._case) || this.match(tt._default)) { const isCase = this.match(tt._case); if (cur) this.finishNode(cur, "SwitchCase"); - node.cases.push(cur = this.startNode()); + cases.push(cur = this.startNode()); cur.consequent = []; this.next(); if (isCase) { @@ -354,7 +358,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "SwitchStatement"); } - parseThrowStatement(node) { + parseThrowStatement(node: N.ThrowStatement): N.ThrowStatement { this.next(); if (lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start))) this.raise(this.state.lastTokEnd, "Illegal newline after throw"); @@ -363,7 +367,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "ThrowStatement"); } - parseTryStatement(node) { + parseTryStatement(node: N.TryStatement): N.TryStatement { this.next(); node.block = this.parseBlock(); @@ -392,14 +396,14 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "TryStatement"); } - parseVarStatement(node, kind) { + parseVarStatement(node: N.VariableDeclaration, kind: TokenType): N.VariableDeclaration { this.next(); this.parseVar(node, false, kind); this.semicolon(); return this.finishNode(node, "VariableDeclaration"); } - parseWhileStatement(node) { + parseWhileStatement(node: N.WhileStatement): N.WhileStatement { this.next(); node.test = this.parseParenExpression(); this.state.labels.push(loopLabel); @@ -408,7 +412,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "WhileStatement"); } - parseWithStatement(node) { + parseWithStatement(node: N.WithStatement): N.WithStatement { if (this.state.strict) this.raise(this.state.start, "'with' in strict mode"); this.next(); node.object = this.parseParenExpression(); @@ -416,13 +420,13 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "WithStatement"); } - parseEmptyStatement(node) { + parseEmptyStatement(node: N.EmptyStatement): N.EmptyStatement { this.next(); return this.finishNode(node, "EmptyStatement"); } - parseLabeledStatement(node, maybeName, expr) { - for (const label of (this.state.labels: Array)) { + parseLabeledStatement(node: N.LabeledStatement, maybeName: string, expr: N.Identifier): N.LabeledStatement { + for (const label of this.state.labels) { if (label.name === maybeName) { this.raise(expr.start, `Label '${maybeName}' is already declared`); } @@ -446,7 +450,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "LabeledStatement"); } - parseExpressionStatement(node, expr) { + parseExpressionStatement(node: N.ExpressionStatement, expr: N.Expression): N.ExpressionStatement { node.expression = expr; this.semicolon(); return this.finishNode(node, "ExpressionStatement"); @@ -456,22 +460,22 @@ export default class StatementParser extends ExpressionParser { // strict"` declarations when `allowStrict` is true (used for // function bodies). - parseBlock(allowDirectives?) { + parseBlock(allowDirectives?: boolean): N.BlockStatement { const node = this.startNode(); this.expect(tt.braceL); this.parseBlockBody(node, allowDirectives, false, tt.braceR); return this.finishNode(node, "BlockStatement"); } - isValidDirective(stmt) { + isValidDirective(stmt: N.Statement): boolean { return stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && !stmt.expression.extra.parenthesized; } - parseBlockBody(node, allowDirectives, topLevel, end) { - node.body = []; - node.directives = []; + parseBlockBody(node: N.BlockStatementLike, allowDirectives: ?boolean, topLevel: boolean, end: TokenType): void { + const body = node.body = []; + const directives = node.directives = []; let parsedNonDirective = false; let oldStrict; @@ -486,7 +490,7 @@ export default class StatementParser extends ExpressionParser { if (allowDirectives && !parsedNonDirective && this.isValidDirective(stmt)) { const directive = this.stmtToDirective(stmt); - node.directives.push(directive); + directives.push(directive); if (oldStrict === undefined && directive.value.value === "use strict") { oldStrict = this.state.strict; @@ -501,7 +505,7 @@ export default class StatementParser extends ExpressionParser { } parsedNonDirective = true; - node.body.push(stmt); + body.push(stmt); } if (oldStrict === false) { @@ -513,7 +517,7 @@ export default class StatementParser extends ExpressionParser { // `parseStatement` will already have parsed the init statement or // expression. - parseFor(node, init) { + parseFor(node: N.ForStatement, init: ?(N.VariableDeclaration | N.Expression)): N.ForStatement { node.init = init; this.expect(tt.semi); node.test = this.match(tt.semi) ? null : this.parseExpression(); @@ -528,7 +532,7 @@ export default class StatementParser extends ExpressionParser { // Parse a `for`/`in` and `for`/`of` loop, which are almost // same from parser's perspective. - parseForIn(node, init, forAwait) { + parseForIn(node: N.ForInOf, init: N.VariableDeclaration, forAwait: boolean): N.ForInOf { const type = this.match(tt._in) ? "ForInStatement" : "ForOfStatement"; if (forAwait) { this.eatContextual("of"); @@ -548,8 +552,8 @@ export default class StatementParser extends ExpressionParser { // Parse a list of variable declarations. - parseVar(node, isFor, kind) { - node.declarations = []; + parseVar(node: N.VariableDeclaration, isFor: boolean, kind: TokenType): N.VariableDeclaration { + const declarations = node.declarations = []; node.kind = kind.keyword; for (;;) { const decl = this.startNode(); @@ -563,13 +567,13 @@ export default class StatementParser extends ExpressionParser { } else { decl.init = null; } - node.declarations.push(this.finishNode(decl, "VariableDeclarator")); + declarations.push(this.finishNode(decl, "VariableDeclarator")); if (!this.eat(tt.comma)) break; } return node; } - parseVarHead(decl) { + parseVarHead(decl: N.VariableDeclarator): void { decl.id = this.parseBindingAtom(); this.checkLVal(decl.id, true, undefined, "variable declaration"); } @@ -577,7 +581,7 @@ export default class StatementParser extends ExpressionParser { // Parse a function declaration or literal (depending on the // `isStatement` parameter). - parseFunction(node, isStatement, allowExpressionBody, isAsync, optionalId) { + parseFunction(node: T, isStatement: boolean, allowExpressionBody?: boolean, isAsync?: boolean, optionalId?: boolean): T { const oldInMethod = this.state.inMethod; this.state.inMethod = false; @@ -608,7 +612,7 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); } - parseFunctionParams(node) { + parseFunctionParams(node: N.NormalFunction): void { this.expect(tt.parenL); node.params = this.parseBindingList(tt.parenR); } @@ -616,7 +620,7 @@ export default class StatementParser extends ExpressionParser { // Parse a class declaration or literal (depending on the // `isStatement` parameter). - parseClass(node, isStatement, optionalId) { + parseClass(node: N.Class, isStatement: boolean, optionalId?: boolean): N.Class { this.next(); this.takeDecorators(node); this.parseClassId(node, isStatement, optionalId); @@ -625,22 +629,22 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression"); } - isClassProperty() { + isClassProperty(): boolean { return this.match(tt.eq) || this.match(tt.semi) || this.match(tt.braceR); } - isClassMethod() { + isClassMethod(): boolean { return this.match(tt.parenL); } - isNonstaticConstructor(method) { + isNonstaticConstructor(method: N.ClassMethod): boolean { return !method.computed && !method.static && ( (method.key.name === "constructor") || // Identifier (method.key.value === "constructor") // Literal ); } - parseClassBody(node) { + parseClassBody(node: N.Class): void { // class bodies are implicitly strict const oldStrict = this.state.strict; this.state.strict = true; @@ -771,7 +775,7 @@ export default class StatementParser extends ExpressionParser { this.state.strict = oldStrict; } - parseClassProperty(node) { + parseClassProperty(node: N.ClassProperty): N.ClassProperty { const hasPlugin = this.hasPlugin("classProperties"); const noPluginMsg = "You can only use Class Properties when the 'classProperties' plugin is enabled."; if (!node.typeAnnotation && !hasPlugin) { @@ -792,12 +796,12 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "ClassProperty"); } - parseClassMethod(classBody, method, isGenerator, isAsync) { + parseClassMethod(classBody: N.ClassBody, method: N.ClassMethod, isGenerator: boolean, isAsync: boolean): void { this.parseMethod(method, isGenerator, isAsync); classBody.body.push(this.finishNode(method, "ClassMethod")); } - parseClassId(node, isStatement, optionalId) { + parseClassId(node: N.Class, isStatement: boolean, optionalId: ?boolean): void { if (this.match(tt.name)) { node.id = this.parseIdentifier(); } else { @@ -809,13 +813,13 @@ export default class StatementParser extends ExpressionParser { } } - parseClassSuper(node) { + parseClassSuper(node: N.Class): void { node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null; } // Parses module export declaration. - parseExport(node) { + parseExport(node: N.ExportNamedDeclaration): N.ExportNamedDeclaration { this.eat(tt._export); // export * from '...' @@ -834,14 +838,15 @@ export default class StatementParser extends ExpressionParser { } else if (this.hasPlugin("exportExtensions") && this.isExportDefaultSpecifier()) { const specifier = this.startNode(); specifier.exported = this.parseIdentifier(true); - node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; + const specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; + node.specifiers = specifiers; if (this.match(tt.comma) && this.lookahead().type === tt.star) { this.expect(tt.comma); const specifier = this.startNode(); this.expect(tt.star); this.expectContextual("as"); specifier.exported = this.parseIdentifier(); - node.specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier")); + specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier")); } else { this.parseExportSpecifiersMaybe(node); } @@ -864,6 +869,7 @@ export default class StatementParser extends ExpressionParser { needsSemi = true; expr = this.parseMaybeAssign(); } + // $FlowFixMe node.declaration = expr; if (needsSemi) this.semicolon(); this.checkExport(node, true, true); @@ -881,11 +887,11 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "ExportNamedDeclaration"); } - parseExportDeclaration() { + parseExportDeclaration(): N.Declaration { return this.parseStatement(true); } - isExportDefaultSpecifier() { + isExportDefaultSpecifier(): boolean { if (this.match(tt.name)) { return this.state.value !== "type" && this.state.value !== "async" @@ -900,13 +906,13 @@ export default class StatementParser extends ExpressionParser { return lookahead.type === tt.comma || (lookahead.type === tt.name && lookahead.value === "from"); } - parseExportSpecifiersMaybe(node) { + parseExportSpecifiersMaybe(node: N.ExportNamedDeclaration): void { if (this.eat(tt.comma)) { node.specifiers = node.specifiers.concat(this.parseExportSpecifiers()); } } - parseExportFrom(node, expect?) { + parseExportFrom(node: N.ExportNamedDeclaration, expect?: boolean): void { if (this.eatContextual("from")) { node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected(); this.checkExport(node); @@ -930,7 +936,7 @@ export default class StatementParser extends ExpressionParser { || this.isContextual("async"); } - checkExport(node, checkNames, isDefault) { + checkExport(node: N.ExportNamedDeclaration, checkNames: ?boolean, isDefault: ?boolean): void { if (checkNames) { // Check for duplicate exports if (isDefault) { @@ -956,15 +962,16 @@ export default class StatementParser extends ExpressionParser { if (this.state.decorators.length) { const isClass = node.declaration && (node.declaration.type === "ClassDeclaration" || node.declaration.type === "ClassExpression"); if (!node.declaration || !isClass) { - this.raise(node.start, "You can only use decorators on an export when exporting a class"); + throw this.raise(node.start, "You can only use decorators on an export when exporting a class"); } this.takeDecorators(node.declaration); } } - checkDeclaration(node) { + checkDeclaration(node: N.Pattern): void { if (node.type === "ObjectPattern") { for (const prop of node.properties) { + // $FlowFixMe (prop may be an AssignmentProperty, in which case this does nothing?) this.checkDeclaration(prop); } } else if (node.type === "ArrayPattern") { @@ -982,15 +989,15 @@ export default class StatementParser extends ExpressionParser { } } - checkDuplicateExports(node, name) { + checkDuplicateExports(node: N.Identifier | N.ExportNamedDeclaration | N.ExportSpecifier, name: string): void { if (this.state.exportedIdentifiers.indexOf(name) > -1) { this.raiseDuplicateExportError(node, name); } this.state.exportedIdentifiers.push(name); } - raiseDuplicateExportError(node, name) { - this.raise(node.start, name === "default" ? + raiseDuplicateExportError(node: N.Identifier | N.ExportNamedDeclaration | N.ExportSpecifier, name: string): empty { + throw this.raise(node.start, name === "default" ? "Only one default export allowed per module." : `\`${name}\` has already been exported. Exported identifiers must be unique.` ); @@ -998,7 +1005,7 @@ export default class StatementParser extends ExpressionParser { // Parses a comma-separated list of module exports. - parseExportSpecifiers() { + parseExportSpecifiers(): $ReadOnlyArray { const nodes = []; let first = true; let needsFrom; @@ -1033,7 +1040,7 @@ export default class StatementParser extends ExpressionParser { // Parses import declaration. - parseImport(node) { + parseImport(node: N.ImportDeclaration): N.ImportDeclaration { this.eat(tt._import); // import '...' @@ -1052,7 +1059,7 @@ export default class StatementParser extends ExpressionParser { // Parses a comma-separated list of module imports. - parseImportSpecifiers(node) { + parseImportSpecifiers(node: N.ImportDeclaration): void { let first = true; if (this.match(tt.name)) { // import defaultObj, { x, y as z } from '...' @@ -1090,7 +1097,7 @@ export default class StatementParser extends ExpressionParser { } } - parseImportSpecifier(node) { + parseImportSpecifier(node: N.ImportDeclaration): void { const specifier = this.startNode(); specifier.imported = this.parseIdentifier(true); if (this.eatContextual("as")) { @@ -1103,7 +1110,7 @@ export default class StatementParser extends ExpressionParser { node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); } - parseImportSpecifierDefault(id, startPos, startLoc) { + parseImportSpecifierDefault(id: N.Identifier, startPos: number, startLoc: Position): N.ImportDefaultSpecifier { const node = this.startNodeAt(startPos, startLoc); node.local = id; this.checkLVal(node.local, true, undefined, "default import specifier"); diff --git a/src/types.js b/src/types.js index e76d738994..50e8bd95d3 100644 --- a/src/types.js +++ b/src/types.js @@ -646,7 +646,7 @@ export type ImportNamespaceSpecifier = ModuleSpecifier & { export type ExportNamedDeclaration = NodeBase & { type: "ExportNamedDeclaration"; declaration: ?Declaration; - specifiers: Array; // TODO: $ReadOnlyArray + specifiers: $ReadOnlyArray; source: ?Literal; exportKind?: "type" | "value"; // TODO: Not in spec From a73887047216797e05fef911ee9a5e9fa466a2e1 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 11 May 2017 07:30:21 -0700 Subject: [PATCH 50/73] Type-check ExpressionParser (#488) * Type-check ExpressionParser * Improve test coverage --- src/parser/expression.js | 115 +++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 52 deletions(-) diff --git a/src/parser/expression.js b/src/parser/expression.js index dac08cec24..f11180ac42 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -1,5 +1,7 @@ /* eslint max-len: 0 */ +// @flow + // A recursive descent parser operates by defining functions for all // syntactic elements, and recursively calling those, each function // advancing the input stream and returning an AST node. Precedence @@ -18,17 +20,26 @@ // // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser -import { types as tt } from "../tokenizer/types"; +import { types as tt, type TokenType } from "../tokenizer/types"; +import * as N from "../types"; import LValParser from "./lval"; import { reservedWords } from "../util/identifier"; +import type { Pos, Position } from "../util/location"; export default class ExpressionParser extends LValParser { + // Forward-declaration: defined in statement.js + +parseBlock: (allowDirectives?: boolean) => N.BlockStatement; + +parseClass: (node: N.Class, isStatement: boolean, optionalId?: boolean) => N.Class; + +parseDecorators: (allowExport?: boolean) => void; + +parseFunction: (node: T, isStatement: boolean, allowExpressionBody?: boolean, isAsync?: boolean, optionalId?: boolean) => T; + +takeDecorators: (node: N.HasDecorators) => void; + // Check if property name clashes with already added. // Object/class getters and setters are not allowed to clash — // either with each other or with an init property — and in // strict mode, init properties are also not allowed to be repeated. - checkPropClash(prop, propHash) { + checkPropClash(prop: N.ObjectMember, propHash: { [key: string]: boolean }): void { if (prop.computed || prop.kind) return; const key = prop.key; @@ -42,7 +53,7 @@ export default class ExpressionParser extends LValParser { } // Convenience method to parse an Expression only - getExpression() { + getExpression(): N.Expression { this.nextToken(); const expr = this.parseExpression(); if (!this.match(tt.eof)) { @@ -66,7 +77,7 @@ export default class ExpressionParser extends LValParser { // and object pattern might appear (so it's possible to raise // delayed syntax error at correct position). - parseExpression(noIn, refShorthandDefaultPos) { + parseExpression(noIn?: boolean, refShorthandDefaultPos?: Pos): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; const expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos); @@ -85,7 +96,7 @@ export default class ExpressionParser extends LValParser { // Parse an assignment expression. This includes applications of // operators like `+=`. - parseMaybeAssign(noIn, refShorthandDefaultPos, afterLeftParse, refNeedsArrowPos) { + parseMaybeAssign(noIn?: ?boolean, refShorthandDefaultPos?: ?Pos, afterLeftParse?: Function, refNeedsArrowPos?: ?Pos): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; @@ -141,7 +152,7 @@ export default class ExpressionParser extends LValParser { // Parse a ternary conditional (`?:`) operator. - parseMaybeConditional(noIn, refShorthandDefaultPos, refNeedsArrowPos) { + parseMaybeConditional(noIn: ?boolean, refShorthandDefaultPos: Pos, refNeedsArrowPos: ?Pos): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; const expr = this.parseExprOps(noIn, refShorthandDefaultPos); @@ -150,7 +161,7 @@ export default class ExpressionParser extends LValParser { return this.parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos); } - parseConditional(expr, noIn, startPos, startLoc) { + parseConditional(expr: N.Expression, noIn: ?boolean, startPos: number, startLoc: Position): N.Expression { if (this.eat(tt.question)) { const node = this.startNodeAt(startPos, startLoc); node.test = expr; @@ -164,7 +175,7 @@ export default class ExpressionParser extends LValParser { // Start the precedence parser. - parseExprOps(noIn, refShorthandDefaultPos) { + parseExprOps(noIn: ?boolean, refShorthandDefaultPos: Pos): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; const expr = this.parseMaybeUnary(refShorthandDefaultPos); @@ -181,7 +192,7 @@ export default class ExpressionParser extends LValParser { // defer further parser to one of its callers when it encounters an // operator that has a lower precedence than the set it is parsing. - parseExprOp(left, leftStartPos, leftStartLoc, minPrec, noIn) { + parseExprOp(left: N.Expression, leftStartPos: number, leftStartLoc: Position, minPrec: number, noIn: ?boolean): N.Expression { const prec = this.state.type.binop; if (prec != null && (!noIn || !this.match(tt._in))) { if (prec > minPrec) { @@ -215,7 +226,7 @@ export default class ExpressionParser extends LValParser { // Parse unary operators, both prefix and postfix. - parseMaybeUnary(refShorthandDefaultPos) { + parseMaybeUnary(refShorthandDefaultPos: ?Pos): N.Expression { if (this.state.type.prefix) { const node = this.startNode(); const update = this.match(tt.incDec); @@ -259,7 +270,7 @@ export default class ExpressionParser extends LValParser { // Parse call, dot, and `[]`-subscript expressions. - parseExprSubscripts(refShorthandDefaultPos) { + parseExprSubscripts(refShorthandDefaultPos: ?Pos): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; const potentialArrowAt = this.state.potentialArrowAt; @@ -276,7 +287,7 @@ export default class ExpressionParser extends LValParser { return this.parseSubscripts(expr, startPos, startLoc); } - parseSubscripts(base, startPos, startLoc, noCalls) { + parseSubscripts(base: N.Expression, startPos: number, startLoc: Position, noCalls?: boolean): N.Expression { for (;;) { if (!noCalls && this.eat(tt.doubleColon)) { const node = this.startNodeAt(startPos, startLoc); @@ -322,9 +333,11 @@ export default class ExpressionParser extends LValParser { return base; } } + // istanbul ignore next + throw new Error("Unreachable"); } - parseCallExpressionArguments(close, possibleAsyncArrow) { + parseCallExpressionArguments(close: TokenType, possibleAsyncArrow: boolean): $ReadOnlyArray { const elts = []; let innerParenStart; let first = true; @@ -353,18 +366,18 @@ export default class ExpressionParser extends LValParser { return elts; } - shouldParseAsyncArrow() { + shouldParseAsyncArrow(): boolean { return this.match(tt.arrow); } - parseAsyncArrowFromCallExpression(node, call) { + parseAsyncArrowFromCallExpression(node: N.ArrowFunctionExpression, call: N.CallExpression): N.ArrowFunctionExpression { this.expect(tt.arrow); return this.parseArrowExpression(node, call.arguments, true); } // Parse a no-call expression (like argument of `new` or `::` operators). - parseNoCallExpr() { + parseNoCallExpr(): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); @@ -375,7 +388,7 @@ export default class ExpressionParser extends LValParser { // `new`, or an expression wrapped in punctuation like `()`, `[]`, // or `{}`. - parseExprAtom(refShorthandDefaultPos) { + parseExprAtom(refShorthandDefaultPos?: ?Pos): N.Expression { const canBeArrow = this.state.potentialArrowAt === this.state.start; let node; @@ -519,15 +532,15 @@ export default class ExpressionParser extends LValParser { if (callee.type === "MemberExpression") { return this.finishNode(node, "BindExpression"); } else { - this.raise(callee.start, "Binding should be performed on object property."); + throw this.raise(callee.start, "Binding should be performed on object property."); } default: - this.unexpected(); + throw this.unexpected(); } } - parseFunctionExpression() { + parseFunctionExpression(): N.FunctionExpression | N.MetaProperty { const node = this.startNode(); const meta = this.parseIdentifier(true); if (this.state.inGenerator && this.eat(tt.dot) && this.hasPlugin("functionSent")) { @@ -537,7 +550,7 @@ export default class ExpressionParser extends LValParser { } } - parseMetaProperty(node, meta, propertyName) { + parseMetaProperty(node: N.MetaProperty, meta: N.Identifier, propertyName: string): N.MetaProperty { node.meta = meta; node.property = this.parseIdentifier(true); @@ -548,7 +561,7 @@ export default class ExpressionParser extends LValParser { return this.finishNode(node, "MetaProperty"); } - parseLiteral(value, type, startPos, startLoc) { + parseLiteral(value: any, type: /*T["kind"]*/string, startPos?: number, startLoc?: Position): T { startPos = startPos || this.state.start; startLoc = startLoc || this.state.startLoc; @@ -560,14 +573,14 @@ export default class ExpressionParser extends LValParser { return this.finishNode(node, type); } - parseParenExpression() { + parseParenExpression(): N.Expression { this.expect(tt.parenL); const val = this.parseExpression(); this.expect(tt.parenR); return val; } - parseParenAndDistinguishExpression(startPos, startLoc, canBeArrow) { + parseParenAndDistinguishExpression(startPos: ?number, startLoc: ?Position, canBeArrow: boolean): N.Expression { startPos = startPos || this.state.start; startLoc = startLoc || this.state.startLoc; @@ -642,17 +655,17 @@ export default class ExpressionParser extends LValParser { return val; } - shouldParseArrow() { + shouldParseArrow(): boolean { return !this.canInsertSemicolon(); } - parseArrow(node) { + parseArrow(node: N.ArrowFunctionExpression): ?N.ArrowFunctionExpression { if (this.eat(tt.arrow)) { return node; } } - parseParenItem(node) { + parseParenItem(node: N.Expression): N.Expression { return node; } @@ -660,7 +673,7 @@ export default class ExpressionParser extends LValParser { // to be a `[]` or dot subscript expression, but not a call — at // least, not without wrapping it in parentheses. Thus, it uses the - parseNew() { + parseNew(): N.NewExpression | N.MetaProperty { const node = this.startNode(); const meta = this.parseIdentifier(true); @@ -688,7 +701,7 @@ export default class ExpressionParser extends LValParser { // Parse template expression. - parseTemplateElement(isTagged) { + parseTemplateElement(isTagged: boolean): N.TemplateElement { const elem = this.startNode(); if (this.state.value === null) { if (!isTagged) { @@ -706,7 +719,7 @@ export default class ExpressionParser extends LValParser { return this.finishNode(elem, "TemplateElement"); } - parseTemplate(isTagged) { + parseTemplate(isTagged: boolean): N.TemplateLiteral { const node = this.startNode(); this.next(); node.expressions = []; @@ -724,7 +737,7 @@ export default class ExpressionParser extends LValParser { // Parse an object literal or binding pattern. - parseObj(isPattern, refShorthandDefaultPos) { + parseObj(isPattern: boolean, refShorthandDefaultPos?: ?Pos): T { let decorators = []; const propHash = Object.create(null); let first = true; @@ -823,7 +836,7 @@ export default class ExpressionParser extends LValParser { return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression"); } - isGetterOrSetterMethod(prop, isPattern) { + isGetterOrSetterMethod(prop: N.ObjectMethod, isPattern: boolean): boolean { return !isPattern && !prop.computed && prop.key.type === "Identifier" && @@ -839,7 +852,7 @@ export default class ExpressionParser extends LValParser { // get methods aren't allowed to have any parameters // set methods must have exactly 1 parameter - checkGetterSetterParamCount(method) { + checkGetterSetterParamCount(method: N.ObjectMethod): void { const paramCount = method.kind === "get" ? 0 : 1; if (method.params.length !== paramCount) { const start = method.start; @@ -851,7 +864,7 @@ export default class ExpressionParser extends LValParser { } } - parseObjectMethod(prop, isGenerator, isAsync, isPattern) { + parseObjectMethod(prop: N.ObjectMethod, isGenerator: boolean, isAsync: boolean, isPattern: boolean): ?N.ObjectMethod { if (isAsync || isGenerator || this.match(tt.parenL)) { if (isPattern) this.unexpected(); prop.kind = "method"; @@ -872,7 +885,7 @@ export default class ExpressionParser extends LValParser { } } - parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos) { + parseObjectProperty(prop: N.ObjectProperty, startPos: ?number, startLoc: ?Position, isPattern: boolean, refShorthandDefaultPos: ?Pos): ?N.ObjectProperty { prop.shorthand = false; if (this.eat(tt.colon)) { @@ -900,17 +913,15 @@ export default class ExpressionParser extends LValParser { } } - parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos) { + parseObjPropValue(prop: any, startPos: ?number, startLoc: ?Position, isGenerator: boolean, isAsync: boolean, isPattern: boolean, refShorthandDefaultPos: ?Pos): void { const node = this.parseObjectMethod(prop, isGenerator, isAsync, isPattern) || this.parseObjectProperty(prop, startPos, startLoc, isPattern, refShorthandDefaultPos); if (!node) this.unexpected(); - - return node; } - parsePropertyName(prop) { + parsePropertyName(prop: N.ObjectMember): N.Identifier { if (this.eat(tt.bracketL)) { prop.computed = true; prop.key = this.parseMaybeAssign(); @@ -927,7 +938,7 @@ export default class ExpressionParser extends LValParser { // Initialize empty function node. - initFunction(node, isAsync) { + initFunction(node: N.Function, isAsync: ?boolean): void { node.id = null; node.generator = false; node.expression = false; @@ -936,7 +947,7 @@ export default class ExpressionParser extends LValParser { // Parse object or class method. - parseMethod(node, isGenerator, isAsync) { + parseMethod(node: N.MethodLike, isGenerator?: boolean, isAsync?: boolean): N.MethodLike { const oldInMethod = this.state.inMethod; this.state.inMethod = node.kind || true; this.initFunction(node, isAsync); @@ -950,16 +961,16 @@ export default class ExpressionParser extends LValParser { // Parse arrow function expression with given parameters. - parseArrowExpression(node, params, isAsync) { + parseArrowExpression(node: N.ArrowFunctionExpression, params: N.Expression[], isAsync?: boolean): N.ArrowFunctionExpression { this.initFunction(node, isAsync); node.params = this.toAssignableList(params, true, "arrow function parameters"); this.parseFunctionBody(node, true); return this.finishNode(node, "ArrowFunctionExpression"); } - isStrictBody(node, isExpression) { + isStrictBody(node: { body: N.BlockStatement }, isExpression?: boolean): boolean { if (!isExpression && node.body.directives.length) { - for (const directive of (node.body.directives: Array)) { + for (const directive of node.body.directives) { if (directive.value.value === "use strict") { return true; } @@ -970,7 +981,7 @@ export default class ExpressionParser extends LValParser { } // Parse function body and check parameters. - parseFunctionBody(node, allowExpression) { + parseFunctionBody(node: N.Function, allowExpression?: boolean): void { const isExpression = allowExpression && !this.match(tt.braceL); const oldInAsync = this.state.inAsync; @@ -1009,7 +1020,7 @@ export default class ExpressionParser extends LValParser { if (node.id) { this.checkLVal(node.id, true, undefined, "function name"); } - for (const param of (node.params: Array)) { + for (const param of node.params) { if (isStrict && param.type !== "Identifier") { this.raise(param.start, "Non-simple parameter in strict mode"); } @@ -1025,7 +1036,7 @@ export default class ExpressionParser extends LValParser { // nothing in between them to be parsed as `null` (which is needed // for array literals). - parseExprList(close, allowEmpty, refShorthandDefaultPos) { + parseExprList(close: TokenType, allowEmpty?: boolean, refShorthandDefaultPos?: Pos): $ReadOnlyArray { const elts = []; let first = true; @@ -1042,7 +1053,7 @@ export default class ExpressionParser extends LValParser { return elts; } - parseExprListItem(allowEmpty, refShorthandDefaultPos, refNeedsArrowPos) { + parseExprListItem(allowEmpty: ?boolean, refShorthandDefaultPos: ?Pos, refNeedsArrowPos: ?Pos): ?N.Expression { let elt; if (allowEmpty && this.match(tt.comma)) { elt = null; @@ -1058,7 +1069,7 @@ export default class ExpressionParser extends LValParser { // when parsing properties), it will also convert keywords into // identifiers. - parseIdentifier(liberal) { + parseIdentifier(liberal?: boolean): N.Identifier { const node = this.startNode(); if (!liberal) { this.checkReservedWord(this.state.value, this.state.start, !!this.state.type.keyword, false); @@ -1082,7 +1093,7 @@ export default class ExpressionParser extends LValParser { return this.finishNode(node, "Identifier"); } - checkReservedWord(word, startLoc, checkKeywords, isBinding) { + checkReservedWord(word: string, startLoc: number, checkKeywords: boolean, isBinding: boolean): void { if (this.isReservedWord(word) || (checkKeywords && this.isKeyword(word))) { this.raise(startLoc, word + " is a reserved word"); } @@ -1094,7 +1105,7 @@ export default class ExpressionParser extends LValParser { // Parses await expression inside async function. - parseAwait(node) { + parseAwait(node: N.AwaitExpression): N.AwaitExpression { // istanbul ignore next: this condition is checked at the call site so won't be hit here if (!this.state.inAsync) { this.unexpected(); @@ -1108,7 +1119,7 @@ export default class ExpressionParser extends LValParser { // Parses yield expression inside generator. - parseYield() { + parseYield(): N.YieldExpression { const node = this.startNode(); this.next(); if ( From d95b5fb83dab5a8814fadb3fee1f8afd39497ec9 Mon Sep 17 00:00:00 2001 From: Andy Date: Sun, 14 May 2017 10:59:03 -0700 Subject: [PATCH 51/73] Remove unused parameters from parseParenAndDistinguishExpression (#522) --- src/parser/expression.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser/expression.js b/src/parser/expression.js index f11180ac42..242a390564 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -495,7 +495,7 @@ export default class ExpressionParser extends LValParser { return this.finishNode(node, "BooleanLiteral"); case tt.parenL: - return this.parseParenAndDistinguishExpression(null, null, canBeArrow); + return this.parseParenAndDistinguishExpression(canBeArrow); case tt.bracketL: node = this.startNode(); @@ -580,9 +580,9 @@ export default class ExpressionParser extends LValParser { return val; } - parseParenAndDistinguishExpression(startPos: ?number, startLoc: ?Position, canBeArrow: boolean): N.Expression { - startPos = startPos || this.state.start; - startLoc = startLoc || this.state.startLoc; + parseParenAndDistinguishExpression(canBeArrow: boolean): N.Expression { + const startPos = this.state.start; + const startLoc = this.state.startLoc; let val; this.expect(tt.parenL); From aa78011666b890772c9be8936f29815ddc4c0af0 Mon Sep 17 00:00:00 2001 From: Andy Date: Sun, 14 May 2017 10:59:56 -0700 Subject: [PATCH 52/73] Fix type check errors (#521) --- src/parser/expression.js | 8 +++++--- src/parser/statement.js | 5 ++++- src/plugins/estree.js | 7 ++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/parser/expression.js b/src/parser/expression.js index 242a390564..23f6875077 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -665,7 +665,8 @@ export default class ExpressionParser extends LValParser { } } - parseParenItem(node: N.Expression): N.Expression { + // eslint-disable-next-line no-unused-vars + parseParenItem(node: N.Expression, startPos: number, startLoc: Position): N.Expression { return node; } @@ -705,6 +706,7 @@ export default class ExpressionParser extends LValParser { const elem = this.startNode(); if (this.state.value === null) { if (!isTagged) { + // $FlowFixMe this.raise(this.state.invalidTemplateEscapePosition, "Invalid escape sequence in template"); } else { this.state.invalidTemplateEscapePosition = null; @@ -846,7 +848,7 @@ export default class ExpressionParser extends LValParser { this.match(tt.num) || // get 1() {} this.match(tt.bracketL) || // get ["string"]() {} this.match(tt.name) || // get foo() {} - this.state.type.keyword // get debugger() {} + !!this.state.type.keyword // get debugger() {} ); } @@ -1036,7 +1038,7 @@ export default class ExpressionParser extends LValParser { // nothing in between them to be parsed as `null` (which is needed // for array literals). - parseExprList(close: TokenType, allowEmpty?: boolean, refShorthandDefaultPos?: Pos): $ReadOnlyArray { + parseExprList(close: TokenType, allowEmpty?: boolean, refShorthandDefaultPos?: ?Pos): $ReadOnlyArray { const elts = []; let first = true; diff --git a/src/parser/statement.js b/src/parser/statement.js index 153b614ce0..f29b2c29a3 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -74,6 +74,7 @@ export default class StatementParser extends ExpressionParser { // complexity. switch (starttype) { + // $FlowFixMe case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword); case tt._debugger: return this.parseDebuggerStatement(node); case tt._do: return this.parseDoStatement(node); @@ -554,6 +555,7 @@ export default class StatementParser extends ExpressionParser { parseVar(node: N.VariableDeclaration, isFor: boolean, kind: TokenType): N.VariableDeclaration { const declarations = node.declarations = []; + // $FlowFixMe node.kind = kind.keyword; for (;;) { const decl = this.startNode(); @@ -887,7 +889,8 @@ export default class StatementParser extends ExpressionParser { return this.finishNode(node, "ExportNamedDeclaration"); } - parseExportDeclaration(): N.Declaration { + // eslint-disable-next-line no-unused-vars + parseExportDeclaration(node: N.ExportNamedDeclaration): ?N.Declaration { return this.parseStatement(true); } diff --git a/src/plugins/estree.js b/src/plugins/estree.js index e4b7041774..347d325378 100644 --- a/src/plugins/estree.js +++ b/src/plugins/estree.js @@ -132,10 +132,11 @@ export default (superClass: Class): Class => class extends super delete node.directives; } - parseClassMethod(classBody, ...args) { + parseClassMethod(classBody: N.ClassBody, ...args) { super.parseClassMethod(classBody, ...args); const body = classBody.body; + // $FlowIgnore body[body.length - 1].type = "MethodDefinition"; } @@ -185,7 +186,9 @@ export default (superClass: Class): Class => class extends super const node = super.parseObjectMethod(...args); if (node) { + // $FlowIgnore if (node.kind === "method") node.kind = "init"; + // $FlowIgnore node.type = "Property"; } @@ -196,7 +199,9 @@ export default (superClass: Class): Class => class extends super const node = super.parseObjectProperty(...args); if (node) { + // $FlowIgnore node.kind = "init"; + // $FlowIgnore node.type = "Property"; } From 4ef964e066a31f2b319ae0460683ca30ad3a5905 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Sun, 14 May 2017 20:03:20 +0200 Subject: [PATCH 53/73] =?UTF-8?q?Update=20cross-env=20to=20the=20latest=20?= =?UTF-8?q?version=20=F0=9F=9A=80=20(#520)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(package): update cross-env to version 5.0.0 * Update yarn.lock --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 8389e7e451..e4a6ce9caf 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "babel-preset-es2015": "^7.0.0-alpha.3", "babel-preset-stage-0": "^7.0.0-alpha.3", "chalk": "^1.1.3", - "cross-env": "^4.0.0", + "cross-env": "^5.0.0", "eslint": "^3.7.1", "eslint-config-babel": "^6.0.0", "eslint-plugin-flowtype": "^2.20.0", diff --git a/yarn.lock b/yarn.lock index a5dc687ace..628fbb48d6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1525,9 +1525,9 @@ create-error-class@^3.0.0: dependencies: capture-stack-trace "^1.0.0" -cross-env@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-4.0.0.tgz#16083862d08275a4628b0b243b121bedaa55dd80" +cross-env@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.0.0.tgz#565ccae4d09676441a5087f406fe7661a29c931b" dependencies: cross-spawn "^5.1.0" is-windows "^1.0.0" From b08fdf87e842733e520452147067077ce514a723 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Wed, 17 May 2017 04:53:14 +0800 Subject: [PATCH 54/73] Fix handling of anonymous parameters in `flowParseObjectTypeMethodish`. (#526) By analogy with `flowParseFunctionTypeParams` (cf. commit 407c97c9c2fe453fc2ae940c3d3b11c90d9dbc8e). --- src/plugins/flow.js | 2 +- .../complex-param-types/actual.js | 1 + .../complex-param-types/expected.json | 238 ++++++++++++++++++ 3 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/flow/object-types/complex-param-types/actual.js create mode 100644 test/fixtures/flow/object-types/complex-param-types/expected.json diff --git a/src/plugins/flow.js b/src/plugins/flow.js index f3a1b739a7..96bd684731 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -470,7 +470,7 @@ export default (superClass: Class): Class => class extends super } this.expect(tt.parenL); - while (this.match(tt.name)) { + while (!this.match(tt.parenR) && !this.match(tt.ellipsis)) { node.params.push(this.flowParseFunctionTypeParam()); if (!this.match(tt.parenR)) { this.expect(tt.comma); diff --git a/test/fixtures/flow/object-types/complex-param-types/actual.js b/test/fixtures/flow/object-types/complex-param-types/actual.js new file mode 100644 index 0000000000..27fe4a3b5b --- /dev/null +++ b/test/fixtures/flow/object-types/complex-param-types/actual.js @@ -0,0 +1 @@ +type o = { m(|int|bool): void } diff --git a/test/fixtures/flow/object-types/complex-param-types/expected.json b/test/fixtures/flow/object-types/complex-param-types/expected.json new file mode 100644 index 0000000000..9665529d8d --- /dev/null +++ b/test/fixtures/flow/object-types/complex-param-types/expected.json @@ -0,0 +1,238 @@ +{ + "type": "File", + "start": 0, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "sourceType": "module", + "body": [ + { + "type": "TypeAlias", + "start": 0, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "id": { + "type": "Identifier", + "start": 5, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 6 + }, + "identifierName": "o" + }, + "name": "o" + }, + "typeParameters": null, + "right": { + "type": "ObjectTypeAnnotation", + "start": 9, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "callProperties": [], + "properties": [ + { + "type": "ObjectTypeProperty", + "start": 11, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 29 + } + }, + "key": { + "type": "Identifier", + "start": 11, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + }, + "identifierName": "m" + }, + "name": "m" + }, + "static": false, + "kind": "init", + "value": { + "type": "FunctionTypeAnnotation", + "start": 11, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 29 + } + }, + "params": [ + { + "type": "FunctionTypeParam", + "start": 13, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 22 + } + }, + "name": null, + "optional": false, + "typeAnnotation": { + "type": "UnionTypeAnnotation", + "start": 13, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 22 + } + }, + "types": [ + { + "type": "GenericTypeAnnotation", + "start": 14, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 17 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 14, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 17 + }, + "identifierName": "int" + }, + "name": "int" + } + }, + { + "type": "BooleanTypeAnnotation", + "start": 18, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 22 + } + } + } + ] + } + } + ], + "rest": null, + "typeParameters": null, + "returnType": { + "type": "VoidTypeAnnotation", + "start": 25, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 25 + }, + "end": { + "line": 1, + "column": 29 + } + } + } + }, + "optional": false + } + ], + "indexers": [], + "exact": false + } + } + ], + "directives": [] + } +} \ No newline at end of file From 23ff45fcfafdf5a61783a60fc74139a0f7465545 Mon Sep 17 00:00:00 2001 From: James Browning Date: Thu, 18 May 2017 02:25:10 +1200 Subject: [PATCH 55/73] Spec fix as BindExpression only have a single object/callee not an Array (#436) [skip ci] * Fixed spec.md to reflect that BindExpressions only have a single node not an array for their properties * Added semicolons to BindExpression props --- ast/spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ast/spec.md b/ast/spec.md index 07c6a6482d..3c49c16a70 100644 --- a/ast/spec.md +++ b/ast/spec.md @@ -855,8 +855,8 @@ A member expression. If `computed` is `true`, the node corresponds to a computed ```js interface BindExpression <: Expression { type: "BindExpression"; - object: [ Expression | null ]; - callee: [ Expression ] + object: Expression | null; + callee: Expression; } ``` From dcef4012a0a67e5d66e819ee0a0cf4ebde2fc58b Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Wed, 17 May 2017 11:07:09 -0500 Subject: [PATCH 56/73] Disallow SpreadElement inside dynamic import (#529) * Disallow SpreadElement inside dynamic import * tweak error message --- src/parser/expression.js | 11 +++++++++-- .../dynamic-import/invalid-arguments-spread/actual.js | 1 + .../invalid-arguments-spread/options.json | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/experimental/dynamic-import/invalid-arguments-spread/actual.js create mode 100644 test/fixtures/experimental/dynamic-import/invalid-arguments-spread/options.json diff --git a/src/parser/expression.js b/src/parser/expression.js index 23f6875077..5d08afd31b 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -314,8 +314,15 @@ export default class ExpressionParser extends LValParser { const node = this.startNodeAt(startPos, startLoc); node.callee = base; node.arguments = this.parseCallExpressionArguments(tt.parenR, possibleAsync); - if (node.callee.type === "Import" && node.arguments.length !== 1) { - this.raise(node.start, "import() requires exactly one argument"); + if (node.callee.type === "Import") { + if (node.arguments.length !== 1) { + this.raise(node.start, "import() requires exactly one argument"); + } + + const importArg = node.arguments[0]; + if (importArg && importArg.type === "SpreadElement") { + this.raise(importArg.start, "... is not allowed in import()"); + } } base = this.finishNode(node, "CallExpression"); diff --git a/test/fixtures/experimental/dynamic-import/invalid-arguments-spread/actual.js b/test/fixtures/experimental/dynamic-import/invalid-arguments-spread/actual.js new file mode 100644 index 0000000000..87bfc54932 --- /dev/null +++ b/test/fixtures/experimental/dynamic-import/invalid-arguments-spread/actual.js @@ -0,0 +1 @@ +import(...[1]) diff --git a/test/fixtures/experimental/dynamic-import/invalid-arguments-spread/options.json b/test/fixtures/experimental/dynamic-import/invalid-arguments-spread/options.json new file mode 100644 index 0000000000..c4e1e2ffeb --- /dev/null +++ b/test/fixtures/experimental/dynamic-import/invalid-arguments-spread/options.json @@ -0,0 +1,3 @@ +{ + "throws": "... is not allowed in import() (1:7)" +} From 6c4acecf00bf8d487f8787d6328fdc0d934cdea1 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Fri, 19 May 2017 01:05:44 -0700 Subject: [PATCH 57/73] Fix #437: only prohibit 'export type from "module" ' when flow is enabled (#438) * Only prohibit 'export type' when flow is enabled * Fix lint --- src/parser/statement.js | 4 +- src/plugins/flow.js | 11 ++ .../default-type-with-flow/actual.js | 1 + .../default-type-with-flow/options.json | 5 + .../default-type-without-flow/actual.js | 1 + .../default-type-without-flow/expected.json | 103 ++++++++++++++++++ 6 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/experimental/export-extensions/default-type-with-flow/actual.js create mode 100644 test/fixtures/experimental/export-extensions/default-type-with-flow/options.json create mode 100644 test/fixtures/experimental/export-extensions/default-type-without-flow/actual.js create mode 100644 test/fixtures/experimental/export-extensions/default-type-without-flow/expected.json diff --git a/src/parser/statement.js b/src/parser/statement.js index f29b2c29a3..c77f435001 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -896,9 +896,7 @@ export default class StatementParser extends ExpressionParser { isExportDefaultSpecifier(): boolean { if (this.match(tt.name)) { - return this.state.value !== "type" - && this.state.value !== "async" - && this.state.value !== "interface"; + return this.state.value !== "async"; } if (!this.match(tt._default)) { diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 96bd684731..83416c3726 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -1061,6 +1061,17 @@ export default (superClass: Class): Class => class extends super || super.shouldParseExportDeclaration(); } + isExportDefaultSpecifier(): boolean { + if ( + this.match(tt.name) && + (this.state.value === "type" || this.state.value === "interface") + ) { + return false; + } + + return super.isExportDefaultSpecifier(); + } + parseConditional(expr: N.Expression, noIn: ?boolean, startPos: number, startLoc: Position, refNeedsArrowPos?: Pos): N.Expression { // only do the expensive clone if there is a question mark // and if we come from inside parens diff --git a/test/fixtures/experimental/export-extensions/default-type-with-flow/actual.js b/test/fixtures/experimental/export-extensions/default-type-with-flow/actual.js new file mode 100644 index 0000000000..2086d067fc --- /dev/null +++ b/test/fixtures/experimental/export-extensions/default-type-with-flow/actual.js @@ -0,0 +1 @@ +export type from 'test'; diff --git a/test/fixtures/experimental/export-extensions/default-type-with-flow/options.json b/test/fixtures/experimental/export-extensions/default-type-with-flow/options.json new file mode 100644 index 0000000000..3d735abd0a --- /dev/null +++ b/test/fixtures/experimental/export-extensions/default-type-with-flow/options.json @@ -0,0 +1,5 @@ +{ + "plugins": ["exportExtensions", "flow"], + "sourceType": "module", + "throws": "Unexpected token, expected = (1:17)" +} diff --git a/test/fixtures/experimental/export-extensions/default-type-without-flow/actual.js b/test/fixtures/experimental/export-extensions/default-type-without-flow/actual.js new file mode 100644 index 0000000000..2086d067fc --- /dev/null +++ b/test/fixtures/experimental/export-extensions/default-type-without-flow/actual.js @@ -0,0 +1 @@ +export type from 'test'; diff --git a/test/fixtures/experimental/export-extensions/default-type-without-flow/expected.json b/test/fixtures/experimental/export-extensions/default-type-without-flow/expected.json new file mode 100644 index 0000000000..8b0ad961f6 --- /dev/null +++ b/test/fixtures/experimental/export-extensions/default-type-without-flow/expected.json @@ -0,0 +1,103 @@ +{ + "type": "File", + "start": 0, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "sourceType": "module", + "body": [ + { + "type": "ExportNamedDeclaration", + "start": 0, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "specifiers": [ + { + "type": "ExportDefaultSpecifier", + "start": 7, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "exported": { + "type": "Identifier", + "start": 7, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "type" + }, + "name": "type" + } + } + ], + "source": { + "type": "StringLiteral", + "start": 17, + "end": 23, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 23 + } + }, + "extra": { + "rawValue": "test", + "raw": "'test'" + }, + "value": "test" + } + } + ], + "directives": [] + } +} \ No newline at end of file From 01da62283c27cbc647301eecbdcfade959c84ece Mon Sep 17 00:00:00 2001 From: Diego Ferreiro Val Date: Mon, 22 May 2017 11:33:48 -0400 Subject: [PATCH 58/73] Modify grammar to support Private Fields proposal: (#260) * Modify grammar to support Private Fields proposal: - Adding optional plugin `classPrivateProperties` - Adding PrivateName type identifier - Adding ClassPrivateProperty to ClassBody - Allow PrivateName in MemberExpression - Allow PrivateName as a reference - Adding tests * Remove unnecesary liberal parameter * Guarding for plugin dependecy for future versioning * update spec.md [skip ci] * move comment [skip ci] * remove unused param [skip ci] * Refactor PrivateName to contain Identifier in name property --- ast/spec.md | 26 +- src/parser/expression.js | 22 +- src/parser/lval.js | 2 + src/parser/statement.js | 25 + src/tokenizer/index.js | 9 + src/tokenizer/state.js | 2 + src/tokenizer/types.js | 1 + src/types.js | 23 +- .../asi-failure-computed/actual.js | 4 + .../asi-failure-computed/options.json | 7 + .../asi-failure-generator/actual.js | 4 + .../asi-failure-generator/options.json | 4 + .../asi-failure-inline/actual.js | 3 + .../asi-failure-inline/options.json | 4 + .../asi-success/actual.js | 4 + .../asi-success/expected.json | 152 ++ .../asi-success/options.json | 3 + .../class-private-properties/inline/actual.js | 3 + .../inline/expected.json | 308 +++ .../inline/options.json | 3 + .../pbn-success.1/actual.js | 19 + .../pbn-success.1/expected.json | 1874 +++++++++++++++++ .../pbn-success.1/options.json | 3 + .../pbn-success/actual.js | 19 + .../pbn-success/expected.json | 1626 ++++++++++++++ .../pbn-success/options.json | 3 + 26 files changed, 4148 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/experimental/class-private-properties/asi-failure-computed/actual.js create mode 100644 test/fixtures/experimental/class-private-properties/asi-failure-computed/options.json create mode 100644 test/fixtures/experimental/class-private-properties/asi-failure-generator/actual.js create mode 100644 test/fixtures/experimental/class-private-properties/asi-failure-generator/options.json create mode 100644 test/fixtures/experimental/class-private-properties/asi-failure-inline/actual.js create mode 100644 test/fixtures/experimental/class-private-properties/asi-failure-inline/options.json create mode 100644 test/fixtures/experimental/class-private-properties/asi-success/actual.js create mode 100644 test/fixtures/experimental/class-private-properties/asi-success/expected.json create mode 100644 test/fixtures/experimental/class-private-properties/asi-success/options.json create mode 100644 test/fixtures/experimental/class-private-properties/inline/actual.js create mode 100644 test/fixtures/experimental/class-private-properties/inline/expected.json create mode 100644 test/fixtures/experimental/class-private-properties/inline/options.json create mode 100644 test/fixtures/experimental/class-private-properties/pbn-success.1/actual.js create mode 100644 test/fixtures/experimental/class-private-properties/pbn-success.1/expected.json create mode 100644 test/fixtures/experimental/class-private-properties/pbn-success.1/options.json create mode 100644 test/fixtures/experimental/class-private-properties/pbn-success/actual.js create mode 100644 test/fixtures/experimental/class-private-properties/pbn-success/expected.json create mode 100644 test/fixtures/experimental/class-private-properties/pbn-success/options.json diff --git a/ast/spec.md b/ast/spec.md index 3c49c16a70..f457645452 100644 --- a/ast/spec.md +++ b/ast/spec.md @@ -3,6 +3,7 @@ These are the core Babylon AST node types. - [Node objects](#node-objects) - [Changes](#changes) - [Identifier](#identifier) +- [PrivateName](#privatename) - [Literals](#literals) - [RegExpLiteral](#regexpliteral) - [NullLiteral](#nullliteral) @@ -90,6 +91,7 @@ These are the core Babylon AST node types. - [ClassBody](#classbody) - [ClassMethod](#classmethod) - [ClassProperty](#classproperty) + - [ClassPrivateProperty](#classprivateproperty) - [ClassDeclaration](#classdeclaration) - [ClassExpression](#classexpression) - [MetaProperty](#metaproperty) @@ -166,6 +168,18 @@ interface Identifier <: Expression, Pattern { An identifier. Note that an identifier may be an expression or a destructuring pattern. + +# PrivateName + +```js +interface PrivateName <: Expression, Pattern { + type: "PrivateName"; + name: Identifier; +} +``` +A Private Name Identifier. + + # Literals ```js @@ -1015,7 +1029,7 @@ interface Class <: Node { ```js interface ClassBody <: Node { type: "ClassBody"; - body: [ ClassMethod | ClassProperty ]; + body: [ ClassMethod | ClassProperty | ClassPrivateProperty ]; } ``` @@ -1043,6 +1057,16 @@ interface ClassProperty <: Node { } ``` +## ClassPrivateProperty + +```js +interface ClassPrivateProperty <: Node { + type: "ClassPrivateProperty"; + key: Identifier; + value: Expression; +} +``` + ## ClassDeclaration ```js diff --git a/src/parser/expression.js b/src/parser/expression.js index 5d08afd31b..d2189e6c40 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -99,7 +99,6 @@ export default class ExpressionParser extends LValParser { parseMaybeAssign(noIn?: ?boolean, refShorthandDefaultPos?: ?Pos, afterLeftParse?: Function, refNeedsArrowPos?: ?Pos): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; - if (this.match(tt._yield) && this.state.inGenerator) { let left = this.parseYield(); if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc); @@ -297,7 +296,7 @@ export default class ExpressionParser extends LValParser { } else if (this.eat(tt.dot)) { const node = this.startNodeAt(startPos, startLoc); node.object = base; - node.property = this.parseIdentifier(true); + node.property = this.hasPlugin("classPrivateProperties") ? this.parseMaybePrivateName() : this.parseIdentifier(true); node.computed = false; base = this.finishNode(node, "MemberExpression"); } else if (this.eat(tt.bracketL)) { @@ -525,6 +524,13 @@ export default class ExpressionParser extends LValParser { this.takeDecorators(node); return this.parseClass(node, false); + case tt.hash: + if (this.hasPlugin("classPrivateProperties")) { + return this.parseMaybePrivateName(); + } else { + this.unexpected(); + } + case tt._new: return this.parseNew(); @@ -547,6 +553,18 @@ export default class ExpressionParser extends LValParser { } } + parseMaybePrivateName(): N.PrivateName | N.Identifier { + const isPrivate = this.eat(tt.hash); + + if (isPrivate) { + const node = this.startNode(); + node.name = this.parseIdentifier(true); + return this.finishNode(node, "PrivateName"); + } else { + return this.parseIdentifier(true); + } + } + parseFunctionExpression(): N.FunctionExpression | N.MetaProperty { const node = this.startNode(); const meta = this.parseIdentifier(true); diff --git a/src/parser/lval.js b/src/parser/lval.js index 8576198b61..d3fcd02900 100644 --- a/src/parser/lval.js +++ b/src/parser/lval.js @@ -26,6 +26,7 @@ export default class LValParser extends NodeUtils { if (node) { switch (node.type) { case "Identifier": + case "PrivateName": case "ObjectPattern": case "ArrayPattern": case "AssignmentPattern": @@ -227,6 +228,7 @@ export default class LValParser extends NodeUtils { checkClashes: ?{ [key: string]: boolean }, contextDescription: string): void { switch (expr.type) { + case "PrivateName": case "Identifier": this.checkReservedWord(expr.name, expr.start, false, true); diff --git a/src/parser/statement.js b/src/parser/statement.js index c77f435001..24a693a5d2 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -650,6 +650,7 @@ export default class StatementParser extends ExpressionParser { // class bodies are implicitly strict const oldStrict = this.state.strict; this.state.strict = true; + this.state.inClass = true; let hadConstructor = false; let decorators = []; @@ -680,6 +681,13 @@ export default class StatementParser extends ExpressionParser { decorators = []; } + if (this.hasPlugin("classPrivateProperties") && this.match(tt.hash)) { // Private property + this.next(); + this.parsePropertyName(method); + classBody.body.push(this.parsePrivateClassProperty(method)); + continue; + } + method.static = false; if (this.match(tt.name) && this.state.value === "static") { const key = this.parseIdentifier(true); // eats 'static' @@ -774,9 +782,26 @@ export default class StatementParser extends ExpressionParser { node.body = this.finishNode(classBody, "ClassBody"); + this.state.inClass = false; this.state.strict = oldStrict; + } + parsePrivateClassProperty(node: N.ClassPrivateProperty): N.ClassPrivateProperty { + this.state.inClassProperty = true; + + if (this.match(tt.eq)) { + this.next(); + node.value = this.parseMaybeAssign(); + } else { + node.value = null; + } + this.semicolon(); + this.state.inClassProperty = false; + return this.finishNode(node, "ClassPrivateProperty"); + } + + parseClassProperty(node: N.ClassProperty): N.ClassProperty { const hasPlugin = this.hasPlugin("classProperties"); const noPluginMsg = "You can only use Class Properties when the 'classProperties' plugin is enabled."; diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index 42273d664c..7727032fcc 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -405,8 +405,17 @@ export default class Tokenizer extends LocationParser { getTokenFromCode(code: number): void { switch (code) { + + case 35: // '#' + if (this.hasPlugin("classPrivateProperties") && this.state.inClass) { + ++this.state.pos; return this.finishToken(tt.hash); + } else { + this.raise(this.state.pos, `Unexpected character '${codePointToString(code)}'`); + } + // The interpretation of a dot depends on whether it is followed // by a digit or another two dots. + case 46: // '.' return this.readToken_dot(); diff --git a/src/tokenizer/state.js b/src/tokenizer/state.js index 8fe08ac001..cb1fedf74c 100644 --- a/src/tokenizer/state.js +++ b/src/tokenizer/state.js @@ -24,6 +24,7 @@ export default class State { this.inAsync = this.inPropertyName = this.inType = + this.inClass = this.inClassProperty = this.noAnonFunctionType = false; @@ -81,6 +82,7 @@ export default class State { noAnonFunctionType: boolean; inPropertyName: boolean; inClassProperty: boolean; + inClass: boolean; // Labels in scope. labels: Array<{ kind: ?("loop" | "switch"), statementStart?: number }>; diff --git a/src/tokenizer/types.js b/src/tokenizer/types.js index e6552249e6..48d075d2b1 100644 --- a/src/tokenizer/types.js +++ b/src/tokenizer/types.js @@ -108,6 +108,7 @@ export const types: { [name: string]: TokenType } = { backQuote: new TokenType("`", { startsExpr }), dollarBraceL: new TokenType("${", { beforeExpr, startsExpr }), at: new TokenType("@"), + hash: new TokenType("#"), // Operators. These carry several kinds of properties to help the // parser use them properly (the presence of these properties is diff --git a/src/types.js b/src/types.js index 50e8bd95d3..5e8013b5de 100644 --- a/src/types.js +++ b/src/types.js @@ -62,6 +62,13 @@ export type Identifier = PatternBase & { __clone(): Identifier; }; +export type PrivateName = PatternBase & { + type: "PrivateName"; + name: string; + + __clone(): Identifier; +}; + // Literals export type Literal = RegExpLiteral | NullLiteral | StringLiteral | BooleanLiteral | NumericLiteral; @@ -334,7 +341,7 @@ export type ObjectExpression = NodeBase & { properties: $ReadOnlyArray; }; -export type ObjectOrClassMember = ClassMethod | ClassProperty | ObjectMember; +export type ObjectOrClassMember = ClassMethod | ClassProperty | ClassPrivateProperty | ObjectMember; export type ObjectMember = ObjectProperty | ObjectMethod; @@ -552,7 +559,7 @@ export type ClassMemberBase = NodeBase & HasDecorators & { export type Accessibility = "public" | "protected" | "private"; -export type ClassMember = ClassMethod | ClassProperty; +export type ClassMember = ClassMethod | ClassProperty | ClassPrivateProperty; export type MethodLike = ObjectMethod | FunctionExpression | ClassMethod; @@ -584,6 +591,18 @@ export type ClassProperty = ClassMemberBase & { readonly?: true; }; +export type ClassPrivateProperty = ClassMemberBase & { + type: "ClassPrivateProperty"; + key: Identifier; + value: ?Expression; // TODO: Not in spec that this is nullable. + + typeAnnotation?: ?FlowTypeAnnotation; // TODO: Not in spec + variance?: ?FlowVariance; // TODO: Not in spec + + // TypeScript only: (TODO: Not in spec) + readonly?: true; +}; + export type OptClassDeclaration = ClassBase & DeclarationBase & HasDecorators & { type: "ClassDeclaration"; // TypeScript only diff --git a/test/fixtures/experimental/class-private-properties/asi-failure-computed/actual.js b/test/fixtures/experimental/class-private-properties/asi-failure-computed/actual.js new file mode 100644 index 0000000000..0fb2172e4d --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/asi-failure-computed/actual.js @@ -0,0 +1,4 @@ +class Foo { + #p = x + [#m] () {} +} diff --git a/test/fixtures/experimental/class-private-properties/asi-failure-computed/options.json b/test/fixtures/experimental/class-private-properties/asi-failure-computed/options.json new file mode 100644 index 0000000000..31d89fa474 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/asi-failure-computed/options.json @@ -0,0 +1,7 @@ +{ + "throws": "Unexpected token, expected ; (3:10)", + "plugins": [ + "classProperties", + "classPrivateProperties" + ] +} diff --git a/test/fixtures/experimental/class-private-properties/asi-failure-generator/actual.js b/test/fixtures/experimental/class-private-properties/asi-failure-generator/actual.js new file mode 100644 index 0000000000..5fa9418229 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/asi-failure-generator/actual.js @@ -0,0 +1,4 @@ +class Foo { + #p = x + *#m () {} +} diff --git a/test/fixtures/experimental/class-private-properties/asi-failure-generator/options.json b/test/fixtures/experimental/class-private-properties/asi-failure-generator/options.json new file mode 100644 index 0000000000..0541546800 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/asi-failure-generator/options.json @@ -0,0 +1,4 @@ +{ + "throws": "Unexpected token, expected ; (3:9)", + "plugins": ["classProperties", "classPrivateProperties"] +} diff --git a/test/fixtures/experimental/class-private-properties/asi-failure-inline/actual.js b/test/fixtures/experimental/class-private-properties/asi-failure-inline/actual.js new file mode 100644 index 0000000000..2b7855c1cb --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/asi-failure-inline/actual.js @@ -0,0 +1,3 @@ +class Foo { + #x #y +} diff --git a/test/fixtures/experimental/class-private-properties/asi-failure-inline/options.json b/test/fixtures/experimental/class-private-properties/asi-failure-inline/options.json new file mode 100644 index 0000000000..123e8aa507 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/asi-failure-inline/options.json @@ -0,0 +1,4 @@ +{ + "throws": "Unexpected token, expected ; (2:5)", + "plugins": ["classProperties", "classPrivateProperties"] +} diff --git a/test/fixtures/experimental/class-private-properties/asi-success/actual.js b/test/fixtures/experimental/class-private-properties/asi-success/actual.js new file mode 100644 index 0000000000..ac2b521a15 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/asi-success/actual.js @@ -0,0 +1,4 @@ +class Foo { + #x + #y +} diff --git a/test/fixtures/experimental/class-private-properties/asi-success/expected.json b/test/fixtures/experimental/class-private-properties/asi-success/expected.json new file mode 100644 index 0000000000..8aa723ae03 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/asi-success/expected.json @@ -0,0 +1,152 @@ +{ + "type": "File", + "start": 0, + "end": 23, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 4, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 23, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 4, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 23, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 4, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + }, + "identifierName": "Foo" + }, + "name": "Foo" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 10, + "end": 23, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 4, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateProperty", + "start": 14, + "end": 16, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 4 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 15, + "end": 16, + "loc": { + "start": { + "line": 2, + "column": 3 + }, + "end": { + "line": 2, + "column": 4 + }, + "identifierName": "x" + }, + "name": "x" + }, + "value": null + }, + { + "type": "ClassPrivateProperty", + "start": 19, + "end": 21, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 4 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 20, + "end": 21, + "loc": { + "start": { + "line": 3, + "column": 3 + }, + "end": { + "line": 3, + "column": 4 + }, + "identifierName": "y" + }, + "name": "y" + }, + "value": null + } + ] + } + } + ], + "directives": [] + } +} diff --git a/test/fixtures/experimental/class-private-properties/asi-success/options.json b/test/fixtures/experimental/class-private-properties/asi-success/options.json new file mode 100644 index 0000000000..19c38d2996 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/asi-success/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties", "classPrivateProperties"] +} diff --git a/test/fixtures/experimental/class-private-properties/inline/actual.js b/test/fixtures/experimental/class-private-properties/inline/actual.js new file mode 100644 index 0000000000..da82b9a9c5 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/inline/actual.js @@ -0,0 +1,3 @@ +class A { #x; #y; } + +class B { #x = 0; #y = 1; } diff --git a/test/fixtures/experimental/class-private-properties/inline/expected.json b/test/fixtures/experimental/class-private-properties/inline/expected.json new file mode 100644 index 0000000000..abb56c7d32 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/inline/expected.json @@ -0,0 +1,308 @@ +{ + "type": "File", + "start": 0, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 27 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 48, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 27 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 19, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 19 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + }, + "identifierName": "A" + }, + "name": "A" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 8, + "end": 19, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 19 + } + }, + "body": [ + { + "type": "ClassPrivateProperty", + "start": 10, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 11, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + }, + "identifierName": "x" + }, + "name": "x" + }, + "value": null + }, + { + "type": "ClassPrivateProperty", + "start": 14, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 17 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 15, + "end": 16, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 16 + }, + "identifierName": "y" + }, + "name": "y" + }, + "value": null + } + ] + } + }, + { + "type": "ClassDeclaration", + "start": 21, + "end": 48, + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 27 + } + }, + "id": { + "type": "Identifier", + "start": 27, + "end": 28, + "loc": { + "start": { + "line": 3, + "column": 6 + }, + "end": { + "line": 3, + "column": 7 + }, + "identifierName": "B" + }, + "name": "B" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 29, + "end": 48, + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 27 + } + }, + "body": [ + { + "type": "ClassPrivateProperty", + "start": 31, + "end": 38, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 17 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 32, + "end": 33, + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 12 + }, + "identifierName": "x" + }, + "name": "x" + }, + "value": { + "type": "NumericLiteral", + "start": 36, + "end": 37, + "loc": { + "start": { + "line": 3, + "column": 15 + }, + "end": { + "line": 3, + "column": 16 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + }, + { + "type": "ClassPrivateProperty", + "start": 39, + "end": 46, + "loc": { + "start": { + "line": 3, + "column": 18 + }, + "end": { + "line": 3, + "column": 25 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 40, + "end": 41, + "loc": { + "start": { + "line": 3, + "column": 19 + }, + "end": { + "line": 3, + "column": 20 + }, + "identifierName": "y" + }, + "name": "y" + }, + "value": { + "type": "NumericLiteral", + "start": 44, + "end": 45, + "loc": { + "start": { + "line": 3, + "column": 23 + }, + "end": { + "line": 3, + "column": 24 + } + }, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + } + ] + } + } + ], + "directives": [] + } +} diff --git a/test/fixtures/experimental/class-private-properties/inline/options.json b/test/fixtures/experimental/class-private-properties/inline/options.json new file mode 100644 index 0000000000..19c38d2996 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/inline/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties", "classPrivateProperties"] +} diff --git a/test/fixtures/experimental/class-private-properties/pbn-success.1/actual.js b/test/fixtures/experimental/class-private-properties/pbn-success.1/actual.js new file mode 100644 index 0000000000..457eaabf1a --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/pbn-success.1/actual.js @@ -0,0 +1,19 @@ +class Point { + #x; + #y; + + constructor(x = 0, y = 0) { + #x = +x; + #y = +y; + } + + get x() { return this.#x } + set x(value) { this.#x = +value } + + get y() { return this.#y } + set y(value) { this.#y = +value } + + equals(p) { return this.#x === p.#x && this.#y === p.#y } + + toString() { return `Point<${ this.#x },${ this.#y }>` } +} diff --git a/test/fixtures/experimental/class-private-properties/pbn-success.1/expected.json b/test/fixtures/experimental/class-private-properties/pbn-success.1/expected.json new file mode 100644 index 0000000000..b462f3ed7a --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/pbn-success.1/expected.json @@ -0,0 +1,1874 @@ +{ + "type": "File", + "start": 0, + "end": 369, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 19, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 369, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 19, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 369, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 19, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "Point" + }, + "name": "Point" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 12, + "end": 369, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 19, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateProperty", + "start": 18, + "end": 21, + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 7 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 19, + "end": 20, + "loc": { + "start": { + "line": 2, + "column": 5 + }, + "end": { + "line": 2, + "column": 6 + }, + "identifierName": "x" + }, + "name": "x" + }, + "value": null + }, + { + "type": "ClassPrivateProperty", + "start": 26, + "end": 29, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 7 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 27, + "end": 28, + "loc": { + "start": { + "line": 3, + "column": 5 + }, + "end": { + "line": 3, + "column": 6 + }, + "identifierName": "y" + }, + "name": "y" + }, + "value": null + }, + { + "type": "ClassMethod", + "start": 35, + "end": 102, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 8, + "column": 5 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 35, + "end": 46, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 15 + }, + "identifierName": "constructor" + }, + "name": "constructor" + }, + "kind": "constructor", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "AssignmentPattern", + "start": 47, + "end": 52, + "loc": { + "start": { + "line": 5, + "column": 16 + }, + "end": { + "line": 5, + "column": 21 + } + }, + "left": { + "type": "Identifier", + "start": 47, + "end": 48, + "loc": { + "start": { + "line": 5, + "column": 16 + }, + "end": { + "line": 5, + "column": 17 + }, + "identifierName": "x" + }, + "name": "x" + }, + "right": { + "type": "NumericLiteral", + "start": 51, + "end": 52, + "loc": { + "start": { + "line": 5, + "column": 20 + }, + "end": { + "line": 5, + "column": 21 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + }, + { + "type": "AssignmentPattern", + "start": 54, + "end": 59, + "loc": { + "start": { + "line": 5, + "column": 23 + }, + "end": { + "line": 5, + "column": 28 + } + }, + "left": { + "type": "Identifier", + "start": 54, + "end": 55, + "loc": { + "start": { + "line": 5, + "column": 23 + }, + "end": { + "line": 5, + "column": 24 + }, + "identifierName": "y" + }, + "name": "y" + }, + "right": { + "type": "NumericLiteral", + "start": 58, + "end": 59, + "loc": { + "start": { + "line": 5, + "column": 27 + }, + "end": { + "line": 5, + "column": 28 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + ], + "body": { + "type": "BlockStatement", + "start": 61, + "end": 102, + "loc": { + "start": { + "line": 5, + "column": 30 + }, + "end": { + "line": 8, + "column": 5 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 71, + "end": 79, + "loc": { + "start": { + "line": 6, + "column": 8 + }, + "end": { + "line": 6, + "column": 16 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 71, + "end": 78, + "loc": { + "start": { + "line": 6, + "column": 8 + }, + "end": { + "line": 6, + "column": 15 + } + }, + "operator": "=", + "left": { + "type": "PrivateName", + "start": 72, + "end": 73, + "loc": { + "start": { + "line": 6, + "column": 9 + }, + "end": { + "line": 6, + "column": 10 + } + }, + "name": { + "type": "Identifier", + "start": 72, + "end": 73, + "loc": { + "start": { + "line": 6, + "column": 9 + }, + "end": { + "line": 6, + "column": 10 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "right": { + "type": "UnaryExpression", + "start": 76, + "end": 78, + "loc": { + "start": { + "line": 6, + "column": 13 + }, + "end": { + "line": 6, + "column": 15 + } + }, + "operator": "+", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 77, + "end": 78, + "loc": { + "start": { + "line": 6, + "column": 14 + }, + "end": { + "line": 6, + "column": 15 + }, + "identifierName": "x" + }, + "name": "x" + }, + "extra": { + "parenthesizedArgument": false + } + } + } + }, + { + "type": "ExpressionStatement", + "start": 88, + "end": 96, + "loc": { + "start": { + "line": 7, + "column": 8 + }, + "end": { + "line": 7, + "column": 16 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 88, + "end": 95, + "loc": { + "start": { + "line": 7, + "column": 8 + }, + "end": { + "line": 7, + "column": 15 + } + }, + "operator": "=", + "left": { + "type": "PrivateName", + "start": 89, + "end": 90, + "loc": { + "start": { + "line": 7, + "column": 9 + }, + "end": { + "line": 7, + "column": 10 + } + }, + "name": { + "type": "Identifier", + "start": 89, + "end": 90, + "loc": { + "start": { + "line": 7, + "column": 9 + }, + "end": { + "line": 7, + "column": 10 + }, + "identifierName": "y" + }, + "name": "y" + } + }, + "right": { + "type": "UnaryExpression", + "start": 93, + "end": 95, + "loc": { + "start": { + "line": 7, + "column": 13 + }, + "end": { + "line": 7, + "column": 15 + } + }, + "operator": "+", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 94, + "end": 95, + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 15 + }, + "identifierName": "y" + }, + "name": "y" + }, + "extra": { + "parenthesizedArgument": false + } + } + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 108, + "end": 134, + "loc": { + "start": { + "line": 10, + "column": 4 + }, + "end": { + "line": 10, + "column": 30 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 112, + "end": 113, + "loc": { + "start": { + "line": 10, + "column": 8 + }, + "end": { + "line": 10, + "column": 9 + }, + "identifierName": "x" + }, + "name": "x" + }, + "kind": "get", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 116, + "end": 134, + "loc": { + "start": { + "line": 10, + "column": 12 + }, + "end": { + "line": 10, + "column": 30 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 118, + "end": 132, + "loc": { + "start": { + "line": 10, + "column": 14 + }, + "end": { + "line": 10, + "column": 28 + } + }, + "argument": { + "type": "MemberExpression", + "start": 125, + "end": 132, + "loc": { + "start": { + "line": 10, + "column": 21 + }, + "end": { + "line": 10, + "column": 28 + } + }, + "object": { + "type": "ThisExpression", + "start": 125, + "end": 129, + "loc": { + "start": { + "line": 10, + "column": 21 + }, + "end": { + "line": 10, + "column": 25 + } + } + }, + "property": { + "type": "PrivateName", + "start": 131, + "end": 132, + "loc": { + "start": { + "line": 10, + "column": 27 + }, + "end": { + "line": 10, + "column": 28 + } + }, + "name": { + "type": "Identifier", + "start": 131, + "end": 132, + "loc": { + "start": { + "line": 10, + "column": 27 + }, + "end": { + "line": 10, + "column": 28 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 139, + "end": 172, + "loc": { + "start": { + "line": 11, + "column": 4 + }, + "end": { + "line": 11, + "column": 37 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 143, + "end": 144, + "loc": { + "start": { + "line": 11, + "column": 8 + }, + "end": { + "line": 11, + "column": 9 + }, + "identifierName": "x" + }, + "name": "x" + }, + "kind": "set", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 145, + "end": 150, + "loc": { + "start": { + "line": 11, + "column": 10 + }, + "end": { + "line": 11, + "column": 15 + }, + "identifierName": "value" + }, + "name": "value" + } + ], + "body": { + "type": "BlockStatement", + "start": 152, + "end": 172, + "loc": { + "start": { + "line": 11, + "column": 17 + }, + "end": { + "line": 11, + "column": 37 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 154, + "end": 170, + "loc": { + "start": { + "line": 11, + "column": 19 + }, + "end": { + "line": 11, + "column": 35 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 154, + "end": 170, + "loc": { + "start": { + "line": 11, + "column": 19 + }, + "end": { + "line": 11, + "column": 35 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 154, + "end": 161, + "loc": { + "start": { + "line": 11, + "column": 19 + }, + "end": { + "line": 11, + "column": 26 + } + }, + "object": { + "type": "ThisExpression", + "start": 154, + "end": 158, + "loc": { + "start": { + "line": 11, + "column": 19 + }, + "end": { + "line": 11, + "column": 23 + } + } + }, + "property": { + "type": "PrivateName", + "start": 160, + "end": 161, + "loc": { + "start": { + "line": 11, + "column": 25 + }, + "end": { + "line": 11, + "column": 26 + } + }, + "name": { + "type": "Identifier", + "start": 160, + "end": 161, + "loc": { + "start": { + "line": 11, + "column": 25 + }, + "end": { + "line": 11, + "column": 26 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false + }, + "right": { + "type": "UnaryExpression", + "start": 164, + "end": 170, + "loc": { + "start": { + "line": 11, + "column": 29 + }, + "end": { + "line": 11, + "column": 35 + } + }, + "operator": "+", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 165, + "end": 170, + "loc": { + "start": { + "line": 11, + "column": 30 + }, + "end": { + "line": 11, + "column": 35 + }, + "identifierName": "value" + }, + "name": "value" + }, + "extra": { + "parenthesizedArgument": false + } + } + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 178, + "end": 204, + "loc": { + "start": { + "line": 13, + "column": 4 + }, + "end": { + "line": 13, + "column": 30 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 182, + "end": 183, + "loc": { + "start": { + "line": 13, + "column": 8 + }, + "end": { + "line": 13, + "column": 9 + }, + "identifierName": "y" + }, + "name": "y" + }, + "kind": "get", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 186, + "end": 204, + "loc": { + "start": { + "line": 13, + "column": 12 + }, + "end": { + "line": 13, + "column": 30 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 188, + "end": 202, + "loc": { + "start": { + "line": 13, + "column": 14 + }, + "end": { + "line": 13, + "column": 28 + } + }, + "argument": { + "type": "MemberExpression", + "start": 195, + "end": 202, + "loc": { + "start": { + "line": 13, + "column": 21 + }, + "end": { + "line": 13, + "column": 28 + } + }, + "object": { + "type": "ThisExpression", + "start": 195, + "end": 199, + "loc": { + "start": { + "line": 13, + "column": 21 + }, + "end": { + "line": 13, + "column": 25 + } + } + }, + "property": { + "type": "PrivateName", + "start": 201, + "end": 202, + "loc": { + "start": { + "line": 13, + "column": 27 + }, + "end": { + "line": 13, + "column": 28 + } + }, + "name": { + "type": "Identifier", + "start": 201, + "end": 202, + "loc": { + "start": { + "line": 13, + "column": 27 + }, + "end": { + "line": 13, + "column": 28 + }, + "identifierName": "y" + }, + "name": "y" + } + }, + "computed": false + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 209, + "end": 242, + "loc": { + "start": { + "line": 14, + "column": 4 + }, + "end": { + "line": 14, + "column": 37 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 213, + "end": 214, + "loc": { + "start": { + "line": 14, + "column": 8 + }, + "end": { + "line": 14, + "column": 9 + }, + "identifierName": "y" + }, + "name": "y" + }, + "kind": "set", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 215, + "end": 220, + "loc": { + "start": { + "line": 14, + "column": 10 + }, + "end": { + "line": 14, + "column": 15 + }, + "identifierName": "value" + }, + "name": "value" + } + ], + "body": { + "type": "BlockStatement", + "start": 222, + "end": 242, + "loc": { + "start": { + "line": 14, + "column": 17 + }, + "end": { + "line": 14, + "column": 37 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 224, + "end": 240, + "loc": { + "start": { + "line": 14, + "column": 19 + }, + "end": { + "line": 14, + "column": 35 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 224, + "end": 240, + "loc": { + "start": { + "line": 14, + "column": 19 + }, + "end": { + "line": 14, + "column": 35 + } + }, + "operator": "=", + "left": { + "type": "MemberExpression", + "start": 224, + "end": 231, + "loc": { + "start": { + "line": 14, + "column": 19 + }, + "end": { + "line": 14, + "column": 26 + } + }, + "object": { + "type": "ThisExpression", + "start": 224, + "end": 228, + "loc": { + "start": { + "line": 14, + "column": 19 + }, + "end": { + "line": 14, + "column": 23 + } + } + }, + "property": { + "type": "PrivateName", + "start": 230, + "end": 231, + "loc": { + "start": { + "line": 14, + "column": 25 + }, + "end": { + "line": 14, + "column": 26 + } + }, + "name": { + "type": "Identifier", + "start": 230, + "end": 231, + "loc": { + "start": { + "line": 14, + "column": 25 + }, + "end": { + "line": 14, + "column": 26 + }, + "identifierName": "y" + }, + "name": "y" + } + }, + "computed": false + }, + "right": { + "type": "UnaryExpression", + "start": 234, + "end": 240, + "loc": { + "start": { + "line": 14, + "column": 29 + }, + "end": { + "line": 14, + "column": 35 + } + }, + "operator": "+", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 235, + "end": 240, + "loc": { + "start": { + "line": 14, + "column": 30 + }, + "end": { + "line": 14, + "column": 35 + }, + "identifierName": "value" + }, + "name": "value" + }, + "extra": { + "parenthesizedArgument": false + } + } + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 248, + "end": 305, + "loc": { + "start": { + "line": 16, + "column": 4 + }, + "end": { + "line": 16, + "column": 61 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 248, + "end": 254, + "loc": { + "start": { + "line": 16, + "column": 4 + }, + "end": { + "line": 16, + "column": 10 + }, + "identifierName": "equals" + }, + "name": "equals" + }, + "kind": "method", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 255, + "end": 256, + "loc": { + "start": { + "line": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 12 + }, + "identifierName": "p" + }, + "name": "p" + } + ], + "body": { + "type": "BlockStatement", + "start": 258, + "end": 305, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 61 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 260, + "end": 303, + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 16, + "column": 59 + } + }, + "argument": { + "type": "LogicalExpression", + "start": 267, + "end": 303, + "loc": { + "start": { + "line": 16, + "column": 23 + }, + "end": { + "line": 16, + "column": 59 + } + }, + "left": { + "type": "BinaryExpression", + "start": 267, + "end": 283, + "loc": { + "start": { + "line": 16, + "column": 23 + }, + "end": { + "line": 16, + "column": 39 + } + }, + "left": { + "type": "MemberExpression", + "start": 267, + "end": 274, + "loc": { + "start": { + "line": 16, + "column": 23 + }, + "end": { + "line": 16, + "column": 30 + } + }, + "object": { + "type": "ThisExpression", + "start": 267, + "end": 271, + "loc": { + "start": { + "line": 16, + "column": 23 + }, + "end": { + "line": 16, + "column": 27 + } + } + }, + "property": { + "type": "PrivateName", + "start": 273, + "end": 274, + "loc": { + "start": { + "line": 16, + "column": 29 + }, + "end": { + "line": 16, + "column": 30 + } + }, + "name": { + "type": "Identifier", + "start": 273, + "end": 274, + "loc": { + "start": { + "line": 16, + "column": 29 + }, + "end": { + "line": 16, + "column": 30 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false + }, + "operator": "===", + "right": { + "type": "MemberExpression", + "start": 279, + "end": 283, + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 39 + } + }, + "object": { + "type": "Identifier", + "start": 279, + "end": 280, + "loc": { + "start": { + "line": 16, + "column": 35 + }, + "end": { + "line": 16, + "column": 36 + }, + "identifierName": "p" + }, + "name": "p" + }, + "property": { + "type": "PrivateName", + "start": 282, + "end": 283, + "loc": { + "start": { + "line": 16, + "column": 38 + }, + "end": { + "line": 16, + "column": 39 + } + }, + "name": { + "type": "Identifier", + "start": 282, + "end": 283, + "loc": { + "start": { + "line": 16, + "column": 38 + }, + "end": { + "line": 16, + "column": 39 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false + } + }, + "operator": "&&", + "right": { + "type": "BinaryExpression", + "start": 287, + "end": 303, + "loc": { + "start": { + "line": 16, + "column": 43 + }, + "end": { + "line": 16, + "column": 59 + } + }, + "left": { + "type": "MemberExpression", + "start": 287, + "end": 294, + "loc": { + "start": { + "line": 16, + "column": 43 + }, + "end": { + "line": 16, + "column": 50 + } + }, + "object": { + "type": "ThisExpression", + "start": 287, + "end": 291, + "loc": { + "start": { + "line": 16, + "column": 43 + }, + "end": { + "line": 16, + "column": 47 + } + } + }, + "property": { + "type": "PrivateName", + "start": 293, + "end": 294, + "loc": { + "start": { + "line": 16, + "column": 49 + }, + "end": { + "line": 16, + "column": 50 + } + }, + "name": { + "type": "Identifier", + "start": 293, + "end": 294, + "loc": { + "start": { + "line": 16, + "column": 49 + }, + "end": { + "line": 16, + "column": 50 + }, + "identifierName": "y" + }, + "name": "y" + } + }, + "computed": false + }, + "operator": "===", + "right": { + "type": "MemberExpression", + "start": 299, + "end": 303, + "loc": { + "start": { + "line": 16, + "column": 55 + }, + "end": { + "line": 16, + "column": 59 + } + }, + "object": { + "type": "Identifier", + "start": 299, + "end": 300, + "loc": { + "start": { + "line": 16, + "column": 55 + }, + "end": { + "line": 16, + "column": 56 + }, + "identifierName": "p" + }, + "name": "p" + }, + "property": { + "type": "PrivateName", + "start": 302, + "end": 303, + "loc": { + "start": { + "line": 16, + "column": 58 + }, + "end": { + "line": 16, + "column": 59 + } + }, + "name": { + "type": "Identifier", + "start": 302, + "end": 303, + "loc": { + "start": { + "line": 16, + "column": 58 + }, + "end": { + "line": 16, + "column": 59 + }, + "identifierName": "y" + }, + "name": "y" + } + }, + "computed": false + } + } + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 311, + "end": 367, + "loc": { + "start": { + "line": 18, + "column": 4 + }, + "end": { + "line": 18, + "column": 60 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 311, + "end": 319, + "loc": { + "start": { + "line": 18, + "column": 4 + }, + "end": { + "line": 18, + "column": 12 + }, + "identifierName": "toString" + }, + "name": "toString" + }, + "kind": "method", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 322, + "end": 367, + "loc": { + "start": { + "line": 18, + "column": 15 + }, + "end": { + "line": 18, + "column": 60 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 324, + "end": 365, + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 58 + } + }, + "argument": { + "type": "TemplateLiteral", + "start": 331, + "end": 365, + "loc": { + "start": { + "line": 18, + "column": 24 + }, + "end": { + "line": 18, + "column": 58 + } + }, + "expressions": [ + { + "type": "MemberExpression", + "start": 341, + "end": 348, + "loc": { + "start": { + "line": 18, + "column": 34 + }, + "end": { + "line": 18, + "column": 41 + } + }, + "object": { + "type": "ThisExpression", + "start": 341, + "end": 345, + "loc": { + "start": { + "line": 18, + "column": 34 + }, + "end": { + "line": 18, + "column": 38 + } + } + }, + "property": { + "type": "PrivateName", + "start": 347, + "end": 348, + "loc": { + "start": { + "line": 18, + "column": 40 + }, + "end": { + "line": 18, + "column": 41 + } + }, + "name": { + "type": "Identifier", + "start": 347, + "end": 348, + "loc": { + "start": { + "line": 18, + "column": 40 + }, + "end": { + "line": 18, + "column": 41 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false + }, + { + "type": "MemberExpression", + "start": 354, + "end": 361, + "loc": { + "start": { + "line": 18, + "column": 47 + }, + "end": { + "line": 18, + "column": 54 + } + }, + "object": { + "type": "ThisExpression", + "start": 354, + "end": 358, + "loc": { + "start": { + "line": 18, + "column": 47 + }, + "end": { + "line": 18, + "column": 51 + } + } + }, + "property": { + "type": "PrivateName", + "start": 360, + "end": 361, + "loc": { + "start": { + "line": 18, + "column": 53 + }, + "end": { + "line": 18, + "column": 54 + } + }, + "name": { + "type": "Identifier", + "start": 360, + "end": 361, + "loc": { + "start": { + "line": 18, + "column": 53 + }, + "end": { + "line": 18, + "column": 54 + }, + "identifierName": "y" + }, + "name": "y" + } + }, + "computed": false + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 332, + "end": 338, + "loc": { + "start": { + "line": 18, + "column": 25 + }, + "end": { + "line": 18, + "column": 31 + } + }, + "value": { + "raw": "Point<", + "cooked": "Point<" + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 350, + "end": 351, + "loc": { + "start": { + "line": 18, + "column": 43 + }, + "end": { + "line": 18, + "column": 44 + } + }, + "value": { + "raw": ",", + "cooked": "," + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 363, + "end": 364, + "loc": { + "start": { + "line": 18, + "column": 56 + }, + "end": { + "line": 18, + "column": 57 + } + }, + "value": { + "raw": ">", + "cooked": ">" + }, + "tail": true + } + ] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} diff --git a/test/fixtures/experimental/class-private-properties/pbn-success.1/options.json b/test/fixtures/experimental/class-private-properties/pbn-success.1/options.json new file mode 100644 index 0000000000..19c38d2996 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/pbn-success.1/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties", "classPrivateProperties"] +} diff --git a/test/fixtures/experimental/class-private-properties/pbn-success/actual.js b/test/fixtures/experimental/class-private-properties/pbn-success/actual.js new file mode 100644 index 0000000000..9c17fc00e8 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/pbn-success/actual.js @@ -0,0 +1,19 @@ +class Point { + #x; + #y; + + constructor(x = 0, y = 0) { + #x = +x; + #y = +y; + } + + get x() { return #x } + set x(value) { #x = +value } + + get y() { return #y } + set y(value) { #y = +value } + + equals(p) { return #x === p.#x && #y === p.#y } + + toString() { return `Point<${ #x },${ #y }>` } +} diff --git a/test/fixtures/experimental/class-private-properties/pbn-success/expected.json b/test/fixtures/experimental/class-private-properties/pbn-success/expected.json new file mode 100644 index 0000000000..837f95fee8 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/pbn-success/expected.json @@ -0,0 +1,1626 @@ +{ + "type": "File", + "start": 0, + "end": 329, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 19, + "column": 1 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 329, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 19, + "column": 1 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ClassDeclaration", + "start": 0, + "end": 329, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 19, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + }, + "identifierName": "Point" + }, + "name": "Point" + }, + "superClass": null, + "body": { + "type": "ClassBody", + "start": 12, + "end": 329, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 19, + "column": 1 + } + }, + "body": [ + { + "type": "ClassPrivateProperty", + "start": 18, + "end": 21, + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 7 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 19, + "end": 20, + "loc": { + "start": { + "line": 2, + "column": 5 + }, + "end": { + "line": 2, + "column": 6 + }, + "identifierName": "x" + }, + "name": "x" + }, + "value": null + }, + { + "type": "ClassPrivateProperty", + "start": 26, + "end": 29, + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 7 + } + }, + "computed": false, + "key": { + "type": "Identifier", + "start": 27, + "end": 28, + "loc": { + "start": { + "line": 3, + "column": 5 + }, + "end": { + "line": 3, + "column": 6 + }, + "identifierName": "y" + }, + "name": "y" + }, + "value": null + }, + { + "type": "ClassMethod", + "start": 35, + "end": 102, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 8, + "column": 5 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 35, + "end": 46, + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 15 + }, + "identifierName": "constructor" + }, + "name": "constructor" + }, + "kind": "constructor", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "AssignmentPattern", + "start": 47, + "end": 52, + "loc": { + "start": { + "line": 5, + "column": 16 + }, + "end": { + "line": 5, + "column": 21 + } + }, + "left": { + "type": "Identifier", + "start": 47, + "end": 48, + "loc": { + "start": { + "line": 5, + "column": 16 + }, + "end": { + "line": 5, + "column": 17 + }, + "identifierName": "x" + }, + "name": "x" + }, + "right": { + "type": "NumericLiteral", + "start": 51, + "end": 52, + "loc": { + "start": { + "line": 5, + "column": 20 + }, + "end": { + "line": 5, + "column": 21 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + }, + { + "type": "AssignmentPattern", + "start": 54, + "end": 59, + "loc": { + "start": { + "line": 5, + "column": 23 + }, + "end": { + "line": 5, + "column": 28 + } + }, + "left": { + "type": "Identifier", + "start": 54, + "end": 55, + "loc": { + "start": { + "line": 5, + "column": 23 + }, + "end": { + "line": 5, + "column": 24 + }, + "identifierName": "y" + }, + "name": "y" + }, + "right": { + "type": "NumericLiteral", + "start": 58, + "end": 59, + "loc": { + "start": { + "line": 5, + "column": 27 + }, + "end": { + "line": 5, + "column": 28 + } + }, + "extra": { + "rawValue": 0, + "raw": "0" + }, + "value": 0 + } + } + ], + "body": { + "type": "BlockStatement", + "start": 61, + "end": 102, + "loc": { + "start": { + "line": 5, + "column": 30 + }, + "end": { + "line": 8, + "column": 5 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 71, + "end": 79, + "loc": { + "start": { + "line": 6, + "column": 8 + }, + "end": { + "line": 6, + "column": 16 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 71, + "end": 78, + "loc": { + "start": { + "line": 6, + "column": 8 + }, + "end": { + "line": 6, + "column": 15 + } + }, + "operator": "=", + "left": { + "type": "PrivateName", + "start": 72, + "end": 73, + "loc": { + "start": { + "line": 6, + "column": 9 + }, + "end": { + "line": 6, + "column": 10 + } + }, + "name": { + "type": "Identifier", + "start": 72, + "end": 73, + "loc": { + "start": { + "line": 6, + "column": 9 + }, + "end": { + "line": 6, + "column": 10 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "right": { + "type": "UnaryExpression", + "start": 76, + "end": 78, + "loc": { + "start": { + "line": 6, + "column": 13 + }, + "end": { + "line": 6, + "column": 15 + } + }, + "operator": "+", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 77, + "end": 78, + "loc": { + "start": { + "line": 6, + "column": 14 + }, + "end": { + "line": 6, + "column": 15 + }, + "identifierName": "x" + }, + "name": "x" + }, + "extra": { + "parenthesizedArgument": false + } + } + } + }, + { + "type": "ExpressionStatement", + "start": 88, + "end": 96, + "loc": { + "start": { + "line": 7, + "column": 8 + }, + "end": { + "line": 7, + "column": 16 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 88, + "end": 95, + "loc": { + "start": { + "line": 7, + "column": 8 + }, + "end": { + "line": 7, + "column": 15 + } + }, + "operator": "=", + "left": { + "type": "PrivateName", + "start": 89, + "end": 90, + "loc": { + "start": { + "line": 7, + "column": 9 + }, + "end": { + "line": 7, + "column": 10 + } + }, + "name": { + "type": "Identifier", + "start": 89, + "end": 90, + "loc": { + "start": { + "line": 7, + "column": 9 + }, + "end": { + "line": 7, + "column": 10 + }, + "identifierName": "y" + }, + "name": "y" + } + }, + "right": { + "type": "UnaryExpression", + "start": 93, + "end": 95, + "loc": { + "start": { + "line": 7, + "column": 13 + }, + "end": { + "line": 7, + "column": 15 + } + }, + "operator": "+", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 94, + "end": 95, + "loc": { + "start": { + "line": 7, + "column": 14 + }, + "end": { + "line": 7, + "column": 15 + }, + "identifierName": "y" + }, + "name": "y" + }, + "extra": { + "parenthesizedArgument": false + } + } + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 108, + "end": 129, + "loc": { + "start": { + "line": 10, + "column": 4 + }, + "end": { + "line": 10, + "column": 25 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 112, + "end": 113, + "loc": { + "start": { + "line": 10, + "column": 8 + }, + "end": { + "line": 10, + "column": 9 + }, + "identifierName": "x" + }, + "name": "x" + }, + "kind": "get", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 116, + "end": 129, + "loc": { + "start": { + "line": 10, + "column": 12 + }, + "end": { + "line": 10, + "column": 25 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 118, + "end": 127, + "loc": { + "start": { + "line": 10, + "column": 14 + }, + "end": { + "line": 10, + "column": 23 + } + }, + "argument": { + "type": "PrivateName", + "start": 126, + "end": 127, + "loc": { + "start": { + "line": 10, + "column": 22 + }, + "end": { + "line": 10, + "column": 23 + } + }, + "name": { + "type": "Identifier", + "start": 126, + "end": 127, + "loc": { + "start": { + "line": 10, + "column": 22 + }, + "end": { + "line": 10, + "column": 23 + }, + "identifierName": "x" + }, + "name": "x" + } + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 134, + "end": 162, + "loc": { + "start": { + "line": 11, + "column": 4 + }, + "end": { + "line": 11, + "column": 32 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 138, + "end": 139, + "loc": { + "start": { + "line": 11, + "column": 8 + }, + "end": { + "line": 11, + "column": 9 + }, + "identifierName": "x" + }, + "name": "x" + }, + "kind": "set", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 140, + "end": 145, + "loc": { + "start": { + "line": 11, + "column": 10 + }, + "end": { + "line": 11, + "column": 15 + }, + "identifierName": "value" + }, + "name": "value" + } + ], + "body": { + "type": "BlockStatement", + "start": 147, + "end": 162, + "loc": { + "start": { + "line": 11, + "column": 17 + }, + "end": { + "line": 11, + "column": 32 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 149, + "end": 160, + "loc": { + "start": { + "line": 11, + "column": 19 + }, + "end": { + "line": 11, + "column": 30 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 149, + "end": 160, + "loc": { + "start": { + "line": 11, + "column": 19 + }, + "end": { + "line": 11, + "column": 30 + } + }, + "operator": "=", + "left": { + "type": "PrivateName", + "start": 150, + "end": 151, + "loc": { + "start": { + "line": 11, + "column": 20 + }, + "end": { + "line": 11, + "column": 21 + } + }, + "name": { + "type": "Identifier", + "start": 150, + "end": 151, + "loc": { + "start": { + "line": 11, + "column": 20 + }, + "end": { + "line": 11, + "column": 21 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "right": { + "type": "UnaryExpression", + "start": 154, + "end": 160, + "loc": { + "start": { + "line": 11, + "column": 24 + }, + "end": { + "line": 11, + "column": 30 + } + }, + "operator": "+", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 155, + "end": 160, + "loc": { + "start": { + "line": 11, + "column": 25 + }, + "end": { + "line": 11, + "column": 30 + }, + "identifierName": "value" + }, + "name": "value" + }, + "extra": { + "parenthesizedArgument": false + } + } + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 168, + "end": 189, + "loc": { + "start": { + "line": 13, + "column": 4 + }, + "end": { + "line": 13, + "column": 25 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 172, + "end": 173, + "loc": { + "start": { + "line": 13, + "column": 8 + }, + "end": { + "line": 13, + "column": 9 + }, + "identifierName": "y" + }, + "name": "y" + }, + "kind": "get", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 176, + "end": 189, + "loc": { + "start": { + "line": 13, + "column": 12 + }, + "end": { + "line": 13, + "column": 25 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 178, + "end": 187, + "loc": { + "start": { + "line": 13, + "column": 14 + }, + "end": { + "line": 13, + "column": 23 + } + }, + "argument": { + "type": "PrivateName", + "start": 186, + "end": 187, + "loc": { + "start": { + "line": 13, + "column": 22 + }, + "end": { + "line": 13, + "column": 23 + } + }, + "name": { + "type": "Identifier", + "start": 186, + "end": 187, + "loc": { + "start": { + "line": 13, + "column": 22 + }, + "end": { + "line": 13, + "column": 23 + }, + "identifierName": "y" + }, + "name": "y" + } + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 194, + "end": 222, + "loc": { + "start": { + "line": 14, + "column": 4 + }, + "end": { + "line": 14, + "column": 32 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 198, + "end": 199, + "loc": { + "start": { + "line": 14, + "column": 8 + }, + "end": { + "line": 14, + "column": 9 + }, + "identifierName": "y" + }, + "name": "y" + }, + "kind": "set", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 200, + "end": 205, + "loc": { + "start": { + "line": 14, + "column": 10 + }, + "end": { + "line": 14, + "column": 15 + }, + "identifierName": "value" + }, + "name": "value" + } + ], + "body": { + "type": "BlockStatement", + "start": 207, + "end": 222, + "loc": { + "start": { + "line": 14, + "column": 17 + }, + "end": { + "line": 14, + "column": 32 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 209, + "end": 220, + "loc": { + "start": { + "line": 14, + "column": 19 + }, + "end": { + "line": 14, + "column": 30 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 209, + "end": 220, + "loc": { + "start": { + "line": 14, + "column": 19 + }, + "end": { + "line": 14, + "column": 30 + } + }, + "operator": "=", + "left": { + "type": "PrivateName", + "start": 210, + "end": 211, + "loc": { + "start": { + "line": 14, + "column": 20 + }, + "end": { + "line": 14, + "column": 21 + } + }, + "name": { + "type": "Identifier", + "start": 210, + "end": 211, + "loc": { + "start": { + "line": 14, + "column": 20 + }, + "end": { + "line": 14, + "column": 21 + }, + "identifierName": "y" + }, + "name": "y" + } + }, + "right": { + "type": "UnaryExpression", + "start": 214, + "end": 220, + "loc": { + "start": { + "line": 14, + "column": 24 + }, + "end": { + "line": 14, + "column": 30 + } + }, + "operator": "+", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 215, + "end": 220, + "loc": { + "start": { + "line": 14, + "column": 25 + }, + "end": { + "line": 14, + "column": 30 + }, + "identifierName": "value" + }, + "name": "value" + }, + "extra": { + "parenthesizedArgument": false + } + } + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 228, + "end": 275, + "loc": { + "start": { + "line": 16, + "column": 4 + }, + "end": { + "line": 16, + "column": 51 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 228, + "end": 234, + "loc": { + "start": { + "line": 16, + "column": 4 + }, + "end": { + "line": 16, + "column": 10 + }, + "identifierName": "equals" + }, + "name": "equals" + }, + "kind": "method", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 235, + "end": 236, + "loc": { + "start": { + "line": 16, + "column": 11 + }, + "end": { + "line": 16, + "column": 12 + }, + "identifierName": "p" + }, + "name": "p" + } + ], + "body": { + "type": "BlockStatement", + "start": 238, + "end": 275, + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 51 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 240, + "end": 273, + "loc": { + "start": { + "line": 16, + "column": 16 + }, + "end": { + "line": 16, + "column": 49 + } + }, + "argument": { + "type": "LogicalExpression", + "start": 247, + "end": 273, + "loc": { + "start": { + "line": 16, + "column": 23 + }, + "end": { + "line": 16, + "column": 49 + } + }, + "left": { + "type": "BinaryExpression", + "start": 247, + "end": 258, + "loc": { + "start": { + "line": 16, + "column": 23 + }, + "end": { + "line": 16, + "column": 34 + } + }, + "left": { + "type": "PrivateName", + "start": 248, + "end": 249, + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 25 + } + }, + "name": { + "type": "Identifier", + "start": 248, + "end": 249, + "loc": { + "start": { + "line": 16, + "column": 24 + }, + "end": { + "line": 16, + "column": 25 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "operator": "===", + "right": { + "type": "MemberExpression", + "start": 254, + "end": 258, + "loc": { + "start": { + "line": 16, + "column": 30 + }, + "end": { + "line": 16, + "column": 34 + } + }, + "object": { + "type": "Identifier", + "start": 254, + "end": 255, + "loc": { + "start": { + "line": 16, + "column": 30 + }, + "end": { + "line": 16, + "column": 31 + }, + "identifierName": "p" + }, + "name": "p" + }, + "property": { + "type": "PrivateName", + "start": 257, + "end": 258, + "loc": { + "start": { + "line": 16, + "column": 33 + }, + "end": { + "line": 16, + "column": 34 + } + }, + "name": { + "type": "Identifier", + "start": 257, + "end": 258, + "loc": { + "start": { + "line": 16, + "column": 33 + }, + "end": { + "line": 16, + "column": 34 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + "computed": false + } + }, + "operator": "&&", + "right": { + "type": "BinaryExpression", + "start": 262, + "end": 273, + "loc": { + "start": { + "line": 16, + "column": 38 + }, + "end": { + "line": 16, + "column": 49 + } + }, + "left": { + "type": "PrivateName", + "start": 263, + "end": 264, + "loc": { + "start": { + "line": 16, + "column": 39 + }, + "end": { + "line": 16, + "column": 40 + } + }, + "name": { + "type": "Identifier", + "start": 263, + "end": 264, + "loc": { + "start": { + "line": 16, + "column": 39 + }, + "end": { + "line": 16, + "column": 40 + }, + "identifierName": "y" + }, + "name": "y" + } + }, + "operator": "===", + "right": { + "type": "MemberExpression", + "start": 269, + "end": 273, + "loc": { + "start": { + "line": 16, + "column": 45 + }, + "end": { + "line": 16, + "column": 49 + } + }, + "object": { + "type": "Identifier", + "start": 269, + "end": 270, + "loc": { + "start": { + "line": 16, + "column": 45 + }, + "end": { + "line": 16, + "column": 46 + }, + "identifierName": "p" + }, + "name": "p" + }, + "property": { + "type": "PrivateName", + "start": 272, + "end": 273, + "loc": { + "start": { + "line": 16, + "column": 48 + }, + "end": { + "line": 16, + "column": 49 + } + }, + "name": { + "type": "Identifier", + "start": 272, + "end": 273, + "loc": { + "start": { + "line": 16, + "column": 48 + }, + "end": { + "line": 16, + "column": 49 + }, + "identifierName": "y" + }, + "name": "y" + } + }, + "computed": false + } + } + } + } + ], + "directives": [] + } + }, + { + "type": "ClassMethod", + "start": 281, + "end": 327, + "loc": { + "start": { + "line": 18, + "column": 4 + }, + "end": { + "line": 18, + "column": 50 + } + }, + "static": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 281, + "end": 289, + "loc": { + "start": { + "line": 18, + "column": 4 + }, + "end": { + "line": 18, + "column": 12 + }, + "identifierName": "toString" + }, + "name": "toString" + }, + "kind": "method", + "id": null, + "generator": false, + "expression": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start": 292, + "end": 327, + "loc": { + "start": { + "line": 18, + "column": 15 + }, + "end": { + "line": 18, + "column": 50 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 294, + "end": 325, + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 18, + "column": 48 + } + }, + "argument": { + "type": "TemplateLiteral", + "start": 301, + "end": 325, + "loc": { + "start": { + "line": 18, + "column": 24 + }, + "end": { + "line": 18, + "column": 48 + } + }, + "expressions": [ + { + "type": "PrivateName", + "start": 312, + "end": 313, + "loc": { + "start": { + "line": 18, + "column": 35 + }, + "end": { + "line": 18, + "column": 36 + } + }, + "name": { + "type": "Identifier", + "start": 312, + "end": 313, + "loc": { + "start": { + "line": 18, + "column": 35 + }, + "end": { + "line": 18, + "column": 36 + }, + "identifierName": "x" + }, + "name": "x" + } + }, + { + "type": "PrivateName", + "start": 320, + "end": 321, + "loc": { + "start": { + "line": 18, + "column": 43 + }, + "end": { + "line": 18, + "column": 44 + } + }, + "name": { + "type": "Identifier", + "start": 320, + "end": 321, + "loc": { + "start": { + "line": 18, + "column": 43 + }, + "end": { + "line": 18, + "column": 44 + }, + "identifierName": "y" + }, + "name": "y" + } + } + ], + "quasis": [ + { + "type": "TemplateElement", + "start": 302, + "end": 308, + "loc": { + "start": { + "line": 18, + "column": 25 + }, + "end": { + "line": 18, + "column": 31 + } + }, + "value": { + "raw": "Point<", + "cooked": "Point<" + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 315, + "end": 316, + "loc": { + "start": { + "line": 18, + "column": 38 + }, + "end": { + "line": 18, + "column": 39 + } + }, + "value": { + "raw": ",", + "cooked": "," + }, + "tail": false + }, + { + "type": "TemplateElement", + "start": 323, + "end": 324, + "loc": { + "start": { + "line": 18, + "column": 46 + }, + "end": { + "line": 18, + "column": 47 + } + }, + "value": { + "raw": ">", + "cooked": ">" + }, + "tail": true + } + ] + } + } + ], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} diff --git a/test/fixtures/experimental/class-private-properties/pbn-success/options.json b/test/fixtures/experimental/class-private-properties/pbn-success/options.json new file mode 100644 index 0000000000..19c38d2996 --- /dev/null +++ b/test/fixtures/experimental/class-private-properties/pbn-success/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["classProperties", "classPrivateProperties"] +} From 2541ab5fdae7c8fc262d5b4919b124584e0c4c75 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 22 May 2017 10:42:32 -0700 Subject: [PATCH 59/73] Simplify PrivateName and ClassPrivateProperty types (#532) * Simplify PrivateName and ClassPrivateProperty types * ClassPrivateProperty is not a ClassMemberBase; can't be static, can't be computed --- src/types.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/types.js b/src/types.js index 5e8013b5de..23597835fd 100644 --- a/src/types.js +++ b/src/types.js @@ -62,11 +62,9 @@ export type Identifier = PatternBase & { __clone(): Identifier; }; -export type PrivateName = PatternBase & { +export type PrivateName = NodeBase & { type: "PrivateName"; name: string; - - __clone(): Identifier; }; // Literals @@ -591,16 +589,10 @@ export type ClassProperty = ClassMemberBase & { readonly?: true; }; -export type ClassPrivateProperty = ClassMemberBase & { +export type ClassPrivateProperty = NodeBase & { type: "ClassPrivateProperty"; key: Identifier; value: ?Expression; // TODO: Not in spec that this is nullable. - - typeAnnotation?: ?FlowTypeAnnotation; // TODO: Not in spec - variance?: ?FlowVariance; // TODO: Not in spec - - // TypeScript only: (TODO: Not in spec) - readonly?: true; }; export type OptClassDeclaration = ClassBase & DeclarationBase & HasDecorators & { From 1a92c1f34c5a1bd1bd1de9f438aec0d2f592568b Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Mon, 22 May 2017 14:57:21 -0400 Subject: [PATCH 60/73] 7.0.0-beta.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e4a6ce9caf..0035c67f24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "babylon", - "version": "7.0.0-beta.8", + "version": "7.0.0-beta.9", "description": "A JavaScript parser", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", From 0f66dbd4b61f93918c75c8fc2f2ea698062085b7 Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Mon, 22 May 2017 17:01:48 -0400 Subject: [PATCH 61/73] add changelog label data [skip ci] --- package.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/package.json b/package.json index 0035c67f24..13ac72d054 100644 --- a/package.json +++ b/package.json @@ -76,5 +76,16 @@ "src/**/*.js", "bin/**/*.js" ] + }, + "changelog": { + "repo": "babel/babylon", + "labels": { + "Tag: Breaking Change": ":boom: Breaking Change", + "Tag: Bug Fix": ":bug: Bug Fix", + "Tag: Docs": ":memo: Documentation", + "Tag: Internal": ":house: Internal", + "Tag: New Feature": ":rocket: New Feature", + "Tag: Polish": ":nail_care: Polish" + } } } From 557696da3ac9f4e25b7d1777daba45b42a03bf36 Mon Sep 17 00:00:00 2001 From: aardito2 Date: Mon, 22 May 2017 17:02:02 -0400 Subject: [PATCH 62/73] Fixed disappearing comments following a trailing comma on the last property of an object literal or the last argument of a call expression (#478) --- src/parser/comments.js | 33 +- .../actual.js | 1 + .../expected.json | 208 ++++++++++ .../basic/function-trailing-comma/actual.js | 1 + .../function-trailing-comma/expected.json | 153 +++++++ .../object-property-trailing-comma/actual.js | 5 + .../expected.json | 372 ++++++++++++++++++ 7 files changed, 772 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/comments/basic/function-trailing-comma-shorthand/actual.js create mode 100644 test/fixtures/comments/basic/function-trailing-comma-shorthand/expected.json create mode 100644 test/fixtures/comments/basic/function-trailing-comma/actual.js create mode 100644 test/fixtures/comments/basic/function-trailing-comma/expected.json create mode 100644 test/fixtures/comments/basic/object-property-trailing-comma/actual.js create mode 100644 test/fixtures/comments/basic/object-property-trailing-comma/expected.json diff --git a/src/parser/comments.js b/src/parser/comments.js index 96e339389b..9f06446030 100644 --- a/src/parser/comments.js +++ b/src/parser/comments.js @@ -45,7 +45,7 @@ export default class CommentsParser extends BaseParser { const stack = this.state.commentStack; - let lastChild, trailingComments, i, j; + let firstChild, lastChild, trailingComments, i, j; if (this.state.trailingComments.length > 0) { // If the first comment in trailingComments comes after the @@ -73,10 +73,41 @@ export default class CommentsParser extends BaseParser { } // Eating the stack. + if (stack.length > 0 && last(stack).start >= node.start) { + firstChild = stack.pop(); + } + while (stack.length > 0 && last(stack).start >= node.start) { lastChild = stack.pop(); } + if (!lastChild && firstChild) lastChild = firstChild; + + // Attach comments that follow a trailing comma on the last + // property in an object literal or a trailing comma in function arguments + // as trailing comments + if (firstChild && + (firstChild.type === "ObjectProperty" || + (node.type === "CallExpression")) && + this.state.leadingComments.length > 0) { + const lastComment = last(this.state.leadingComments); + if (lastComment.start >= node.start) { + if (this.state.commentPreviousNode) { + for (j = 0; j < this.state.leadingComments.length; j++) { + if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) { + this.state.leadingComments.splice(j, 1); + j--; + } + } + + if (this.state.leadingComments.length > 0) { + firstChild.trailingComments = this.state.leadingComments; + this.state.leadingComments = []; + } + } + } + } + if (lastChild) { if (lastChild.leadingComments) { if (lastChild !== node && last(lastChild.leadingComments).end <= node.start) { diff --git a/test/fixtures/comments/basic/function-trailing-comma-shorthand/actual.js b/test/fixtures/comments/basic/function-trailing-comma-shorthand/actual.js new file mode 100644 index 0000000000..0936c59b4e --- /dev/null +++ b/test/fixtures/comments/basic/function-trailing-comma-shorthand/actual.js @@ -0,0 +1 @@ +fn(a, { b }, /* comment */); diff --git a/test/fixtures/comments/basic/function-trailing-comma-shorthand/expected.json b/test/fixtures/comments/basic/function-trailing-comma-shorthand/expected.json new file mode 100644 index 0000000000..95184b49b6 --- /dev/null +++ b/test/fixtures/comments/basic/function-trailing-comma-shorthand/expected.json @@ -0,0 +1,208 @@ +{ + "type": "File", + "start": 0, + "end": 28, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 28 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 28, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 28 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 28, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 28 + } + }, + "expression": { + "type": "CallExpression", + "start": 0, + "end": 27, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 27 + } + }, + "callee": { + "type": "Identifier", + "start": 0, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 2 + }, + "identifierName": "fn" + }, + "name": "fn" + }, + "arguments": [ + { + "type": "Identifier", + "start": 3, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 4 + }, + "identifierName": "a" + }, + "name": "a" + }, + { + "type": "ObjectExpression", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 8, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 8, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 9 + }, + "identifierName": "b" + }, + "name": "b" + }, + "value": { + "type": "Identifier", + "start": 8, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 9 + }, + "identifierName": "b" + }, + "name": "b" + }, + "extra": { + "shorthand": true + } + } + ], + "trailingComments": [ + { + "type": "CommentBlock", + "value": " comment ", + "start": 13, + "end": 26, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 26 + } + } + } + ] + } + ] + } + } + ], + "directives": [] + }, + "comments": [ + { + "type": "CommentBlock", + "value": " comment ", + "start": 13, + "end": 26, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 26 + } + } + } + ] +} \ No newline at end of file diff --git a/test/fixtures/comments/basic/function-trailing-comma/actual.js b/test/fixtures/comments/basic/function-trailing-comma/actual.js new file mode 100644 index 0000000000..d8611dab0c --- /dev/null +++ b/test/fixtures/comments/basic/function-trailing-comma/actual.js @@ -0,0 +1 @@ +fn(a, b, /* comment */); diff --git a/test/fixtures/comments/basic/function-trailing-comma/expected.json b/test/fixtures/comments/basic/function-trailing-comma/expected.json new file mode 100644 index 0000000000..4f4b3c2604 --- /dev/null +++ b/test/fixtures/comments/basic/function-trailing-comma/expected.json @@ -0,0 +1,153 @@ +{ + "type": "File", + "start": 0, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 24, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "expression": { + "type": "CallExpression", + "start": 0, + "end": 23, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 23 + } + }, + "callee": { + "type": "Identifier", + "start": 0, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 2 + }, + "identifierName": "fn" + }, + "name": "fn" + }, + "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": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + }, + "identifierName": "b" + }, + "name": "b", + "trailingComments": [ + { + "type": "CommentBlock", + "value": " comment ", + "start": 9, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 22 + } + } + } + ] + } + ] + } + } + ], + "directives": [] + }, + "comments": [ + { + "type": "CommentBlock", + "value": " comment ", + "start": 9, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 22 + } + } + } + ] +} \ No newline at end of file diff --git a/test/fixtures/comments/basic/object-property-trailing-comma/actual.js b/test/fixtures/comments/basic/object-property-trailing-comma/actual.js new file mode 100644 index 0000000000..acd5921a7c --- /dev/null +++ b/test/fixtures/comments/basic/object-property-trailing-comma/actual.js @@ -0,0 +1,5 @@ +var obj = { + a: '1', // comment 1 + b: '2', // comment 2 + c: '3', // comment 3 +}; diff --git a/test/fixtures/comments/basic/object-property-trailing-comma/expected.json b/test/fixtures/comments/basic/object-property-trailing-comma/expected.json new file mode 100644 index 0000000000..3e55ef7129 --- /dev/null +++ b/test/fixtures/comments/basic/object-property-trailing-comma/expected.json @@ -0,0 +1,372 @@ +{ + "type": "File", + "start": 0, + "end": 83, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 2 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 83, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 2 + } + }, + "sourceType": "script", + "body": [ + { + "type": "VariableDeclaration", + "start": 0, + "end": 83, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 2 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 4, + "end": 82, + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "start": 4, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 1, + "column": 7 + }, + "identifierName": "obj" + }, + "name": "obj" + }, + "init": { + "type": "ObjectExpression", + "start": 10, + "end": 82, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "properties": [ + { + "type": "ObjectProperty", + "start": 14, + "end": 20, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 8 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 14, + "end": 15, + "loc": { + "start": { + "line": 2, + "column": 2 + }, + "end": { + "line": 2, + "column": 3 + }, + "identifierName": "a" + }, + "name": "a" + }, + "value": { + "type": "StringLiteral", + "start": 17, + "end": 20, + "loc": { + "start": { + "line": 2, + "column": 5 + }, + "end": { + "line": 2, + "column": 8 + } + }, + "extra": { + "rawValue": "1", + "raw": "'1'" + }, + "value": "1" + } + }, + { + "type": "ObjectProperty", + "start": 37, + "end": 43, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 8 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 37, + "end": 38, + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 3 + }, + "identifierName": "b" + }, + "name": "b", + "leadingComments": null + }, + "value": { + "type": "StringLiteral", + "start": 40, + "end": 43, + "loc": { + "start": { + "line": 3, + "column": 5 + }, + "end": { + "line": 3, + "column": 8 + } + }, + "extra": { + "rawValue": "2", + "raw": "'2'" + }, + "value": "2" + }, + "leadingComments": [ + { + "type": "CommentLine", + "value": " comment 1", + "start": 22, + "end": 34, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 22 + } + } + } + ] + }, + { + "type": "ObjectProperty", + "start": 60, + "end": 66, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 4, + "column": 8 + } + }, + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "start": 60, + "end": 61, + "loc": { + "start": { + "line": 4, + "column": 2 + }, + "end": { + "line": 4, + "column": 3 + }, + "identifierName": "c" + }, + "name": "c", + "leadingComments": null + }, + "value": { + "type": "StringLiteral", + "start": 63, + "end": 66, + "loc": { + "start": { + "line": 4, + "column": 5 + }, + "end": { + "line": 4, + "column": 8 + } + }, + "extra": { + "rawValue": "3", + "raw": "'3'" + }, + "value": "3" + }, + "leadingComments": [ + { + "type": "CommentLine", + "value": " comment 2", + "start": 45, + "end": 57, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 22 + } + } + } + ], + "trailingComments": [ + { + "type": "CommentLine", + "value": " comment 3", + "start": 68, + "end": 80, + "loc": { + "start": { + "line": 4, + "column": 10 + }, + "end": { + "line": 4, + "column": 22 + } + } + } + ] + } + ] + } + } + ], + "kind": "var" + } + ], + "directives": [] + }, + "comments": [ + { + "type": "CommentLine", + "value": " comment 1", + "start": 22, + "end": 34, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 22 + } + } + }, + { + "type": "CommentLine", + "value": " comment 2", + "start": 45, + "end": 57, + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 22 + } + } + }, + { + "type": "CommentLine", + "value": " comment 3", + "start": 68, + "end": 80, + "loc": { + "start": { + "line": 4, + "column": 10 + }, + "end": { + "line": 4, + "column": 22 + } + } + } + ] +} \ No newline at end of file From 9709c8d932731273c7f936595491fe1568c48cc2 Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Mon, 22 May 2017 17:02:42 -0400 Subject: [PATCH 63/73] 7.0.0-beta.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 13ac72d054..93d70da773 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "babylon", - "version": "7.0.0-beta.9", + "version": "7.0.0-beta.10", "description": "A JavaScript parser", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", From 6eeb0317b97684459f66864c0e03c8cc66d62eb1 Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Fri, 26 May 2017 12:27:28 -0400 Subject: [PATCH 64/73] pin to alpha.9 --- package.json | 12 +- yarn.lock | 680 +++++++++++++++++++++++++-------------------------- 2 files changed, 342 insertions(+), 350 deletions(-) diff --git a/package.json b/package.json index 93d70da773..f1fb0802a1 100644 --- a/package.json +++ b/package.json @@ -22,14 +22,14 @@ }, "devDependencies": { "ava": "^0.19.0", - "babel-cli": "^7.0.0-alpha.6", + "babel-cli": "7.0.0-alpha.9", "babel-eslint": "^7.0.0", - "babel-helper-fixtures": "^7.0.0-alpha.3", - "babel-plugin-external-helpers": "^7.0.0-alpha.3", + "babel-helper-fixtures": "7.0.0-alpha.9", + "babel-plugin-external-helpers": "7.0.0-alpha.9", "babel-plugin-istanbul": "^4.0.0", - "babel-plugin-transform-flow-strip-types": "^7.0.0-alpha.3", - "babel-preset-es2015": "^7.0.0-alpha.3", - "babel-preset-stage-0": "^7.0.0-alpha.3", + "babel-plugin-transform-flow-strip-types": "7.0.0-alpha.9", + "babel-preset-es2015": "7.0.0-alpha.9", + "babel-preset-stage-0": "7.0.0-alpha.9", "chalk": "^1.1.3", "cross-env": "^5.0.0", "eslint": "^3.7.1", diff --git a/yarn.lock b/yarn.lock index 628fbb48d6..e7500624ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -309,13 +309,13 @@ aws4@^1.2.1: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -babel-cli@^7.0.0-alpha.6: - version "7.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-7.0.0-alpha.6.tgz#80c2888379dc91bbb8171512bfa58ebe96819b4d" +babel-cli@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-7.0.0-alpha.9.tgz#4d32556e5b97b71b5dd273ee672f2e5d9f862ef5" dependencies: - babel-core "7.0.0-alpha.6" - babel-polyfill "7.0.0-alpha.3" - babel-register "7.0.0-alpha.6" + babel-core "7.0.0-alpha.9" + babel-polyfill "7.0.0-alpha.9" + babel-register "7.0.0-alpha.9" commander "^2.8.1" convert-source-map "^1.1.0" fs-readdir-recursive "^1.0.0" @@ -328,9 +328,9 @@ babel-cli@^7.0.0-alpha.6: optionalDependencies: chokidar "^1.6.1" -babel-code-frame@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-7.0.0-alpha.3.tgz#9ff265eaaac94b58dfc7ca4a4eecf389d5f4d344" +babel-code-frame@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-7.0.0-alpha.9.tgz#b861deec3e9f744a30405137d4ad0216ccef0cba" dependencies: chalk "^1.1.0" esutils "^2.0.2" @@ -368,18 +368,18 @@ babel-core@6, babel-core@^6.17.0, babel-core@^6.24.0: slash "^1.0.0" source-map "^0.5.0" -babel-core@7.0.0-alpha.6: - version "7.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-alpha.6.tgz#a4c59f5cd5ef0374365a37937e5c585510eed718" +babel-core@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-alpha.9.tgz#1868005f160dbcd2325e6b3472f3f9ea010a9313" dependencies: - babel-code-frame "7.0.0-alpha.3" - babel-generator "7.0.0-alpha.3" - babel-helpers "7.0.0-alpha.3" - babel-messages "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" - babel-traverse "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" - babylon "7.0.0-beta.7" + babel-code-frame "7.0.0-alpha.9" + babel-generator "7.0.0-alpha.9" + babel-helpers "7.0.0-alpha.9" + babel-messages "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" + babel-traverse "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" + babylon "7.0.0-beta.8" convert-source-map "^1.1.0" debug "^2.1.1" json5 "^0.5.0" @@ -399,12 +399,12 @@ babel-eslint@^7.0.0: babel-types "^6.23.0" babylon "^6.16.1" -babel-generator@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-7.0.0-alpha.3.tgz#92af29b9e75fbe6888ef0d28b39e34f9ec83a06c" +babel-generator@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-7.0.0-alpha.9.tgz#4b4f41963e70beda87d94a3d358a6caf86172692" dependencies: - babel-messages "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-messages "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" detect-indent "^4.0.0" jsesc "^1.3.0" lodash "^4.2.0" @@ -432,13 +432,13 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.22.0: babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-helper-call-delegate@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-7.0.0-alpha.3.tgz#23c12acd22ade7ed05b27a51ad2c7d1016929dbf" +babel-helper-call-delegate@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-7.0.0-alpha.9.tgz#be5eb3e7cd170a95a1bc5c87f1382c1912d62e67" dependencies: - babel-helper-hoist-variables "7.0.0-alpha.3" - babel-traverse "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-helper-hoist-variables "7.0.0-alpha.9" + babel-traverse "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" babel-helper-call-delegate@^6.22.0: version "6.22.0" @@ -449,12 +449,12 @@ babel-helper-call-delegate@^6.22.0: babel-traverse "^6.22.0" babel-types "^6.22.0" -babel-helper-define-map@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-7.0.0-alpha.3.tgz#1d67803d202440e70ed10ddff74600e143be50fa" +babel-helper-define-map@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-7.0.0-alpha.9.tgz#b8ffc122cdc415222c8b575bc9b39b0578e506e1" dependencies: - babel-helper-function-name "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-helper-function-name "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" lodash "^4.2.0" babel-helper-define-map@^6.23.0: @@ -474,21 +474,21 @@ babel-helper-explode-assignable-expression@^6.22.0: babel-traverse "^6.22.0" babel-types "^6.22.0" -babel-helper-fixtures@^7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-helper-fixtures/-/babel-helper-fixtures-7.0.0-alpha.3.tgz#7095057fe51432cc0300c7de0f84cba9e8057ecc" +babel-helper-fixtures@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-helper-fixtures/-/babel-helper-fixtures-7.0.0-alpha.9.tgz#f329546232f5045c575930ca5b1686dea317c9c6" dependencies: lodash "^4.2.0" try-resolve "^1.0.0" -babel-helper-function-name@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-7.0.0-alpha.3.tgz#c20acaadfff6632b7c7efccab31d60d5e8e59814" +babel-helper-function-name@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-7.0.0-alpha.9.tgz#03d62dd9e68385085668367fce861a8a5b30a886" dependencies: - babel-helper-get-function-arity "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" - babel-traverse "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-helper-get-function-arity "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" + babel-traverse "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" babel-helper-function-name@^6.22.0, babel-helper-function-name@^6.23.0: version "6.23.0" @@ -500,11 +500,11 @@ babel-helper-function-name@^6.22.0, babel-helper-function-name@^6.23.0: babel-traverse "^6.23.0" babel-types "^6.23.0" -babel-helper-get-function-arity@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-7.0.0-alpha.3.tgz#e2c2db48d65300da135cabd91d8e9629b07ca5e8" +babel-helper-get-function-arity@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-7.0.0-alpha.9.tgz#6c55e28e30d111074ab5a5f5881a7569d6f1dcbc" dependencies: - babel-types "7.0.0-alpha.3" + babel-types "7.0.0-alpha.9" babel-helper-get-function-arity@^6.22.0: version "6.22.0" @@ -513,11 +513,11 @@ babel-helper-get-function-arity@^6.22.0: babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-helper-hoist-variables@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-7.0.0-alpha.3.tgz#6bd71cdea55d848877acf14c3751b8598c0fd198" +babel-helper-hoist-variables@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-7.0.0-alpha.9.tgz#51b5dc0a0ca04eff44e0c2eb418d1223d5d80897" dependencies: - babel-types "7.0.0-alpha.3" + babel-types "7.0.0-alpha.9" babel-helper-hoist-variables@^6.22.0: version "6.22.0" @@ -526,11 +526,11 @@ babel-helper-hoist-variables@^6.22.0: babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-helper-optimise-call-expression@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-7.0.0-alpha.3.tgz#a3c5ba4a5e59c651c74f9e17351ff8d4093f13b2" +babel-helper-optimise-call-expression@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-7.0.0-alpha.9.tgz#a57ddbe40c17ede3d24ebb4375164dd657ff7a58" dependencies: - babel-types "7.0.0-alpha.3" + babel-types "7.0.0-alpha.9" babel-helper-optimise-call-expression@^6.23.0: version "6.23.0" @@ -539,11 +539,11 @@ babel-helper-optimise-call-expression@^6.23.0: babel-runtime "^6.22.0" babel-types "^6.23.0" -babel-helper-regex@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-7.0.0-alpha.3.tgz#c74440fc1418b6e92290c4880e15e3738f31a366" +babel-helper-regex@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-7.0.0-alpha.9.tgz#bea1160d204b4f3e6547992234b2a23002dbe0fb" dependencies: - babel-types "7.0.0-alpha.3" + babel-types "7.0.0-alpha.9" lodash "^4.2.0" babel-helper-regex@^6.18.0, babel-helper-regex@^6.22.0: @@ -554,14 +554,14 @@ babel-helper-regex@^6.18.0, babel-helper-regex@^6.22.0: babel-types "^6.22.0" lodash "^4.2.0" -babel-helper-remap-async-to-generator@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-7.0.0-alpha.3.tgz#9b137a1222a186f1cfb6fa292af5d302085e1aa7" +babel-helper-remap-async-to-generator@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-7.0.0-alpha.9.tgz#22fce32bd1d66c206d766a74ca948149836d04ff" dependencies: - babel-helper-function-name "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" - babel-traverse "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-helper-function-name "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" + babel-traverse "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" babel-helper-remap-async-to-generator@^6.22.0: version "6.22.0" @@ -573,15 +573,15 @@ babel-helper-remap-async-to-generator@^6.22.0: babel-traverse "^6.22.0" babel-types "^6.22.0" -babel-helper-replace-supers@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-7.0.0-alpha.3.tgz#04c701909509867fa84bceeb2b0e51b34cf2d657" +babel-helper-replace-supers@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-7.0.0-alpha.9.tgz#501fba74d5bb2c169f52b1146bcb7005a0f8a86f" dependencies: - babel-helper-optimise-call-expression "7.0.0-alpha.3" - babel-messages "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" - babel-traverse "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-helper-optimise-call-expression "7.0.0-alpha.9" + babel-messages "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" + babel-traverse "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" babel-helper-replace-supers@^6.23.0: version "6.23.0" @@ -594,11 +594,11 @@ babel-helper-replace-supers@^6.23.0: babel-traverse "^6.23.0" babel-types "^6.23.0" -babel-helpers@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-7.0.0-alpha.3.tgz#e9a5362d84bfa6730dca16f762e185a077afc45e" +babel-helpers@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-7.0.0-alpha.9.tgz#653f391654e0c18556e78d39fe58fd7f9e730f27" dependencies: - babel-template "7.0.0-alpha.3" + babel-template "7.0.0-alpha.9" babel-helpers@^6.23.0: version "6.23.0" @@ -607,9 +607,9 @@ babel-helpers@^6.23.0: babel-runtime "^6.22.0" babel-template "^6.23.0" -babel-messages@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-7.0.0-alpha.3.tgz#c8390a468478b8384da134612e12a6bc31a684e9" +babel-messages@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-7.0.0-alpha.9.tgz#472b5e7158c4b3fded5eec0fb76f0ad930cb4ea8" babel-messages@^6.23.0: version "6.23.0" @@ -617,9 +617,9 @@ babel-messages@^6.23.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-check-es2015-constants@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-7.0.0-alpha.3.tgz#bc83e61842bf8769515e7f69cb43cf7f2546aaba" +babel-plugin-check-es2015-constants@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-7.0.0-alpha.9.tgz#66acf31594b95fb01b585af58c2f342cdc2c5b8d" babel-plugin-check-es2015-constants@^6.8.0: version "6.22.0" @@ -639,9 +639,9 @@ babel-plugin-espower@^2.3.2: espurify "^1.6.0" estraverse "^4.1.1" -babel-plugin-external-helpers@^7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-external-helpers/-/babel-plugin-external-helpers-7.0.0-alpha.3.tgz#0fd8b75ae487025f1ad61616aaeb3850d1c9ad63" +babel-plugin-external-helpers@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-external-helpers/-/babel-plugin-external-helpers-7.0.0-alpha.9.tgz#43040aa36e66dfae660ffb003ca17a290c18b4a2" babel-plugin-istanbul@^4.0.0: version "4.1.1" @@ -655,56 +655,56 @@ babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" -babel-plugin-syntax-async-generators@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-7.0.0-alpha.3.tgz#2b248b8d1d12c26728571f004b0b633f8c192a7f" +babel-plugin-syntax-async-generators@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-7.0.0-alpha.9.tgz#2e19abfde0da639e6bfae5872ef66e4e1a8a9375" -babel-plugin-syntax-class-properties@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-7.0.0-alpha.3.tgz#d1324dc38545f8365f51bd174bdc03fc1a1f6d8e" +babel-plugin-syntax-class-properties@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-7.0.0-alpha.9.tgz#a79f336c5aa729fac70b20790157ebc81bb41c13" -babel-plugin-syntax-decorators@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-7.0.0-alpha.3.tgz#b7a3c443df608966599e771b4a94a31a7cda3d4f" +babel-plugin-syntax-decorators@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-7.0.0-alpha.9.tgz#5b2b6d7c549f5dd10c9c44cdb85a1b8ff62089e6" -babel-plugin-syntax-do-expressions@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-7.0.0-alpha.3.tgz#f012a7640b3581a2e3fd4b0ccb95598248355237" +babel-plugin-syntax-do-expressions@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-7.0.0-alpha.9.tgz#82974b4e3052e826b883b69b89ab2ec06528d0e8" -babel-plugin-syntax-dynamic-import@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-7.0.0-alpha.3.tgz#c181227705398ea333071ca7ff59196d8ba6d953" +babel-plugin-syntax-dynamic-import@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-7.0.0-alpha.9.tgz#84cc7ad10524082a59fe6c5dd1714fb5d8fac226" babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" -babel-plugin-syntax-export-extensions@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-7.0.0-alpha.3.tgz#cf0caca528af0508ee34eb5d3cd9309bbe025f61" +babel-plugin-syntax-export-extensions@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-7.0.0-alpha.9.tgz#563924d129942d6209989bba2ee57ee1f602d62e" -babel-plugin-syntax-flow@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-7.0.0-alpha.3.tgz#9776060b86674a5375a53eaabbd305ca4f5ab2fa" +babel-plugin-syntax-flow@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-7.0.0-alpha.9.tgz#63937567c4179bf23fa6b1c954ba6ab2090e8ba1" -babel-plugin-syntax-function-bind@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-7.0.0-alpha.3.tgz#7ed78e62b87b2f38d2cf02d90e9c8b5d77309f57" +babel-plugin-syntax-function-bind@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-7.0.0-alpha.9.tgz#e5cd183b0950ccbac310a3d85286a09bc3840054" -babel-plugin-syntax-object-rest-spread@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-7.0.0-alpha.3.tgz#52dd2698be335f1c0297d5d34ac526537ef63576" +babel-plugin-syntax-object-rest-spread@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-7.0.0-alpha.9.tgz#4b9c6d325dede89e9f7374e1381833528d5d31d7" babel-plugin-syntax-trailing-function-commas@^6.20.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" -babel-plugin-transform-async-generator-functions@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-7.0.0-alpha.3.tgz#ba61d374ca649e9cf48f5ddb70c893d87d3af31e" +babel-plugin-transform-async-generator-functions@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-7.0.0-alpha.9.tgz#24bc94904b70adf4174ef3b85a0f222fcb11f937" dependencies: - babel-helper-remap-async-to-generator "7.0.0-alpha.3" - babel-plugin-syntax-async-generators "7.0.0-alpha.3" + babel-helper-remap-async-to-generator "7.0.0-alpha.9" + babel-plugin-syntax-async-generators "7.0.0-alpha.9" babel-plugin-transform-async-to-generator@^6.16.0: version "6.22.0" @@ -714,57 +714,56 @@ babel-plugin-transform-async-to-generator@^6.16.0: babel-plugin-syntax-async-functions "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-class-properties@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-7.0.0-alpha.3.tgz#74b48911411c2e000a74c0c8a08bb8e36afb17df" +babel-plugin-transform-class-properties@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-7.0.0-alpha.9.tgz#2beb155476d7db0c26c4d548d3fe53ce8af1dcb5" dependencies: - babel-helper-function-name "7.0.0-alpha.3" - babel-plugin-syntax-class-properties "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" + babel-helper-function-name "7.0.0-alpha.9" + babel-plugin-syntax-class-properties "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" -babel-plugin-transform-decorators@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-7.0.0-alpha.3.tgz#a0d3586d399d59d8b43d14c8f5b87efe9f5d0ae2" +babel-plugin-transform-decorators@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-7.0.0-alpha.9.tgz#848a3d6cc58360fbf3bb27fe6ce56438b4b7fb2b" dependencies: - babel-plugin-syntax-decorators "7.0.0-alpha.3" - babel-runtime "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" + babel-plugin-syntax-decorators "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" -babel-plugin-transform-do-expressions@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-7.0.0-alpha.3.tgz#9a0442f5f8a6314d3c6e5f086ff6cade2fb3a382" +babel-plugin-transform-do-expressions@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-7.0.0-alpha.9.tgz#0127887eecfa32a617ea6b771f194f8d8eb37653" dependencies: - babel-plugin-syntax-do-expressions "7.0.0-alpha.3" + babel-plugin-syntax-do-expressions "7.0.0-alpha.9" -babel-plugin-transform-es2015-arrow-functions@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-7.0.0-alpha.3.tgz#1c07e322a1d6d58173f69e0a48f7b7e89a1d64ef" +babel-plugin-transform-es2015-arrow-functions@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-7.0.0-alpha.9.tgz#1679372c8485a5af41d8ae18eee8e2f73df4f463" -babel-plugin-transform-es2015-block-scoped-functions@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-7.0.0-alpha.3.tgz#fa5f3f3715e05ec3a1ef2c1ec8bb1f1fe3a4ce0a" +babel-plugin-transform-es2015-block-scoped-functions@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-7.0.0-alpha.9.tgz#0fc73e54fe3e937dfa6a9f98374622fe88d8e613" -babel-plugin-transform-es2015-block-scoping@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-7.0.0-alpha.3.tgz#8c939676d0be68ef55500455b785ed1b4c0160bd" +babel-plugin-transform-es2015-block-scoping@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-7.0.0-alpha.9.tgz#a33aa7b5d977e8aa62f1643decaa9ebf6480dafd" dependencies: - babel-template "7.0.0-alpha.3" - babel-traverse "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-template "7.0.0-alpha.9" + babel-traverse "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" lodash "^4.2.0" -babel-plugin-transform-es2015-classes@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-7.0.0-alpha.3.tgz#98e6fc79f1d3ac9ed2c51ee7c3f14d8c38ffe2c6" +babel-plugin-transform-es2015-classes@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-7.0.0-alpha.9.tgz#869dba3c94934ebbb44159536d48c7fe7eb3c48e" dependencies: - babel-helper-define-map "7.0.0-alpha.3" - babel-helper-function-name "7.0.0-alpha.3" - babel-helper-optimise-call-expression "7.0.0-alpha.3" - babel-helper-replace-supers "7.0.0-alpha.3" - babel-messages "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" - babel-traverse "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-helper-define-map "7.0.0-alpha.9" + babel-helper-function-name "7.0.0-alpha.9" + babel-helper-optimise-call-expression "7.0.0-alpha.9" + babel-helper-replace-supers "7.0.0-alpha.9" + babel-messages "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" + babel-traverse "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" babel-plugin-transform-es2015-classes@^6.9.0: version "6.23.0" @@ -780,15 +779,15 @@ babel-plugin-transform-es2015-classes@^6.9.0: babel-traverse "^6.23.0" babel-types "^6.23.0" -babel-plugin-transform-es2015-computed-properties@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-7.0.0-alpha.3.tgz#9577e8d3a45e63da5c5ddf14163fb2ef67bb26c8" +babel-plugin-transform-es2015-computed-properties@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-7.0.0-alpha.9.tgz#fadd49ec2945dbb1c6a6871cbcf1ed68228ad961" dependencies: - babel-template "7.0.0-alpha.3" + babel-template "7.0.0-alpha.9" -babel-plugin-transform-es2015-destructuring@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-7.0.0-alpha.3.tgz#509333f153ba1b58fa1a4b48286cbdce11b028a0" +babel-plugin-transform-es2015-destructuring@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-7.0.0-alpha.9.tgz#ef66f4e6eed8ea3f5d26f8a2464d3815f6250236" babel-plugin-transform-es2015-destructuring@^6.19.0: version "6.23.0" @@ -796,22 +795,22 @@ babel-plugin-transform-es2015-destructuring@^6.19.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-duplicate-keys@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-7.0.0-alpha.3.tgz#1a4add3548ffd64f209be62695409d3d616b0d64" +babel-plugin-transform-es2015-duplicate-keys@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-7.0.0-alpha.9.tgz#5889b47777098aae1268217479b8800f1c469a3d" dependencies: - babel-types "7.0.0-alpha.3" + babel-types "7.0.0-alpha.9" -babel-plugin-transform-es2015-for-of@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-7.0.0-alpha.3.tgz#6a959e8995a21ae796deaa2db7d74b7009a9dd79" +babel-plugin-transform-es2015-for-of@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-7.0.0-alpha.9.tgz#b5975301de392944b613cf56466e5719a9de2779" -babel-plugin-transform-es2015-function-name@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-7.0.0-alpha.3.tgz#39d08ce84f45d7652f20a2123b556a9de24459c2" +babel-plugin-transform-es2015-function-name@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-7.0.0-alpha.9.tgz#337ae95ceb4201a989a98eec62d1d7c88840bf1c" dependencies: - babel-helper-function-name "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-helper-function-name "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" babel-plugin-transform-es2015-function-name@^6.9.0: version "6.22.0" @@ -821,24 +820,24 @@ babel-plugin-transform-es2015-function-name@^6.9.0: babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-plugin-transform-es2015-literals@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-7.0.0-alpha.3.tgz#748048faebe88da55cad28e9c1d50c83e1eb0de7" +babel-plugin-transform-es2015-literals@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-7.0.0-alpha.9.tgz#113081b0f38e4080e1cbb4e59fe65521b7622c9a" -babel-plugin-transform-es2015-modules-amd@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-7.0.0-alpha.3.tgz#960aa59d67e76948beea0cd2a5bb6771cea36c7f" +babel-plugin-transform-es2015-modules-amd@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-7.0.0-alpha.9.tgz#427375507363280ebffdd32da42c3044ddd067a9" dependencies: - babel-plugin-transform-es2015-modules-commonjs "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" + babel-plugin-transform-es2015-modules-commonjs "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" -babel-plugin-transform-es2015-modules-commonjs@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-7.0.0-alpha.3.tgz#9d5b06621da4f6f665345d4ecc86084f74f608ce" +babel-plugin-transform-es2015-modules-commonjs@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-7.0.0-alpha.9.tgz#590b1461aadbe0247498f93185f54e1ac4914a0a" dependencies: - babel-plugin-transform-strict-mode "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-plugin-transform-strict-mode "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" babel-plugin-transform-es2015-modules-commonjs@^6.18.0: version "6.24.0" @@ -849,35 +848,35 @@ babel-plugin-transform-es2015-modules-commonjs@^6.18.0: babel-template "^6.23.0" babel-types "^6.23.0" -babel-plugin-transform-es2015-modules-systemjs@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-7.0.0-alpha.3.tgz#b725ff684cf660001700fb9377b58940a6977b91" +babel-plugin-transform-es2015-modules-systemjs@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-7.0.0-alpha.9.tgz#bec788c8064fd846034da6997540f99bda422acf" dependencies: - babel-helper-hoist-variables "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" + babel-helper-hoist-variables "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" -babel-plugin-transform-es2015-modules-umd@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-7.0.0-alpha.3.tgz#ec37fa367540262900b0b14cda7f2006bb1e1430" +babel-plugin-transform-es2015-modules-umd@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-7.0.0-alpha.9.tgz#27398241f7c8965f39451ebb9daac0d5ff58e53a" dependencies: - babel-plugin-transform-es2015-modules-amd "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" + babel-plugin-transform-es2015-modules-amd "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" -babel-plugin-transform-es2015-object-super@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-7.0.0-alpha.3.tgz#b27368c505aa951656cc96749b485401da620429" +babel-plugin-transform-es2015-object-super@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-7.0.0-alpha.9.tgz#21fd8d96977753af28ad2c29f04e247e6976d214" dependencies: - babel-helper-replace-supers "7.0.0-alpha.3" + babel-helper-replace-supers "7.0.0-alpha.9" -babel-plugin-transform-es2015-parameters@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-7.0.0-alpha.3.tgz#909e780d1e5bf9d972f80f389de95d45c36d40e6" +babel-plugin-transform-es2015-parameters@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-7.0.0-alpha.9.tgz#a93197ac19a1230ecf483895f22af6c864f4420e" dependencies: - babel-helper-call-delegate "7.0.0-alpha.3" - babel-helper-get-function-arity "7.0.0-alpha.3" - babel-template "7.0.0-alpha.3" - babel-traverse "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-helper-call-delegate "7.0.0-alpha.9" + babel-helper-get-function-arity "7.0.0-alpha.9" + babel-template "7.0.0-alpha.9" + babel-traverse "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" babel-plugin-transform-es2015-parameters@^6.21.0: version "6.23.0" @@ -890,15 +889,15 @@ babel-plugin-transform-es2015-parameters@^6.21.0: babel-traverse "^6.23.0" babel-types "^6.23.0" -babel-plugin-transform-es2015-shorthand-properties@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-7.0.0-alpha.3.tgz#6c704d77495994c91f17f2e8e39d89fa6f3d978c" +babel-plugin-transform-es2015-shorthand-properties@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-7.0.0-alpha.9.tgz#527adce1276fdd266539c73e2fb014abf244684d" dependencies: - babel-types "7.0.0-alpha.3" + babel-types "7.0.0-alpha.9" -babel-plugin-transform-es2015-spread@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-7.0.0-alpha.3.tgz#2d4b831e6b0e7c73e8201c38a824fe88d6168567" +babel-plugin-transform-es2015-spread@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-7.0.0-alpha.9.tgz#f82d6783784fa16c7d9e257133b222cee369a76f" babel-plugin-transform-es2015-spread@^6.8.0: version "6.22.0" @@ -906,12 +905,12 @@ babel-plugin-transform-es2015-spread@^6.8.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-sticky-regex@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-7.0.0-alpha.3.tgz#abc021c8ad9a9ced19c27b0d94d1817abf2a8a2b" +babel-plugin-transform-es2015-sticky-regex@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-7.0.0-alpha.9.tgz#af8d52db9096e49de15a1fc1009ae8427a55c72e" dependencies: - babel-helper-regex "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" + babel-helper-regex "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" babel-plugin-transform-es2015-sticky-regex@^6.8.0: version "6.22.0" @@ -921,19 +920,19 @@ babel-plugin-transform-es2015-sticky-regex@^6.8.0: babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-plugin-transform-es2015-template-literals@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-7.0.0-alpha.3.tgz#ccad4e75903dc5ee1989a5108b83740c80b3629a" +babel-plugin-transform-es2015-template-literals@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-7.0.0-alpha.9.tgz#7ad77b7efd9a00fdd8334ef557ffd59bd4f19233" -babel-plugin-transform-es2015-typeof-symbol@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-7.0.0-alpha.3.tgz#6592d301f2c40e5e943e5a3e26e56adc6db736ac" +babel-plugin-transform-es2015-typeof-symbol@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-7.0.0-alpha.9.tgz#436e1139b288fab3cbd6c406f87f9a424d3e1c4a" -babel-plugin-transform-es2015-unicode-regex@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-7.0.0-alpha.3.tgz#0c8acf70e05dcfceaf9c3bfa10f123a645c44bac" +babel-plugin-transform-es2015-unicode-regex@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-7.0.0-alpha.9.tgz#109bdf7c2ff930548cd5e00d9acc9a119dce4524" dependencies: - babel-helper-regex "7.0.0-alpha.3" + babel-helper-regex "7.0.0-alpha.9" regexpu-core "^4.0.2" babel-plugin-transform-es2015-unicode-regex@^6.11.0: @@ -952,41 +951,41 @@ babel-plugin-transform-exponentiation-operator@^6.8.0: babel-plugin-syntax-exponentiation-operator "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-export-extensions@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-7.0.0-alpha.3.tgz#c5b9e386db077eb6f63f0d6cabeccbc399245d6d" +babel-plugin-transform-export-extensions@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-7.0.0-alpha.9.tgz#aa18c659c446cfeb73f57a188fdd52b0b2b1c663" dependencies: - babel-plugin-syntax-export-extensions "7.0.0-alpha.3" + babel-plugin-syntax-export-extensions "7.0.0-alpha.9" -babel-plugin-transform-flow-strip-types@^7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-7.0.0-alpha.3.tgz#35681202b913f5b1a73d29a3f555dffff8ecad64" +babel-plugin-transform-flow-strip-types@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-7.0.0-alpha.9.tgz#2902fbbaa9b17216eea35349b6e38557a100965b" dependencies: - babel-plugin-syntax-flow "7.0.0-alpha.3" + babel-plugin-syntax-flow "7.0.0-alpha.9" -babel-plugin-transform-function-bind@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-7.0.0-alpha.3.tgz#1f10da630b4aeb2dc88ed368cd13cd54c70e7cec" +babel-plugin-transform-function-bind@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-7.0.0-alpha.9.tgz#e8c55c154d6c2992251ddff82ff2c03189e2d78a" dependencies: - babel-plugin-syntax-function-bind "7.0.0-alpha.3" + babel-plugin-syntax-function-bind "7.0.0-alpha.9" -babel-plugin-transform-object-rest-spread@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-7.0.0-alpha.3.tgz#111a7e158ee02adf212933d9ad829f3d63eff207" +babel-plugin-transform-object-rest-spread@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-7.0.0-alpha.9.tgz#3a87b7cd92e3e33e42135777ab6148ee2b035cd7" dependencies: - babel-plugin-syntax-object-rest-spread "7.0.0-alpha.3" + babel-plugin-syntax-object-rest-spread "7.0.0-alpha.9" -babel-plugin-transform-regenerator@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-7.0.0-alpha.3.tgz#5d76d87e8e1a0b73bf77aaefd704cdb535182a4e" +babel-plugin-transform-regenerator@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-7.0.0-alpha.9.tgz#8f4acdda69c176461e9a5b0e61952f1430a944ae" dependencies: regenerator-transform "0.9.11" -babel-plugin-transform-strict-mode@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-7.0.0-alpha.3.tgz#308068db94074f368eac190a854ebaf43118e03f" +babel-plugin-transform-strict-mode@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-7.0.0-alpha.9.tgz#ae40edc8cf49ba2a7a57b12517970e4c1fedc471" dependencies: - babel-types "7.0.0-alpha.3" + babel-types "7.0.0-alpha.9" babel-plugin-transform-strict-mode@^6.22.0: version "6.22.0" @@ -1003,79 +1002,79 @@ babel-plugin-transform-unicode-property-regex@^2.0.0: babel-runtime "^6.23.0" regexpu-core "^4.0.4" -babel-polyfill@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-7.0.0-alpha.3.tgz#2f0f39b7a537fcdb03f506add010a71013a07bd3" +babel-polyfill@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-7.0.0-alpha.9.tgz#d565d2695bfed7ab07c812093e1f3222107e8fb8" dependencies: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-preset-es2015@^7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-7.0.0-alpha.3.tgz#16534cf8dbc86369dbf5d6bb08c9d43101b81628" +babel-preset-es2015@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-7.0.0-alpha.9.tgz#e0de59ce2f4e0caa18c322ca50261fc15a31a98b" dependencies: - babel-plugin-check-es2015-constants "7.0.0-alpha.3" - babel-plugin-transform-es2015-arrow-functions "7.0.0-alpha.3" - babel-plugin-transform-es2015-block-scoped-functions "7.0.0-alpha.3" - babel-plugin-transform-es2015-block-scoping "7.0.0-alpha.3" - babel-plugin-transform-es2015-classes "7.0.0-alpha.3" - babel-plugin-transform-es2015-computed-properties "7.0.0-alpha.3" - babel-plugin-transform-es2015-destructuring "7.0.0-alpha.3" - babel-plugin-transform-es2015-duplicate-keys "7.0.0-alpha.3" - babel-plugin-transform-es2015-for-of "7.0.0-alpha.3" - babel-plugin-transform-es2015-function-name "7.0.0-alpha.3" - babel-plugin-transform-es2015-literals "7.0.0-alpha.3" - babel-plugin-transform-es2015-modules-amd "7.0.0-alpha.3" - babel-plugin-transform-es2015-modules-commonjs "7.0.0-alpha.3" - babel-plugin-transform-es2015-modules-systemjs "7.0.0-alpha.3" - babel-plugin-transform-es2015-modules-umd "7.0.0-alpha.3" - babel-plugin-transform-es2015-object-super "7.0.0-alpha.3" - babel-plugin-transform-es2015-parameters "7.0.0-alpha.3" - babel-plugin-transform-es2015-shorthand-properties "7.0.0-alpha.3" - babel-plugin-transform-es2015-spread "7.0.0-alpha.3" - babel-plugin-transform-es2015-sticky-regex "7.0.0-alpha.3" - babel-plugin-transform-es2015-template-literals "7.0.0-alpha.3" - babel-plugin-transform-es2015-typeof-symbol "7.0.0-alpha.3" - babel-plugin-transform-es2015-unicode-regex "7.0.0-alpha.3" - babel-plugin-transform-regenerator "7.0.0-alpha.3" + babel-plugin-check-es2015-constants "7.0.0-alpha.9" + babel-plugin-transform-es2015-arrow-functions "7.0.0-alpha.9" + babel-plugin-transform-es2015-block-scoped-functions "7.0.0-alpha.9" + babel-plugin-transform-es2015-block-scoping "7.0.0-alpha.9" + babel-plugin-transform-es2015-classes "7.0.0-alpha.9" + babel-plugin-transform-es2015-computed-properties "7.0.0-alpha.9" + babel-plugin-transform-es2015-destructuring "7.0.0-alpha.9" + babel-plugin-transform-es2015-duplicate-keys "7.0.0-alpha.9" + babel-plugin-transform-es2015-for-of "7.0.0-alpha.9" + babel-plugin-transform-es2015-function-name "7.0.0-alpha.9" + babel-plugin-transform-es2015-literals "7.0.0-alpha.9" + babel-plugin-transform-es2015-modules-amd "7.0.0-alpha.9" + babel-plugin-transform-es2015-modules-commonjs "7.0.0-alpha.9" + babel-plugin-transform-es2015-modules-systemjs "7.0.0-alpha.9" + babel-plugin-transform-es2015-modules-umd "7.0.0-alpha.9" + babel-plugin-transform-es2015-object-super "7.0.0-alpha.9" + babel-plugin-transform-es2015-parameters "7.0.0-alpha.9" + babel-plugin-transform-es2015-shorthand-properties "7.0.0-alpha.9" + babel-plugin-transform-es2015-spread "7.0.0-alpha.9" + babel-plugin-transform-es2015-sticky-regex "7.0.0-alpha.9" + babel-plugin-transform-es2015-template-literals "7.0.0-alpha.9" + babel-plugin-transform-es2015-typeof-symbol "7.0.0-alpha.9" + babel-plugin-transform-es2015-unicode-regex "7.0.0-alpha.9" + babel-plugin-transform-regenerator "7.0.0-alpha.9" -babel-preset-stage-0@^7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-preset-stage-0/-/babel-preset-stage-0-7.0.0-alpha.3.tgz#f2db6c2ec82975ca99b77c867d95d821d61e3731" +babel-preset-stage-0@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-preset-stage-0/-/babel-preset-stage-0-7.0.0-alpha.9.tgz#c05bac07cc2c52f57dfbf60159e43839f23c5892" dependencies: - babel-plugin-transform-do-expressions "7.0.0-alpha.3" - babel-plugin-transform-function-bind "7.0.0-alpha.3" - babel-preset-stage-1 "7.0.0-alpha.3" + babel-plugin-transform-do-expressions "7.0.0-alpha.9" + babel-plugin-transform-function-bind "7.0.0-alpha.9" + babel-preset-stage-1 "7.0.0-alpha.9" -babel-preset-stage-1@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-7.0.0-alpha.3.tgz#2de86602a75aa3f908a4d16054a1a1b46756d897" +babel-preset-stage-1@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-7.0.0-alpha.9.tgz#594a008e3e4d24ca2a2160827864e1446c58fd9c" dependencies: - babel-plugin-transform-decorators "7.0.0-alpha.3" - babel-plugin-transform-export-extensions "7.0.0-alpha.3" - babel-preset-stage-2 "7.0.0-alpha.3" + babel-plugin-transform-decorators "7.0.0-alpha.9" + babel-plugin-transform-export-extensions "7.0.0-alpha.9" + babel-preset-stage-2 "7.0.0-alpha.9" -babel-preset-stage-2@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-7.0.0-alpha.3.tgz#96fab02bced0c6f3a9fda031185abd23ae69a60b" +babel-preset-stage-2@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-7.0.0-alpha.9.tgz#9e08dcae2163389ceab90019ab1f9f6839987b6b" dependencies: - babel-plugin-syntax-dynamic-import "7.0.0-alpha.3" - babel-plugin-transform-class-properties "7.0.0-alpha.3" + babel-plugin-transform-class-properties "7.0.0-alpha.9" babel-plugin-transform-unicode-property-regex "^2.0.0" - babel-preset-stage-3 "7.0.0-alpha.3" + babel-preset-stage-3 "7.0.0-alpha.9" -babel-preset-stage-3@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-7.0.0-alpha.3.tgz#3196bf3699c980372bc9f260fa0db70786d4d4a1" +babel-preset-stage-3@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-7.0.0-alpha.9.tgz#9c4fe45075f8bdff0e7213c4224b5b9aa99ddd63" dependencies: - babel-plugin-transform-async-generator-functions "7.0.0-alpha.3" - babel-plugin-transform-object-rest-spread "7.0.0-alpha.3" + babel-plugin-syntax-dynamic-import "7.0.0-alpha.9" + babel-plugin-transform-async-generator-functions "7.0.0-alpha.9" + babel-plugin-transform-object-rest-spread "7.0.0-alpha.9" -babel-register@7.0.0-alpha.6: - version "7.0.0-alpha.6" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-7.0.0-alpha.6.tgz#adb337fdfca6d74c90d51232b5b3d8f532ca91bc" +babel-register@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-7.0.0-alpha.9.tgz#580216ae64b58f009273ac413c87eb9ffe97ead9" dependencies: - babel-core "7.0.0-alpha.6" + babel-core "7.0.0-alpha.9" core-js "^2.4.0" home-or-tmp "^3.0.0" lodash "^4.2.0" @@ -1094,13 +1093,6 @@ babel-register@^6.24.0: mkdirp "^0.5.1" source-map-support "^0.4.2" -babel-runtime@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-7.0.0-alpha.3.tgz#fb71839b64115026a014f62891bdff9bee71079f" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.10.0" - babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" @@ -1108,13 +1100,13 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-template@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-7.0.0-alpha.3.tgz#eff537d49216ae6e70722f3556a17cc3de62b117" +babel-template@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-7.0.0-alpha.9.tgz#e32c51ea13f8ed391ed4a1c9adcfd3ed9ca928dc" dependencies: - babel-traverse "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" - babylon "7.0.0-beta.7" + babel-traverse "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" + babylon "7.0.0-beta.8" lodash "^4.2.0" babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.23.0: @@ -1127,14 +1119,14 @@ babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.23.0: babylon "^6.11.0" lodash "^4.2.0" -babel-traverse@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-7.0.0-alpha.3.tgz#ac5bd86d101b410daf705ff4a6cbfc0123ca49f0" +babel-traverse@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-7.0.0-alpha.9.tgz#749abf53c908ca80a8c96f5ca958d33732e0714f" dependencies: - babel-code-frame "7.0.0-alpha.3" - babel-messages "7.0.0-alpha.3" - babel-types "7.0.0-alpha.3" - babylon "7.0.0-beta.7" + babel-code-frame "7.0.0-alpha.9" + babel-messages "7.0.0-alpha.9" + babel-types "7.0.0-alpha.9" + babylon "7.0.0-beta.8" debug "^2.2.0" globals "^9.0.0" invariant "^2.2.0" @@ -1154,9 +1146,9 @@ babel-traverse@^6.18.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-tr invariant "^2.2.0" lodash "^4.2.0" -babel-types@7.0.0-alpha.3: - version "7.0.0-alpha.3" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-alpha.3.tgz#36c20f7a4e4d3f32fc00ab38893004a6f52b22a8" +babel-types@7.0.0-alpha.9: + version "7.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-alpha.9.tgz#45e48b93cecdd9d306ab6953d7819622a7c1462b" dependencies: esutils "^2.0.2" lodash "^4.2.0" @@ -1171,9 +1163,9 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23 lodash "^4.2.0" to-fast-properties "^1.0.1" -babylon@7.0.0-beta.7: - version "7.0.0-beta.7" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.7.tgz#61454c26b0e285ffe826dd237d5b5d179f602e16" +babylon@7.0.0-beta.8: + version "7.0.0-beta.8" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.8.tgz#2bdc5ae366041442c27e068cce6f0d7c06ea9949" babylon@^6.1.0, babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0, babylon@^6.16.1: version "6.16.1" From dd83ad6d6069fdca9e43abb5fd2a904f62a0e2f5 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Fri, 26 May 2017 15:48:56 -0400 Subject: [PATCH 65/73] =?UTF-8?q?Update=20flow-bin=20to=20the=20latest=20v?= =?UTF-8?q?ersion=20=F0=9F=9A=80=20(#537)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(package): update flow-bin to version 0.47.0 * Update yarn.lock --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f1fb0802a1..5bb717126d 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "eslint": "^3.7.1", "eslint-config-babel": "^6.0.0", "eslint-plugin-flowtype": "^2.20.0", - "flow-bin": "^0.46.0", + "flow-bin": "^0.47.0", "nyc": "^10.0.0", "rimraf": "^2.5.4", "rollup": "^0.41.0", diff --git a/yarn.lock b/yarn.lock index e7500624ee..48acd7a61b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1986,9 +1986,9 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -flow-bin@^0.46.0: - version "0.46.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.46.0.tgz#06ad7fe19dddb1042264438064a2a32fee12b872" +flow-bin@^0.47.0: + version "0.47.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.47.0.tgz#a2a08ab3e0d1f1cb57d17e27b30b118b62fda367" fn-name@^2.0.0: version "2.0.1" From 702d413b83ca09ccddf2cf1505049e065167468f Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Fri, 26 May 2017 16:24:10 -0400 Subject: [PATCH 66/73] add contributing docs on making a plugin [skip ci] (#542) * add contributing docs on making a plugin [skip ci] * fixes [skip ci] --- CONTRIBUTING.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eefd2e2706..326c383446 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -106,3 +106,14 @@ make test ``` From now on Babel will use your local checkout of Babylon for its tests. + +## Creating a new plugin (`spec-new`) + +> Example: https://github.com/babel/babylon/pull/541 + +- Create a new issue that describes the proposal (ex: [#538](https://github.com/babel/babylon/issues/538)). Include any relevant information like proposal repo/author, examples, parsing approaches, meeting notes, presentation slides, and more. +- The pull request should include: + - [ ] An update to the [#plugins](https://github.com/babel/babylon#plugins) part of the readme. Add a new entry to that list for the new plugin flag (and link to the proposal) + - [ ] If any new nodes or modifications need to be added to the AST, update [ast/spec.md](https://github.com/babel/babylon/blob/master/ast/spec.md) + - [ ] Make sure you use the `this.hasPlugin("plugin-name-here")` check so that your new plugin code only runs when that flag is turned on (not default behavior) + - [ ] Add failing/passing tests according to spec behavior From ed1809c2d196babea476d3025be87e085f6a5005 Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Fri, 26 May 2017 16:25:45 -0400 Subject: [PATCH 67/73] link to contributing [skip ci] --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f3764fed44..034e0c4016 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,13 @@ - The latest ECMAScript version enabled by default (ES2017). - Comment attachment. - - Support for JSX and Flow. + - Support for JSX, Flow, Typescript (WIP). - Support for experimental language proposals (accepting PRs for anything at least [stage-0](https://github.com/tc39/proposals/blob/master/stage-0-proposals.md)). +## Contributing + +Check out [contributing.md](https://github.com/babel/babylon/blob/master/CONTRIBUTING.md) + ## Credits Heavily based on [acorn](https://github.com/marijnh/acorn) and [acorn-jsx](https://github.com/RReverser/acorn-jsx), From 589ceb4ee7dc37e29b0d504bb42ca8bb84a6524a Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Fri, 26 May 2017 16:27:16 -0400 Subject: [PATCH 68/73] add extra note [skip ci] --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 326c383446..1e444d8e18 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -117,3 +117,4 @@ From now on Babel will use your local checkout of Babylon for its tests. - [ ] If any new nodes or modifications need to be added to the AST, update [ast/spec.md](https://github.com/babel/babylon/blob/master/ast/spec.md) - [ ] Make sure you use the `this.hasPlugin("plugin-name-here")` check so that your new plugin code only runs when that flag is turned on (not default behavior) - [ ] Add failing/passing tests according to spec behavior +- [ ] Start working about the Babel transform itself! From b344f6205698fac7a2a73a2da00891bfdeed560e Mon Sep 17 00:00:00 2001 From: Rick Waldron Date: Fri, 26 May 2017 16:37:05 -0400 Subject: [PATCH 69/73] NumberLiteralSeparator: Stage 1 feature plugin. Closes gh-538 (#541) * NumberLiteralSeparator: Stage 1 feature plugin Signed-off-by: Rick Waldron * fix-up per review Signed-off-by: Rick Waldron * nit: forbiddenNumericLiteralSeparatorSibling -> forbiddenNumericLiteralSeparatorSiblings Signed-off-by: Rick Waldron * fix-up to change includes -> indexOf Signed-off-by: Rick Waldron --- README.md | 1 + src/tokenizer/index.js | 36 +++++++++- .../invalid-0/actual.js | 1 + .../invalid-0/options.json | 1 + .../invalid-1/actual.js | 1 + .../invalid-1/options.json | 1 + .../invalid-10/actual.js | 1 + .../invalid-10/options.json | 1 + .../invalid-11/actual.js | 1 + .../invalid-11/options.json | 1 + .../invalid-12/actual.js | 1 + .../invalid-12/options.json | 1 + .../invalid-13/actual.js | 1 + .../invalid-13/options.json | 1 + .../invalid-14/actual.js | 1 + .../invalid-14/options.json | 1 + .../invalid-15/actual.js | 1 + .../invalid-15/options.json | 1 + .../invalid-16/actual.js | 1 + .../invalid-16/options.json | 1 + .../invalid-17/actual.js | 1 + .../invalid-17/options.json | 1 + .../invalid-18/actual.js | 1 + .../invalid-18/options.json | 1 + .../invalid-19/actual.js | 1 + .../invalid-19/options.json | 1 + .../invalid-2/actual.js | 1 + .../invalid-2/options.json | 1 + .../invalid-20/actual.js | 1 + .../invalid-20/options.json | 1 + .../invalid-21/actual.js | 1 + .../invalid-21/options.json | 1 + .../invalid-22/actual.js | 1 + .../invalid-22/options.json | 1 + .../invalid-23/actual.js | 1 + .../invalid-23/options.json | 1 + .../invalid-24/actual.js | 1 + .../invalid-24/options.json | 1 + .../invalid-25/actual.js | 1 + .../invalid-25/options.json | 1 + .../invalid-26/actual.js | 1 + .../invalid-26/options.json | 1 + .../invalid-27/actual.js | 1 + .../invalid-27/options.json | 1 + .../invalid-3/actual.js | 1 + .../invalid-3/options.json | 1 + .../invalid-4/actual.js | 1 + .../invalid-4/options.json | 1 + .../invalid-5/actual.js | 1 + .../invalid-5/options.json | 1 + .../invalid-6/actual.js | 1 + .../invalid-6/options.json | 1 + .../invalid-7/actual.js | 1 + .../invalid-7/options.json | 1 + .../invalid-8/actual.js | 1 + .../invalid-8/options.json | 1 + .../invalid-9/actual.js | 1 + .../invalid-9/options.json | 1 + .../numeric-literal-separator/options.json | 3 + .../valid-0/actual.js | 1 + .../valid-0/expected.json | 69 +++++++++++++++++++ .../valid-1/actual.js | 1 + .../valid-1/expected.json | 69 +++++++++++++++++++ .../valid-10/actual.js | 1 + .../valid-10/expected.json | 69 +++++++++++++++++++ .../valid-11/actual.js | 1 + .../valid-11/expected.json | 69 +++++++++++++++++++ .../valid-2/actual.js | 1 + .../valid-2/expected.json | 69 +++++++++++++++++++ .../valid-3/actual.js | 1 + .../valid-3/expected.json | 69 +++++++++++++++++++ .../valid-4/actual.js | 1 + .../valid-4/expected.json | 69 +++++++++++++++++++ .../valid-5/actual.js | 1 + .../valid-5/expected.json | 69 +++++++++++++++++++ .../valid-6/actual.js | 1 + .../valid-6/expected.json | 69 +++++++++++++++++++ .../valid-7/actual.js | 1 + .../valid-7/expected.json | 69 +++++++++++++++++++ .../valid-8/actual.js | 1 + .../valid-8/expected.json | 69 +++++++++++++++++++ .../valid-9/actual.js | 1 + .../valid-9/expected.json | 69 +++++++++++++++++++ 83 files changed, 935 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-0/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-0/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-1/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-1/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-10/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-10/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-11/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-11/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-12/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-12/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-13/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-13/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-14/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-14/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-15/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-15/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-16/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-16/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-17/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-17/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-18/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-18/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-19/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-19/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-2/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-2/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-20/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-20/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-21/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-21/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-22/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-22/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-23/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-23/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-24/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-24/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-25/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-25/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-26/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-26/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-27/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-27/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-3/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-3/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-4/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-4/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-5/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-5/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-6/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-6/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-7/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-7/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-8/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-8/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-9/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/invalid-9/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/options.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-0/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-0/expected.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-1/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-1/expected.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-10/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-10/expected.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-11/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-11/expected.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-2/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-2/expected.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-3/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-3/expected.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-4/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-4/expected.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-5/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-5/expected.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-6/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-6/expected.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-7/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-7/expected.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-8/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-8/expected.json create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-9/actual.js create mode 100644 test/fixtures/experimental/numeric-literal-separator/valid-9/expected.json diff --git a/README.md b/README.md index 034e0c4016..fd3ee86de3 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,7 @@ require("babylon").parse("code", { - `functionBind` - `functionSent` - `dynamicImport` + - `numericSeparator` ([proposal](https://github.com/samuelgoto/proposal-numeric-separator)) ### FAQ diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index 7727032fcc..b41067c43b 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -13,6 +13,23 @@ import { SourceLocation } from "../util/location"; import { lineBreak, lineBreakG, isNewLine, nonASCIIwhitespace } from "../util/whitespace"; import State from "./state"; + +// The following character codes are forbidden from being +// an immediate sibling of NumericLiteralSeparator _ + +const forbiddenNumericLiteralSeparatorSiblings = [ + 46, // . + 66, // B + 69, // E + 79, // O + 88, // X + 95, // _ (multiple separators are not allowed) + 98, // b + 101, // e + 111, // o + 120, // x +]; + // Object type used to represent tokens. Note that normally, tokens // simply exist as properties on the parser object. This is only // used for the onToken callback and the external tokenizer. @@ -555,6 +572,23 @@ export default class Tokenizer extends LocationParser { for (let i = 0, e = len == null ? Infinity : len; i < e; ++i) { const code = this.input.charCodeAt(this.state.pos); let val; + + if (this.hasPlugin("numericSeparator")) { + const prev = this.input.charCodeAt(this.state.pos - 1); + const next = this.input.charCodeAt(this.state.pos + 1); + if (code === 95) { + if ((forbiddenNumericLiteralSeparatorSiblings.indexOf(prev) > -1) || + (forbiddenNumericLiteralSeparatorSiblings.indexOf(next) > -1) || + Number.isNaN(next)) { + this.raise(this.state.pos, "Invalid NumericLiteralSeparator"); + } + + // Ignore this _ character + ++this.state.pos; + continue; + } + } + if (code >= 97) { val = code - 97 + 10; // a } else if (code >= 65) { @@ -608,7 +642,7 @@ export default class Tokenizer extends LocationParser { if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.state.pos, "Identifier directly after number"); - const str = this.input.slice(start, this.state.pos); + const str = this.input.slice(start, this.state.pos).replace(/_/g, ""); let val; if (isFloat) { val = parseFloat(str); diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-0/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-0/actual.js new file mode 100644 index 0000000000..c9cc894a14 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-0/actual.js @@ -0,0 +1 @@ +1_ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-0/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-0/options.json new file mode 100644 index 0000000000..98f3821203 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-0/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:1)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-1/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-1/actual.js new file mode 100644 index 0000000000..812b799044 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-1/actual.js @@ -0,0 +1 @@ +1_1_ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-1/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-1/options.json new file mode 100644 index 0000000000..38a0b25968 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-1/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:3)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-10/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-10/actual.js new file mode 100644 index 0000000000..f650ef5da9 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-10/actual.js @@ -0,0 +1 @@ +0x1_1_ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-10/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-10/options.json new file mode 100644 index 0000000000..c338d94e7c --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-10/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:5)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-11/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-11/actual.js new file mode 100644 index 0000000000..256223f609 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-11/actual.js @@ -0,0 +1 @@ +0xa_1_ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-11/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-11/options.json new file mode 100644 index 0000000000..c338d94e7c --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-11/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:5)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-12/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-12/actual.js new file mode 100644 index 0000000000..207475c37c --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-12/actual.js @@ -0,0 +1 @@ +0x_a_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-12/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-12/options.json new file mode 100644 index 0000000000..3a8821e671 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-12/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-13/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-13/actual.js new file mode 100644 index 0000000000..e8d858ceb4 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-13/actual.js @@ -0,0 +1 @@ +0x__1_1_ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-13/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-13/options.json new file mode 100644 index 0000000000..3a8821e671 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-13/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-14/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-14/actual.js new file mode 100644 index 0000000000..6ebcc5c3b0 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-14/actual.js @@ -0,0 +1 @@ +0x_1__1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-14/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-14/options.json new file mode 100644 index 0000000000..3a8821e671 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-14/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-15/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-15/actual.js new file mode 100644 index 0000000000..8c634a9b35 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-15/actual.js @@ -0,0 +1 @@ +0x_1_1_ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-15/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-15/options.json new file mode 100644 index 0000000000..3a8821e671 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-15/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-16/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-16/actual.js new file mode 100644 index 0000000000..5f57dcea0e --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-16/actual.js @@ -0,0 +1 @@ +0o_1_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-16/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-16/options.json new file mode 100644 index 0000000000..3a8821e671 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-16/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-17/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-17/actual.js new file mode 100644 index 0000000000..a28b7cad4f --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-17/actual.js @@ -0,0 +1 @@ +0o_11 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-17/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-17/options.json new file mode 100644 index 0000000000..3a8821e671 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-17/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-18/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-18/actual.js new file mode 100644 index 0000000000..2b1b875436 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-18/actual.js @@ -0,0 +1 @@ +0o_01_1_ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-18/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-18/options.json new file mode 100644 index 0000000000..3a8821e671 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-18/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-19/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-19/actual.js new file mode 100644 index 0000000000..da9556b3c2 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-19/actual.js @@ -0,0 +1 @@ +0b_0_1_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-19/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-19/options.json new file mode 100644 index 0000000000..3a8821e671 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-19/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-2/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-2/actual.js new file mode 100644 index 0000000000..0e5fddb35e --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-2/actual.js @@ -0,0 +1 @@ +1_1__ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-2/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-2/options.json new file mode 100644 index 0000000000..38a0b25968 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-2/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:3)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-20/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-20/actual.js new file mode 100644 index 0000000000..2562e4dd9b --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-20/actual.js @@ -0,0 +1 @@ +0b_01_1_ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-20/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-20/options.json new file mode 100644 index 0000000000..3a8821e671 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-20/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-21/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-21/actual.js new file mode 100644 index 0000000000..202ace50bd --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-21/actual.js @@ -0,0 +1 @@ +0b01_1_ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-21/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-21/options.json new file mode 100644 index 0000000000..02c2fdc2bb --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-21/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:6)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-22/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-22/actual.js new file mode 100644 index 0000000000..72b11abe72 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-22/actual.js @@ -0,0 +1 @@ +0o1_1_ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-22/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-22/options.json new file mode 100644 index 0000000000..c338d94e7c --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-22/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:5)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-23/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-23/actual.js new file mode 100644 index 0000000000..2de75d54ec --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-23/actual.js @@ -0,0 +1 @@ +0o_1_1_ \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-23/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-23/options.json new file mode 100644 index 0000000000..3a8821e671 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-23/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-24/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-24/actual.js new file mode 100644 index 0000000000..b31c6f7290 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-24/actual.js @@ -0,0 +1 @@ +._1_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-24/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-24/options.json new file mode 100644 index 0000000000..e9dcc85b6f --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-24/options.json @@ -0,0 +1 @@ +{ "throws": "Unexpected token (1:0)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-25/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-25/actual.js new file mode 100644 index 0000000000..105d580ea8 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-25/actual.js @@ -0,0 +1 @@ +0o01_8 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-25/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-25/options.json new file mode 100644 index 0000000000..b284ab4dae --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-25/options.json @@ -0,0 +1 @@ +{ "throws": "Unexpected token, expected ; (1:5)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-26/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-26/actual.js new file mode 100644 index 0000000000..0a3a15970b --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-26/actual.js @@ -0,0 +1 @@ +0b2_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-26/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-26/options.json new file mode 100644 index 0000000000..c9bd15c007 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-26/options.json @@ -0,0 +1 @@ +{ "throws": "Expected number in radix 2 (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-27/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-27/actual.js new file mode 100644 index 0000000000..08352eee51 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-27/actual.js @@ -0,0 +1 @@ +0xZ_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-27/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-27/options.json new file mode 100644 index 0000000000..7ec714f598 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-27/options.json @@ -0,0 +1 @@ +{ "throws": "Expected number in radix 16 (1:2)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-3/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-3/actual.js new file mode 100644 index 0000000000..6873b31a70 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-3/actual.js @@ -0,0 +1 @@ +1__1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-3/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-3/options.json new file mode 100644 index 0000000000..98f3821203 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-3/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:1)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-4/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-4/actual.js new file mode 100644 index 0000000000..2ba4925b82 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-4/actual.js @@ -0,0 +1 @@ +1_1_.1_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-4/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-4/options.json new file mode 100644 index 0000000000..38a0b25968 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-4/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:3)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-5/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-5/actual.js new file mode 100644 index 0000000000..5b9f31e521 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-5/actual.js @@ -0,0 +1 @@ +1_1._1_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-5/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-5/options.json new file mode 100644 index 0000000000..9af0551149 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-5/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:4)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-6/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-6/actual.js new file mode 100644 index 0000000000..6527da3a34 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-6/actual.js @@ -0,0 +1 @@ +1_1.1_e1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-6/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-6/options.json new file mode 100644 index 0000000000..c338d94e7c --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-6/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:5)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-7/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-7/actual.js new file mode 100644 index 0000000000..a42c9013ab --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-7/actual.js @@ -0,0 +1 @@ +1_1.1_E1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-7/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-7/options.json new file mode 100644 index 0000000000..c338d94e7c --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-7/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:5)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-8/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-8/actual.js new file mode 100644 index 0000000000..015dfb2cca --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-8/actual.js @@ -0,0 +1 @@ +1_1.1e_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-8/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-8/options.json new file mode 100644 index 0000000000..02c2fdc2bb --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-8/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:6)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-9/actual.js b/test/fixtures/experimental/numeric-literal-separator/invalid-9/actual.js new file mode 100644 index 0000000000..69b401af73 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-9/actual.js @@ -0,0 +1 @@ +1_1.1E_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/invalid-9/options.json b/test/fixtures/experimental/numeric-literal-separator/invalid-9/options.json new file mode 100644 index 0000000000..02c2fdc2bb --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/invalid-9/options.json @@ -0,0 +1 @@ +{ "throws": "Invalid NumericLiteralSeparator (1:6)" } \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/options.json b/test/fixtures/experimental/numeric-literal-separator/options.json new file mode 100644 index 0000000000..7832463eea --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["numericSeparator"] +} diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-0/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-0/actual.js new file mode 100644 index 0000000000..1444c527e6 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-0/actual.js @@ -0,0 +1 @@ +1_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-0/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-0/expected.json new file mode 100644 index 0000000000..4165833ec2 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-0/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "extra": { + "rawValue": 11, + "raw": "1_1" + }, + "value": 11 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-1/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-1/actual.js new file mode 100644 index 0000000000..5dc4398746 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-1/actual.js @@ -0,0 +1 @@ +1_1.1_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-1/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-1/expected.json new file mode 100644 index 0000000000..8260e3a36f --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-1/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "extra": { + "rawValue": 11.11, + "raw": "1_1.1_1" + }, + "value": 11.11 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-10/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-10/actual.js new file mode 100644 index 0000000000..70c7d458e9 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-10/actual.js @@ -0,0 +1 @@ +0o1_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-10/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-10/expected.json new file mode 100644 index 0000000000..79c01565f8 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-10/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "extra": { + "rawValue": 9, + "raw": "0o1_1" + }, + "value": 9 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-11/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-11/actual.js new file mode 100644 index 0000000000..a8ad08acec --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-11/actual.js @@ -0,0 +1 @@ +0o0_11 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-11/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-11/expected.json new file mode 100644 index 0000000000..010ed236b8 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-11/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "extra": { + "rawValue": 9, + "raw": "0o0_11" + }, + "value": 9 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-2/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-2/actual.js new file mode 100644 index 0000000000..a601c9a6c4 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-2/actual.js @@ -0,0 +1 @@ +1.1_0_1e1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-2/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-2/expected.json new file mode 100644 index 0000000000..0fe859c994 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-2/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "extra": { + "rawValue": 11.01, + "raw": "1.1_0_1e1" + }, + "value": 11.01 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-3/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-3/actual.js new file mode 100644 index 0000000000..77285bba7c --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-3/actual.js @@ -0,0 +1 @@ +1.1_0_1E1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-3/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-3/expected.json new file mode 100644 index 0000000000..e2e79f52c3 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-3/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 9, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "extra": { + "rawValue": 11.01, + "raw": "1.1_0_1E1" + }, + "value": 11.01 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-4/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-4/actual.js new file mode 100644 index 0000000000..cf6d034fda --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-4/actual.js @@ -0,0 +1 @@ +.1_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-4/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-4/expected.json new file mode 100644 index 0000000000..b799415f3c --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-4/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "extra": { + "rawValue": 0.11, + "raw": ".1_1" + }, + "value": 0.11 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-5/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-5/actual.js new file mode 100644 index 0000000000..bd1002cd74 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-5/actual.js @@ -0,0 +1 @@ +0x1_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-5/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-5/expected.json new file mode 100644 index 0000000000..c198cab891 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-5/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "extra": { + "rawValue": 17, + "raw": "0x1_1" + }, + "value": 17 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-6/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-6/actual.js new file mode 100644 index 0000000000..ed1eb193f7 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-6/actual.js @@ -0,0 +1 @@ +0xa_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-6/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-6/expected.json new file mode 100644 index 0000000000..3d60200076 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-6/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "extra": { + "rawValue": 161, + "raw": "0xa_1" + }, + "value": 161 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-7/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-7/actual.js new file mode 100644 index 0000000000..2c83531afc --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-7/actual.js @@ -0,0 +1 @@ +0xA_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-7/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-7/expected.json new file mode 100644 index 0000000000..53bfa89514 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-7/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "extra": { + "rawValue": 161, + "raw": "0xA_1" + }, + "value": 161 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-8/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-8/actual.js new file mode 100644 index 0000000000..522c24653c --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-8/actual.js @@ -0,0 +1 @@ +0b01_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-8/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-8/expected.json new file mode 100644 index 0000000000..9ec67ee581 --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-8/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "extra": { + "rawValue": 3, + "raw": "0b01_1" + }, + "value": 3 + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-9/actual.js b/test/fixtures/experimental/numeric-literal-separator/valid-9/actual.js new file mode 100644 index 0000000000..9eed82d99e --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-9/actual.js @@ -0,0 +1 @@ +0b0_1_1 \ No newline at end of file diff --git a/test/fixtures/experimental/numeric-literal-separator/valid-9/expected.json b/test/fixtures/experimental/numeric-literal-separator/valid-9/expected.json new file mode 100644 index 0000000000..8619859fec --- /dev/null +++ b/test/fixtures/experimental/numeric-literal-separator/valid-9/expected.json @@ -0,0 +1,69 @@ +{ + "type": "File", + "start": 0, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "expression": { + "type": "NumericLiteral", + "start": 0, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "extra": { + "rawValue": 3, + "raw": "0b0_1_1" + }, + "value": 3 + } + } + ], + "directives": [] + } +} \ No newline at end of file From 81ce4153591206aafc8ca6f0012a4a0fd987f6fd Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Fri, 26 May 2017 16:44:25 -0400 Subject: [PATCH 70/73] add proposal links [skip ci] --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fd3ee86de3..be6f771feb 100644 --- a/README.md +++ b/README.md @@ -130,14 +130,14 @@ require("babylon").parse("code", { - `jsx` - `flow` - `doExpressions` - - `objectRestSpread` + - `objectRestSpread` ([proposal](https://github.com/tc39/proposal-object-rest-spread)) - `decorators` (Based on an outdated version of the Decorators proposal. Will be removed in a future version of `Babylon`) - - `classProperties` - - `exportExtensions` - - `asyncGenerators` - - `functionBind` + - `classProperties` ([proposal](https://github.com/zenparsing/es-function-bind)) + - `exportExtensions` ([proposal 1](https://github.com/leebyron/ecmascript-export-default-from)), ([proposal 2](https://github.com/leebyron/ecmascript-export-ns-from)) + - `asyncGenerators` ([proposal](https://github.com/tc39/proposal-async-iteration)) + - `functionBind` ([proposal](https://github.com/zenparsing/es-function-bind)) - `functionSent` - - `dynamicImport` + - `dynamicImport` ([proposal](https://github.com/tc39/proposal-dynamic-import)) - `numericSeparator` ([proposal](https://github.com/samuelgoto/proposal-numeric-separator)) ### FAQ From aad95c63ec8e89262744e0ab2308bf6e5cccc26b Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Fri, 26 May 2017 22:44:36 -0500 Subject: [PATCH 71/73] Fix some flow unused warnings (#543) --- src/parser/expression.js | 14 +++++++++++--- src/plugins/flow.js | 6 +++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/parser/expression.js b/src/parser/expression.js index d2189e6c40..c03b2b57ee 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -151,7 +151,7 @@ export default class ExpressionParser extends LValParser { // Parse a ternary conditional (`?:`) operator. - parseMaybeConditional(noIn: ?boolean, refShorthandDefaultPos: Pos, refNeedsArrowPos: ?Pos): N.Expression { + parseMaybeConditional(noIn: ?boolean, refShorthandDefaultPos: Pos, refNeedsArrowPos?: ?Pos): N.Expression { const startPos = this.state.start; const startLoc = this.state.startLoc; const expr = this.parseExprOps(noIn, refShorthandDefaultPos); @@ -160,7 +160,15 @@ export default class ExpressionParser extends LValParser { return this.parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos); } - parseConditional(expr: N.Expression, noIn: ?boolean, startPos: number, startLoc: Position): N.Expression { + parseConditional( + expr: N.Expression, + noIn: ?boolean, + startPos: number, + startLoc: Position, + // FIXME: Disabling this for now since can't seem to get it to play nicely + // eslint-disable-next-line no-unused-vars + refNeedsArrowPos?: ?Pos + ): N.Expression { if (this.eat(tt.question)) { const node = this.startNodeAt(startPos, startLoc); node.test = expr; @@ -470,7 +478,7 @@ export default class ExpressionParser extends LValParser { const oldLabels = this.state.labels; this.state.labels = []; this.state.inFunction = false; - node.body = this.parseBlock(false, true); + node.body = this.parseBlock(false); this.state.inFunction = oldInFunction; this.state.labels = oldLabels; return this.finishNode(node, "DoExpression"); diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 83416c3726..1f0d079ecf 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -1072,7 +1072,7 @@ export default (superClass: Class): Class => class extends super return super.isExportDefaultSpecifier(); } - parseConditional(expr: N.Expression, noIn: ?boolean, startPos: number, startLoc: Position, refNeedsArrowPos?: Pos): N.Expression { + parseConditional(expr: N.Expression, noIn: ?boolean, startPos: number, startLoc: Position, refNeedsArrowPos?: ?Pos): N.Expression { // only do the expensive clone if there is a question mark // and if we come from inside parens if (refNeedsArrowPos && this.match(tt.question)) { @@ -1260,8 +1260,8 @@ export default (superClass: Class): Class => class extends super } // parse a the super class type parameters and implements - parseClassSuper(node: N.Class, isStatement?: boolean): void { - super.parseClassSuper(node, isStatement); + parseClassSuper(node: N.Class): void { + super.parseClassSuper(node); if (node.superClass && this.isRelational("<")) { node.superTypeParameters = this.flowParseTypeParameterInstantiation(); } From 50694f99b12295b7515bb2c6c8f44b86a05deeca Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 26 May 2017 20:44:56 -0700 Subject: [PATCH 72/73] Extract 'parseClassMember' method (#533) --- src/parser/expression.js | 6 +- src/parser/statement.js | 208 +++++++++++++++++++++------------------ src/plugins/estree.js | 3 +- src/plugins/flow.js | 5 +- 4 files changed, 120 insertions(+), 102 deletions(-) diff --git a/src/parser/expression.js b/src/parser/expression.js index c03b2b57ee..b097be7e10 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -887,7 +887,7 @@ export default class ExpressionParser extends LValParser { // get methods aren't allowed to have any parameters // set methods must have exactly 1 parameter - checkGetterSetterParamCount(method: N.ObjectMethod): void { + checkGetterSetterParamCount(method: N.ObjectMethod | N.ClassMethod): void { const paramCount = method.kind === "get" ? 0 : 1; if (method.params.length !== paramCount) { const start = method.start; @@ -956,12 +956,14 @@ export default class ExpressionParser extends LValParser { if (!node) this.unexpected(); } - parsePropertyName(prop: N.ObjectMember): N.Identifier { + parsePropertyName(prop: N.ObjectOrClassMember): N.Identifier { if (this.eat(tt.bracketL)) { + // $FlowFixMe (ClassPrivateMember shouldn't be allowed to be computed!) prop.computed = true; prop.key = this.parseMaybeAssign(); this.expect(tt.bracketR); } else { + // $FlowFixMe (ClassPrivateMember shouldn't be allowed to be computed!) prop.computed = false; const oldInPropertyName = this.state.inPropertyName; this.state.inPropertyName = true; diff --git a/src/parser/statement.js b/src/parser/statement.js index 24a693a5d2..080b3a0e02 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -639,9 +639,11 @@ export default class StatementParser extends ExpressionParser { return this.match(tt.parenL); } - isNonstaticConstructor(method: N.ClassMethod): boolean { + isNonstaticConstructor(method: N.ClassMethod | N.ClassProperty): boolean { return !method.computed && !method.static && ( + // $FlowFixMe ('key' downcasting) (method.key.name === "constructor") || // Identifier + // $FlowFixMe ('key' downcasting) (method.key.value === "constructor") // Literal ); } @@ -652,7 +654,7 @@ export default class StatementParser extends ExpressionParser { this.state.strict = true; this.state.inClass = true; - let hadConstructor = false; + const state = { hadConstructor: false }; let decorators = []; const classBody = this.startNode(); @@ -673,107 +675,15 @@ export default class StatementParser extends ExpressionParser { continue; } - const method = this.startNode(); + const member = this.startNode(); // steal the decorators if there are any if (decorators.length) { - method.decorators = decorators; + member.decorators = decorators; decorators = []; } - if (this.hasPlugin("classPrivateProperties") && this.match(tt.hash)) { // Private property - this.next(); - this.parsePropertyName(method); - classBody.body.push(this.parsePrivateClassProperty(method)); - continue; - } - - method.static = false; - if (this.match(tt.name) && this.state.value === "static") { - const key = this.parseIdentifier(true); // eats 'static' - if (this.isClassMethod()) { - // a method named 'static' - method.kind = "method"; - method.computed = false; - method.key = key; - this.parseClassMethod(classBody, method, false, false); - continue; - } else if (this.isClassProperty()) { - // a property named 'static' - method.computed = false; - method.key = key; - classBody.body.push(this.parseClassProperty(method)); - continue; - } - // otherwise something static - method.static = true; - } - - if (this.eat(tt.star)) { - // a generator - method.kind = "method"; - this.parsePropertyName(method); - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Constructor can't be a generator"); - } - if (!method.computed && method.static && (method.key.name === "prototype" || method.key.value === "prototype")) { - this.raise(method.key.start, "Classes may not have static property named prototype"); - } - this.parseClassMethod(classBody, method, true, false); - } else { - const isSimple = this.match(tt.name); - const key = this.parsePropertyName(method); - if (!method.computed && method.static && (method.key.name === "prototype" || method.key.value === "prototype")) { - this.raise(method.key.start, "Classes may not have static property named prototype"); - } - if (this.isClassMethod()) { - // a normal method - if (this.isNonstaticConstructor(method)) { - if (hadConstructor) { - this.raise(key.start, "Duplicate constructor in the same class"); - } else if (method.decorators) { - this.raise(method.start, "You can't attach decorators to a class constructor"); - } - hadConstructor = true; - method.kind = "constructor"; - } else { - method.kind = "method"; - } - this.parseClassMethod(classBody, method, false, false); - } else if (this.isClassProperty()) { - // a normal property - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Classes may not have a non-static field named 'constructor'"); - } - classBody.body.push(this.parseClassProperty(method)); - } else if (isSimple && key.name === "async" && !this.isLineTerminator()) { - // an async method - const isGenerator = this.hasPlugin("asyncGenerators") && this.eat(tt.star); - method.kind = "method"; - this.parsePropertyName(method); - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Constructor can't be an async function"); - } - this.parseClassMethod(classBody, method, isGenerator, true); - } else if (isSimple && (key.name === "get" || key.name === "set") && !(this.isLineTerminator() && this.match(tt.star))) { // `get\n*` is an uninitialized property named 'get' followed by a generator. - // a getter or setter - method.kind = key.name; - this.parsePropertyName(method); - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Constructor can't have get/set modifier"); - } - this.parseClassMethod(classBody, method, false, false); - this.checkGetterSetterParamCount(method); - } else if (this.isLineTerminator()) { - // an uninitialized class property (due to ASI, since we don't otherwise recognize the next token) - if (this.isNonstaticConstructor(method)) { - this.raise(method.key.start, "Classes may not have a non-static field named 'constructor'"); - } - classBody.body.push(this.parseClassProperty(method)); - } else { - this.unexpected(); - } - } + this.parseClassMember(classBody, member, state); } if (decorators.length) { @@ -784,7 +694,111 @@ export default class StatementParser extends ExpressionParser { this.state.inClass = false; this.state.strict = oldStrict; + } + parseClassMember(classBody: N.ClassBody, member: N.ClassMember, state: { hadConstructor: boolean }): void { + // Use the appropriate variable to represent `member` once a more specific type is known. + const memberAny: any = member; + const methodOrProp: N.ClassMethod | N.ClassProperty = memberAny; + const method: N.ClassMethod = memberAny; + const prop: N.ClassProperty = memberAny; + + if (this.hasPlugin("classPrivateProperties") && this.match(tt.hash)) { // Private property + this.next(); + const privateProp: N.ClassPrivateProperty = memberAny; + this.parsePropertyName(privateProp); + classBody.body.push(this.parsePrivateClassProperty(privateProp)); + return; + } + + methodOrProp.static = false; + if (this.match(tt.name) && this.state.value === "static") { + const key = this.parseIdentifier(true); // eats 'static' + if (this.isClassMethod()) { + // a method named 'static' + method.kind = "method"; + method.computed = false; + method.key = key; + this.parseClassMethod(classBody, method, false, false); + return; + } else if (this.isClassProperty()) { + // a property named 'static' + prop.computed = false; + prop.key = key; + classBody.body.push(this.parseClassProperty(prop)); + return; + } + // otherwise something static + methodOrProp.static = true; + } + + if (this.eat(tt.star)) { + // a generator + method.kind = "method"; + this.parsePropertyName(method); + if (this.isNonstaticConstructor(method)) { + this.raise(method.key.start, "Constructor can't be a generator"); + } + if (!method.computed && method.static && (method.key.name === "prototype" || method.key.value === "prototype")) { + this.raise(method.key.start, "Classes may not have static property named prototype"); + } + this.parseClassMethod(classBody, method, true, false); + return; + } + + const isSimple = this.match(tt.name); + const key = this.parsePropertyName(methodOrProp); + // $FlowFixMe ('key' downcasting) + if (!methodOrProp.computed && methodOrProp.static && (methodOrProp.key.name === "prototype" || methodOrProp.key.value === "prototype")) { + this.raise(methodOrProp.key.start, "Classes may not have static property named prototype"); + } + if (this.isClassMethod()) { + // a normal method + if (this.isNonstaticConstructor(method)) { + if (state.hadConstructor) { + this.raise(key.start, "Duplicate constructor in the same class"); + } else if (method.decorators) { + this.raise(method.start, "You can't attach decorators to a class constructor"); + } + state.hadConstructor = true; + method.kind = "constructor"; + } else { + method.kind = "method"; + } + this.parseClassMethod(classBody, method, false, false); + } else if (this.isClassProperty()) { + // a normal property + if (this.isNonstaticConstructor(prop)) { + this.raise(prop.key.start, "Classes may not have a non-static field named 'constructor'"); + } + classBody.body.push(this.parseClassProperty(prop)); + } else if (isSimple && key.name === "async" && !this.isLineTerminator()) { + // an async method + const isGenerator = this.hasPlugin("asyncGenerators") && this.eat(tt.star); + method.kind = "method"; + this.parsePropertyName(method); + if (this.isNonstaticConstructor(method)) { + this.raise(method.key.start, "Constructor can't be an async function"); + } + this.parseClassMethod(classBody, method, isGenerator, true); + } else if (isSimple && (key.name === "get" || key.name === "set") && !(this.isLineTerminator() && this.match(tt.star))) { // `get\n*` is an uninitialized property named 'get' followed by a generator. + // a getter or setter + method.kind = key.name; + this.parsePropertyName(method); + if (this.isNonstaticConstructor(method)) { + this.raise(method.key.start, "Constructor can't have get/set modifier"); + } + this.parseClassMethod(classBody, method, false, false); + this.checkGetterSetterParamCount(method); + } else if (this.isLineTerminator()) { + // an uninitialized class property (due to ASI, since we don't otherwise recognize the next token) + if (this.isNonstaticConstructor(prop)) { + this.raise(prop.key.start, "Classes may not have a non-static field named 'constructor'"); + } + classBody.body.push(this.parseClassProperty(prop)); + } else { + this.unexpected(); + } } parsePrivateClassProperty(node: N.ClassPrivateProperty): N.ClassPrivateProperty { diff --git a/src/plugins/estree.js b/src/plugins/estree.js index 347d325378..637f8e23d8 100644 --- a/src/plugins/estree.js +++ b/src/plugins/estree.js @@ -59,8 +59,9 @@ export default (superClass: Class): Class => class extends super } } - checkGetterSetterParamCount(prop: N.ObjectMethod): void { + checkGetterSetterParamCount(prop: N.ObjectMethod | N.ClassMethod): void { const paramCount = prop.kind === "get" ? 0 : 1; + // $FlowFixMe (prop.value present for ObjectMethod, but for ClassMethod should use prop.params?) if (prop.value.params.length !== paramCount) { const start = prop.start; if (prop.kind === "get") { diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 1f0d079ecf..289ed536ee 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -1242,7 +1242,7 @@ export default (superClass: Class): Class => class extends super return this.match(tt.colon) || super.isClassProperty(); } - isNonstaticConstructor(method: N.ClassMethod): boolean { + isNonstaticConstructor(method: N.ClassMethod | N.ClassProperty): boolean { return !this.match(tt.colon) && super.isNonstaticConstructor(method); } @@ -1281,9 +1281,10 @@ export default (superClass: Class): Class => class extends super } } - parsePropertyName(node: N.ObjectMember): N.Identifier { + parsePropertyName(node: N.ObjectOrClassMember): N.Identifier { const variance = this.flowParseVariance(); const key = super.parsePropertyName(node); + // $FlowFixMe (variance not defined on ClassPrivateProperty) node.variance = variance; return key; } From f326ef6424ecd63094e076d6bc30148a879186cc Mon Sep 17 00:00:00 2001 From: Henry Zhu Date: Sat, 27 May 2017 00:19:22 -0400 Subject: [PATCH 73/73] 7.0.0-beta.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5bb717126d..56928ae0c1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "babylon", - "version": "7.0.0-beta.10", + "version": "7.0.0-beta.11", "description": "A JavaScript parser", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/",