Captured wildcards

Jan Lahoda jan.lahoda at oracle.com
Thu Mar 19 11:28:31 UTC 2015


Hello,

Assume this declaration:
List<? extends String> list = Arrays.asList("a");

This expression fails:
-> list.iterator().next()
|  Error:
|  illegal start of type
|  list.iterator().next()
|  ^

The reason is that "? extends String" is used as the type of the 
expression, instead of "String":
---
package REPL;
import java.util.regex.*;import java.util.*;import 
java.util.concurrent.*;import java.util.prefs.*;import java.net.*;import 
java.io.*;import java.math.*;import static REPL.$REPL8.printf;
import static REPL.$REPL9.list;
public class $REPL11 {
     public static
     ? extends String $2;
     public static Object do_it$() throws Throwable {
         return $2 =
         list.iterator().next();
     }
}
---

Attached is a possible fix - what do you think?

Thanks,
     Jan
-------------- next part --------------
# HG changeset patch
# Parent 083645ec502a473bca67a524385a18a8d21f0951
diff -r 083645ec502a -r 34f1d952e2d6 repl/src/impl/TreeDissector.java
--- a/repl/src/impl/TreeDissector.java	Wed Mar 18 13:53:15 2015 -0700
+++ b/repl/src/impl/TreeDissector.java	Thu Mar 19 12:13:47 2015 +0100
@@ -203,8 +203,9 @@
                 if (viPath != null) {
                     TypeMirror tm = trees().getTypeMirror(viPath);
                     if (tm != null) {
-                        TypePrinter tp = new TypePrinter(messages, fullClassNameAndPackageToClass);
-                        ei.typeName = tp.visit((Type)tm, Locale.getDefault());
+                        Type type = (Type)tm;
+                        TypePrinter tp = new TypePrinter(messages, fullClassNameAndPackageToClass, type);
+                        ei.typeName = tp.visit(type, Locale.getDefault());
                         switch (tm.getKind()) {
                             case VOID:
                             case NONE:
diff -r 083645ec502a -r 34f1d952e2d6 repl/src/impl/TypePrinter.java
--- a/repl/src/impl/TypePrinter.java	Wed Mar 18 13:53:15 2015 -0700
+++ b/repl/src/impl/TypePrinter.java	Thu Mar 19 12:13:47 2015 +0100
@@ -41,10 +41,12 @@
 
     private final JavacMessages messages;
     private final BinaryOperator<String> fullClassNameAndPackageToClass;
+    private final Type typeToPrint;
 
-    TypePrinter(JavacMessages messages, BinaryOperator<String> fullClassNameAndPackageToClass) {
+    TypePrinter(JavacMessages messages, BinaryOperator<String> fullClassNameAndPackageToClass, Type typeToPrint) {
         this.messages = messages;
         this.fullClassNameAndPackageToClass = fullClassNameAndPackageToClass;
+        this.typeToPrint = typeToPrint;
     }
 
     @Override
@@ -59,7 +61,15 @@
 
     @Override
     public String visitCapturedType(Type.CapturedType t, Locale locale) {
-        return visit(t.wildcard, locale);
+        if (t == typeToPrint) {
+            if (t.wildcard.getExtendsBound() != null) {
+                return visit(t.wildcard.getExtendsBound(), locale);
+            } else {
+                return "Object";
+            }
+        } else {
+            return visit(t.wildcard, locale);
+        }
     }
 
     @Override
diff -r 083645ec502a -r 34f1d952e2d6 repl/testng/test/TypeNameTest.java
--- a/repl/testng/test/TypeNameTest.java	Wed Mar 18 13:53:15 2015 -0700
+++ b/repl/testng/test/TypeNameTest.java	Thu Mar 19 12:13:47 2015 +0100
@@ -68,4 +68,15 @@
         assertEquals(sn.typeName(), "java.lang.reflect.Method");
     }
     
+    public void testBounds() {
+        assertEval1("java.util.List<? extends String> list1 = java.util.Arrays.asList(\"\");");
+        VarInfo sn1 = (VarInfo) assertEval1("list1.iterator().next()");
+        assertEquals(sn1.typeName(), "String");
+        assertEval1("java.util.List<? super String> list2 = java.util.Arrays.asList(\"\");");
+        VarInfo sn2 = (VarInfo) assertEval1("list2.iterator().next()");
+        assertEquals(sn2.typeName(), "Object");
+        assertEval1("java.util.List<?> list3 = java.util.Arrays.asList(\"\");");
+        VarInfo sn3 = (VarInfo) assertEval1("list3.iterator().next()");
+        assertEquals(sn3.typeName(), "Object");
+    }
 }


More information about the kulla-dev mailing list