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 =
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()");
}
}
}