changeset 1712:867db5e69121

Fix: generalize parser treatment of keyword as identifiers
author mcimadamore
date Wed, 09 Jan 2013 11:43:14 +0100
parents 839d5feb156c
children ff18dac7865e
files src/share/classes/com/sun/tools/javac/parser/JavacParser.java src/share/classes/com/sun/tools/javac/parser/Tokens.java test/tools/javac/lambda/WarnUnderscoreAsIdent.java test/tools/javac/lambda/WarnUnderscoreAsIdent.out
diffstat 4 files changed, 79 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Tue Jan 08 15:24:05 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Jan 09 11:43:14 2013 +0100
@@ -261,40 +261,42 @@
         token = S.token();
     }
 
-    protected boolean peekToken(TokenKind tk) {
+    protected boolean peekToken(Filter<TokenKind> tk) {
         return peekToken(0, tk);
     }
 
-    protected boolean peekToken(int lookahead, TokenKind tk) {
-        return S.token(lookahead + 1).kind == tk;
+    protected boolean peekToken(int lookahead, Filter<TokenKind> tk) {
+        return tk.accepts(S.token(lookahead + 1).kind);
     }
 
-    protected boolean peekToken(TokenKind tk1, TokenKind tk2) {
+    protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
         return peekToken(0, tk1, tk2);
     }
 
-    protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2) {
-        return S.token(lookahead + 1).kind == tk1 &&
-                S.token(lookahead + 2).kind == tk2;
+    protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
+        return tk1.accepts(S.token(lookahead + 1).kind) &&
+                tk2.accepts(S.token(lookahead + 2).kind);
     }
 
-    protected boolean peekToken(TokenKind tk1, TokenKind tk2, TokenKind tk3) {
+    protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
         return peekToken(0, tk1, tk2, tk3);
     }
 
-    protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2, TokenKind tk3) {
-        return S.token(lookahead + 1).kind == tk1 &&
-                S.token(lookahead + 2).kind == tk2 &&
-                S.token(lookahead + 3).kind == tk3;
+    protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
+        return tk1.accepts(S.token(lookahead + 1).kind) &&
+                tk2.accepts(S.token(lookahead + 2).kind) &&
+                tk3.accepts(S.token(lookahead + 3).kind);
     }
 
