1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
import java.lang.reflect.Method;
import testlib.reflection.qual.ReflectBottom;
import testlib.reflection.qual.Sibling1;
import testlib.reflection.qual.Sibling2;
import testlib.reflection.qual.Top;
public class AnonymousClassTest {
/**
* To build/run outside of the JUnit tests:
*
* <p>Build with $CHECKERFRAMEWOKR/framework/tests/build/ on the classpath. Need to either use
* Java 8 or the langtools compiler, because annotations on cast are used.
*
* <p>java AnonymousClassTest MyClass$1.getSib1() MyClass$1.setSib1() MyClass$1.setSib1()
* MyClass$1.setSib2() MyClass$1.setSib2() MyClass$1.getSib2()
*/
public static void main(String[] args) {
AnonymousClassTest act = new AnonymousClassTest();
act.returnTypePass();
act.argumentTypePass();
act.argumentTypeFail();
act.returnTypeFail();
}
@Sibling1 int sibling1;
@Sibling2 int sibling2;
public void returnTypePass() {
try {
Class<?> c = Class.forName("AnonymousClassTest$1");
Method m = c.getMethod("getSib1", new Class[] {});
// TODO: Can we resolve anonymous classes?
// :: error: (assignment.type.incompatible)
@Sibling1 Object a = m.invoke(anonymous, (@ReflectBottom Object[]) null);
} catch (Exception ignore) {
ignore.printStackTrace();
}
}
public void argumentTypePass() {
String str = "setSib1";
@Sibling1 int val1 = sibling1;
@Sibling1 Integer val2 = val1;
try {
Class<?> c = Class.forName("AnonymousClassTest$1");
Method m = c.getMethod(str, new Class[] {int.class});
// TODO: Can we resolve anonymous classes?
// :: error: (argument.type.incompatible)
m.invoke(anonymous, val1);
// TODO: Can we resolve anonymous classes?
// :: error: (argument.type.incompatible)
m.invoke(anonymous, val2);
} catch (Exception ignore) {
ignore.printStackTrace();
}
}
public void argumentTypeFail() {
String str = "setSib2";
@Sibling1 int val1 = sibling1;
@Sibling1 Integer val2 = val1;
try {
Class<?> c = Class.forName("AnonymousClassTest$1");
Method m = c.getMethod(str, new Class[] {int.class});
// :: error: (argument.type.incompatible)
m.invoke(anonymous, val1);
// :: error: (argument.type.incompatible)
m.invoke(anonymous, val2);
} catch (Exception ignore) {
ignore.printStackTrace();
}
}
public void returnTypeFail() {
try {
Class<?> c = Class.forName("AnonymousClassTest$1");
Method m = c.getMethod("getSib2", new Class[] {});
// :: error: (assignment.type.incompatible)
@Sibling1 Object a = m.invoke(anonymous, (@ReflectBottom Object[]) null);
} catch (Exception ignore) {
ignore.printStackTrace();
}
}
public @ReflectBottom MyClass anonymous =
// :: warning: (cast.unsafe.constructor.invocation)
new @ReflectBottom MyClass() {
public @Sibling1 int getSib1() {
System.out.println("MyClass$1.getSib1()");
return 1;
}
public @Sibling2 int getSib2() {
System.out.println("MyClass$1.getSib2()");
return 1;
}
public void setSib1(@Sibling1 int a) {
System.out.println("MyClass$1.setSib1()");
}
public void setSib2(@Sibling2 int a) {
System.out.println("MyClass$1.setSib2()");
}
};
class MyClass {
public @Top int getSib1() {
System.out.println("MyClass.getSib1()");
return 1;
}
public @Top int getSib2() {
System.out.println("MyClass.getSib1()");
return 1;
}
public void setSib1(@ReflectBottom int a) {
System.out.println("MyClass.setSib1()");
}
public void setSib2(@ReflectBottom int a) {
System.out.println("MyClass.setSib2()");
}
}
}
|