| import java.lang.reflect.Method; |
| import org.checkerframework.framework.testchecker.reflection.qual.ReflectBottom; |
| import org.checkerframework.framework.testchecker.reflection.qual.Sibling1; |
| import org.checkerframework.framework.testchecker.reflection.qual.Sibling2; |
| import org.checkerframework.framework.testchecker.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) |
| @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) |
| m.invoke(anonymous, val1); |
| // TODO: Can we resolve anonymous classes? |
| // :: error: (argument) |
| 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) |
| m.invoke(anonymous, val1); |
| // :: error: (argument) |
| 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) |
| @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()"); |
| } |
| } |
| } |