Factor parseSubscript out of parseSubscripts (#576)

This commit is contained in:
Andy 2017-06-13 15:26:12 -07:00 committed by Daniel Tschinder
parent dc87d99713
commit 50ae16de38

View File

@ -294,12 +294,21 @@ export default class ExpressionParser extends LValParser {
return this.parseSubscripts(expr, startPos, startLoc); return this.parseSubscripts(expr, startPos, startLoc);
} }
parseSubscripts(base: N.Expression, startPos: number, startLoc: Position, noCalls?: boolean): N.Expression { parseSubscripts(base: N.Expression, startPos: number, startLoc: Position, noCalls?: ?boolean) {
for (;;) { const state = { stop: false };
do {
base = this.parseSubscript(base, startPos, startLoc, noCalls, state);
} while (!state.stop);
return base;
}
/** @param state Set 'state.stop = true' to indicate that we should stop parsing subscripts. */
parseSubscript(base: N.Expression, startPos: number, startLoc: Position, noCalls: ?boolean, state: { stop: boolean }): N.Expression {
if (!noCalls && this.eat(tt.doubleColon)) { if (!noCalls && this.eat(tt.doubleColon)) {
const node = this.startNodeAt(startPos, startLoc); const node = this.startNodeAt(startPos, startLoc);
node.object = base; node.object = base;
node.callee = this.parseNoCallExpr(); node.callee = this.parseNoCallExpr();
state.stop = true;
return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls); return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls);
} else if (this.match(tt.questionDot)) { } else if (this.match(tt.questionDot)) {
@ -308,6 +317,7 @@ export default class ExpressionParser extends LValParser {
} }
if (noCalls && this.lookahead().type == tt.parenL) { if (noCalls && this.lookahead().type == tt.parenL) {
state.stop = true;
return base; return base;
} }
this.next(); this.next();
@ -320,7 +330,7 @@ export default class ExpressionParser extends LValParser {
node.computed = true; node.computed = true;
node.optional = true; node.optional = true;
this.expect(tt.bracketR); this.expect(tt.bracketR);
base = this.finishNode(node, "MemberExpression"); return this.finishNode(node, "MemberExpression");
} else if (this.eat(tt.parenL)) { } else if (this.eat(tt.parenL)) {
const possibleAsync = this.state.potentialArrowAt === base.start && const possibleAsync = this.state.potentialArrowAt === base.start &&
base.type === "Identifier" && base.type === "Identifier" &&
@ -331,27 +341,27 @@ export default class ExpressionParser extends LValParser {
node.arguments = this.parseCallExpressionArguments(tt.parenR, possibleAsync); node.arguments = this.parseCallExpressionArguments(tt.parenR, possibleAsync);
node.optional = true; node.optional = true;
base = this.finishNode(node, "CallExpression"); return this.finishNode(node, "CallExpression");
} else { } else {
node.object = base; node.object = base;
node.property = this.parseIdentifier(true); node.property = this.parseIdentifier(true);
node.computed = false; node.computed = false;
node.optional = true; node.optional = true;
base = this.finishNode(node, "MemberExpression"); return this.finishNode(node, "MemberExpression");
} }
} else if (this.eat(tt.dot)) { } else if (this.eat(tt.dot)) {
const node = this.startNodeAt(startPos, startLoc); const node = this.startNodeAt(startPos, startLoc);
node.object = base; node.object = base;
node.property = this.hasPlugin("classPrivateProperties") ? this.parseMaybePrivateName() : this.parseIdentifier(true); node.property = this.hasPlugin("classPrivateProperties") ? this.parseMaybePrivateName() : this.parseIdentifier(true);
node.computed = false; node.computed = false;
base = this.finishNode(node, "MemberExpression"); return this.finishNode(node, "MemberExpression");
} else if (this.eat(tt.bracketL)) { } else if (this.eat(tt.bracketL)) {
const node = this.startNodeAt(startPos, startLoc); const node = this.startNodeAt(startPos, startLoc);
node.object = base; node.object = base;
node.property = this.parseExpression(); node.property = this.parseExpression();
node.computed = true; node.computed = true;
this.expect(tt.bracketR); this.expect(tt.bracketR);
base = this.finishNode(node, "MemberExpression"); return this.finishNode(node, "MemberExpression");
} else if (!noCalls && this.match(tt.parenL)) { } else if (!noCalls && this.match(tt.parenL)) {
const possibleAsync = this.state.potentialArrowAt === base.start && base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon(); const possibleAsync = this.state.potentialArrowAt === base.start && base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon();
this.next(); this.next();
@ -369,25 +379,25 @@ export default class ExpressionParser extends LValParser {
this.raise(importArg.start, "... is not allowed in import()"); this.raise(importArg.start, "... is not allowed in import()");
} }
} }
base = this.finishNode(node, "CallExpression"); this.finishNode(node, "CallExpression");
if (possibleAsync && this.shouldParseAsyncArrow()) { if (possibleAsync && this.shouldParseAsyncArrow()) {
state.stop = true;
return this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node); return this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node);
} else { } else {
this.toReferencedList(node.arguments); this.toReferencedList(node.arguments);
} }
return node;
} else if (this.match(tt.backQuote)) { } else if (this.match(tt.backQuote)) {
const node = this.startNodeAt(startPos, startLoc); const node = this.startNodeAt(startPos, startLoc);
node.tag = base; node.tag = base;
node.quasi = this.parseTemplate(true); node.quasi = this.parseTemplate(true);
base = this.finishNode(node, "TaggedTemplateExpression"); return this.finishNode(node, "TaggedTemplateExpression");
} else { } else {
state.stop = true;
return base; return base;
} }
} }
// istanbul ignore next
throw new Error("Unreachable");
}
parseCallExpressionArguments(close: TokenType, possibleAsyncArrow: boolean): $ReadOnlyArray<?N.Expression> { parseCallExpressionArguments(close: TokenType, possibleAsyncArrow: boolean): $ReadOnlyArray<?N.Expression> {
const elts = []; const elts = [];