Search in sources :

Example 1 with OptionalMemberExpressionTree

use of com.google.javascript.jscomp.parsing.parser.trees.OptionalMemberExpressionTree in project closure-compiler by google.

the class Parser method maybeParseOptionalExpression.

/**
 * Tries to parse the expression as an optional expression.
 *
 * <p>`operand?.identifier` or `operand?.[expression]` or `operand?.(arg1, arg2)`
 *
 * <p>returns parse tree after trying to parse it as an optional expression
 */
private ParseTree maybeParseOptionalExpression(ParseTree operand) {
    // The optional chain's source info should cover the lhs operand also
    SourcePosition start = operand.location.start;
    while (peek(TokenType.QUESTION_DOT)) {
        eat(TokenType.QUESTION_DOT);
        switch(peekType()) {
            case OPEN_PAREN:
                ArgumentListTree arguments = parseArguments();
                operand = new OptChainCallExpressionTree(getTreeLocation(start), operand, arguments, /* isStartOfOptionalChain = */
                true, arguments.hasTrailingComma);
                break;
            case OPEN_SQUARE:
                eat(TokenType.OPEN_SQUARE);
                ParseTree member = parseExpression();
                eat(TokenType.CLOSE_SQUARE);
                operand = new OptionalMemberLookupExpressionTree(getTreeLocation(start), operand, member, /* isStartOfOptionalChain = */
                true);
                break;
            case NO_SUBSTITUTION_TEMPLATE:
            case TEMPLATE_HEAD:
                reportError("template literal cannot be used within optional chaining");
                break;
            default:
                if (peekIdOrKeyword()) {
                    IdentifierToken id = eatIdOrKeywordAsId();
                    operand = new OptionalMemberExpressionTree(getTreeLocation(start), operand, id, /* isStartOfOptionalChain = */
                    true);
                } else {
                    reportError("syntax error: %s not allowed in optional chain", peekType());
                }
        }
        operand = parseRemainingOptionalChainSegment(operand);
    }
    return operand;
}
Also used : ArgumentListTree(com.google.javascript.jscomp.parsing.parser.trees.ArgumentListTree) OptionalMemberLookupExpressionTree(com.google.javascript.jscomp.parsing.parser.trees.OptionalMemberLookupExpressionTree) OptChainCallExpressionTree(com.google.javascript.jscomp.parsing.parser.trees.OptChainCallExpressionTree) SourcePosition(com.google.javascript.jscomp.parsing.parser.util.SourcePosition) OptionalMemberExpressionTree(com.google.javascript.jscomp.parsing.parser.trees.OptionalMemberExpressionTree) ParseTree(com.google.javascript.jscomp.parsing.parser.trees.ParseTree)

Example 2 with OptionalMemberExpressionTree

use of com.google.javascript.jscomp.parsing.parser.trees.OptionalMemberExpressionTree 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;
}
Also used : ArgumentListTree(com.google.javascript.jscomp.parsing.parser.trees.ArgumentListTree) OptionalMemberLookupExpressionTree(com.google.javascript.jscomp.parsing.parser.trees.OptionalMemberLookupExpressionTree) OptChainCallExpressionTree(com.google.javascript.jscomp.parsing.parser.trees.OptChainCallExpressionTree) SourcePosition(com.google.javascript.jscomp.parsing.parser.util.SourcePosition) OptionalMemberExpressionTree(com.google.javascript.jscomp.parsing.parser.trees.OptionalMemberExpressionTree) ParseTree(com.google.javascript.jscomp.parsing.parser.trees.ParseTree)

Aggregations

ArgumentListTree (com.google.javascript.jscomp.parsing.parser.trees.ArgumentListTree)2 OptChainCallExpressionTree (com.google.javascript.jscomp.parsing.parser.trees.OptChainCallExpressionTree)2 OptionalMemberExpressionTree (com.google.javascript.jscomp.parsing.parser.trees.OptionalMemberExpressionTree)2 OptionalMemberLookupExpressionTree (com.google.javascript.jscomp.parsing.parser.trees.OptionalMemberLookupExpressionTree)2 ParseTree (com.google.javascript.jscomp.parsing.parser.trees.ParseTree)2 SourcePosition (com.google.javascript.jscomp.parsing.parser.util.SourcePosition)2