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