diff --git a/acorn-loose/src/statement.js b/acorn-loose/src/statement.js index ac208424e..a5b574044 100644 --- a/acorn-loose/src/statement.js +++ b/acorn-loose/src/statement.js @@ -10,9 +10,7 @@ lp.parseTopLevel = function() { while (this.tok.type !== tt.eof) node.body.push(this.parseStatement()) this.toks.adaptDirectivePrologue(node.body) this.last = this.tok - if (this.options.ecmaVersion >= 6) { - node.sourceType = this.options.sourceType - } + node.sourceType = this.options.sourceType return this.finishNode(node, "Program") } diff --git a/acorn/README.md b/acorn/README.md index fa372ee68..bcf85ccba 100644 --- a/acorn/README.md +++ b/acorn/README.md @@ -64,6 +64,9 @@ an object containing any of these fields: either `"script"` or `"module"`. This influences global strict mode and parsing of `import` and `export` declarations. + **NOTE**: If set to `"module"`, then static `import` / `export` syntax + will be valid, even if `ecmaVersion` is less than 6. + - **onInsertedSemicolon**: If given a callback, that callback will be called whenever a missing semicolon is inserted by the parser. The callback will be given the character offset of the point where the diff --git a/acorn/src/identifier.js b/acorn/src/identifier.js index c768a2d79..339066260 100644 --- a/acorn/src/identifier.js +++ b/acorn/src/identifier.js @@ -14,6 +14,7 @@ const ecma5AndLessKeywords = "break case catch continue debugger default do else export const keywords = { 5: ecma5AndLessKeywords, + "5module": ecma5AndLessKeywords + " export import", 6: ecma5AndLessKeywords + " const class extends export import super" } diff --git a/acorn/src/state.js b/acorn/src/state.js index 73e49b9f3..eb4e0e120 100644 --- a/acorn/src/state.js +++ b/acorn/src/state.js @@ -9,7 +9,7 @@ export class Parser { constructor(options, input, startPos) { this.options = options = getOptions(options) this.sourceFile = options.sourceFile - this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]) + this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]) let reserved = "" if (options.allowReserved !== true) { for (let v = options.ecmaVersion;; v--) diff --git a/acorn/src/statement.js b/acorn/src/statement.js index d423b5910..8cadb5118 100644 --- a/acorn/src/statement.js +++ b/acorn/src/statement.js @@ -27,9 +27,7 @@ pp.parseTopLevel = function(node) { this.raiseRecoverable(this.undefinedExports[name].start, `Export '${name}' is not defined`) this.adaptDirectivePrologue(node.body) this.next() - if (this.options.ecmaVersion >= 6) { - node.sourceType = this.options.sourceType - } + node.sourceType = this.options.sourceType return this.finishNode(node, "Program") } diff --git a/test/tests.js b/test/tests.js index eeaaf0d7f..35fe29ca5 100644 --- a/test/tests.js +++ b/test/tests.js @@ -7,6 +7,35 @@ if (typeof exports != "undefined") { var acorn = require("../acorn"); } +test("import ''", { + type: "Program", + start: 0, + end: 9, + body: [ + { + type: "ImportDeclaration", + start: 0, + end: 9, + specifiers: [], + source: { + type: "Literal", + start: 7, + end: 9, + value: "", + raw: "''" + } + } + ] +}, { + ecmaVersion: 5, + sourceType: "module" +}); + +testFail("import('')", "Unexpected token (1:6)", { + ecmaVersion: 5, + sourceType: "module" +}); + test("new Object", { type: "Program", start: 0,