* </pre>
*
* @return the argument list that was parsed
*/
protected ArgumentList parseArgumentList() {
Token leftParenthesis = expect(TokenType.OPEN_PAREN);
List<Expression> arguments = new ArrayList<Expression>();
if (matches(TokenType.CLOSE_PAREN)) {
return new ArgumentList(leftParenthesis, arguments, getAndAdvance());
}
//
// Even though unnamed arguments must all appear before any named arguments, we allow them to
// appear in any order so that we can recover faster.
//
boolean wasInInitializer = inInitializer;
inInitializer = false;
try {
Expression argument = parseArgument();
arguments.add(argument);
boolean foundNamedArgument = argument instanceof NamedExpression;
boolean generatedError = false;
while (optional(TokenType.COMMA)) {
argument = parseArgument();
arguments.add(argument);
if (foundNamedArgument) {
boolean blankArgument = argument instanceof SimpleIdentifier
&& ((SimpleIdentifier) argument).getName().isEmpty();
if (!generatedError && !(argument instanceof NamedExpression && !blankArgument)) {
// Report the error, once, but allow the arguments to be in any order in the AST.
reportErrorForCurrentToken(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT);
generatedError = true;
}
} else if (argument instanceof NamedExpression) {
foundNamedArgument = true;
}
}
// TODO(brianwilkerson) Recovery: Look at the left parenthesis to see whether there is a
// matching right parenthesis. If there is, then we're more likely missing a comma and should
// go back to parsing arguments.
Token rightParenthesis = expect(TokenType.CLOSE_PAREN);
return new ArgumentList(leftParenthesis, arguments, rightParenthesis);
} finally {
inInitializer = wasInInitializer;
}
}