1 /* |
1 /* |
2 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
24 */ |
24 */ |
25 package com.sun.tools.javac.code; |
25 package com.sun.tools.javac.code; |
26 |
26 |
27 import java.lang.annotation.Annotation; |
27 import java.lang.annotation.Annotation; |
28 import java.lang.annotation.Inherited; |
28 import java.lang.annotation.Inherited; |
|
29 import java.lang.annotation.Repeatable; |
29 import java.lang.reflect.InvocationTargetException; |
30 import java.lang.reflect.InvocationTargetException; |
30 import java.lang.reflect.Method; |
31 import java.lang.reflect.Method; |
31 |
32 |
32 import javax.lang.model.AnnotatedConstruct; |
33 import javax.lang.model.AnnotatedConstruct; |
33 |
34 |
181 |
182 |
182 Attribute.Compound c = getAttribute(annoType); |
183 Attribute.Compound c = getAttribute(annoType); |
183 return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType); |
184 return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType); |
184 } |
185 } |
185 |
186 |
186 // Needed to unpack the runtime view of containing annotations |
|
187 private static final Class<? extends Annotation> REPEATABLE_CLASS = initRepeatable(); |
|
188 private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod(); |
|
189 |
|
190 private static Class<? extends Annotation> initRepeatable() { |
|
191 try { |
|
192 // Repeatable will not be available when bootstrapping on |
|
193 // JDK 7 so use a reflective lookup instead of a class |
|
194 // literal for Repeatable.class. |
|
195 return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class); |
|
196 } catch (ClassNotFoundException | SecurityException e) { |
|
197 return null; |
|
198 } |
|
199 } |
|
200 |
|
201 private static Method initValueElementMethod() { |
|
202 if (REPEATABLE_CLASS == null) |
|
203 return null; |
|
204 |
|
205 Method m = null; |
|
206 try { |
|
207 m = REPEATABLE_CLASS.getMethod("value"); |
|
208 if (m != null) |
|
209 m.setAccessible(true); |
|
210 return m; |
|
211 } catch (NoSuchMethodException e) { |
|
212 return null; |
|
213 } |
|
214 } |
|
215 |
|
216 |
|
217 // Helper to getAnnotationsByType |
187 // Helper to getAnnotationsByType |
218 private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) { |
188 private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) { |
219 // Since we can not refer to java.lang.annotation.Repeatable until we are |
189 Repeatable repeatable = annoType.getAnnotation(Repeatable.class); |
220 // bootstrapping with java 8 we need to get the Repeatable annotation using |
190 return (repeatable == null) ? null : repeatable.value(); |
221 // reflective invocations instead of just using its type and element method. |
191 } |
222 if (REPEATABLE_CLASS != null && |
|
223 VALUE_ELEMENT_METHOD != null) { |
|
224 // Get the Repeatable instance on the annotations declaration |
|
225 Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS); |
|
226 if (repeatable != null) { |
|
227 try { |
|
228 // Get the value element, it should be a class |
|
229 // indicating the containing annotation type |
|
230 @SuppressWarnings("unchecked") |
|
231 Class<? extends Annotation> containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable); |
|
232 if (containerType == null) |
|
233 return null; |
|
234 |
|
235 return containerType; |
|
236 } catch (ClassCastException | IllegalAccessException | InvocationTargetException e) { |
|
237 return null; |
|
238 } |
|
239 } |
|
240 } |
|
241 return null; |
|
242 } |
|
243 |
|
244 |
192 |
245 // Helper to getAnnotationsByType |
193 // Helper to getAnnotationsByType |
246 private static Attribute[] unpackAttributes(Attribute.Compound container) { |
194 private static Attribute[] unpackAttributes(Attribute.Compound container) { |
247 // We now have an instance of the container, |
195 // We now have an instance of the container, |
248 // unpack it returning an instance of the |
196 // unpack it returning an instance of the |