Requiring reference to enums as soon as they are used in annotations reflection
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 03 Feb 2013 23:18:47 +0100
branchreflection
changeset 655044c72732424
parent 654 26a86cc00224
child 658 578cea5b4359
Requiring reference to enums as soon as they are used in annotations
javap/src/main/java/org/apidesign/javap/AnnotationParser.java
vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
vm/src/test/java/org/apidesign/vm4brwsr/Classes.java
vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java
     1.1 --- a/javap/src/main/java/org/apidesign/javap/AnnotationParser.java	Sun Feb 03 22:58:42 2013 +0100
     1.2 +++ b/javap/src/main/java/org/apidesign/javap/AnnotationParser.java	Sun Feb 03 23:18:47 2013 +0100
     1.3 @@ -60,6 +60,12 @@
     1.4      ) throws IOException {
     1.5      }
     1.6      
     1.7 +    protected void visitEnumAttr(
     1.8 +        String annoType, String attr, String attrType, String value
     1.9 +    ) throws IOException {
    1.10 +        visitAttr(annoType, attr, attrType, value);
    1.11 +    }
    1.12 +    
    1.13      /** Initialize the parsing with constant pool from <code>cd</code>.
    1.14       * 
    1.15       * @param attr the attribute defining annotations
    1.16 @@ -130,10 +136,7 @@
    1.17              String attrType = cd.stringValue(enumT, textual);
    1.18              int enumN = dis.readUnsignedShort();
    1.19              String val = cd.stringValue(enumN, textual);
    1.20 -            if (textual) {
    1.21 -                val = "vm." + attrType.substring(1, attrType.length() - 1).replace('/', '_') + "(false).constructor." + val;
    1.22 -            }
    1.23 -            visitAttr(typeName, attrName, attrType, val);
    1.24 +            visitEnumAttr(typeName, attrName, attrType, val);
    1.25          } else {
    1.26              throw new IOException("Unknown type " + type);
    1.27          }
     2.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sun Feb 03 22:58:42 2013 +0100
     2.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sun Feb 03 23:18:47 2013 +0100
     2.3 @@ -1699,7 +1699,7 @@
     2.4          return " = null;";
     2.5      }
     2.6  
     2.7 -    private static void generateAnno(ClassData cd, final Appendable out, byte[] data) throws IOException {
     2.8 +    private void generateAnno(ClassData cd, final Appendable out, byte[] data) throws IOException {
     2.9          AnnotationParser ap = new AnnotationParser(true, false) {
    2.10              int[] cnt = new int[32];
    2.11              int depth;
    2.12 @@ -1749,6 +1749,16 @@
    2.13                  }
    2.14                  out.append(value);
    2.15              }
    2.16 +
    2.17 +            @Override
    2.18 +            protected void visitEnumAttr(String type, String attr, String attrType, String value) 
    2.19 +            throws IOException {
    2.20 +                final String slashType = attrType.substring(1, attrType.length() - 1);
    2.21 +                requireReference(slashType);
    2.22 +                
    2.23 +                out.append(accessClass(slashType.replace('/', '_')))
    2.24 +                   .append("(false).constructor.").append(value);
    2.25 +            }
    2.26          };
    2.27          ap.parse(data, cd);
    2.28      }
     3.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java	Sun Feb 03 22:58:42 2013 +0100
     3.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java	Sun Feb 03 23:18:47 2013 +0100
     3.3 @@ -19,7 +19,6 @@
     3.4  
     3.5  import java.io.IOException;
     3.6  import java.lang.annotation.Annotation;
     3.7 -import java.lang.annotation.ElementType;
     3.8  import java.lang.annotation.Retention;
     3.9  import java.lang.annotation.RetentionPolicy;
    3.10  import java.lang.reflect.Method;
    3.11 @@ -42,9 +41,6 @@
    3.12      }
    3.13      
    3.14      private static final Class<?> PRELOAD = Runnable.class;
    3.15 -    private static final Class<?> PRELOAD2 = ClassesMarker.E.class;
    3.16 -    private static final Class<?> PRELOAD3 = RetentionPolicy.class;
    3.17 -    private static final Class<?> PRELOAD4 = ElementType.class;
    3.18      
    3.19      public static boolean isInterface(String s) throws ClassNotFoundException {
    3.20          return Class.forName(s).isInterface();
     4.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Sun Feb 03 22:58:42 2013 +0100
     4.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Sun Feb 03 23:18:47 2013 +0100
     4.3 @@ -17,6 +17,8 @@
     4.4   */
     4.5  package org.apidesign.bck2brwsr.tck;
     4.6  
     4.7 +import java.lang.annotation.Retention;
     4.8 +import java.lang.annotation.RetentionPolicy;
     4.9  import java.lang.reflect.Method;
    4.10  import java.util.Arrays;
    4.11  import java.util.Collections;
    4.12 @@ -67,6 +69,19 @@
    4.13          }
    4.14          return sb.toString();
    4.15      }
    4.16 +
    4.17 +    @Compare public String namesOfDeclaringClassesOfMethods() {
    4.18 +        StringBuilder sb = new StringBuilder();
    4.19 +        String[] arr = new String[20];
    4.20 +        int i = 0;
    4.21 +        for (Method m : StaticUse.class.getMethods()) {
    4.22 +            arr[i++] = m.getName() + "@" + m.getDeclaringClass().getName();
    4.23 +        }
    4.24 +        for (String s : sort(arr, i)) {
    4.25 +            sb.append(s).append("\n");
    4.26 +        }
    4.27 +        return sb.toString();
    4.28 +    }
    4.29      
    4.30      @Compare public String cannotCallNonStaticMethodWithNull() throws Exception {
    4.31          StaticUse.class.getMethod("instanceMethod").invoke(null);
    4.32 @@ -77,6 +92,17 @@
    4.33          return StaticUse.class.getMethod("instanceMethod").getReturnType();
    4.34      }
    4.35      
    4.36 +    @Retention(RetentionPolicy.RUNTIME)
    4.37 +    @interface Ann {
    4.38 +    }
    4.39 +    
    4.40 +    @Compare public String annoClass() throws Exception {
    4.41 +        Retention r = Ann.class.getAnnotation(Retention.class);
    4.42 +        assert r != null : "Annotation is present";
    4.43 +        assert r.value() == RetentionPolicy.RUNTIME : "Policy value is OK: " + r.value();
    4.44 +        return r.annotationType().getName();
    4.45 +    }
    4.46 +    
    4.47      enum E { A, B };
    4.48      @Compare public boolean isEnum() {
    4.49          return E.A.getClass().isEnum();