Introduce helpers for contextual keywords.

This commit is contained in:
Ingvar Stepanyan 2015-01-23 21:36:16 +02:00
parent 08b34933d7
commit 41ad304955
2 changed files with 43 additions and 47 deletions

View File

@ -1414,6 +1414,24 @@
}
}
// Tests whether parsed token is a contextual keyword.
function isContextual(name) {
return tokType === _name && tokVal === name;
}
// Consumes contextual keyword if possible.
function eatContextual(name) {
return tokVal === name && eat(_name);
}
// Asserts that following token is given contextual keyword.
function expectContextual(name) {
if (!eatContextual(name)) unexpected();
}
// Test whether a semicolon can be inserted at the current position.
function canInsertSemicolon() {
@ -1814,13 +1832,13 @@
next();
parseVar(init, true, varKind);
finishNode(init, "VariableDeclaration");
if ((tokType === _in || (options.ecmaVersion >= 6 && tokType === _name && tokVal === "of")) && init.declarations.length === 1 &&
if ((tokType === _in || (options.ecmaVersion >= 6 && isContextual("of"))) && init.declarations.length === 1 &&
!(isLet && init.declarations[0].init))
return parseForIn(node, init);
return parseFor(node, init);
}
var init = parseExpression(false, true);
if (tokType === _in || (options.ecmaVersion >= 6 && tokType === _name && tokVal === "of")) {
if (tokType === _in || (options.ecmaVersion >= 6 && isContextual("of"))) {
checkLVal(init);
return parseForIn(node, init);
}
@ -2631,8 +2649,7 @@
node.declaration = null;
node['default'] = false;
node.specifiers = parseExportSpecifiers();
if (tokType === _name && tokVal === "from") {
next();
if (eatContextual("from")) {
node.source = tokType === _string ? parseExprAtom() : unexpected();
} else {
if (isBatch) unexpected();
@ -2663,12 +2680,7 @@
var node = startNode();
node.id = parseIdent(tokType === _default);
if (tokType === _name && tokVal === "as") {
next();
node.name = parseIdent(true);
} else {
node.name = null;
}
node.name = eatContextual("as") ? parseIdent(true) : null;
nodes.push(finishNode(node, "ExportSpecifier"));
}
}
@ -2686,8 +2698,7 @@
node.kind = "";
} else {
node.specifiers = parseImportSpecifiers();
if (tokType !== _name || tokVal !== "from") unexpected();
next();
expectContextual("from");
node.source = tokType === _string ? parseExprAtom() : unexpected();
}
semicolon();
@ -2711,8 +2722,7 @@
if (tokType === _star) {
var node = startNode();
next();
if (tokType !== _name || tokVal !== "as") unexpected();
next();
expectContextual("as");
node.name = parseIdent();
checkLVal(node.name, true);
nodes.push(finishNode(node, "ImportBatchSpecifier"));
@ -2727,12 +2737,7 @@
var node = startNode();
node.id = parseIdent(true);
if (tokType === _name && tokVal === "as") {
next();
node.name = parseIdent();
} else {
node.name = null;
}
node.name = eatContextual("as") ? parseIdent() : null;
checkLVal(node.name || node.id, true);
node['default'] = false;
nodes.push(finishNode(node, "ImportSpecifier"));
@ -2765,8 +2770,7 @@
expect(_parenL);
block.left = parseAssignableAtom();
checkLVal(block.left, true);
if (tokType !== _name || tokVal !== "of") unexpected();
next();
expectContextual("of");
block.right = parseExpression();
expect(_parenR);
node.blocks.push(finishNode(block, "ComprehensionBlock"));

View File

@ -271,9 +271,18 @@
}
}
function isContextual(name) {
return token.type === tt.name && token.value === name;
}
function eatContextual(name) {
return token.value === name && eat(tt.name);
}
function canInsertSemicolon() {
return (token.type === tt.eof || token.type === tt.braceR || newline.test(input.slice(lastEnd, token.start)));
}
function semicolon() {
return eat(tt.semi);
}
@ -352,13 +361,13 @@
if (token.type === tt.semi) return parseFor(node, null);
if (token.type === tt._var || token.type === tt._let) {
var init = parseVar(true);
if (init.declarations.length === 1 && (token.type === tt._in || token.type === tt.name && token.value === "of")) {
if (init.declarations.length === 1 && (token.type === tt._in || isContextual("of"))) {
return parseForIn(node, init);
}
return parseFor(node, init);
}
var init = parseExpression(false, true);
if (token.type === tt._in || token.type === tt.name && token.value === "of") {
if (token.type === tt._in || isContextual("of")) {
return parseForIn(node, checkLVal(init));
}
return parseFor(node, init);
@ -1080,10 +1089,7 @@
if (token.type === tt.star) {
var elt = startNode();
next();
if (token.type === tt.name && token.value === "as") {
next();
elt.name = parseIdent();
}
if (eatContextual("as")) elt.name = parseIdent();
elts.push(finishNode(elt, prefix + "BatchSpecifier"));
} else {
var indent = curIndent, line = curLineStart, continuedLine = nextLineStart;
@ -1092,22 +1098,13 @@
if (curLineStart > continuedLine) continuedLine = curLineStart;
while (!closes(tt.braceR, indent + (curLineStart <= continuedLine ? 1 : 0), line)) {
var elt = startNode();
if (token.type === tt.star) {
next();
if (token.type === tt.name && token.value === "as") {
next();
elt.name = parseIdent();
}
if (eat(tt.star)) {
if (eatContextual("as")) elt.name = parseIdent();
finishNode(elt, prefix + "BatchSpecifier");
} else {
if (token.type === tt.name && token.value === "from") break;
if (isContextual("from")) break;
elt.id = parseIdent();
if (token.type === tt.name && token.value === "as") {
next();
elt.name = parseIdent();
} else {
elt.name = null;
}
elt.name = eatContextual("as") ? parseIdent() : null;
finishNode(elt, prefix + "Specifier");
}
elts.push(elt);
@ -1116,12 +1113,7 @@
eat(tt.braceR);
popCx();
}
if (token.type === tt.name && token.value === "from") {
next();
node.source = parseExprAtom();
} else {
node.source = null;
}
node.source = eatContextual("from") ? parseExprAtom() : null;
}
function parseExprList(close, allowEmpty) {