Factor parseSubscript out of parseSubscripts (#576)
This commit is contained in:
parent
dc87d99713
commit
50ae16de38
@ -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 = [];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user