diff --git a/acorn.js b/acorn.js index 48de20d3b1..9555ddfacf 100644 --- a/acorn.js +++ b/acorn.js @@ -2241,6 +2241,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() { @@ -2691,13 +2709,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); } @@ -3716,8 +3734,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(); @@ -3748,12 +3765,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")); } } @@ -3770,8 +3782,7 @@ node.source = parseExprAtom(); } else { node.specifiers = parseImportSpecifiers(); - if (tokType !== _name || tokVal !== "from") unexpected(); - next(); + expectContextual("from"); node.source = tokType === _string ? parseExprAtom() : unexpected(); } semicolon(); @@ -3795,8 +3806,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")); @@ -3811,12 +3821,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")); @@ -3860,8 +3865,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")); diff --git a/acorn_loose.js b/acorn_loose.js index 651cb24476..c3f17d352e 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -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); @@ -1081,10 +1090,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; @@ -1093,22 +1099,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); @@ -1117,12 +1114,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) {