1.1 --- a/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java Wed Jul 24 17:35:42 2013 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java Thu Jul 25 11:02:27 2013 +0200 1.3 @@ -108,20 +108,38 @@ 1.4 } 1.5 1.6 // Helper to getAnnotation[s] 1.7 - private static <A extends Annotation> Attribute.Compound getAttributeOnClass(ClassSymbol annotated, 1.8 - Class<A> annoType) { 1.9 + private static <A extends Annotation> Attribute.Compound getAttributeOnClass( 1.10 + ClassSymbol annotated, 1.11 + final Class<A> annoType) 1.12 + { 1.13 boolean inherited = annoType.isAnnotationPresent(Inherited.class); 1.14 Attribute.Compound result = null; 1.15 - while (annotated.name != annotated.name.table.names.java_lang_Object) { 1.16 + 1.17 + result = getAttribute(annotated, annoType); 1.18 + if (result != null || !inherited) 1.19 + return result; 1.20 + 1.21 + while ((annotated = nextSupertypeToSearch(annotated)) != null) { 1.22 result = getAttribute(annotated, annoType); 1.23 - if (result != null || !inherited) 1.24 - break; 1.25 - Type sup = annotated.getSuperclass(); 1.26 - if (!sup.hasTag(CLASS) || sup.isErroneous()) 1.27 - break; 1.28 - annotated = (ClassSymbol) sup.tsym; 1.29 + if (result != null) 1.30 + return result; 1.31 } 1.32 - return result; 1.33 + return null; // no more supertypes to search 1.34 + } 1.35 + 1.36 + /** 1.37 + * Returns the next type to search for inherited annotations or {@code null} 1.38 + * if the next type can't be found. 1.39 + */ 1.40 + private static ClassSymbol nextSupertypeToSearch(ClassSymbol annotated) { 1.41 + if (annotated.name == annotated.name.table.names.java_lang_Object) 1.42 + return null; 1.43 + 1.44 + Type sup = annotated.getSuperclass(); 1.45 + if (!sup.hasTag(CLASS) || sup.isErroneous()) 1.46 + return null; 1.47 + 1.48 + return (ClassSymbol) sup.tsym; 1.49 } 1.50 1.51 /** 1.52 @@ -129,8 +147,9 @@ 1.53 * annotations. This is the implementation of 1.54 * Element.getAnnotations(Class). 1.55 */ 1.56 - public static <A extends Annotation> A[] getAnnotations(Symbol annotated, 1.57 - Class<A> annoType) { 1.58 + public static <A extends Annotation> A[] getAnnotationsByType(Symbol annotated, 1.59 + Class<A> annoType) 1.60 + { 1.61 if (!annoType.isAnnotation()) 1.62 throw new IllegalArgumentException("Not an annotation type: " 1.63 + annoType); 1.64 @@ -153,62 +172,48 @@ 1.65 } 1.66 1.67 // So we have a containing type 1.68 - String name = annoType.getName(); 1.69 String annoTypeName = annoType.getSimpleName(); 1.70 String containerTypeName = containerType.getSimpleName(); 1.71 int directIndex = -1, containerIndex = -1; 1.72 Attribute.Compound direct = null, container = null; 1.73 - Attribute.Compound[] rawAttributes = annotated.getRawAttributes().toArray(new Attribute.Compound[0]); 1.74 - 1.75 - // Find directly present annotations 1.76 - for (int i = 0; i < rawAttributes.length; i++) { 1.77 - if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) { 1.78 - directIndex = i; 1.79 - direct = rawAttributes[i]; 1.80 + // Find directly (explicit or implicit) present annotations 1.81 + int index = -1; 1.82 + for (List<Attribute.Compound> list = annotated.getAnnotationMirrors(); 1.83 + !list.isEmpty(); 1.84 + list = list.tail) { 1.85 + Attribute.Compound attribute = list.head; 1.86 + index++; 1.87 + if (attribute.type.tsym.flatName().contentEquals(annoTypeName)) { 1.88 + directIndex = index; 1.89 + direct = attribute; 1.90 } else if(containerTypeName != null && 1.91 - containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) { 1.92 - containerIndex = i; 1.93 - container = rawAttributes[i]; 1.94 + attribute.type.tsym.flatName().contentEquals(containerTypeName)) { 1.95 + containerIndex = index; 1.96 + container = attribute; 1.97 } 1.98 } 1.99 1.100 // Deal with inherited annotations 1.101 - if (annotated.kind == Kinds.TYP && 1.102 - (annotated instanceof ClassSymbol)) { 1.103 - ClassSymbol s = (ClassSymbol)annotated; 1.104 - if (direct == null && container == null) { 1.105 - direct = getAttributeOnClass(s, annoType); 1.106 - container = getAttributeOnClass(s, containerType); 1.107 - 1.108 - // both are inherited and found, put container last 1.109 - if (direct != null && container != null) { 1.110 - directIndex = 0; 1.111 - containerIndex = 1; 1.112 - } else if (direct != null) { 1.113 - directIndex = 0; 1.114 - } else { 1.115 - containerIndex = 0; 1.116 - } 1.117 - } else if (direct == null) { 1.118 - direct = getAttributeOnClass(s, annoType); 1.119 - if (direct != null) 1.120 - directIndex = containerIndex + 1; 1.121 - } else if (container == null) { 1.122 - container = getAttributeOnClass(s, containerType); 1.123 - if (container != null) 1.124 - containerIndex = directIndex + 1; 1.125 + if (direct == null && container == null) { 1.126 + if (annotated.kind == Kinds.TYP && 1.127 + (annotated instanceof ClassSymbol)) { 1.128 + ClassSymbol s = nextSupertypeToSearch((ClassSymbol)annotated); 1.129 + if (s != null) 1.130 + return getAnnotationsByType(s, annoType); 1.131 } 1.132 } 1.133 1.134 // Pack them in an array 1.135 - Attribute[] contained0 = new Attribute[0]; 1.136 + Attribute[] contained0 = null; 1.137 if (container != null) 1.138 contained0 = unpackAttributes(container); 1.139 ListBuffer<Attribute.Compound> compounds = ListBuffer.lb(); 1.140 - for (Attribute a : contained0) 1.141 - if (a instanceof Attribute.Compound) 1.142 - compounds = compounds.append((Attribute.Compound)a); 1.143 - Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]); 1.144 + if (contained0 != null) { 1.145 + for (Attribute a : contained0) 1.146 + if (a instanceof Attribute.Compound) 1.147 + compounds = compounds.append((Attribute.Compound)a); 1.148 + } 1.149 + Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[compounds.size()]); 1.150 1.151 int size = (direct == null ? 0 : 1) + contained.length; 1.152 @SuppressWarnings("unchecked") // annoType is the Class for A 1.153 @@ -298,35 +303,38 @@ 1.154 } 1.155 1.156 // So we have a containing type 1.157 - String name = annoType.getName(); 1.158 String annoTypeName = annoType.getSimpleName(); 1.159 String containerTypeName = containerType.getSimpleName(); 1.160 int directIndex = -1, containerIndex = -1; 1.161 Attribute.Compound direct = null, container = null; 1.162 - Attribute.Compound[] rawAttributes = annotated.getAnnotationMirrors().toArray(new Attribute.Compound[0]); 1.163 - 1.164 - // Find directly present annotations 1.165 - for (int i = 0; i < rawAttributes.length; i++) { 1.166 - if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) { 1.167 - directIndex = i; 1.168 - direct = rawAttributes[i]; 1.169 + // Find directly (explicit or implicit) present annotations 1.170 + int index = -1; 1.171 + for (List<? extends Attribute.Compound> list = annotated.getAnnotationMirrors(); 1.172 + !list.isEmpty(); 1.173 + list = list.tail) { 1.174 + Attribute.Compound attribute = list.head; 1.175 + index++; 1.176 + if (attribute.type.tsym.flatName().contentEquals(annoTypeName)) { 1.177 + directIndex = index; 1.178 + direct = attribute; 1.179 } else if(containerTypeName != null && 1.180 - containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) { 1.181 - containerIndex = i; 1.182 - container = rawAttributes[i]; 1.183 + attribute.type.tsym.flatName().contentEquals(containerTypeName)) { 1.184 + containerIndex = index; 1.185 + container = attribute; 1.186 } 1.187 } 1.188 1.189 // Pack them in an array 1.190 - Attribute[] contained0 = new Attribute[0]; 1.191 + Attribute[] contained0 = null; 1.192 if (container != null) 1.193 contained0 = unpackAttributes(container); 1.194 ListBuffer<Attribute.Compound> compounds = ListBuffer.lb(); 1.195 - for (Attribute a : contained0) { 1.196 - if (a instanceof Attribute.Compound) 1.197 - compounds = compounds.append((Attribute.Compound)a); 1.198 + if (contained0 != null) { 1.199 + for (Attribute a : contained0) 1.200 + if (a instanceof Attribute.Compound) 1.201 + compounds = compounds.append((Attribute.Compound)a); 1.202 } 1.203 - Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]); 1.204 + Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[compounds.size()]); 1.205 1.206 int size = (direct == null ? 0 : 1) + contained.length; 1.207 @SuppressWarnings("unchecked") // annoType is the Class for A