From d8597cb1614b4b885b7ee2fa43bd87d0c5f76b02 Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Tue, 20 Oct 2020 17:05:33 +0900 Subject: [PATCH 1/2] Fix parsing of imports with module string name in flow plugin --- packages/babel-parser/src/plugins/flow.js | 25 ++-- .../default-import/input.js | 1 + .../default-import/output.json | 48 ++++++++ .../import-local-is-string/input.js | 1 + .../import-local-is-string/options.json | 8 ++ .../flow/module-string-names/mixed/input.js | 2 + .../module-string-names/mixed/output.json | 115 ++++++++++++++++++ .../named-imports/input.js | 1 + .../named-imports/output.json | 48 ++++++++ .../flow/module-string-names/options.json | 4 + .../type-import-shorthand/input.js | 2 + .../type-import-shorthand/output.json | 83 +++++++++++++ 12 files changed, 331 insertions(+), 7 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/default-import/input.js create mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/default-import/output.json create mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/import-local-is-string/input.js create mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/import-local-is-string/options.json create mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/mixed/input.js create mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/mixed/output.json create mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/named-imports/input.js create mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/named-imports/output.json create mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/options.json create mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/input.js create mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/output.json diff --git a/packages/babel-parser/src/plugins/flow.js b/packages/babel-parser/src/plugins/flow.js index 26ddfeaae787..eafd40c3b4ce 100644 --- a/packages/babel-parser/src/plugins/flow.js +++ b/packages/babel-parser/src/plugins/flow.js @@ -2496,13 +2496,15 @@ export default (superClass: Class): Class => parseImportSpecifier(node: N.ImportDeclaration): void { const specifier = this.startNode(); const firstIdentLoc = this.state.start; - const firstIdent = this.parseIdentifier(true); + const firstIdent = this.parseModuleExportName(); let specifierTypeKind = null; - if (firstIdent.name === "type") { - specifierTypeKind = "type"; - } else if (firstIdent.name === "typeof") { - specifierTypeKind = "typeof"; + if (firstIdent.type === "Identifier") { + if (firstIdent.name === "type") { + specifierTypeKind = "type"; + } else if (firstIdent.name === "typeof") { + specifierTypeKind = "typeof"; + } } let isBinding = false; @@ -2525,10 +2527,12 @@ export default (superClass: Class): Class => } } else if ( specifierTypeKind !== null && - (this.match(tt.name) || this.state.type.keyword) + (this.match(tt.name) || + this.match(tt.string) || + this.state.type.keyword) ) { // `import {type foo` - specifier.imported = this.parseIdentifier(true); + specifier.imported = this.parseModuleExportName(); specifier.importKind = specifierTypeKind; if (this.eatContextual("as")) { specifier.local = this.parseIdentifier(); @@ -2537,6 +2541,13 @@ export default (superClass: Class): Class => specifier.local = specifier.imported.__clone(); } } else { + if (firstIdent.type === "StringLiteral") { + throw this.raise( + specifier.start, + Errors.ImportBindingIsString, + firstIdent.value, + ); + } isBinding = true; specifier.imported = firstIdent; specifier.importKind = null; diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/default-import/input.js b/packages/babel-parser/test/fixtures/flow/module-string-names/default-import/input.js new file mode 100644 index 000000000000..1317bee62b01 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/module-string-names/default-import/input.js @@ -0,0 +1 @@ +import {"default" as quotation} from "Confucius"; diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/default-import/output.json b/packages/babel-parser/test/fixtures/flow/module-string-names/default-import/output.json new file mode 100644 index 000000000000..992ecbbabc1e --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/module-string-names/default-import/output.json @@ -0,0 +1,48 @@ +{ + "type": "File", + "start":0,"end":49,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":49}}, + "program": { + "type": "Program", + "start":0,"end":49,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":49}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ImportDeclaration", + "start":0,"end":49,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":49}}, + "specifiers": [ + { + "type": "ImportSpecifier", + "start":8,"end":30,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":30}}, + "imported": { + "type": "StringLiteral", + "start":8,"end":17,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":17}}, + "extra": { + "rawValue": "default", + "raw": "\"default\"" + }, + "value": "default" + }, + "importKind": null, + "local": { + "type": "Identifier", + "start":21,"end":30,"loc":{"start":{"line":1,"column":21},"end":{"line":1,"column":30},"identifierName":"quotation"}, + "name": "quotation" + } + } + ], + "importKind": "value", + "source": { + "type": "StringLiteral", + "start":37,"end":48,"loc":{"start":{"line":1,"column":37},"end":{"line":1,"column":48}}, + "extra": { + "rawValue": "Confucius", + "raw": "\"Confucius\"" + }, + "value": "Confucius" + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/import-local-is-string/input.js b/packages/babel-parser/test/fixtures/flow/module-string-names/import-local-is-string/input.js new file mode 100644 index 000000000000..dcbde35b6d79 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/module-string-names/import-local-is-string/input.js @@ -0,0 +1 @@ +import { "foo" } from "baz"; diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/import-local-is-string/options.json b/packages/babel-parser/test/fixtures/flow/module-string-names/import-local-is-string/options.json new file mode 100644 index 000000000000..a7e941c241fe --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/module-string-names/import-local-is-string/options.json @@ -0,0 +1,8 @@ +{ + "sourceType": "module", + "plugins": [ + "moduleStringNames", + "flow" + ], + "throws": "A string literal cannot be used as an imported binding.\n- Did you mean `import { \"foo\" as foo }`? (1:9)" +} diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/mixed/input.js b/packages/babel-parser/test/fixtures/flow/module-string-names/mixed/input.js new file mode 100644 index 000000000000..a6cfd5e177b6 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/module-string-names/mixed/input.js @@ -0,0 +1,2 @@ +import { "foo" as bar, "default" as qux } from "module-a"; +export * as "foo", { default as "quux" } from "module-b"; diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/mixed/output.json b/packages/babel-parser/test/fixtures/flow/module-string-names/mixed/output.json new file mode 100644 index 000000000000..9b52e08d1c61 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/module-string-names/mixed/output.json @@ -0,0 +1,115 @@ +{ + "type": "File", + "start":0,"end":116,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":57}}, + "program": { + "type": "Program", + "start":0,"end":116,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":57}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ImportDeclaration", + "start":0,"end":58,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":58}}, + "specifiers": [ + { + "type": "ImportSpecifier", + "start":9,"end":21,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":21}}, + "imported": { + "type": "StringLiteral", + "start":9,"end":14,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":14}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "importKind": null, + "local": { + "type": "Identifier", + "start":18,"end":21,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":21},"identifierName":"bar"}, + "name": "bar" + } + }, + { + "type": "ImportSpecifier", + "start":23,"end":39,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":39}}, + "imported": { + "type": "StringLiteral", + "start":23,"end":32,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":32}}, + "extra": { + "rawValue": "default", + "raw": "\"default\"" + }, + "value": "default" + }, + "importKind": null, + "local": { + "type": "Identifier", + "start":36,"end":39,"loc":{"start":{"line":1,"column":36},"end":{"line":1,"column":39},"identifierName":"qux"}, + "name": "qux" + } + } + ], + "importKind": "value", + "source": { + "type": "StringLiteral", + "start":47,"end":57,"loc":{"start":{"line":1,"column":47},"end":{"line":1,"column":57}}, + "extra": { + "rawValue": "module-a", + "raw": "\"module-a\"" + }, + "value": "module-a" + } + }, + { + "type": "ExportNamedDeclaration", + "start":59,"end":116,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":57}}, + "specifiers": [ + { + "type": "ExportNamespaceSpecifier", + "start":66,"end":76,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":17}}, + "exported": { + "type": "StringLiteral", + "start":71,"end":76,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":17}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + } + }, + { + "type": "ExportSpecifier", + "start":80,"end":97,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":38}}, + "local": { + "type": "Identifier", + "start":80,"end":87,"loc":{"start":{"line":2,"column":21},"end":{"line":2,"column":28},"identifierName":"default"}, + "name": "default" + }, + "exported": { + "type": "StringLiteral", + "start":91,"end":97,"loc":{"start":{"line":2,"column":32},"end":{"line":2,"column":38}}, + "extra": { + "rawValue": "quux", + "raw": "\"quux\"" + }, + "value": "quux" + } + } + ], + "source": { + "type": "StringLiteral", + "start":105,"end":115,"loc":{"start":{"line":2,"column":46},"end":{"line":2,"column":56}}, + "extra": { + "rawValue": "module-b", + "raw": "\"module-b\"" + }, + "value": "module-b" + }, + "declaration": null, + "exportKind": "value" + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/named-imports/input.js b/packages/babel-parser/test/fixtures/flow/module-string-names/named-imports/input.js new file mode 100644 index 000000000000..74d6bc295369 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/module-string-names/named-imports/input.js @@ -0,0 +1 @@ +import {"學而時習之,不亦說乎?" as quotation} from "Confucius"; diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/named-imports/output.json b/packages/babel-parser/test/fixtures/flow/module-string-names/named-imports/output.json new file mode 100644 index 000000000000..3c276be536e7 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/module-string-names/named-imports/output.json @@ -0,0 +1,48 @@ +{ + "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", + "interpreter": null, + "body": [ + { + "type": "ImportDeclaration", + "start":0,"end":53,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":53}}, + "specifiers": [ + { + "type": "ImportSpecifier", + "start":8,"end":34,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":34}}, + "imported": { + "type": "StringLiteral", + "start":8,"end":21,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":21}}, + "extra": { + "rawValue": "學而時習之,不亦說乎?", + "raw": "\"學而時習之,不亦說乎?\"" + }, + "value": "學而時習之,不亦說乎?" + }, + "importKind": null, + "local": { + "type": "Identifier", + "start":25,"end":34,"loc":{"start":{"line":1,"column":25},"end":{"line":1,"column":34},"identifierName":"quotation"}, + "name": "quotation" + } + } + ], + "importKind": "value", + "source": { + "type": "StringLiteral", + "start":41,"end":52,"loc":{"start":{"line":1,"column":41},"end":{"line":1,"column":52}}, + "extra": { + "rawValue": "Confucius", + "raw": "\"Confucius\"" + }, + "value": "Confucius" + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/options.json b/packages/babel-parser/test/fixtures/flow/module-string-names/options.json new file mode 100644 index 000000000000..bd72c92b9d9b --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/module-string-names/options.json @@ -0,0 +1,4 @@ +{ + "sourceType": "module", + "plugins": ["flow", "moduleStringNames"] +} diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/input.js b/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/input.js new file mode 100644 index 000000000000..f82f7495df01 --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/input.js @@ -0,0 +1,2 @@ +import { type "foo" as bar1 } from "baz"; +import { typeof "foo" as bar2 } from "baz"; diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/output.json b/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/output.json new file mode 100644 index 000000000000..97093cec0ccb --- /dev/null +++ b/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/output.json @@ -0,0 +1,83 @@ +{ + "type": "File", + "start":0,"end":85,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":43}}, + "program": { + "type": "Program", + "start":0,"end":85,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":43}}, + "sourceType": "module", + "interpreter": null, + "body": [ + { + "type": "ImportDeclaration", + "start":0,"end":41,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":41}}, + "specifiers": [ + { + "type": "ImportSpecifier", + "start":9,"end":27,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":27}}, + "imported": { + "type": "StringLiteral", + "start":14,"end":19,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":19}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "importKind": "type", + "local": { + "type": "Identifier", + "start":23,"end":27,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":27},"identifierName":"bar1"}, + "name": "bar1" + } + } + ], + "importKind": "value", + "source": { + "type": "StringLiteral", + "start":35,"end":40,"loc":{"start":{"line":1,"column":35},"end":{"line":1,"column":40}}, + "extra": { + "rawValue": "baz", + "raw": "\"baz\"" + }, + "value": "baz" + } + }, + { + "type": "ImportDeclaration", + "start":42,"end":85,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":43}}, + "specifiers": [ + { + "type": "ImportSpecifier", + "start":51,"end":71,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":29}}, + "imported": { + "type": "StringLiteral", + "start":58,"end":63,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":21}}, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "importKind": "typeof", + "local": { + "type": "Identifier", + "start":67,"end":71,"loc":{"start":{"line":2,"column":25},"end":{"line":2,"column":29},"identifierName":"bar2"}, + "name": "bar2" + } + } + ], + "importKind": "value", + "source": { + "type": "StringLiteral", + "start":79,"end":84,"loc":{"start":{"line":2,"column":37},"end":{"line":2,"column":42}}, + "extra": { + "rawValue": "baz", + "raw": "\"baz\"" + }, + "value": "baz" + } + } + ], + "directives": [] + } +} \ No newline at end of file From a65978b8d31ad3aa1e4141f98594a399d056111c Mon Sep 17 00:00:00 2001 From: sosukesuzuki Date: Tue, 20 Oct 2020 23:55:48 +0900 Subject: [PATCH 2/2] Remove support for type import with module-string-names --- packages/babel-parser/src/plugins/flow.js | 6 +- .../type-import-shorthand/input.js | 2 - .../type-import-shorthand/output.json | 83 ------------------- 3 files changed, 2 insertions(+), 89 deletions(-) delete mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/input.js delete mode 100644 packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/output.json diff --git a/packages/babel-parser/src/plugins/flow.js b/packages/babel-parser/src/plugins/flow.js index eafd40c3b4ce..a9700c216698 100644 --- a/packages/babel-parser/src/plugins/flow.js +++ b/packages/babel-parser/src/plugins/flow.js @@ -2527,12 +2527,10 @@ export default (superClass: Class): Class => } } else if ( specifierTypeKind !== null && - (this.match(tt.name) || - this.match(tt.string) || - this.state.type.keyword) + (this.match(tt.name) || this.state.type.keyword) ) { // `import {type foo` - specifier.imported = this.parseModuleExportName(); + specifier.imported = this.parseIdentifier(true); specifier.importKind = specifierTypeKind; if (this.eatContextual("as")) { specifier.local = this.parseIdentifier(); diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/input.js b/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/input.js deleted file mode 100644 index f82f7495df01..000000000000 --- a/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/input.js +++ /dev/null @@ -1,2 +0,0 @@ -import { type "foo" as bar1 } from "baz"; -import { typeof "foo" as bar2 } from "baz"; diff --git a/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/output.json b/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/output.json deleted file mode 100644 index 97093cec0ccb..000000000000 --- a/packages/babel-parser/test/fixtures/flow/module-string-names/type-import-shorthand/output.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "type": "File", - "start":0,"end":85,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":43}}, - "program": { - "type": "Program", - "start":0,"end":85,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":43}}, - "sourceType": "module", - "interpreter": null, - "body": [ - { - "type": "ImportDeclaration", - "start":0,"end":41,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":41}}, - "specifiers": [ - { - "type": "ImportSpecifier", - "start":9,"end":27,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":27}}, - "imported": { - "type": "StringLiteral", - "start":14,"end":19,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":19}}, - "extra": { - "rawValue": "foo", - "raw": "\"foo\"" - }, - "value": "foo" - }, - "importKind": "type", - "local": { - "type": "Identifier", - "start":23,"end":27,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":27},"identifierName":"bar1"}, - "name": "bar1" - } - } - ], - "importKind": "value", - "source": { - "type": "StringLiteral", - "start":35,"end":40,"loc":{"start":{"line":1,"column":35},"end":{"line":1,"column":40}}, - "extra": { - "rawValue": "baz", - "raw": "\"baz\"" - }, - "value": "baz" - } - }, - { - "type": "ImportDeclaration", - "start":42,"end":85,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":43}}, - "specifiers": [ - { - "type": "ImportSpecifier", - "start":51,"end":71,"loc":{"start":{"line":2,"column":9},"end":{"line":2,"column":29}}, - "imported": { - "type": "StringLiteral", - "start":58,"end":63,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":21}}, - "extra": { - "rawValue": "foo", - "raw": "\"foo\"" - }, - "value": "foo" - }, - "importKind": "typeof", - "local": { - "type": "Identifier", - "start":67,"end":71,"loc":{"start":{"line":2,"column":25},"end":{"line":2,"column":29},"identifierName":"bar2"}, - "name": "bar2" - } - } - ], - "importKind": "value", - "source": { - "type": "StringLiteral", - "start":79,"end":84,"loc":{"start":{"line":2,"column":37},"end":{"line":2,"column":42}}, - "extra": { - "rawValue": "baz", - "raw": "\"baz\"" - }, - "value": "baz" - } - } - ], - "directives": [] - } -} \ No newline at end of file