[es6][estree] Add support for sourceType: script|module modes.
+ Fix list of keywords and reserved words in ES6.
This commit is contained in:
parent
024a98431d
commit
0473c368e6
@ -54,6 +54,9 @@ object referring to that same position.
|
||||
either 3, 5, or 6. This influences support for strict mode, the set
|
||||
of reserved words, and support for new syntax features. Default is 5.
|
||||
|
||||
- **sourceType**: Indicate the mode the code should be parsed in. Can be
|
||||
either `"script"` or `"module"`.
|
||||
|
||||
- **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
|
||||
|
||||
42
acorn.js
42
acorn.js
@ -51,6 +51,8 @@
|
||||
// mode, the set of reserved words, support for getters and
|
||||
// setters and other features.
|
||||
ecmaVersion: 5,
|
||||
// Source type ("script" or "module") for different semantics
|
||||
sourceType: "script",
|
||||
// `onInsertedSemicolon` can be a callback that will be called
|
||||
// when a semicolon is automatically inserted. It will be passed
|
||||
// th position of the comma as an offset, and if `locations` is
|
||||
@ -342,6 +344,7 @@
|
||||
kw("with");
|
||||
kw("new", beforeExpr);
|
||||
kw("this");
|
||||
kw("super");
|
||||
kw("class");
|
||||
kw("extends", beforeExpr);
|
||||
kw("export");
|
||||
@ -412,6 +415,10 @@
|
||||
|
||||
var isReservedWord5 = makePredicate("class enum extends super const export import");
|
||||
|
||||
// ECMAScript 6 reserved words.
|
||||
|
||||
var isReservedWord6 = makePredicate("enum await");
|
||||
|
||||
// The additional reserved words in strict mode.
|
||||
|
||||
var isStrictReservedWord = makePredicate("implements interface let package private protected public static yield");
|
||||
@ -426,7 +433,7 @@
|
||||
|
||||
var isEcma5AndLessKeyword = makePredicate(ecma5AndLessKeywords);
|
||||
|
||||
var isEcma6Keyword = makePredicate(ecma5AndLessKeywords + " let const class extends export import yield");
|
||||
var isEcma6Keyword = makePredicate(ecma5AndLessKeywords + " let const class extends export import yield super");
|
||||
|
||||
// ## Character categories
|
||||
|
||||
@ -543,6 +550,7 @@
|
||||
this.loadPlugins(this.options.plugins);
|
||||
this.sourceFile = this.options.sourceFile || null;
|
||||
this.isKeyword = this.options.ecmaVersion >= 6 ? isEcma6Keyword : isEcma5AndLessKeyword;
|
||||
this.isReservedWord = this.options.ecmaVersion === 3 ? isReservedWord3 : this.options.ecmaVersion === 5 ? isReservedWord5 : isReservedWord6;
|
||||
this.input = String(input);
|
||||
|
||||
// Set up token state
|
||||
@ -578,9 +586,11 @@
|
||||
this.context = [tc.b_stat];
|
||||
this.exprAllowed = true;
|
||||
|
||||
// Flags to track whether we are in strict mode, a function, a
|
||||
// generator.
|
||||
this.strict = this.inFunction = this.inGenerator = false;
|
||||
// Figure out if it's a module code.
|
||||
this.strict = this.inModule = this.options.sourceType === "module";
|
||||
|
||||
// Flags to track whether we are in a function, a generator.
|
||||
this.inFunction = this.inGenerator = false;
|
||||
// Labels in scope.
|
||||
this.labels = [];
|
||||
|
||||
@ -946,6 +956,7 @@
|
||||
}
|
||||
if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 &&
|
||||
this.input.charCodeAt(this.pos + 3) == 45) {
|
||||
if (this.inModule) unexpected();
|
||||
// `<!--`, an XML-style comment that should be interpreted as a line comment
|
||||
this.skipLineComment(4);
|
||||
this.skipSpace();
|
||||
@ -1763,8 +1774,10 @@
|
||||
if (first && this.isUseStrict(stmt)) this.setStrict(true);
|
||||
first = false;
|
||||
}
|
||||
|
||||
this.next();
|
||||
if (this.options.ecmaVersion >= 6) {
|
||||
node.sourceType = this.options.sourceType;
|
||||
}
|
||||
return this.finishNode(node, "Program");
|
||||
};
|
||||
|
||||
@ -1808,8 +1821,12 @@
|
||||
case tt.semi: return this.parseEmptyStatement(node);
|
||||
case tt._export:
|
||||
case tt._import:
|
||||
if (!topLevel && !this.options.allowImportExportEverywhere)
|
||||
this.raise(this.start, "'import' and 'export' may only appear at the top level");
|
||||
if (!this.options.allowImportExportEverywhere) {
|
||||
if (!topLevel)
|
||||
this.raise(this.start, "'import' and 'export' may only appear at the top level");
|
||||
if (!this.inModule)
|
||||
this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
|
||||
}
|
||||
return starttype === tt._import ? this.parseImport(node) : this.parseExport(node);
|
||||
|
||||
// If the statement does not start with a statement keyword or a
|
||||
@ -2307,19 +2324,16 @@
|
||||
pp.parseExprAtom = function(refShorthandDefaultPos) {
|
||||
switch (this.type) {
|
||||
case tt._this:
|
||||
case tt._super:
|
||||
var type = this.type === tt._this ? "ThisExpression" : "SuperExpression";
|
||||
var node = this.startNode();
|
||||
this.next();
|
||||
return this.finishNode(node, "ThisExpression");
|
||||
return this.finishNode(node, type);
|
||||
|
||||
case tt._yield:
|
||||
if (this.inGenerator) unexpected();
|
||||
|
||||
case tt.name:
|
||||
if (this.value === "super") {
|
||||
var node = this.startNode();
|
||||
this.next();
|
||||
return this.finishNode(node, "SuperExpression");
|
||||
}
|
||||
var start = this.currentPos();
|
||||
var id = this.parseIdent(this.type !== tt.name);
|
||||
if (!this.canInsertSemicolon() && this.eat(tt.arrow)) {
|
||||
@ -2722,7 +2736,7 @@
|
||||
if (this.type === tt.name) {
|
||||
if (!liberal &&
|
||||
(!this.options.allowReserved &&
|
||||
(this.options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(this.value) ||
|
||||
this.isReservedWord(this.value) ||
|
||||
this.strict && isStrictReservedWord(this.value)) &&
|
||||
this.input.slice(this.start, this.end).indexOf("\\") == -1)
|
||||
this.raise(this.start, "The keyword '" + this.value + "' is reserved");
|
||||
|
||||
@ -311,6 +311,9 @@
|
||||
node.body = [];
|
||||
while (this.tok.type !== tt.eof) node.body.push(this.parseStatement());
|
||||
this.last = this.tok;
|
||||
if (this.options.ecmaVersion >= 6) {
|
||||
node.sourceType = this.options.sourceType;
|
||||
}
|
||||
return this.finishNode(node, "Program");
|
||||
};
|
||||
|
||||
@ -694,16 +697,13 @@
|
||||
lp.parseExprAtom = function() {
|
||||
switch (this.tok.type) {
|
||||
case tt._this:
|
||||
case tt._super:
|
||||
var type = this.tok.type === tt._this ? "ThisExpression" : "SuperExpression";
|
||||
var node = this.startNode();
|
||||
this.next();
|
||||
return this.finishNode(node, "ThisExpression");
|
||||
return this.finishNode(node, type);
|
||||
|
||||
case tt.name:
|
||||
if (this.tok.value === "super") {
|
||||
var node = this.startNode();
|
||||
this.next();
|
||||
return this.finishNode(node, "SuperExpression");
|
||||
}
|
||||
var start = this.storeCurrentPos();
|
||||
var id = this.parseIdent();
|
||||
return this.eat(tt.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id]) : id;
|
||||
|
||||
@ -4381,6 +4381,7 @@ test("let {a:b} = {}", {
|
||||
|
||||
test("var {a:b} = {}", {
|
||||
type: "Program",
|
||||
sourceType: "script",
|
||||
body: [{
|
||||
type: "VariableDeclaration",
|
||||
declarations: [{
|
||||
@ -4452,6 +4453,7 @@ test("var {a:b} = {}", {
|
||||
|
||||
test("export var document", {
|
||||
type: "Program",
|
||||
sourceType: "module",
|
||||
body: [{
|
||||
type: "ExportNamedDeclaration",
|
||||
declaration: {
|
||||
@ -4491,6 +4493,7 @@ test("export var document", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -4543,6 +4546,7 @@ test("export var document = { }", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -4588,6 +4592,7 @@ test("export let document", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -4640,6 +4645,7 @@ test("export let document = { }", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -4692,6 +4698,7 @@ test("export const document = { }", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -4739,6 +4746,7 @@ test("export function parse() { }", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -4784,6 +4792,7 @@ test("export class Class {}", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -4812,6 +4821,7 @@ test("export default 42", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -4836,7 +4846,7 @@ test("export default function () {}", {
|
||||
}
|
||||
}
|
||||
}]
|
||||
}, {ecmaVersion: 6, ranges: true});
|
||||
}, {ecmaVersion: 6, sourceType: "module", ranges: true});
|
||||
|
||||
test("export default function f() {}", {
|
||||
type: "Program",
|
||||
@ -4862,7 +4872,7 @@ test("export default function f() {}", {
|
||||
}
|
||||
}
|
||||
}]
|
||||
}, {ecmaVersion: 6, ranges: true});
|
||||
}, {ecmaVersion: 6, sourceType: "module", ranges: true});
|
||||
|
||||
test("export default class {}", {
|
||||
type: "Program",
|
||||
@ -4882,7 +4892,7 @@ test("export default class {}", {
|
||||
}
|
||||
}
|
||||
}]
|
||||
}, {ecmaVersion: 6, ranges: true});
|
||||
}, {ecmaVersion: 6, sourceType: "module", ranges: true});
|
||||
|
||||
test("export default class A {}", {
|
||||
type: "Program",
|
||||
@ -4906,9 +4916,9 @@ test("export default class A {}", {
|
||||
}
|
||||
}
|
||||
}]
|
||||
}, {ecmaVersion: 6, ranges: true});
|
||||
}, {ecmaVersion: 6, sourceType: "module", ranges: true});
|
||||
|
||||
testFail("export *", "Unexpected token (1:8)", {ecmaVersion: 6});
|
||||
testFail("export *", "Unexpected token (1:8)", {ecmaVersion: 6, sourceType: "module"});
|
||||
|
||||
test("export * from \"crypto\"", {
|
||||
type: "Program",
|
||||
@ -4934,6 +4944,7 @@ test("export * from \"crypto\"", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -4978,6 +4989,7 @@ test("export { encrypt }", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5047,6 +5059,7 @@ test("export { encrypt, decrypt }", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5091,6 +5104,7 @@ test("export { encrypt as default }", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5160,6 +5174,7 @@ test("export { encrypt, decrypt as dec }", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5220,6 +5235,7 @@ test("export { default } from \"other\"", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5249,6 +5265,7 @@ test("import \"jquery\"", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5292,6 +5309,7 @@ test("import $ from \"jquery\"", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5368,6 +5386,7 @@ test("import { encrypt, decrypt } from \"crypto\"", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5419,6 +5438,7 @@ test("import { encrypt as enc } from \"crypto\"", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5510,11 +5530,12 @@ test("import crypto, { decrypt, encrypt as enc } from \"crypto\"", {
|
||||
}]
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
|
||||
testFail("import default from \"foo\"", "Unexpected token (1:7)", {ecmaVersion: 6});
|
||||
testFail("import default from \"foo\"", "Unexpected token (1:7)", {ecmaVersion: 6, sourceType: "module"});
|
||||
|
||||
test("import { null as nil } from \"bar\"", {
|
||||
type: "Program",
|
||||
@ -5563,6 +5584,7 @@ test("import { null as nil } from \"bar\"", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5606,6 +5628,7 @@ test("import * as crypto from \"crypto\"", {
|
||||
}]
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5668,6 +5691,7 @@ test("(function* () { yield v })", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -5738,6 +5762,7 @@ test("(function* () { yield\nv })", {
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
sourceType: "module",
|
||||
ranges: true,
|
||||
locations: true
|
||||
});
|
||||
@ -13899,7 +13924,7 @@ testFail("function hello() {'use strict'; ({ i: 10, s(eval) { } }); }", "Definin
|
||||
|
||||
testFail("function a() { \"use strict\"; ({ b(t, t) { } }); }", "Argument name clash in strict mode (1:37)", {ecmaVersion: 6});
|
||||
|
||||
testFail("var super", "The keyword 'super' is reserved (1:4)", {ecmaVersion: 6, allowReserved: false});
|
||||
testFail("var super", "Unexpected token (1:4)", {ecmaVersion: 6});
|
||||
|
||||
testFail("var default", "Unexpected token (1:4)", {ecmaVersion: 6});
|
||||
|
||||
@ -13915,11 +13940,11 @@ testFail("for (let x = 42 in list) process(x);", "Unexpected token (1:16)", {ecm
|
||||
|
||||
testFail("for (let x = 42 of list) process(x);", "Unexpected token (1:16)", {ecmaVersion: 6});
|
||||
|
||||
testFail("import foo", "Unexpected token (1:10)", {ecmaVersion: 6});
|
||||
testFail("import foo", "Unexpected token (1:10)", {ecmaVersion: 6, sourceType: "module"});
|
||||
|
||||
testFail("import { foo, bar }", "Unexpected token (1:19)", {ecmaVersion: 6});
|
||||
testFail("import { foo, bar }", "Unexpected token (1:19)", {ecmaVersion: 6, sourceType: "module"});
|
||||
|
||||
testFail("import foo from bar", "Unexpected token (1:16)", {ecmaVersion: 6});
|
||||
testFail("import foo from bar", "Unexpected token (1:16)", {ecmaVersion: 6, sourceType: "module"});
|
||||
|
||||
testFail("((a)) => 42", "Unexpected token (1:1)", {ecmaVersion: 6});
|
||||
|
||||
@ -14415,7 +14440,7 @@ test("import foo, * as bar from 'baz';", {
|
||||
raw: "'baz'"
|
||||
}
|
||||
}]
|
||||
}, {ecmaVersion: 6});
|
||||
}, {ecmaVersion: 6, sourceType: "module"});
|
||||
|
||||
// https://github.com/marijnh/acorn/issues/173
|
||||
test("`{${x}}`, `}`", {
|
||||
@ -15404,3 +15429,5 @@ testFail("if (1) ; else class Cls {}", "Unexpected token (1:14)", {ecmaVersion:
|
||||
|
||||
testFail("'use strict'; [...eval] = arr", "Assigning to eval in strict mode (1:18)", {ecmaVersion: 6});
|
||||
testFail("'use strict'; ({eval = defValue} = obj)", "Assigning to eval in strict mode (1:16)", {ecmaVersion: 6});
|
||||
|
||||
testFail("[...eval] = arr", "Assigning to eval in strict mode (1:4)", {ecmaVersion: 6, sourceType: "module"});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user