Support for for (const ...).
Fixes #213. Also changes API to pass token type to `parseVar` to reduce string comparison ops.
This commit is contained in:
parent
ff60ee4fdb
commit
34050d3917
18
acorn.js
18
acorn.js
@ -1773,7 +1773,7 @@
|
||||
case tt._throw: return this.parseThrowStatement(node);
|
||||
case tt._try: return this.parseTryStatement(node);
|
||||
case tt._let: case tt._const: if (!declaration) this.unexpected(); // NOTE: falls through to _var
|
||||
case tt._var: return this.parseVarStatement(node, starttype.keyword);
|
||||
case tt._var: return this.parseVarStatement(node, starttype);
|
||||
case tt._while: return this.parseWhileStatement(node);
|
||||
case tt._with: return this.parseWithStatement(node);
|
||||
case tt.braceL: return this.parseBlock(); // no point creating a function for this
|
||||
@ -1853,13 +1853,13 @@
|
||||
this.labels.push(loopLabel);
|
||||
this.expect(tt.parenL);
|
||||
if (this.type === tt.semi) return this.parseFor(node, null);
|
||||
if (this.type === tt._var || this.type === tt._let) {
|
||||
var init = this.startNode(), varKind = this.type.keyword, isLet = this.type === tt._let;
|
||||
if (this.type === tt._var || this.type === tt._let || this.type === tt._const) {
|
||||
var init = this.startNode(), varKind = this.type;
|
||||
this.next();
|
||||
this.parseVar(init, true, varKind);
|
||||
this.finishNode(init, "VariableDeclaration");
|
||||
if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1 &&
|
||||
!(isLet && init.declarations[0].init))
|
||||
!(varKind !== tt._var && init.declarations[0].init))
|
||||
return this.parseForIn(node, init);
|
||||
return this.parseFor(node, init);
|
||||
}
|
||||
@ -2079,12 +2079,18 @@
|
||||
|
||||
pp.parseVar = function(node, noIn, kind) {
|
||||
node.declarations = [];
|
||||
node.kind = kind;
|
||||
node.kind = kind.keyword;
|
||||
for (;;) {
|
||||
var decl = this.startNode();
|
||||
decl.id = this.parseBindingAtom();
|
||||
this.checkLVal(decl.id, true);
|
||||
decl.init = this.eat(tt.eq) ? this.parseMaybeAssign(noIn) : (kind === tt._const.keyword ? this.unexpected() : null);
|
||||
if (this.eat(tt.eq)) {
|
||||
decl.init = this.parseMaybeAssign(noIn);
|
||||
} else if (kind === tt._const && !(this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) {
|
||||
this.unexpected();
|
||||
} else {
|
||||
decl.init = null;
|
||||
}
|
||||
node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
|
||||
if (!this.eat(tt.comma)) break;
|
||||
}
|
||||
|
||||
@ -346,7 +346,7 @@
|
||||
this.pushCx();
|
||||
this.expect(tt.parenL);
|
||||
if (this.tok.type === tt.semi) return this.parseFor(node, null);
|
||||
if (this.tok.type === tt._var || this.tok.type === tt._let) {
|
||||
if (this.tok.type === tt._var || this.tok.type === tt._let || this.tok.type === tt._const) {
|
||||
var init = this.parseVar(true);
|
||||
if (init.declarations.length === 1 && (this.tok.type === tt._in || this.isContextual("of"))) {
|
||||
return this.parseForIn(node, init);
|
||||
|
||||
@ -14970,6 +14970,55 @@ test("class A { static() {} }", {
|
||||
locations: true
|
||||
});
|
||||
|
||||
// https://github.com/marijnh/acorn/issues/213
|
||||
|
||||
test("for (const x of list) process(x);", {
|
||||
type: "Program",
|
||||
body: [{
|
||||
type: "ForOfStatement",
|
||||
left: {
|
||||
type: "VariableDeclaration",
|
||||
declarations: [{
|
||||
type: "VariableDeclarator",
|
||||
id: {
|
||||
type: "Identifier",
|
||||
name: "x",
|
||||
range: [11, 12]
|
||||
},
|
||||
init: null,
|
||||
range: [11, 12]
|
||||
}],
|
||||
kind: "const",
|
||||
range: [5, 12]
|
||||
},
|
||||
right: {
|
||||
type: "Identifier",
|
||||
name: "list",
|
||||
range: [16, 20]
|
||||
},
|
||||
body: {
|
||||
type: "ExpressionStatement",
|
||||
expression: {
|
||||
type: "CallExpression",
|
||||
callee: {
|
||||
type: "Identifier",
|
||||
name: "process",
|
||||
range: [22, 29]
|
||||
},
|
||||
arguments: [{
|
||||
type: "Identifier",
|
||||
name: "x",
|
||||
range: [30, 31]
|
||||
}],
|
||||
range: [22, 32]
|
||||
},
|
||||
range: [22, 33]
|
||||
},
|
||||
range: [0, 33]
|
||||
}],
|
||||
range: [0, 33]
|
||||
}, {ecmaVersion: 6, ranges: true});
|
||||
|
||||
test("class A { *static() {} }", {
|
||||
type: "Program",
|
||||
range: [0, 24],
|
||||
|
||||
@ -28682,7 +28682,39 @@ test("const x = 14, y = 3, z = 1977", {
|
||||
|
||||
testFail("const a;", "Unexpected token (1:7)", {ecmaVersion: 6});
|
||||
|
||||
testFail("for(const x = 0;;);", "Unexpected token (1:4)", {ecmaVersion: 6});
|
||||
test("for(const x = 0;;);", {
|
||||
type: "Program",
|
||||
body: [{
|
||||
type: "ForStatement",
|
||||
init: {
|
||||
type: "VariableDeclaration",
|
||||
declarations: [{
|
||||
type: "VariableDeclarator",
|
||||
id: {
|
||||
type: "Identifier",
|
||||
name: "x",
|
||||
range: [10, 11]
|
||||
},
|
||||
init: {
|
||||
type: "Literal",
|
||||
value: 0,
|
||||
range: [14, 15]
|
||||
},
|
||||
range: [10, 15]
|
||||
}],
|
||||
kind: "const",
|
||||
range: [4, 15]
|
||||
},
|
||||
test: null,
|
||||
update: null,
|
||||
body: {
|
||||
type: "EmptyStatement",
|
||||
range: [18, 19]
|
||||
},
|
||||
range: [0, 19]
|
||||
}],
|
||||
range: [0, 19]
|
||||
}, {ecmaVersion: 6, ranges: true});
|
||||
|
||||
testFail("for(x of a);", "Unexpected token (1:6)");
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user