| Index: compiler/java/com/google/dart/compiler/parser/DartParser.java
|
| diff --git a/compiler/java/com/google/dart/compiler/parser/DartParser.java b/compiler/java/com/google/dart/compiler/parser/DartParser.java
|
| index 2d6611da1b9b651a53283303c6cb90cc49d17a93..e281614ddddb747df33c0b92732b7d50982e61dc 100644
|
| --- a/compiler/java/com/google/dart/compiler/parser/DartParser.java
|
| +++ b/compiler/java/com/google/dart/compiler/parser/DartParser.java
|
| @@ -113,7 +113,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| private final boolean isDietParse;
|
| private final Set<String> prefixes;
|
| private final boolean corelibParse;
|
| - private Set<Integer> errorHistory = new HashSet<Integer>();
|
| + private final Set<Integer> errorHistory = new HashSet<Integer>();
|
| private boolean isParsingInterface;
|
| private boolean isTopLevelAbstract;
|
| private DartScanner.Position topLevelAbstractModifierPosition;
|
| @@ -161,7 +161,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| STATIC_KEYWORD,
|
| TYPEDEF_KEYWORD
|
| };
|
| -
|
| +
|
| public DartParser(Source source,
|
| String sourceCode,
|
| DartCompilerListener listener) {
|
| @@ -278,12 +278,12 @@ public class DartParser extends CompletionHooksParserBase {
|
| if (optional(Token.CLASS)) {
|
| isParsingClass = true;
|
| node = done(parseClass());
|
| - } else if (peekPseudoKeyword(0, INTERFACE_KEYWORD)
|
| + } else if (peekPseudoKeyword(0, INTERFACE_KEYWORD)
|
| && peek(1).equals(Token.IDENTIFIER)) {
|
| consume(Token.IDENTIFIER);
|
| isParsingInterface = true;
|
| node = done(parseClass());
|
| - } else if (peekPseudoKeyword(0, TYPEDEF_KEYWORD)
|
| + } else if (peekPseudoKeyword(0, TYPEDEF_KEYWORD)
|
| && (peek(1).equals(Token.IDENTIFIER) || peek(1).equals(Token.VOID))) {
|
| consume(Token.IDENTIFIER);
|
| node = done(parseFunctionTypeAlias());
|
| @@ -329,7 +329,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| || peekPseudoKeyword(n, INTERFACE_KEYWORD)
|
| || peekPseudoKeyword(n, TYPEDEF_KEYWORD);
|
| }
|
| -
|
| +
|
| /**
|
| * 'interface' and 'typedef' are valid to use as names of fields and methods, so you can't
|
| * just blindly recover when you see them in any context. This does a further test to make
|
| @@ -340,10 +340,10 @@ public class DartParser extends CompletionHooksParserBase {
|
| if (peek(0).equals(Token.CLASS)) {
|
| return true;
|
| }
|
| - if (peekPseudoKeyword(0, INTERFACE_KEYWORD)
|
| + if (peekPseudoKeyword(0, INTERFACE_KEYWORD)
|
| && peek(1).equals(Token.IDENTIFIER)) {
|
| return true;
|
| - } else if (peekPseudoKeyword(0, TYPEDEF_KEYWORD)
|
| + } else if (peekPseudoKeyword(0, TYPEDEF_KEYWORD)
|
| && (peek(1).equals(Token.IDENTIFIER) || peek(1).equals(Token.VOID))) {
|
| return true;
|
| }
|
| @@ -518,6 +518,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| do {
|
| DartTypeParameter typeParameter = parseTypeParameter();
|
| types.add(typeParameter);
|
| +
|
| } while (optional(Token.COMMA));
|
| expect(Token.GT);
|
| return types;
|
| @@ -958,7 +959,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| member = parseMethodOrAccessor(modifiers, null);
|
| break;
|
| }
|
| -
|
| +
|
| member = parseFieldDeclaration(modifiers, null);
|
| expectStatmentTerminator();
|
| break;
|
| @@ -990,13 +991,13 @@ public class DartParser extends CompletionHooksParserBase {
|
| && peek(1) != Token.ASSIGN
|
| && peek(1) != Token.SEMICOLON) {
|
| type = parseTypeAnnotation();
|
| -
|
| +
|
| // Check again for malformed method starting with 'final': final String ^ foo() { }
|
| if (peek(0).equals(Token.IDENTIFIER) && looksLikeMethodOrAccessorDefinition()) {
|
| reportError(position(), ParserErrorCode.FINAL_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION);
|
| member = parseMethodOrAccessor(modifiers, null);
|
| break;
|
| - }
|
| + }
|
| }
|
| member = parseFieldDeclaration(modifiers, type);
|
| expectStatmentTerminator();
|
| @@ -1061,8 +1062,8 @@ public class DartParser extends CompletionHooksParserBase {
|
| * | set identifier (
|
| * | operator (
|
| * | operator <op> (
|
| - * | identifier (
|
| - * | identifier DOT identifier (
|
| + * | identifier (
|
| + * | identifier DOT identifier (
|
| * | identifier DOT identifier DOT identifier (
|
| *
|
| * @return <code>true</code> if the signature of a method has been found. No tokens are consumed.
|
| @@ -1085,40 +1086,40 @@ public class DartParser extends CompletionHooksParserBase {
|
| if (peekPseudoKeyword(0, NEGATE_KEYWORD) && peek(1).equals(Token.LPAREN)) {
|
| return true;
|
| }
|
| - // TODO(zundel): Look for valid operator overload tokens. For now just assuming
|
| + // TODO(zundel): Look for valid operator overload tokens. For now just assuming
|
| // non-idents are good enough
|
| // operator ??? (
|
| if (!(peek(0).equals(Token.IDENTIFIER) && peek(1).equals(Token.LPAREN))) {
|
| return true;
|
| }
|
| if (peek(0).equals(Token.LBRACK) && peek(1).equals(Token.RBRACK)) {
|
| - // operator [] (
|
| + // operator [] (
|
| if (peek(2).equals(Token.LPAREN)) {
|
| return true;
|
| }
|
| - // operator []= (
|
| + // operator []= (
|
| if (peek(2).equals(Token.ASSIGN) && peek(3).equals(Token.LPAREN)) {
|
| return true;
|
| }
|
| }
|
| return false;
|
| }
|
| -
|
| +
|
| if (peekPseudoKeyword(0, GETTER_KEYWORD)
|
| || peekPseudoKeyword(0, SETTER_KEYWORD)) {
|
| next();
|
| // Using 'get' or 'set' as a field name is valid
|
| if (peek(0).equals(Token.SEMICOLON) || peek(0).equals(Token.ASSIGN)) {
|
| return false;
|
| - }
|
| + }
|
| // Using 'get' or 'set' as a method name is valid (but discouraged)
|
| if (peek(0).equals(Token.LPAREN)) {
|
| return true;
|
| - }
|
| + }
|
| // normal case: get foo (
|
| if (peek(0).equals(Token.IDENTIFIER) && peek(1).equals(Token.LPAREN)) {
|
| return true;
|
| - }
|
| + }
|
| return false;
|
| }
|
|
|
| @@ -1227,7 +1228,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| found = true;
|
| break;
|
| }
|
| - }
|
| + }
|
| StringBuilder buf = new StringBuilder();
|
| buf.append(operation.getSyntax());
|
| if (found) {
|
| @@ -1578,6 +1579,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| * ;
|
| * </pre>
|
| */
|
| + @Terminals(tokens = {Token.RBRACK, Token.COMMA, Token.RPAREN})
|
| private List<DartParameter> parseFormalParameterList() {
|
| beginFormalParameterList();
|
| List<DartParameter> params = new ArrayList<DartParameter>();
|
| @@ -1592,15 +1594,18 @@ public class DartParser extends CompletionHooksParserBase {
|
| DartParameter param = parseFormalParameter(isNamed);
|
| params.add(param);
|
|
|
| + // Must keep in sync with @Terminals above
|
| done = optional(Token.RBRACK);
|
| if (done) {
|
| expectCloseParen();
|
| } else {
|
| + // Must keep in sync with @Terminals above
|
| done = optional(Token.RPAREN);
|
| }
|
|
|
| if (!done) {
|
| // Ensure termination if token is anything other than COMMA.
|
| + // Must keep in sync with @Terminals above
|
| done = !expect(Token.COMMA);
|
| }
|
| }
|
| @@ -1791,6 +1796,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| private DartExpression parseExpressionList() {
|
| beginExpressionList();
|
| DartExpression result = parseExpression();
|
| + // Must keep in sync with @Terminals above
|
| while (optional(Token.COMMA)) {
|
| result = new DartBinaryExpression(Token.COMMA, result, parseExpression());
|
| if (match(Token.COMMA)) {
|
| @@ -1858,9 +1864,9 @@ public class DartParser extends CompletionHooksParserBase {
|
| Position prevPositionStart = ctx.getTokenLocation().getBegin();
|
| Position prevPositionEnd = ctx.getTokenLocation().getEnd();
|
| Token token = next();
|
| - if (lastResult instanceof DartSuperExpression
|
| + if (lastResult instanceof DartSuperExpression
|
| && (token == Token.AND || token == Token.OR)) {
|
| - reportErrorAtPosition(prevPositionStart, prevPositionEnd,
|
| + reportErrorAtPosition(prevPositionStart, prevPositionEnd,
|
| ParserErrorCode.SUPER_IS_NOT_VALID_AS_A_BOOLEAN_OPERAND);
|
| }
|
| DartExpression right;
|
| @@ -1879,7 +1885,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| if (right instanceof DartSuperExpression) {
|
| reportError(position(), ParserErrorCode.SUPER_CANNOT_BE_USED_AS_THE_SECOND_OPERAND);
|
| }
|
| -
|
| +
|
| lastResult = right;
|
| result = doneWithoutConsuming(new DartBinaryExpression(token, result, right));
|
| if ((token == Token.IS)
|
| @@ -1940,9 +1946,11 @@ public class DartParser extends CompletionHooksParserBase {
|
| }
|
| arguments.add(done(expression));
|
| switch(peek(0)) {
|
| + // Must keep in sync with @Terminals above
|
| case COMMA:
|
| consume(Token.COMMA);
|
| break;
|
| + // Must keep in sync with @Terminals above
|
| case RPAREN:
|
| break;
|
| default:
|
| @@ -1972,9 +1980,9 @@ public class DartParser extends CompletionHooksParserBase {
|
| private DartExpression parseConditionalExpression() {
|
| beginConditionalExpression();
|
| DartExpression result = parseBinaryExpression(4);
|
| - if (result instanceof DartSuperExpression) {
|
| + if (result instanceof DartSuperExpression) {
|
| reportError(position(), ParserErrorCode.SUPER_IS_NOT_VALID_ALONE_OR_AS_A_BOOLEAN_OPERAND);
|
| - }
|
| + }
|
| if (peek(0) != Token.CONDITIONAL) {
|
| return done(result);
|
| }
|
| @@ -2078,7 +2086,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| case STRING_SEGMENT:
|
| case STRING_EMBED_EXP_START:
|
| return parseStringInterpolation();
|
| -
|
| +
|
| default:
|
| DartExpression expression = parseExpression();
|
| reportError(position(), ParserErrorCode.EXPECTED_STRING_LITERAL);
|
| @@ -2324,7 +2332,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| ensureAssignable(result);
|
| consume(token);
|
| result = doneWithoutConsuming(new DartUnaryExpression(token, result, false));
|
| - }
|
| + }
|
|
|
| return done(result);
|
| }
|
| @@ -2368,8 +2376,8 @@ public class DartParser extends CompletionHooksParserBase {
|
|
|
| private class DartStringInterpolationBuilder {
|
|
|
| - private List<DartStringLiteral> strings = new ArrayList<DartStringLiteral>();
|
| - private List<DartExpression> expressions = new ArrayList<DartExpression>();
|
| + private final List<DartStringLiteral> strings = new ArrayList<DartStringLiteral>();
|
| + private final List<DartExpression> expressions = new ArrayList<DartExpression>();
|
| private LastSeenNode lastSeen = LastSeenNode.NONE;
|
|
|
| DartStringInterpolationBuilder() {
|
| @@ -2971,7 +2979,7 @@ public class DartParser extends CompletionHooksParserBase {
|
| // Allow recovery back to the top level.
|
| reportErrorWithoutAdvancing(ParserErrorCode.UNEXPECTED_TOKEN);
|
| return done(new DartBlock(new ArrayList<DartStatement>()));
|
| - }
|
| + }
|
| expect(Token.LBRACE);
|
| while (!match(Token.RBRACE) && !EOS()) {
|
| if (looksLikeTopLevelKeyword()) {
|
| @@ -3266,12 +3274,12 @@ public class DartParser extends CompletionHooksParserBase {
|
|
|
| // Things that we know can't be valid statements get a synthetic error statement
|
| case RBRACE:
|
| - case CLASS:
|
| + case CLASS:
|
| // no need to create a separate parser event as the AST node is enough
|
| beginEmptyStatement();
|
| // TODO(jat): other tokens that should be caught here?
|
| return done(parseErrorStatement());
|
| -
|
| +
|
| case IDENTIFIER:
|
| // We have already eliminated function declarations earlier, so check for:
|
| // a) variable declarations;
|
|
|