// ECMA-262 12.3 Left-Hand-Side Expressions public Node parseLeftHandSideExpression() { Node quasi; Node expr; Node property; Token startToken; assert(state.allowIn, "callee of new expression always allow in keyword."); startToken = lookahead; if (matchKeyword("super") && state.inFunctionBody) { expr = new Node(); lex(); expr = expr.finishSuper(); if (!match("[") && !match(".")) { throwUnexpectedToken(lookahead); } } else { expr = inheritCoverGrammar(() => { if (matchKeyword("new")) return parseNewExpression(); return parsePrimaryExpression(); }); } for (; ; ) { if (match("[")) { isBindingElement = false; isAssignmentTarget = true; property = parseComputedMember(); expr = new Node(startToken).finishMemberExpression("[", expr, property); } else if (match(".")) { isBindingElement = false; isAssignmentTarget = true; property = parseNonComputedMember(); expr = new Node(startToken).finishMemberExpression(".", expr, property); } else if (lookahead.type == TokenType.Template && lookahead.head) { quasi = parseTemplateLiteral(); expr = new Node(startToken).finishTaggedTemplateExpression(expr, quasi); } else { break; } } return expr; }
// ECMA-262 12.3.4 Function Calls public Node parseLeftHandSideExpressionAllowCall() { Node quasi; Node expr; List<Node> args; Node property; Token startToken; bool previousAllowIn = state.allowIn; startToken = lookahead; state.allowIn = true; if (matchKeyword("super") && state.inFunctionBody) { expr = new Node(); lex(); expr = expr.finishSuper(); if (!match("(") && !match(".") && !match("[")) { throwUnexpectedToken(lookahead); } } else { expr = inheritCoverGrammar(() => { if (matchKeyword("new")) return parseNewExpression(); return parsePrimaryExpression(); }); } for (; ; ) { if (match(".")) { isBindingElement = false; isAssignmentTarget = true; property = parseNonComputedMember(); expr = new Node(startToken).finishMemberExpression(".", expr, property); } else if (match("(")) { isBindingElement = false; isAssignmentTarget = false; args = parseArguments(); expr = new Node(startToken).finishCallExpression(expr, args); } else if (match("[")) { isBindingElement = false; isAssignmentTarget = true; property = parseComputedMember(); expr = new Node(startToken).finishMemberExpression("[", expr, property); } else if (lookahead.type == TokenType.Template && lookahead.head) { quasi = parseTemplateLiteral(); expr = new Node(startToken).finishTaggedTemplateExpression(expr, quasi); } else { break; } } state.allowIn = previousAllowIn; return expr; }