changeset 69:ba0c588680a8

Resolved some cases that would cause a failure to parse or a crash in semantic processing of eta expansion expressions in which the qualifying type has a wildcard argument.
author gafter
date Mon, 07 Jul 2008 23:45:47 -0700
parents e7a8bdf18063
children 7ad432c709e6
files src/share/classes/com/sun/tools/javac/comp/DeClosure.java src/share/classes/com/sun/tools/javac/parser/Parser.java test/tools/javac/closures/ParseEta.java
diffstat 3 files changed, 31 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/DeClosure.java	Mon Jul 07 00:51:51 2008 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/DeClosure.java	Mon Jul 07 23:45:47 2008 -0700
@@ -165,13 +165,17 @@
             }
         }
 
-        @Override
-        public void visitLambda(JCLambda tree) {
+        private void retypeClosure(JCTree tree) {
             // If it hasn't been given a type yet, use the natural function
             // type for the lambda.
             if (tree.type.tag == TypeTags.METHOD) {
                 tree.type = ftypes.typeFor((MethodType)tree.type, true);
             }
+        }
+
+        @Override
+        public void visitLambda(JCLambda tree) {
+            retypeClosure(tree);
             if (tree.result != null) {
                 List<Type> resultType = List.nil();
                 for (MethodSymbol abs : types.findUniqueAbstracts((ClassType)tree.type)) {
@@ -206,6 +210,7 @@
 
         @Override
         public void visitEtaExpansion(JCEtaExpansion tree) {
+            retypeClosure(tree);
             super.visitEtaExpansion(tree);
             translationNeeded = true;
         }
--- a/src/share/classes/com/sun/tools/javac/parser/Parser.java	Mon Jul 07 00:51:51 2008 -0700
+++ b/src/share/classes/com/sun/tools/javac/parser/Parser.java	Mon Jul 07 23:45:47 2008 -0700
@@ -1499,7 +1499,16 @@
         top: switch (S.token()) {
             case LBRACE:
                 if (!skipLambdaOrFunction(false)) return false;
-                break top;
+                break;
+            case QUES:
+                S.nextToken();
+                switch (S.token()) {
+                    case EXTENDS: case SUPER:
+                        S.nextToken();
+                        if (!skipType()) return false;
+                        break;
+                }
+                break;
             case IDENTIFIER:
                 S.nextToken();
                 while (true) {
@@ -1539,8 +1548,15 @@
         } else if (allowClosures && (mode & EXPR) != 0) {
             // check to see if we have type arguments followed by . or #.
             Token afterArgs = peekTypeArguments();
-            if (afterArgs == DOT || afterArgs == OCTOTHORPE || afterArgs == LBRACKET)
-                return typeArguments(t);
+            if (afterArgs == DOT || afterArgs == OCTOTHORPE || afterArgs == LBRACKET) {
+                int oldMode = mode;
+                try {
+                    mode |= TYPE;
+                    return typeArguments(t);
+                } finally {
+                    mode = oldMode;
+                }
+            }
         }
         return t;
     }
@@ -1569,11 +1585,11 @@
         if (S.token() == LT) {
             S.nextToken();
             args.append((S.token() == THROWS) ? disjunctivExceptionType() :
-			((mode & EXPR) == 0) ? typeArgument() : type());
+			((mode & TYPE) != 0) ? typeArgument() : type());
             while (S.token() == COMMA) {
                 S.nextToken();
                 args.append((S.token() == THROWS) ? disjunctivExceptionType() :
-			    ((mode & EXPR) == 0) ? typeArgument() : type());
+			    ((mode & TYPE) != 0) ? typeArgument() : type());
             }
             switch (S.token()) {
             case GTGTGTEQ:
--- a/test/tools/javac/closures/ParseEta.java	Mon Jul 07 00:51:51 2008 -0700
+++ b/test/tools/javac/closures/ParseEta.java	Mon Jul 07 23:45:47 2008 -0700
@@ -45,6 +45,9 @@
 	Object o4 = Outer<Outer<String>>.Inner<Integer>[]#getClass();
 	Object o5 = {=>Outer.Inner}#getClass();
 	Outer<Outer<String>>[]#getClass().invoke(null);
+
+	Object o6 = Outer<Integer>#getClass();
+	Object o7 = Outer<?>#getClass();
     }
 
     public static void main(String[] args) throws Exception {