From 7987e410aa93a446e5aeb3e3934fd1696eb3c9f3 Mon Sep 17 00:00:00 2001 From: Toru Nagashima Date: Mon, 16 Mar 2020 02:19:13 +0900 Subject: [PATCH] Support `export * as ns from "source"` --- acorn-loose/src/statement.js | 7 ++ acorn-walk/src/index.js | 2 + acorn/src/statement.js | 8 ++ bin/run_test262.js | 1 - test/run.js | 1 + test/tests-export-all-as-ns-from-source.js | 93 ++++++++++++++++++++++ 6 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 test/tests-export-all-as-ns-from-source.js diff --git a/acorn-loose/src/statement.js b/acorn-loose/src/statement.js index a5b574044..40230d2ee 100644 --- a/acorn-loose/src/statement.js +++ b/acorn-loose/src/statement.js @@ -358,6 +358,13 @@ lp.parseExport = function() { let node = this.startNode() this.next() if (this.eat(tt.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseExprAtom() + } else { + node.exported = null + } + } node.source = this.eatContextual("from") ? this.parseExprAtom() : this.dummyString() return this.finishNode(node, "ExportAllDeclaration") } diff --git a/acorn-walk/src/index.js b/acorn-walk/src/index.js index d95af12be..498b1fc48 100644 --- a/acorn-walk/src/index.js +++ b/acorn-walk/src/index.js @@ -353,6 +353,8 @@ base.ExportNamedDeclaration = base.ExportDefaultDeclaration = (node, st, c) => { if (node.source) c(node.source, st, "Expression") } base.ExportAllDeclaration = (node, st, c) => { + if (node.exported) + c(node.exported, st) c(node.source, st, "Expression") } base.ImportDeclaration = (node, st, c) => { diff --git a/acorn/src/statement.js b/acorn/src/statement.js index d15bb8e73..8c7e171a9 100644 --- a/acorn/src/statement.js +++ b/acorn/src/statement.js @@ -676,6 +676,14 @@ pp.parseExport = function(node, exports) { this.next() // export * from '...' if (this.eat(tt.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseIdent(true) + this.checkExport(exports, node.exported.name, this.lastTokStart) + } else { + node.exported = null + } + } this.expectContextual("from") if (this.type !== tt.string) this.unexpected() node.source = this.parseExprAtom() diff --git a/bin/run_test262.js b/bin/run_test262.js index 6a2f9b05c..4e0bc6b31 100644 --- a/bin/run_test262.js +++ b/bin/run_test262.js @@ -11,7 +11,6 @@ const unsupportedFeatures = [ "class-static-fields-public", "class-static-methods-private", "coalesce-expression", - "export-star-as-namespace-from-module", "import.meta", "numeric-separator-literal", "optional-chaining", diff --git a/test/run.js b/test/run.js index 4ea981b90..b34720f7e 100644 --- a/test/run.js +++ b/test/run.js @@ -16,6 +16,7 @@ require("./tests-optional-catch-binding.js"); require("./tests-bigint.js"); require("./tests-dynamic-import.js"); + require("./tests-export-all-as-ns-from-source.js"); var acorn = require("../acorn") var acorn_loose = require("../acorn-loose") diff --git a/test/tests-export-all-as-ns-from-source.js b/test/tests-export-all-as-ns-from-source.js new file mode 100644 index 000000000..8a7145e71 --- /dev/null +++ b/test/tests-export-all-as-ns-from-source.js @@ -0,0 +1,93 @@ + +if (typeof exports != "undefined") { + var driver = require("./driver.js"); + var test = driver.test, testFail = driver.testFail; + var acorn = require("../acorn"); +} + +//------------------------------------------------------------------------------ +// export * as ns from "source" +//------------------------------------------------------------------------------ + +test("export * as ns from \"source\"", { + "type": "Program", + "start": 0, + "end": 28, + "body": [ + { + "type": "ExportAllDeclaration", + "start": 0, + "end": 28, + "exported": { + "type": "Identifier", + "start": 12, + "end": 14, + "name": "ns" + }, + "source": { + "type": "Literal", + "start": 20, + "end": 28, + "value": "source", + "raw": "\"source\"" + } + } + ], + "sourceType": "module" +}, { sourceType: "module", ecmaVersion: 11 }) + +test("export * as foo from \"bar\"", { + "type": "Program", + "start": 0, + "end": 26, + "body": [ + { + "type": "ExportAllDeclaration", + "start": 0, + "end": 26, + "exported": { + "type": "Identifier", + "start": 12, + "end": 15, + "name": "foo" + }, + "source": { + "type": "Literal", + "start": 21, + "end": 26, + "value": "bar", + "raw": "\"bar\"" + } + } + ], + "sourceType": "module" +}, { sourceType: "module", ecmaVersion: 11 }) + +test("export * from \"source\"", { + "type": "Program", + "start": 0, + "end": 22, + "body": [ + { + "type": "ExportAllDeclaration", + "start": 0, + "end": 22, + "exported": null, + "source": { + "type": "Literal", + "start": 14, + "end": 22, + "value": "source", + "raw": "\"source\"" + } + } + ], + "sourceType": "module" +}, { sourceType: "module", ecmaVersion: 11 }) + +testFail("export * as ns from \"source\"", "'import' and 'export' may appear only with 'sourceType: module' (1:0)", { sourceType: "script", ecmaVersion: 11 }) +testFail("export * as ns from \"source\"", "Unexpected token (1:9)", { sourceType: "module", ecmaVersion: 10 }) +testFail("export * as ns", "Unexpected token (1:14)", { sourceType: "module", ecmaVersion: 11 }) +testFail("export * as from \"source\"", "Unexpected token (1:17)", { sourceType: "module", ecmaVersion: 11 }) +testFail("export * as ns \"source\"", "Unexpected token (1:15)", { sourceType: "module", ecmaVersion: 11 }) +testFail("export {} as ns from \"source\"", "Unexpected token (1:10)", { sourceType: "module", ecmaVersion: 11 })