use of com.google.javascript.jscomp.parsing.parser.trees.ParseTree in project closure-compiler by google.
the class Parser method parseRemainingOptionalChainSegment.
/**
* Parses the remaining components of an optional chain till the current chain's end, or a new
* chain's start.
*
* <p>`optionalExpression.identifier`, `optionalExpression[expression]`, `optionalExpression(arg1,
* arg2)`, or `optionalExpression?.optionalExpression`
*
* <p>returns parse tree after trying to parse it as an optional chain
*/
private ParseTree parseRemainingOptionalChainSegment(ParseTree optionalExpression) {
// The optional chain's source info should cover the lhs operand also
SourcePosition start = optionalExpression.location.start;
while (peekOptionalChainSuffix()) {
if (peekType() == TokenType.NO_SUBSTITUTION_TEMPLATE || peekType() == TokenType.TEMPLATE_HEAD) {
reportError("template literal cannot be used within optional chaining");
break;
}
switch(peekType()) {
case PERIOD:
eat(TokenType.PERIOD);
IdentifierToken id = eatIdOrKeywordAsId();
optionalExpression = new OptionalMemberExpressionTree(getTreeLocation(start), optionalExpression, id, /*isStartOfOptionalChain=*/
false);
break;
case OPEN_PAREN:
ArgumentListTree arguments = parseArguments();
optionalExpression = new OptChainCallExpressionTree(getTreeLocation(start), optionalExpression, arguments, /* isStartOfOptionalChain = */
false, arguments.hasTrailingComma);
break;
case OPEN_SQUARE:
eat(TokenType.OPEN_SQUARE);
ParseTree member = parseExpression();
eat(TokenType.CLOSE_SQUARE);
optionalExpression = new OptionalMemberLookupExpressionTree(getTreeLocation(start), optionalExpression, member, /* isStartOfOptionalChain = */
false);
break;
default:
throw new AssertionError("unexpected case: " + peekType());
}
}
return optionalExpression;
}
use of com.google.javascript.jscomp.parsing.parser.trees.ParseTree in project closure-compiler by google.
the class Parser method parseAdditiveExpression.
// 11.6 Additive Expression
private ParseTree parseAdditiveExpression() {
SourcePosition start = getTreeStartLocation();
ParseTree left = parseMultiplicativeExpression();
while (peekAdditiveOperator()) {
Token operator = nextToken();
ParseTree right = parseMultiplicativeExpression();
left = new BinaryOperatorTree(getTreeLocation(start), left, operator, right);
}
return left;
}
use of com.google.javascript.jscomp.parsing.parser.trees.ParseTree in project closure-compiler by google.
the class Parser method parseLeftHandSideExpression.
/**
* Parse LeftHandSideExpression.
*/
@SuppressWarnings("incomplete-switch")
private ParseTree parseLeftHandSideExpression() {
SourcePosition start = getTreeStartLocation();
// We have these possible productions.
// LeftHandSideExpression -> NewExpression
// -> CallExpression
// -> MemberExpression
// -> OptionalExpression
//
// NewExpression -> new NewExpression
// -> MemberExpression
//
// CallExpression -> MemberExpression Arguments
// -> CallExpression ... see below
//
// OptionalExpression -> MemberExpression OptionalChain
// -> CallExpression OptionalChain
// -> OptionalExpression OptionalChain
//
// We try parsing a NewExpression, here, because that will include parsing MemberExpression.
// If what we really have is a CallExpression or OptionalExpression, then the MemberExpression
// we get back from parseNewExpression will be the first part of it, and we'll build the
// rest later.
ParseTree operand = parseNewExpression();
// this test is equivalent to is member expression
if (!(operand instanceof NewExpressionTree) || ((NewExpressionTree) operand).arguments != null) {
// Attempt to gather the rest of the CallExpression, if so.
while (peekCallSuffix()) {
switch(peekType()) {
case OPEN_PAREN:
ArgumentListTree arguments = parseArguments();
operand = new CallExpressionTree(getTreeLocation(start), operand, arguments);
break;
case OPEN_SQUARE:
eat(TokenType.OPEN_SQUARE);
ParseTree member = parseExpression();
eat(TokenType.CLOSE_SQUARE);
operand = new MemberLookupExpressionTree(getTreeLocation(start), operand, member);
break;
case PERIOD:
eat(TokenType.PERIOD);
IdentifierToken id = eatIdOrKeywordAsId();
operand = new MemberExpressionTree(getTreeLocation(start), operand, id);
break;
case NO_SUBSTITUTION_TEMPLATE:
case TEMPLATE_HEAD:
operand = parseTemplateLiteral(operand);
break;
default:
throw new AssertionError("unexpected case: " + peekType());
}
}
operand = maybeParseOptionalExpression(operand);
}
return operand;
}
use of com.google.javascript.jscomp.parsing.parser.trees.ParseTree in project closure-compiler by google.
the class Parser method parseDynamicImportExpression.
// https://tc39.github.io/proposal-dynamic-import
private DynamicImportTree parseDynamicImportExpression() {
SourcePosition start = getTreeStartLocation();
eat(TokenType.IMPORT);
if (peek(TokenType.QUESTION_DOT)) {
// import?.() not allowed
reportError("Optional chaining is forbidden in import?.");
}
eat(TokenType.OPEN_PAREN);
ParseTree argument = parseAssignmentExpression();
eat(TokenType.CLOSE_PAREN);
recordFeatureUsed(Feature.DYNAMIC_IMPORT);
return new DynamicImportTree(getTreeLocation(start), argument);
}
use of com.google.javascript.jscomp.parsing.parser.trees.ParseTree in project closure-compiler by google.
the class Parser method completeAssignmentExpressionParseAtArrow.
private ParseTree completeAssignmentExpressionParseAtArrow(CallExpressionTree callExpression) {
ParseTree operand = callExpression.operand;
ParseTree arguments = callExpression.arguments;
ParseTree result;
if (operand.location.end.line < arguments.location.start.line) {
// break at the implicit semicolon
// Example:
// foo.bar // operand and implicit semicolon
// () => { doSomething; };
resetScannerAfter(operand);
result = operand;
} else {
reportError("'=>' unexpected");
result = callExpression;
}
return result;
}
Aggregations