author | martin |
Thu, 06 Nov 2014 13:18:44 -0800 | |
changeset 27489 | cf53b2c02ebb |
parent 25859 | 3317bb8137f4 |
child 28056 | 0cab6eb92852 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
15510
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
2 |
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package sun.reflect.generics.reflectiveObjects; |
|
27 |
||
15510
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
28 |
import java.lang.annotation.*; |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
29 |
import java.lang.reflect.AnnotatedType; |
14676
985410ec95e3
7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents:
14342
diff
changeset
|
30 |
import java.lang.reflect.Array; |
22323 | 31 |
import java.lang.reflect.Constructor; |
2 | 32 |
import java.lang.reflect.GenericDeclaration; |
22323 | 33 |
import java.lang.reflect.Member; |
34 |
import java.lang.reflect.Method; |
|
2 | 35 |
import java.lang.reflect.Type; |
36 |
import java.lang.reflect.TypeVariable; |
|
15510
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
37 |
import java.util.LinkedHashMap; |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
38 |
import java.util.Map; |
10433
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
39 |
import java.util.Objects; |
15510
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
40 |
import sun.reflect.annotation.AnnotationSupport; |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
41 |
import sun.reflect.annotation.TypeAnnotationParser; |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
42 |
import sun.reflect.annotation.AnnotationType; |
2 | 43 |
import sun.reflect.generics.factory.GenericsFactory; |
44 |
import sun.reflect.generics.tree.FieldTypeSignature; |
|
45 |
import sun.reflect.generics.visitor.Reifier; |
|
22323 | 46 |
import sun.reflect.misc.ReflectUtil; |
2 | 47 |
|
48 |
/** |
|
49 |
* Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface |
|
50 |
* for core reflection. |
|
51 |
*/ |
|
52 |
public class TypeVariableImpl<D extends GenericDeclaration> |
|
53 |
extends LazyReflectiveObjectGenerator implements TypeVariable<D> { |
|
54 |
D genericDeclaration; |
|
55 |
private String name; |
|
56 |
// upper bounds - evaluated lazily |
|
57 |
private Type[] bounds; |
|
58 |
||
59 |
// The ASTs for the bounds. We are required to evaluate the bounds |
|
60 |
// lazily, so we store these at least until we are first asked |
|
61 |
// for the bounds. This also neatly solves the |
|
62 |
// problem with F-bounds - you can't reify them before the formal |
|
63 |
// is defined. |
|
64 |
private FieldTypeSignature[] boundASTs; |
|
65 |
||
66 |
// constructor is private to enforce access through static factory |
|
67 |
private TypeVariableImpl(D decl, String n, FieldTypeSignature[] bs, |
|
68 |
GenericsFactory f) { |
|
69 |
super(f); |
|
70 |
genericDeclaration = decl; |
|
71 |
name = n; |
|
72 |
boundASTs = bs; |
|
73 |
} |
|
74 |
||
75 |
// Accessors |
|
76 |
||
77 |
// accessor for ASTs for bounds. Must not be called after |
|
78 |
// bounds have been evaluated, because we might throw the ASTs |
|
79 |
// away (but that is not thread-safe, is it?) |
|
80 |
private FieldTypeSignature[] getBoundASTs() { |
|
81 |
// check that bounds were not evaluated yet |
|
82 |
assert(bounds == null); |
|
83 |
return boundASTs; |
|
84 |
} |
|
85 |
||
86 |
/** |
|
87 |
* Factory method. |
|
88 |
* @param decl - the reflective object that declared the type variable |
|
89 |
* that this method should create |
|
90 |
* @param name - the name of the type variable to be returned |
|
91 |
* @param bs - an array of ASTs representing the bounds for the type |
|
92 |
* variable to be created |
|
93 |
* @param f - a factory that can be used to manufacture reflective |
|
94 |
* objects that represent the bounds of this type variable |
|
95 |
* @return A type variable with name, bounds, declaration and factory |
|
96 |
* specified |
|
97 |
*/ |
|
98 |
public static <T extends GenericDeclaration> |
|
99 |
TypeVariableImpl<T> make(T decl, String name, |
|
100 |
FieldTypeSignature[] bs, |
|
101 |
GenericsFactory f) { |
|
22323 | 102 |
|
103 |
if (!((decl instanceof Class) || |
|
104 |
(decl instanceof Method) || |
|
105 |
(decl instanceof Constructor))) { |
|
106 |
throw new AssertionError("Unexpected kind of GenericDeclaration" + |
|
107 |
decl.getClass().toString()); |
|
108 |
} |
|
2 | 109 |
return new TypeVariableImpl<T>(decl, name, bs, f); |
110 |
} |
|
111 |
||
112 |
||
113 |
/** |
|
114 |
* Returns an array of <tt>Type</tt> objects representing the |
|
115 |
* upper bound(s) of this type variable. Note that if no upper bound is |
|
116 |
* explicitly declared, the upper bound is <tt>Object</tt>. |
|
117 |
* |
|
118 |
* <p>For each upper bound B: |
|
119 |
* <ul> |
|
120 |
* <li>if B is a parameterized type or a type variable, it is created, |
|
121 |
* (see {@link #ParameterizedType} for the details of the creation |
|
122 |
* process for parameterized types). |
|
123 |
* <li>Otherwise, B is resolved. |
|
124 |
* </ul> |
|
125 |
* |
|
126 |
* @throws <tt>TypeNotPresentException</tt> if any of the |
|
127 |
* bounds refers to a non-existent type declaration |
|
128 |
* @throws <tt>MalformedParameterizedTypeException</tt> if any of the |
|
129 |
* bounds refer to a parameterized type that cannot be instantiated |
|
130 |
* for any reason |
|
131 |
* @return an array of Types representing the upper bound(s) of this |
|
132 |
* type variable |
|
133 |
*/ |
|
134 |
public Type[] getBounds() { |
|
135 |
// lazily initialize bounds if necessary |
|
136 |
if (bounds == null) { |
|
137 |
FieldTypeSignature[] fts = getBoundASTs(); // get AST |
|
138 |
// allocate result array; note that |
|
139 |
// keeping ts and bounds separate helps with threads |
|
140 |
Type[] ts = new Type[fts.length]; |
|
141 |
// iterate over bound trees, reifying each in turn |
|
142 |
for ( int j = 0; j < fts.length; j++) { |
|
143 |
Reifier r = getReifier(); |
|
144 |
fts[j].accept(r); |
|
145 |
ts[j] = r.getResult(); |
|
146 |
} |
|
147 |
// cache result |
|
148 |
bounds = ts; |
|
149 |
// could throw away bound ASTs here; thread safety? |
|
150 |
} |
|
151 |
return bounds.clone(); // return cached bounds |
|
152 |
} |
|
153 |
||
154 |
/** |
|
155 |
* Returns the <tt>GenericDeclaration</tt> object representing the |
|
156 |
* generic declaration that declared this type variable. |
|
157 |
* |
|
158 |
* @return the generic declaration that declared this type variable. |
|
159 |
* |
|
160 |
* @since 1.5 |
|
161 |
*/ |
|
162 |
public D getGenericDeclaration(){ |
|
22323 | 163 |
if (genericDeclaration instanceof Class) |
164 |
ReflectUtil.checkPackageAccess((Class)genericDeclaration); |
|
165 |
else if ((genericDeclaration instanceof Method) || |
|
166 |
(genericDeclaration instanceof Constructor)) |
|
167 |
ReflectUtil.conservativeCheckMemberAccess((Member)genericDeclaration); |
|
168 |
else |
|
169 |
throw new AssertionError("Unexpected kind of GenericDeclaration"); |
|
2 | 170 |
return genericDeclaration; |
171 |
} |
|
172 |
||
173 |
||
174 |
/** |
|
175 |
* Returns the name of this type variable, as it occurs in the source code. |
|
176 |
* |
|
177 |
* @return the name of this type variable, as it appears in the source code |
|
178 |
*/ |
|
179 |
public String getName() { return name; } |
|
180 |
||
181 |
public String toString() {return getName();} |
|
182 |
||
183 |
@Override |
|
184 |
public boolean equals(Object o) { |
|
22323 | 185 |
if (o instanceof TypeVariable && |
186 |
o.getClass() == TypeVariableImpl.class) { |
|
10342
ca0984bc9d32
7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
187 |
TypeVariable<?> that = (TypeVariable<?>) o; |
2 | 188 |
|
189 |
GenericDeclaration thatDecl = that.getGenericDeclaration(); |
|
190 |
String thatName = that.getName(); |
|
191 |
||
17456
0f2c187cd188
8014357: Minor refactorings to sun.reflect.generics.reflectiveObjects.*
darcy
parents:
15659
diff
changeset
|
192 |
return Objects.equals(genericDeclaration, thatDecl) && |
0f2c187cd188
8014357: Minor refactorings to sun.reflect.generics.reflectiveObjects.*
darcy
parents:
15659
diff
changeset
|
193 |
Objects.equals(name, thatName); |
2 | 194 |
|
195 |
} else |
|
196 |
return false; |
|
197 |
} |
|
198 |
||
199 |
@Override |
|
200 |
public int hashCode() { |
|
201 |
return genericDeclaration.hashCode() ^ name.hashCode(); |
|
202 |
} |
|
10433
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
203 |
|
15510
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
204 |
// Implementations of AnnotatedElement methods. |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
205 |
@SuppressWarnings("unchecked") |
10433
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
206 |
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { |
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
207 |
Objects.requireNonNull(annotationClass); |
15510
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
208 |
// T is an Annotation type, the return value of get will be an annotation |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
209 |
return (T)mapAnnotations(getAnnotations()).get(annotationClass); |
10433
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
210 |
} |
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
211 |
|
14676
985410ec95e3
7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents:
14342
diff
changeset
|
212 |
public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) { |
985410ec95e3
7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents:
14342
diff
changeset
|
213 |
Objects.requireNonNull(annotationClass); |
15510
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
214 |
return getAnnotation(annotationClass); |
14676
985410ec95e3
7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents:
14342
diff
changeset
|
215 |
} |
985410ec95e3
7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents:
14342
diff
changeset
|
216 |
|
15659
e575dab44ff5
8007278: Rename j.l.r.AnnotatedElement.getAnnotations(Class) to getAnnotationsByType(Class)
jfranck
parents:
15534
diff
changeset
|
217 |
@Override |
e575dab44ff5
8007278: Rename j.l.r.AnnotatedElement.getAnnotations(Class) to getAnnotationsByType(Class)
jfranck
parents:
15534
diff
changeset
|
218 |
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) { |
14676
985410ec95e3
7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents:
14342
diff
changeset
|
219 |
Objects.requireNonNull(annotationClass); |
21316
ca0a7cd228c9
8004912: Repeating annotations - getAnnotationsByType(Class<T>) is not working as expected for few inheritance scenarios
alundblad
parents:
17456
diff
changeset
|
220 |
return AnnotationSupport.getDirectlyAndIndirectlyPresent(mapAnnotations(getAnnotations()), annotationClass); |
14676
985410ec95e3
7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents:
14342
diff
changeset
|
221 |
} |
985410ec95e3
7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents:
14342
diff
changeset
|
222 |
|
15659
e575dab44ff5
8007278: Rename j.l.r.AnnotatedElement.getAnnotations(Class) to getAnnotationsByType(Class)
jfranck
parents:
15534
diff
changeset
|
223 |
@Override |
e575dab44ff5
8007278: Rename j.l.r.AnnotatedElement.getAnnotations(Class) to getAnnotationsByType(Class)
jfranck
parents:
15534
diff
changeset
|
224 |
public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) { |
14676
985410ec95e3
7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents:
14342
diff
changeset
|
225 |
Objects.requireNonNull(annotationClass); |
15659
e575dab44ff5
8007278: Rename j.l.r.AnnotatedElement.getAnnotations(Class) to getAnnotationsByType(Class)
jfranck
parents:
15534
diff
changeset
|
226 |
return getAnnotationsByType(annotationClass); |
14676
985410ec95e3
7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents:
14342
diff
changeset
|
227 |
} |
985410ec95e3
7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents:
14342
diff
changeset
|
228 |
|
10433
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
229 |
public Annotation[] getAnnotations() { |
15510
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
230 |
int myIndex = typeVarIndex(); |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
231 |
if (myIndex < 0) |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
232 |
throw new AssertionError("Index must be non-negative."); |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
233 |
return TypeAnnotationParser.parseTypeVariableAnnotations(getGenericDeclaration(), myIndex); |
10433
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
234 |
} |
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
235 |
|
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
236 |
public Annotation[] getDeclaredAnnotations() { |
15510
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
237 |
return getAnnotations(); |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
238 |
} |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
239 |
|
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
240 |
public AnnotatedType[] getAnnotatedBounds() { |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
241 |
return TypeAnnotationParser.parseAnnotatedBounds(getBounds(), |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
242 |
getGenericDeclaration(), |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
243 |
typeVarIndex()); |
10433
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
244 |
} |
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
245 |
|
3154f134c8d9
7086192: (reflect) Have TypeVariable extend AnnotatedElement
darcy
parents:
10342
diff
changeset
|
246 |
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; |
15510
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
247 |
|
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
248 |
// Helpers for annotation methods |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
249 |
private int typeVarIndex() { |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
250 |
TypeVariable<?>[] tVars = getGenericDeclaration().getTypeParameters(); |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
251 |
int i = -1; |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
252 |
for (TypeVariable<?> v : tVars) { |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
253 |
i++; |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
254 |
if (equals(v)) |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
255 |
return i; |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
256 |
} |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
257 |
return -1; |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
258 |
} |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
259 |
|
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
260 |
private static Map<Class<? extends Annotation>, Annotation> mapAnnotations(Annotation[] annos) { |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
261 |
Map<Class<? extends Annotation>, Annotation> result = |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
262 |
new LinkedHashMap<>(); |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
263 |
for (Annotation a : annos) { |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
264 |
Class<? extends Annotation> klass = a.annotationType(); |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
265 |
AnnotationType type = AnnotationType.getInstance(klass); |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
266 |
if (type.retention() == RetentionPolicy.RUNTIME) |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
267 |
if (result.put(klass, a) != null) |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
268 |
throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a); |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
269 |
} |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
270 |
return result; |
898d924a7efd
8004698: Implement Core Reflection for Type Annotations
jfranck
parents:
14676
diff
changeset
|
271 |
} |
2 | 272 |
} |