update to latest acorn, better array shortcuts, don't add code frame to error message
This commit is contained in:
parent
f830892ab8
commit
0d143f005f
110
acorn.js
110
acorn.js
@ -243,6 +243,7 @@
|
||||
this.label = label;
|
||||
this.keyword = conf.keyword;
|
||||
this.beforeExpr = !!conf.beforeExpr;
|
||||
this.startsExpr = !!conf.startsExpr;
|
||||
this.rightAssociative = !!conf.rightAssociative;
|
||||
this.isLoop = !!conf.isLoop;
|
||||
this.isAssign = !!conf.isAssign;
|
||||
@ -255,21 +256,21 @@
|
||||
function binop(name, prec) {
|
||||
return new TokenType(name, {beforeExpr: true, binop: prec});
|
||||
}
|
||||
var beforeExpr = {beforeExpr: true};
|
||||
var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true};;
|
||||
|
||||
var tt = exports.tokTypes = {
|
||||
num: new TokenType("num"),
|
||||
regexp: new TokenType("regexp"),
|
||||
string: new TokenType("string"),
|
||||
name: new TokenType("name"),
|
||||
num: new TokenType("num", startsExpr),
|
||||
regexp: new TokenType("regexp", startsExpr),
|
||||
string: new TokenType("string", startsExpr),
|
||||
name: new TokenType("name", startsExpr),
|
||||
eof: new TokenType("eof"),
|
||||
|
||||
// Punctuation token types.
|
||||
bracketL: new TokenType("[", beforeExpr),
|
||||
bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
|
||||
bracketR: new TokenType("]"),
|
||||
braceL: new TokenType("{", beforeExpr),
|
||||
braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
|
||||
braceR: new TokenType("}"),
|
||||
parenL: new TokenType("(", beforeExpr),
|
||||
parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
|
||||
parenR: new TokenType(")"),
|
||||
comma: new TokenType(",", beforeExpr),
|
||||
semi: new TokenType(";", beforeExpr),
|
||||
@ -279,8 +280,8 @@
|
||||
arrow: new TokenType("=>", beforeExpr),
|
||||
template: new TokenType("template"),
|
||||
ellipsis: new TokenType("...", beforeExpr),
|
||||
backQuote: new TokenType("`"),
|
||||
dollarBraceL: new TokenType("${", beforeExpr),
|
||||
backQuote: new TokenType("`", startsExpr),
|
||||
dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
|
||||
|
||||
// Operators. These carry several kinds of properties to help the
|
||||
// parser use them properly (the presence of these properties is
|
||||
@ -298,8 +299,8 @@
|
||||
|
||||
eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
|
||||
assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
|
||||
incDec: new TokenType("++/--", {prefix: true, postfix: true}),
|
||||
prefix: new TokenType("prefix", {beforeExpr: true, prefix: true}),
|
||||
incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
|
||||
prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}),
|
||||
logicalOR: binop("||", 1),
|
||||
logicalAND: binop("&&", 2),
|
||||
bitwiseOR: binop("|", 3),
|
||||
@ -308,7 +309,7 @@
|
||||
equality: binop("==/!=", 6),
|
||||
relational: binop("</>", 7),
|
||||
bitShift: binop("<</>>", 8),
|
||||
plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true}),
|
||||
plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
|
||||
modulo: binop("%", 10),
|
||||
star: binop("*", 10),
|
||||
slash: binop("/", 10),
|
||||
@ -347,22 +348,22 @@
|
||||
kw("const");
|
||||
kw("while", {isLoop: true});
|
||||
kw("with");
|
||||
kw("new", beforeExpr);
|
||||
kw("this");
|
||||
kw("super");
|
||||
kw("new", {beforeExpr: true, startsExpr: true});
|
||||
kw("this", startsExpr);
|
||||
kw("super", startsExpr);
|
||||
kw("class");
|
||||
kw("extends", beforeExpr);
|
||||
kw("export");
|
||||
kw("import");
|
||||
kw("yield", beforeExpr);
|
||||
kw("null");
|
||||
kw("true");
|
||||
kw("false");
|
||||
kw("yield", {beforeExpr: true, startsExpr: true});
|
||||
kw("null", startsExpr);
|
||||
kw("true", startsExpr);
|
||||
kw("false", startsExpr);
|
||||
kw("in", {beforeExpr: true, binop: 7});
|
||||
kw("instanceof", {beforeExpr: true, binop: 7});
|
||||
kw("typeof", {beforeExpr: true, prefix: true});
|
||||
kw("void", {beforeExpr: true, prefix: true});
|
||||
kw("delete", {beforeExpr: true, prefix: true});
|
||||
kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true});
|
||||
kw("void", {beforeExpr: true, prefix: true, startsExpr: true});
|
||||
kw("delete", {beforeExpr: true, prefix: true, startsExpr: true});
|
||||
|
||||
// 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
|
||||
@ -1125,13 +1126,15 @@
|
||||
if (this.options.ecmaVersion >= 6) validFlags = /^[gmsiyu]*$/;
|
||||
if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag");
|
||||
if (mods.indexOf('u') >= 0 && !regexpUnicodeSupport) {
|
||||
// Replace each astral symbol and every Unicode code point
|
||||
// escape sequence that represents such a symbol with a single
|
||||
// ASCII symbol to avoid throwing on regular expressions that
|
||||
// Replace each astral symbol and every Unicode escape sequence that
|
||||
// possibly represents an astral symbol or a paired surrogate with a
|
||||
// single ASCII symbol to avoid throwing on regular expressions that
|
||||
// are only valid in combination with the `/u` flag.
|
||||
tmp = tmp
|
||||
.replace(/\\u\{([0-9a-fA-F]+)\}/g, "x")
|
||||
.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
|
||||
// Note: replacing with the ASCII symbol `x` might cause false
|
||||
// negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
|
||||
// perfectly valid pattern that is equivalent to `[a-b]`, but it would
|
||||
// be replaced by `[x-b]` which throws an error.
|
||||
tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x")
|
||||
}
|
||||
}
|
||||
// Detect invalid regular expressions.
|
||||
@ -1604,24 +1607,23 @@
|
||||
// Convert list of expression atoms to binding list.
|
||||
|
||||
pp.toAssignableList = function(exprList, isBinding) {
|
||||
if (exprList.length) {
|
||||
for (var i = 0; i < exprList.length - 1; i++) {
|
||||
this.toAssignable(exprList[i], isBinding);
|
||||
}
|
||||
var last = exprList[exprList.length - 1];
|
||||
switch (last.type) {
|
||||
case "RestElement":
|
||||
break;
|
||||
case "SpreadElement":
|
||||
last.type = "RestElement";
|
||||
var arg = last.argument;
|
||||
this.toAssignable(arg, isBinding);
|
||||
if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern")
|
||||
this.unexpected(arg.start);
|
||||
break;
|
||||
default:
|
||||
this.toAssignable(last, isBinding);
|
||||
}
|
||||
var end = exprList.length;
|
||||
if (end) {
|
||||
var last = exprList[end - 1];
|
||||
if (last && last.type == "RestElement") {
|
||||
--end;
|
||||
} else if (last && last.type == "SpreadElement") {
|
||||
last.type = "RestElement";
|
||||
var arg = last.argument;
|
||||
this.toAssignable(arg, isBinding);
|
||||
if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern")
|
||||
this.unexpected(arg.start);
|
||||
--end;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < end; i++) {
|
||||
var elt = exprList[i];
|
||||
if (elt) this.toAssignable(elt, isBinding);
|
||||
}
|
||||
return exprList;
|
||||
};
|
||||
@ -2193,6 +2195,8 @@
|
||||
decl.init = this.parseMaybeAssign(noIn);
|
||||
} else if (kind === tt._const && !(this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) {
|
||||
this.unexpected();
|
||||
} else if (decl.id.type != "Identifier") {
|
||||
this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
|
||||
} else {
|
||||
decl.init = null;
|
||||
}
|
||||
@ -2634,12 +2638,10 @@
|
||||
if (this.options.ecmaVersion >= 6) {
|
||||
prop.method = false;
|
||||
prop.shorthand = false;
|
||||
if (isPattern || refShorthandDefaultPos) {
|
||||
if (isPattern || refShorthandDefaultPos)
|
||||
start = this.currentPos();
|
||||
}
|
||||
if (!isPattern) {
|
||||
if (!isPattern)
|
||||
isGenerator = this.eat(tt.star);
|
||||
}
|
||||
}
|
||||
if (this.options.features["es7.asyncFunctions"] && this.isContextual("async")) {
|
||||
if (isGenerator || isPattern) this.unexpected();
|
||||
@ -2680,6 +2682,10 @@
|
||||
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
|
||||
prop.kind = "init";
|
||||
if (isPattern) {
|
||||
if (this.isKeyword(prop.key.name) ||
|
||||
(this.strict && (isStrictBadIdWord(prop.key.name) || isStrictReservedWord(prop.key.name))) ||
|
||||
(!this.options.allowReserved && this.isReservedWord(prop.key.name)))
|
||||
this.raise(prop.key.start, "Binding " + prop.key.name);
|
||||
prop.value = this.parseMaybeDefault(start, prop.key);
|
||||
} else if (this.type === tt.eq && refShorthandDefaultPos) {
|
||||
if (!refShorthandDefaultPos.start)
|
||||
@ -3040,7 +3046,7 @@
|
||||
pp.parseYield = function() {
|
||||
var node = this.startNode();
|
||||
this.next();
|
||||
if (this.type == tt.semi || this.canInsertSemicolon()) {
|
||||
if (this.type == tt.semi || this.canInsertSemicolon() || (this.type != tt.star && !this.type.startsExpr)) {
|
||||
node.delegate = false;
|
||||
node.argument = null;
|
||||
} else {
|
||||
|
||||
@ -5989,6 +5989,53 @@ test("var x = { *test () { yield *v } };", {
|
||||
locations: true
|
||||
});
|
||||
|
||||
test("function* foo() { console.log(yield); }", {
|
||||
body: [
|
||||
{
|
||||
id: {
|
||||
name: "foo",
|
||||
type: "Identifier",
|
||||
},
|
||||
generator: true,
|
||||
expression: false,
|
||||
params: [],
|
||||
body: {
|
||||
body: [
|
||||
{
|
||||
expression: {
|
||||
callee: {
|
||||
object: {
|
||||
name: "console",
|
||||
type: "Identifier",
|
||||
},
|
||||
property: {
|
||||
name: "log",
|
||||
type: "Identifier",
|
||||
},
|
||||
computed: false,
|
||||
type: "MemberExpression",
|
||||
},
|
||||
arguments: [
|
||||
{
|
||||
delegate: false,
|
||||
argument: null,
|
||||
type: "YieldExpression",
|
||||
}
|
||||
],
|
||||
type: "CallExpression",
|
||||
},
|
||||
type: "ExpressionStatement",
|
||||
}
|
||||
],
|
||||
type: "BlockStatement",
|
||||
},
|
||||
type: "FunctionDeclaration",
|
||||
}
|
||||
],
|
||||
sourceType: "script",
|
||||
type: "Program"
|
||||
}, {ecmaVersion: 6})
|
||||
|
||||
test("function* t() {}", {
|
||||
type: "Program",
|
||||
body: [{
|
||||
@ -13814,6 +13861,34 @@ test("/[a-z]/u", {
|
||||
ecmaVersion: 6
|
||||
});
|
||||
|
||||
test("/[\\uD834\\uDF06-\\uD834\\uDF08a-z]/u", {
|
||||
type: "Program",
|
||||
body: [
|
||||
{
|
||||
type: "ExpressionStatement",
|
||||
expression: {
|
||||
type: "Literal",
|
||||
regex: {
|
||||
pattern: "[\\uD834\\uDF06-\\uD834\\uDF08a-z]",
|
||||
flags: "u"
|
||||
},
|
||||
loc: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 0
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 33
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}, {
|
||||
locations: true,
|
||||
ecmaVersion: 6
|
||||
});
|
||||
|
||||
test("do {} while (false) foo();", {
|
||||
type: "Program",
|
||||
@ -15419,6 +15494,36 @@ test("let {x} = y", {
|
||||
"end": 11
|
||||
}, {ecmaVersion: 6})
|
||||
|
||||
test("[x,,] = 1", {
|
||||
type: "Program",
|
||||
body: [
|
||||
{
|
||||
type: "ExpressionStatement",
|
||||
expression: {
|
||||
type: "AssignmentExpression",
|
||||
operator: "=",
|
||||
left: {
|
||||
type: "ArrayPattern",
|
||||
elements: [
|
||||
{
|
||||
type: "Identifier",
|
||||
name: "x"
|
||||
},
|
||||
null
|
||||
]
|
||||
},
|
||||
right: {
|
||||
type: "Literal",
|
||||
value: 1,
|
||||
raw: "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}, {ecmaVersion: 6});
|
||||
|
||||
testFail("let [x]", "Complex binding patterns require an initialization value (1:7)", {ecmaVersion: 6})
|
||||
testFail("var [x]", "Complex binding patterns require an initialization value (1:7)", {ecmaVersion: 6})
|
||||
testFail("var _𖫵 = 11;", "Unexpected character '𖫵' (1:5)", {ecmaVersion: 6});
|
||||
testFail("var _ = 12;", "Unexpected character '' (1:4)", {ecmaVersion: 6});
|
||||
testFail("var 𫠝_ = 10;", "Unexpected character '𫠝' (1:4)", {ecmaVersion: 5});
|
||||
@ -15431,3 +15536,5 @@ testFail("'use strict'; [...eval] = arr", "Assigning to eval in strict mode (1:1
|
||||
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"});
|
||||
|
||||
testFail("function* y({yield}) {}", "Binding yield (1:13)", {ecmaVersion: 6});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user