Status of retrieving annotations on type parameters?

Joel Borggrén-Franck joel.franck at oracle.com
Thu Mar 28 07:59:37 PDT 2013


Hi All,

On 27 mar 2013, at 09:43, Joel Borggrén-Franck <joel.franck at oracle.com> wrote:
> 
> On 03/26/2013 10:10 PM, Joe Darcy wrote:

>> When using the tip of TL with some local changes, the behavior I'm seeing is
>> that declaration annotations on type parameters are *not* being retrieved
>> from the AnnotedConstruct methods when called on a TypeParameterElement. I
>> wanted to double check if this was the expected behavior right now or if I
>> should continue to look for operator error on my part. (I see there are some
>> langtools tests which reference TYPE_PARAMETER, but I haven't traced through
>> what they test.)
>> 
>> -Joe

This is due to type annotations being stored as

1)  type attributes since they are going to be emitted in Runtime[In}VisibleTypeAnnotations

and

2) the type attributes are stored on the owning class or method symbol.

I made a quick fix for this, see inline patch. I'm not sure this is the proper way and I don't have time at the moment to find out, but if it is urgent to you you should be able to work with this patch. If it isn't that urgent I will fix this week after next.

cheers
/Joel

diff -r 33b6a52f0037 src/share/classes/com/sun/tools/javac/code/Symbol.java
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Mar 26 18:15:24 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Mar 28 15:51:33 2013 +0100
@@ -466,7 +466,7 @@
      * This is the implementation for {@code
      * javax.lang.model.element.Element.getAnnotationMirrors()}.
      */
-    public final List<? extends AnnotationMirror> getAnnotationMirrors() {
+    public List<? extends AnnotationMirror> getAnnotationMirrors() {
         return getRawAttributes();
     }
 
@@ -474,7 +474,7 @@
      * TODO: Should there be a {@code
      * javax.lang.model.element.Element.getTypeAnnotationMirrors()}.
      */
-    public final List<Attribute.TypeCompound> getTypeAnnotationMirrors() {
+    public List<Attribute.TypeCompound> getTypeAnnotationMirrors() {
         return getRawTypeAttributes();
     }
 
@@ -658,6 +658,22 @@
                 return ct.interfaces_field;
             }
         }
+
+        @Override
+        public List<? extends AnnotationMirror> getAnnotationMirrors() {
+            return onlyTypeParameterAnnos(owner.getRawTypeAttributes());
+        }
+ 
+        private List<Attribute.Compound> onlyTypeParameterAnnos(List<Attribute.TypeCompound> candidates) {
+            // Declaration annotations on TypeParameters are stored in type attributes
+            List<Attribute.Compound> res = List.nil();
+            for (Attribute.TypeCompound a : candidates)
+                if (a.position.type == TargetType.CLASS_TYPE_PARAMETER ||
+                    a.position.type == TargetType.METHOD_TYPE_PARAMETER)
+                    res = res.prepend(a);
+
+            return res = res.reverse();
+        }
     }
 
     /** A class for package symbols
diff -r 33b6a52f0037 src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java
--- a/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java	Tue Mar 26 18:15:24 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java	Thu Mar 28 15:51:33 2013 +0100
@@ -33,10 +33,13 @@
 import com.sun.tools.javac.code.Kinds;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.TypeSymbol;
+import com.sun.tools.javac.code.TargetType;
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.code.Type.AnnotatedType;
 import com.sun.tools.javac.util.ListBuffer;
 import static com.sun.tools.javac.code.TypeTag.CLASS;
+import com.sun.tools.javac.util.List;
 
 /**
  * Utility methods for operating on annotated constructs.
@@ -61,8 +64,12 @@
             throw new IllegalArgumentException("Not an annotation type: "
                                                + annoType);
         Attribute.Compound c;
-        if (annotated.kind == Kinds.TYP && annotated instanceof ClassSymbol) {
+        if (annotated.kind == Kinds.TYP &&
+                annotated instanceof ClassSymbol) {
             c = getAttributeOnClass((ClassSymbol)annotated, annoType);
+        } else if (annotated.kind == Kinds.TYP &&
+                   annotated instanceof TypeSymbol) {
+            c = getAttributeOnTypeSym((TypeSymbol)annotated, annoType);
         } else {
             c = getAttribute(annotated, annoType);
         }
@@ -83,8 +90,32 @@
     }
 
     // Helper to getAnnotation[s]
+    private static <A extends Annotation> Attribute.Compound
+            getAttributeOnTypeSym(TypeSymbol annotated, Class<A> annoType) {
+        String name = annoType.getName();
+ 
+        // Declaration annotations on TypeParameters are stored in type attributes
+        // on the owner of the TypeSymbol
+        List<Attribute.Compound> res = List.nil();
+        List<Attribute.TypeCompound> candidates = annotated.owner.getRawTypeAttributes();
+        for (Attribute.TypeCompound a : candidates)
+            if (a.position.type == TargetType.CLASS_TYPE_PARAMETER ||
+                a.position.type == TargetType.METHOD_TYPE_PARAMETER)
+                res = res.prepend(a);
+
+        res = res.reverse();
+
+        for (Attribute.Compound anno : res) {
+            if (name.equals(anno.type.tsym.flatName().toString()))
+                return anno;
+        }
+
+        return null;
+    }
+    
+    // Helper to getAnnotation[s]
     private static <A extends Annotation> Attribute.Compound getAttributeOnClass(ClassSymbol annotated,
-                                                                Class<A> annoType) {
+            Class<A> annoType) {
         boolean inherited = annoType.isAnnotationPresent(Inherited.class);
         Attribute.Compound result = null;
         while (annotated.name != annotated.name.table.names.java_lang_Object) {


More information about the type-annotations-dev mailing list