-    protected boolean peekToken(TokenKind... kinds) {
+    @SuppressWarnings("unchecked")
+    protected boolean peekToken(Filter<TokenKind>... kinds) {
         return peekToken(0, kinds);
     }
 
-    protected boolean peekToken(int lookahead, TokenKind... kinds) {
+    @SuppressWarnings("unchecked")
+    protected boolean peekToken(int lookahead, Filter<TokenKind>... kinds) {
         for (; lookahead < kinds.length ; lookahead++) {
-            if (S.token(lookahead + 1).kind != kinds[lookahead]) {
+            if (!kinds[lookahead].accepts(S.token(lookahead + 1).kind)) {
                 return false;
             }
         }
@@ -349,6 +351,7 @@
                     if (stopAtMemberDecl)
                         return;
                     break;
+                case UNDERSCORE:
                 case IDENTIFIER:
                    if (stopAtIdentifier)
                         return;
@@ -577,7 +580,7 @@
             accept(IDENTIFIER);
             return names.error;
         }
-}
+    }
 
     /**
      * Qualident = Ident { DOT Ident }
@@ -1301,7 +1304,7 @@
         int pos = 0, depth = 0;
         for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
             switch (t.kind) {
-                case IDENTIFIER: case QUES: case EXTENDS: case SUPER:
+                case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
                 case DOUBLE: case BOOLEAN: case CHAR:
@@ -1350,8 +1353,8 @@
                     if (peekToken(lookahead, RPAREN)) {
                         //Type, ')' -> cast
                         return ParensResult.CAST;
-                    } else if (peekToken(lookahead, IDENTIFIER)) {
-                        //Type, 'Identifier -> explicit lambda
+                    } else if (peekToken(lookahead, EXT_IDENTIFIER)) {
+                        //Type, 'Identifier/'_' -> explicit lambda
                         return ParensResult.EXPLICIT_LAMBDA;
                     }
                     break;
@@ -1384,30 +1387,25 @@
                         default:
                             return ParensResult.PARENS;
                     }
+                case UNDERSCORE:
+                case ASSERT:
+                case ENUM:
                 case IDENTIFIER:
-                    if (peekToken(lookahead, IDENTIFIER) ||
-                            peekToken(lookahead, UNDERSCORE)) {
-                        // Identifier, Identifier/'_' -> explicit lambda
+                    if (peekToken(lookahead, EXT_IDENTIFIER)) {
+                        // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
                         return ParensResult.EXPLICIT_LAMBDA;
                     } else if (peekToken(lookahead, RPAREN, ARROW)) {
                         // Identifier, ')' '->' -> implicit lambda
                         return ParensResult.IMPLICIT_LAMBDA;
                     }
                     break;
-                case UNDERSCORE:
-                    if (peekToken(lookahead, RPAREN, ARROW)) {
-                        // '_', ')' '->' -> implicit lambda
-                        return ParensResult.IMPLICIT_LAMBDA;
-                    }
-                    break;
                 case FINAL:
                 case ELLIPSIS:
                 case MONKEYS_AT:
                     //those can only appear in explicit lambdas
                     return ParensResult.EXPLICIT_LAMBDA;
                 case LBRACKET:
-                    if (peekToken(lookahead, RBRACKET, IDENTIFIER) ||
-                            peekToken(lookahead, RBRACKET, UNDERSCORE)) {
+                    if (peekToken(lookahead, RBRACKET, EXT_IDENTIFIER)) {
                         // '[', ']', Identifier/'_' -> explicit lambda
                         return ParensResult.EXPLICIT_LAMBDA;
                     } else if (peekToken(lookahead, RBRACKET, RPAREN) ||
@@ -1437,13 +1435,11 @@
                             // '>', ')' -> cast
                             // '>', '&' -> cast
                             return ParensResult.CAST;
-                        } else if (peekToken(lookahead, IDENTIFIER, COMMA) ||
-                                peekToken(lookahead, UNDERSCORE, COMMA) ||
-                                peekToken(lookahead, IDENTIFIER, RPAREN, ARROW) ||
-                                peekToken(lookahead, UNDERSCORE, RPAREN, ARROW) ||
+                        } else if (peekToken(lookahead, EXT_IDENTIFIER, COMMA) ||
+                                peekToken(lookahead, EXT_IDENTIFIER, RPAREN, ARROW) ||
                                 peekToken(lookahead, ELLIPSIS)) {
-                            // '>', Identifier/'_', ',' -> explicit lambda
-                            // '>', Identifier/'_', ')', '->' -> explicit lambda
+                            // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
+                            // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
                             // '>', '...' -> explicit lambda
                             return ParensResult.EXPLICIT_LAMBDA;
                         }
@@ -1462,6 +1458,12 @@
             }
         }
     }
+    
+    Filter<TokenKind> EXT_IDENTIFIER = new Filter<TokenKind>() {
+        public boolean accepts(TokenKind t) {
+            return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
+        }
+    };
 
     enum ParensResult {
         CAST,
@@ -1653,7 +1655,7 @@
             nextToken();
             JCExpression bound = parseType();
             return F.at(pos).Wildcard(t, bound);
-        } else if (token.kind == IDENTIFIER) {
+        } else if (EXT_IDENTIFIER.accepts(token.kind)) {
             //error recovery
             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
             JCExpression wc = toP(F.at(pos).Wildcard(t, null));
@@ -1703,7 +1705,7 @@
             if (token.pos == endPosTable.errorEndPos) {
                 // error recovery
                 Name name = null;
-                if (token.kind == IDENTIFIER) {
+                if (EXT_IDENTIFIER.accepts(token.kind)) {
                     name = token.name();
                     nextToken();
                 } else {
@@ -2051,10 +2053,7 @@
                 nextToken();
                 JCStatement stat = parseStatement();
                 return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
-            } else if ((lastmode & TYPE) != 0 &&
-                       (token.kind == IDENTIFIER ||
-                        token.kind == ASSERT ||
-                        token.kind == ENUM)) {
+            } else if ((lastmode & TYPE) != 0 && EXT_IDENTIFIER.accepts(token.kind)) {
                 pos = token.pos;
                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
                 F.at(pos);
@@ -2208,14 +2207,14 @@
         }
         case BREAK: {
             nextToken();
-            Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM || token.kind == UNDERSCORE) ? ident() : null;
+            Name label = EXT_IDENTIFIER.accepts(token.kind) ? ident() : null;
             JCBreak t = to(F.at(pos).Break(label));
             accept(SEMI);
             return t;
         }
         case CONTINUE: {
             nextToken();
-            Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM || token.kind == UNDERSCORE) ? ident() : null;
+            Name label = EXT_IDENTIFIER.accepts(token.kind) ? ident() : null;
             JCContinue t =  to(F.at(pos).Continue(label));
             accept(SEMI);
             return t;
@@ -2376,9 +2375,7 @@
             return variableDeclarators(optFinal(0), parseType(), stats).toList();
         } else {
             JCExpression t = term(EXPR | TYPE);
-            if ((lastmode & TYPE) != 0 &&
-                (token.kind == IDENTIFIER || token.kind == ASSERT ||
-                 token.kind == ENUM || token.kind == UNDERSCORE)) {
+            if ((lastmode & TYPE) != 0 && EXT_IDENTIFIER.accepts(token.kind)) {
                 return variableDeclarators(modifiersOpt(), t, stats).toList();
             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
                 error(pos, "bad.initializer", "for-loop");
@@ -2701,7 +2698,7 @@
             mods = modifiersOpt(true);
 
         if (token.kind == PACKAGE) {
-            if (peekToken(IDENTIFIER)) {
+            if (peekToken(EXT_IDENTIFIER)) {
                 seenPackage = true;
                 if (mods != null) {
                     checkNoMods(mods.flags);
@@ -2813,7 +2810,7 @@
             } else {
                 int pos = token.pos;
                 List<JCTree> errs;
-                if (token.kind == IDENTIFIER) {
+                if (EXT_IDENTIFIER.accepts(token.kind)) {
                     errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
                     setErrorEndPos(token.pos);
                 } else {
@@ -2830,7 +2827,7 @@
             }
             int pos = token.pos;
             List<JCTree> errs;
-            if (token.kind == IDENTIFIER) {
+            if (EXT_IDENTIFIER.accepts(token.kind)) {
                 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
                 setErrorEndPos(token.pos);
             } else {
@@ -3241,7 +3238,7 @@
             params.append(lastParam = formalParameter(lambdaParameters));
             while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
                 nextToken();
-                params.append(lastParam = formalParameter());
+                params.append(lastParam = formalParameter(lambdaParameters));
             }
         }
         accept(RPAREN);
--- a/src/share/classes/com/sun/tools/javac/parser/Tokens.java	Tue Jan 08 15:24:05 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/parser/Tokens.java	Wed Jan 09 11:43:14 2013 +0100
@@ -33,6 +33,7 @@
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Filter;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Names;
 
@@ -112,7 +113,7 @@
      * This enum defines all tokens used by the javac scanner. A token is
      * optionally associated with a name.
      */
-    public enum TokenKind implements Formattable {
+    public enum TokenKind implements Formattable, Filter<TokenKind> {
         EOF(),
         ERROR(),
         IDENTIFIER(Tag.NAMED),
@@ -283,6 +284,11 @@
         public String toString(Locale locale, Messages messages) {
             return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString());
         }
+
+        @Override
+        public boolean accepts(TokenKind that) {
+            return this == that;
+        }
     }
 
     public interface Comment {
--- a/test/tools/javac/lambda/WarnUnderscoreAsIdent.java	Tue Jan 08 15:24:05 2013 +0100
+++ b/test/tools/javac/lambda/WarnUnderscoreAsIdent.java	Wed Jan 09 11:43:14 2013 +0100
@@ -26,9 +26,16 @@
  * @summary Check usages of underscore as identifier generate warnings
  * @compile/fail/ref=WarnUnderscoreAsIdent.out -XDrawDiagnostics -Werror WarnUnderscoreAsIdent.java
  */
+package _._;
+
+import _._;
+
 class _ {
     String _ = null;
     void _(String _) { }
+    void testLocal() {
+        String _ = null;
+    }
     void testFor() {
         for (int _ = 0; _ < 10; _++);
     }
--- a/test/tools/javac/lambda/WarnUnderscoreAsIdent.out	Tue Jan 08 15:24:05 2013 +0100
+++ b/test/tools/javac/lambda/WarnUnderscoreAsIdent.out	Wed Jan 09 11:43:14 2013 +0100
@@ -1,15 +1,20 @@
-WarnUnderscoreAsIdent.java:29:7: compiler.warn.underscore.as.identifier
-WarnUnderscoreAsIdent.java:30:12: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:29:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:29:11: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:31:8: compiler.warn.underscore.as.identifier
 WarnUnderscoreAsIdent.java:31:10: compiler.warn.underscore.as.identifier
-WarnUnderscoreAsIdent.java:31:19: compiler.warn.underscore.as.identifier
-WarnUnderscoreAsIdent.java:33:18: compiler.warn.underscore.as.identifier
-WarnUnderscoreAsIdent.java:33:25: compiler.warn.underscore.as.identifier
-WarnUnderscoreAsIdent.java:33:33: compiler.warn.underscore.as.identifier
-WarnUnderscoreAsIdent.java:36:34: compiler.warn.underscore.as.identifier
-WarnUnderscoreAsIdent.java:39:9: compiler.warn.underscore.as.identifier
-WarnUnderscoreAsIdent.java:41:19: compiler.warn.underscore.as.identifier
-WarnUnderscoreAsIdent.java:43:9: compiler.warn.underscore.as.identifier
-WarnUnderscoreAsIdent.java:45:22: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:33:7: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:34:12: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:35:10: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:35:19: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:37:16: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:18: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:25: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:33: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:43:34: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:46:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:48:19: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:50:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:52:22: compiler.warn.underscore.as.identifier
 - compiler.err.warnings.and.werror
 1 error
-12 warnings
+17 warnings