8007803: Implement javax.lang.model API for Type Annotations
Reviewed-by: darcy
This commit is contained in:
parent
0e8a3df6c7
commit
49d55f9300
@ -311,9 +311,9 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||
}
|
||||
if (args.head.unannotatedType().getKind() == TypeKind.ARRAY) {
|
||||
buf.append(visit(((ArrayType) args.head.unannotatedType()).elemtype, locale));
|
||||
if (args.head.getAnnotations().nonEmpty()) {
|
||||
if (args.head.getAnnotationMirrors().nonEmpty()) {
|
||||
buf.append(' ');
|
||||
buf.append(args.head.getAnnotations());
|
||||
buf.append(args.head.getAnnotationMirrors());
|
||||
buf.append(' ');
|
||||
}
|
||||
buf.append("...");
|
||||
|
@ -483,12 +483,12 @@ public abstract class Symbol implements Element {
|
||||
*/
|
||||
@Deprecated
|
||||
public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
|
||||
return JavacElements.getAnnotation(this, annoType);
|
||||
return JavacAnnoConstructs.getAnnotation(this, annoType);
|
||||
}
|
||||
|
||||
// This method is part of the javax.lang.model API, do not use this in javac code.
|
||||
public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(Class<A> annoType) {
|
||||
return JavacElements.getAnnotations(this, annoType);
|
||||
return JavacAnnoConstructs.getAnnotations(this, annoType);
|
||||
}
|
||||
|
||||
// TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
|
||||
@ -935,11 +935,12 @@ public abstract class Symbol implements Element {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated this method should never be used by javac internally.
|
||||
* Since this method works in terms of the runtime representation
|
||||
* of annotations, it should never be used by javac internally.
|
||||
*/
|
||||
@Override @Deprecated
|
||||
@Override
|
||||
public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
|
||||
return JavacElements.getAnnotation(this, annoType);
|
||||
return JavacAnnoConstructs.getAnnotation(this, annoType);
|
||||
}
|
||||
|
||||
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
|
||||
@ -1444,6 +1445,10 @@ public abstract class Symbol implements Element {
|
||||
return v.visitMethodSymbol(this, p);
|
||||
}
|
||||
|
||||
public Type getReceiverType() {
|
||||
return asType().getReceiverType();
|
||||
}
|
||||
|
||||
public Type getReturnType() {
|
||||
return asType().getReturnType();
|
||||
}
|
||||
|
@ -25,6 +25,9 @@
|
||||
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
import com.sun.tools.javac.model.JavacAnnoConstructs;
|
||||
import com.sun.tools.javac.model.JavacTypes;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
@ -258,6 +261,23 @@ public class Type implements PrimitiveType {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Attribute.TypeCompound> getAnnotationMirrors() {
|
||||
return List.nil();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
|
||||
@SuppressWarnings("unchecked")
|
||||
A[] tmp = (A[]) java.lang.reflect.Array.newInstance(annotationType, 0);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/** Return the base types of a list of types.
|
||||
*/
|
||||
public static List<Type> baseTypes(List<Type> ts) {
|
||||
@ -354,8 +374,8 @@ public class Type implements PrimitiveType {
|
||||
}
|
||||
if (args.head.unannotatedType().tag == ARRAY) {
|
||||
buf.append(((ArrayType)args.head.unannotatedType()).elemtype);
|
||||
if (args.head.getAnnotations().nonEmpty()) {
|
||||
buf.append(args.head.getAnnotations());
|
||||
if (args.head.getAnnotationMirrors().nonEmpty()) {
|
||||
buf.append(args.head.getAnnotationMirrors());
|
||||
}
|
||||
buf.append("...");
|
||||
} else {
|
||||
@ -366,7 +386,6 @@ public class Type implements PrimitiveType {
|
||||
|
||||
/** Access methods.
|
||||
*/
|
||||
public List<? extends AnnotationMirror> getAnnotations() { return List.nil(); }
|
||||
public List<Type> getTypeArguments() { return List.nil(); }
|
||||
public Type getEnclosingType() { return null; }
|
||||
public List<Type> getParameterTypes() { return List.nil(); }
|
||||
@ -1581,13 +1600,23 @@ public class Type implements PrimitiveType {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeKind getKind() {
|
||||
return underlyingType.getKind();
|
||||
public List<? extends Attribute.TypeCompound> getAnnotationMirrors() {
|
||||
return typeAnnotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends AnnotationMirror> getAnnotations() {
|
||||
return typeAnnotations;
|
||||
public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
|
||||
return JavacAnnoConstructs.getAnnotation(this, annotationType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
|
||||
return JavacAnnoConstructs.getAnnotationsByType(this, annotationType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeKind getKind() {
|
||||
return underlyingType.getKind();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -4279,7 +4279,7 @@ public class Attr extends JCTree.Visitor {
|
||||
validateAnnotatedType(errtree, type);
|
||||
if (type.tsym != null &&
|
||||
type.tsym.isStatic() &&
|
||||
type.getAnnotations().nonEmpty()) {
|
||||
type.getAnnotationMirrors().nonEmpty()) {
|
||||
// Enclosing static classes cannot have type annotations.
|
||||
log.error(errtree.pos(), "cant.annotate.static.class");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -273,7 +273,7 @@ public class AnnotationProxyMaker {
|
||||
|
||||
/**
|
||||
* ExceptionProxy for MirroredTypeException.
|
||||
* The toString, hashCode, and equals methods foward to the underlying
|
||||
* The toString, hashCode, and equals methods forward to the underlying
|
||||
* type.
|
||||
*/
|
||||
private static final class MirroredTypeExceptionProxy extends ExceptionProxy {
|
||||
|
@ -0,0 +1,412 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.tools.javac.model;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.sun.tools.javac.code.Attribute;
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* Utility methods for operating on annotated constructs.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own
|
||||
* risk. This code and its internal interfaces are subject to change
|
||||
* or deletion without notice.</b></p>
|
||||
*/
|
||||
public class JavacAnnoConstructs {
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Symbols">
|
||||
|
||||
/**
|
||||
* An internal-use utility that creates a runtime view of an
|
||||
* annotation. This is the implementation of
|
||||
* Element.getAnnotation(Class).
|
||||
*/
|
||||
public static <A extends Annotation> A getAnnotation(Symbol annotated,
|
||||
Class<A> annoType) {
|
||||
if (!annoType.isAnnotation())
|
||||
throw new IllegalArgumentException("Not an annotation type: "
|
||||
+ annoType);
|
||||
Attribute.Compound c;
|
||||
if (annotated.kind == Kinds.TYP && annotated instanceof ClassSymbol) {
|
||||
c = getAttributeOnClass((ClassSymbol)annotated, annoType);
|
||||
} else {
|
||||
c = getAttribute(annotated, annoType);
|
||||
}
|
||||
return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType);
|
||||
}
|
||||
|
||||
// Helper to getAnnotation[s]
|
||||
private static <A extends Annotation> Attribute.Compound getAttribute(Symbol annotated,
|
||||
Class<A> annoType) {
|
||||
String name = annoType.getName();
|
||||
|
||||
for (Attribute.Compound anno : annotated.getRawAttributes()) {
|
||||
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) {
|
||||
boolean inherited = annoType.isAnnotationPresent(Inherited.class);
|
||||
Attribute.Compound result = null;
|
||||
while (annotated.name != annotated.name.table.names.java_lang_Object) {
|
||||
result = getAttribute(annotated, annoType);
|
||||
if (result != null || !inherited)
|
||||
break;
|
||||
Type sup = annotated.getSuperclass();
|
||||
if (!sup.hasTag(CLASS) || sup.isErroneous())
|
||||
break;
|
||||
annotated = (ClassSymbol) sup.tsym;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal-use utility that creates a runtime view of
|
||||
* annotations. This is the implementation of
|
||||
* Element.getAnnotations(Class).
|
||||
*/
|
||||
public static <A extends Annotation> A[] getAnnotations(Symbol annotated,
|
||||
Class<A> annoType) {
|
||||
if (!annoType.isAnnotation())
|
||||
throw new IllegalArgumentException("Not an annotation type: "
|
||||
+ annoType);
|
||||
// If annoType does not declare a container this is equivalent to wrapping
|
||||
// getAnnotation(...) in an array.
|
||||
Class <? extends Annotation> containerType = getContainer(annoType);
|
||||
if (containerType == null) {
|
||||
A res = getAnnotation(annotated, annoType);
|
||||
int size;
|
||||
if (res == null) {
|
||||
size = 0;
|
||||
} else {
|
||||
size = 1;
|
||||
}
|
||||
@SuppressWarnings("unchecked") // annoType is the Class for A
|
||||
A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
|
||||
if (res != null)
|
||||
arr[0] = res;
|
||||
return arr;
|
||||
}
|
||||
|
||||
// So we have a containing type
|
||||
String name = annoType.getName();
|
||||
String annoTypeName = annoType.getSimpleName();
|
||||
String containerTypeName = containerType.getSimpleName();
|
||||
int directIndex = -1, containerIndex = -1;
|
||||
Attribute.Compound direct = null, container = null;
|
||||
Attribute.Compound[] rawAttributes = annotated.getRawAttributes().toArray(new Attribute.Compound[0]);
|
||||
|
||||
// Find directly present annotations
|
||||
for (int i = 0; i < rawAttributes.length; i++) {
|
||||
if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
|
||||
directIndex = i;
|
||||
direct = rawAttributes[i];
|
||||
} else if(containerTypeName != null &&
|
||||
containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
|
||||
containerIndex = i;
|
||||
container = rawAttributes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Deal with inherited annotations
|
||||
if (annotated.kind == Kinds.TYP &&
|
||||
(annotated instanceof ClassSymbol)) {
|
||||
ClassSymbol s = (ClassSymbol)annotated;
|
||||
if (direct == null && container == null) {
|
||||
direct = getAttributeOnClass(s, annoType);
|
||||
container = getAttributeOnClass(s, containerType);
|
||||
|
||||
// both are inherited and found, put container last
|
||||
if (direct != null && container != null) {
|
||||
directIndex = 0;
|
||||
containerIndex = 1;
|
||||
} else if (direct != null) {
|
||||
directIndex = 0;
|
||||
} else {
|
||||
containerIndex = 0;
|
||||
}
|
||||
} else if (direct == null) {
|
||||
direct = getAttributeOnClass(s, annoType);
|
||||
if (direct != null)
|
||||
directIndex = containerIndex + 1;
|
||||
} else if (container == null) {
|
||||
container = getAttributeOnClass(s, containerType);
|
||||
if (container != null)
|
||||
containerIndex = directIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Pack them in an array
|
||||
Attribute[] contained0 = new Attribute[0];
|
||||
if (container != null)
|
||||
contained0 = unpackAttributes(container);
|
||||
ListBuffer<Attribute.Compound> compounds = ListBuffer.lb();
|
||||
for (Attribute a : contained0)
|
||||
if (a instanceof Attribute.Compound)
|
||||
compounds = compounds.append((Attribute.Compound)a);
|
||||
Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]);
|
||||
|
||||
int size = (direct == null ? 0 : 1) + contained.length;
|
||||
@SuppressWarnings("unchecked") // annoType is the Class for A
|
||||
A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
|
||||
|
||||
// if direct && container, which is first?
|
||||
int insert = -1;
|
||||
int length = arr.length;
|
||||
if (directIndex >= 0 && containerIndex >= 0) {
|
||||
if (directIndex < containerIndex) {
|
||||
arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
insert = 1;
|
||||
} else {
|
||||
arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
insert = 0;
|
||||
length--;
|
||||
}
|
||||
} else if (directIndex >= 0) {
|
||||
arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
return arr;
|
||||
} else {
|
||||
// Only container
|
||||
insert = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i + insert < length; i++)
|
||||
arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Types">
|
||||
|
||||
/**
|
||||
* An internal-use utility that creates a runtime view of an
|
||||
* annotation. This is the implementation of
|
||||
* TypeMirror.getAnnotation(Class).
|
||||
*/
|
||||
public static <A extends Annotation> A getAnnotation(AnnotatedType annotated, Class<A> annoType) {
|
||||
if (!annoType.isAnnotation())
|
||||
throw new IllegalArgumentException("Not an annotation type: "
|
||||
+ annoType);
|
||||
Attribute.Compound c = getAttribute(annotated, annoType);
|
||||
return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType);
|
||||
}
|
||||
|
||||
// Helper to getAnnotation[s]
|
||||
private static <A extends Annotation> Attribute.Compound getAttribute(Type annotated,
|
||||
Class<A> annoType) {
|
||||
String name = annoType.getName();
|
||||
|
||||
for (Attribute.Compound anno : annotated.getAnnotationMirrors()) {
|
||||
if (name.equals(anno.type.tsym.flatName().toString()))
|
||||
return anno;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal-use utility that creates a runtime view of
|
||||
* annotations. This is the implementation of
|
||||
* TypeMirror.getAnnotationsByType(Class).
|
||||
*/
|
||||
public static <A extends Annotation> A[] getAnnotationsByType(AnnotatedType annotated, Class<A> annoType) {
|
||||
if (!annoType.isAnnotation())
|
||||
throw new IllegalArgumentException("Not an annotation type: "
|
||||
+ annoType);
|
||||
// If annoType does not declare a container this is equivalent to wrapping
|
||||
// getAnnotation(...) in an array.
|
||||
Class <? extends Annotation> containerType = getContainer(annoType);
|
||||
if (containerType == null) {
|
||||
A res = getAnnotation(annotated, annoType);
|
||||
int size;
|
||||
if (res == null) {
|
||||
size = 0;
|
||||
} else {
|
||||
size = 1;
|
||||
}
|
||||
@SuppressWarnings("unchecked") // annoType is the Class for A
|
||||
A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
|
||||
if (res != null)
|
||||
arr[0] = res;
|
||||
return arr;
|
||||
}
|
||||
|
||||
// So we have a containing type
|
||||
String name = annoType.getName();
|
||||
String annoTypeName = annoType.getSimpleName();
|
||||
String containerTypeName = containerType.getSimpleName();
|
||||
int directIndex = -1, containerIndex = -1;
|
||||
Attribute.Compound direct = null, container = null;
|
||||
Attribute.Compound[] rawAttributes = annotated.getAnnotationMirrors().toArray(new Attribute.Compound[0]);
|
||||
|
||||
// Find directly present annotations
|
||||
for (int i = 0; i < rawAttributes.length; i++) {
|
||||
if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
|
||||
directIndex = i;
|
||||
direct = rawAttributes[i];
|
||||
} else if(containerTypeName != null &&
|
||||
containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
|
||||
containerIndex = i;
|
||||
container = rawAttributes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Pack them in an array
|
||||
Attribute[] contained0 = new Attribute[0];
|
||||
if (container != null)
|
||||
contained0 = unpackAttributes(container);
|
||||
ListBuffer<Attribute.Compound> compounds = ListBuffer.lb();
|
||||
for (Attribute a : contained0) {
|
||||
if (a instanceof Attribute.Compound)
|
||||
compounds = compounds.append((Attribute.Compound)a);
|
||||
}
|
||||
Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]);
|
||||
|
||||
int size = (direct == null ? 0 : 1) + contained.length;
|
||||
@SuppressWarnings("unchecked") // annoType is the Class for A
|
||||
A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
|
||||
|
||||
// if direct && container, which is first?
|
||||
int insert = -1;
|
||||
int length = arr.length;
|
||||
if (directIndex >= 0 && containerIndex >= 0) {
|
||||
if (directIndex < containerIndex) {
|
||||
arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
insert = 1;
|
||||
} else {
|
||||
arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
insert = 0;
|
||||
length--;
|
||||
}
|
||||
} else if (directIndex >= 0) {
|
||||
arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
return arr;
|
||||
} else {
|
||||
// Only container
|
||||
insert = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i + insert < length; i++)
|
||||
arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Container support">
|
||||
|
||||
// Needed to unpack the runtime view of containing annotations
|
||||
private static final Class<? extends Annotation> REPEATABLE_CLASS = initRepeatable();
|
||||
private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod();
|
||||
|
||||
private static Class<? extends Annotation> initRepeatable() {
|
||||
try {
|
||||
// Repeatable will not be available when bootstrapping on
|
||||
// JDK 7 so use a reflective lookup instead of a class
|
||||
// literal for Repeatable.class.
|
||||
return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
} catch (SecurityException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method initValueElementMethod() {
|
||||
if (REPEATABLE_CLASS == null)
|
||||
return null;
|
||||
|
||||
Method m = null;
|
||||
try {
|
||||
m = REPEATABLE_CLASS.getMethod("value");
|
||||
if (m != null)
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to getAnnotations
|
||||
private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) {
|
||||
// Since we can not refer to java.lang.annotation.Repeatable until we are
|
||||
// bootstrapping with java 8 we need to get the Repeatable annotation using
|
||||
// reflective invocations instead of just using its type and element method.
|
||||
if (REPEATABLE_CLASS != null &&
|
||||
VALUE_ELEMENT_METHOD != null) {
|
||||
// Get the Repeatable instance on the annotations declaration
|
||||
Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS);
|
||||
if (repeatable != null) {
|
||||
try {
|
||||
// Get the value element, it should be a class
|
||||
// indicating the containing annotation type
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends Annotation> containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable);
|
||||
if (containerType == null)
|
||||
return null;
|
||||
|
||||
return containerType;
|
||||
} catch (ClassCastException e) {
|
||||
return null;
|
||||
} catch (IllegalAccessException e) {
|
||||
return null;
|
||||
} catch (InvocationTargetException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Helper to getAnnotations
|
||||
private static Attribute[] unpackAttributes(Attribute.Compound container) {
|
||||
// We now have an instance of the container,
|
||||
// unpack it returning an instance of the
|
||||
// contained type or null
|
||||
return ((Attribute.Array)container.member(container.type.tsym.name.table.names.value)).values;
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
}
|
@ -25,10 +25,6 @@
|
||||
|
||||
package com.sun.tools.javac.model;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.lang.model.SourceVersion;
|
||||
@ -40,7 +36,6 @@ import static javax.lang.model.util.ElementFilter.methodsIn;
|
||||
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.TypeTag;
|
||||
import com.sun.tools.javac.comp.AttrContext;
|
||||
import com.sun.tools.javac.comp.Enter;
|
||||
import com.sun.tools.javac.comp.Env;
|
||||
@ -98,237 +93,6 @@ public class JavacElements implements Elements {
|
||||
enter = Enter.instance(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal-use utility that creates a runtime view of an
|
||||
* annotation. This is the implementation of
|
||||
* Element.getAnnotation(Class).
|
||||
*/
|
||||
public static <A extends Annotation> A getAnnotation(Symbol annotated,
|
||||
Class<A> annoType) {
|
||||
if (!annoType.isAnnotation())
|
||||
throw new IllegalArgumentException("Not an annotation type: "
|
||||
+ annoType);
|
||||
Attribute.Compound c;
|
||||
if (annotated.kind == Kinds.TYP && annotated instanceof ClassSymbol) {
|
||||
c = getAttributeOnClass((ClassSymbol)annotated, annoType);
|
||||
} else {
|
||||
c = getAttribute(annotated, annoType);
|
||||
}
|
||||
return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType);
|
||||
}
|
||||
|
||||
// Helper to getAnnotation[s]
|
||||
private static <A extends Annotation> Attribute.Compound getAttribute(Symbol annotated,
|
||||
Class<A> annoType) {
|
||||
String name = annoType.getName();
|
||||
|
||||
for (Attribute.Compound anno : annotated.getRawAttributes())
|
||||
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) {
|
||||
boolean inherited = annoType.isAnnotationPresent(Inherited.class);
|
||||
Attribute.Compound result = null;
|
||||
while (annotated.name != annotated.name.table.names.java_lang_Object) {
|
||||
result = getAttribute(annotated, annoType);
|
||||
if (result != null || !inherited)
|
||||
break;
|
||||
Type sup = annotated.getSuperclass();
|
||||
if (!sup.hasTag(CLASS) || sup.isErroneous())
|
||||
break;
|
||||
annotated = (ClassSymbol) sup.tsym;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal-use utility that creates a runtime view of
|
||||
* annotations. This is the implementation of
|
||||
* Element.getAnnotations(Class).
|
||||
*/
|
||||
public static <A extends Annotation> A[] getAnnotations(Symbol annotated,
|
||||
Class<A> annoType) {
|
||||
if (!annoType.isAnnotation())
|
||||
throw new IllegalArgumentException("Not an annotation type: "
|
||||
+ annoType);
|
||||
// If annoType does not declare a container this is equivalent to wrapping
|
||||
// getAnnotation(...) in an array.
|
||||
Class <? extends Annotation> containerType = getContainer(annoType);
|
||||
if (containerType == null) {
|
||||
A res = getAnnotation(annotated, annoType);
|
||||
int size;
|
||||
if (res == null) {
|
||||
size = 0;
|
||||
} else {
|
||||
size = 1;
|
||||
}
|
||||
@SuppressWarnings("unchecked") // annoType is the Class for A
|
||||
A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
|
||||
if (res != null)
|
||||
arr[0] = res;
|
||||
return arr;
|
||||
}
|
||||
|
||||
// So we have a containing type
|
||||
String name = annoType.getName();
|
||||
String annoTypeName = annoType.getSimpleName();
|
||||
String containerTypeName = containerType.getSimpleName();
|
||||
int directIndex = -1, containerIndex = -1;
|
||||
Attribute.Compound direct = null, container = null;
|
||||
Attribute.Compound[] rawAttributes = annotated.getRawAttributes().toArray(new Attribute.Compound[0]);
|
||||
|
||||
// Find directly present annotations
|
||||
for (int i = 0; i < rawAttributes.length; i++) {
|
||||
if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
|
||||
directIndex = i;
|
||||
direct = rawAttributes[i];
|
||||
} else if(containerTypeName != null &&
|
||||
containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
|
||||
containerIndex = i;
|
||||
container = rawAttributes[i];
|
||||
}
|
||||
}
|
||||
// Deal with inherited annotations
|
||||
if (annotated.kind == Kinds.TYP &&
|
||||
(annotated instanceof ClassSymbol)) {
|
||||
ClassSymbol s = (ClassSymbol)annotated;
|
||||
if (direct == null && container == null) {
|
||||
direct = getAttributeOnClass(s, annoType);
|
||||
container = getAttributeOnClass(s, containerType);
|
||||
|
||||
// both are inherited and found, put container last
|
||||
if (direct != null && container != null) {
|
||||
directIndex = 0;
|
||||
containerIndex = 1;
|
||||
} else if (direct != null) {
|
||||
directIndex = 0;
|
||||
} else {
|
||||
containerIndex = 0;
|
||||
}
|
||||
} else if (direct == null) {
|
||||
direct = getAttributeOnClass(s, annoType);
|
||||
if (direct != null)
|
||||
directIndex = containerIndex + 1;
|
||||
} else if (container == null) {
|
||||
container = getAttributeOnClass(s, containerType);
|
||||
if (container != null)
|
||||
containerIndex = directIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Pack them in an array
|
||||
Attribute[] contained0 = new Attribute[0];
|
||||
if (container != null)
|
||||
contained0 = unpackAttributes(container);
|
||||
ListBuffer<Attribute.Compound> compounds = ListBuffer.lb();
|
||||
for (Attribute a : contained0)
|
||||
if (a instanceof Attribute.Compound)
|
||||
compounds = compounds.append((Attribute.Compound)a);
|
||||
Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]);
|
||||
|
||||
int size = (direct == null ? 0 : 1) + contained.length;
|
||||
@SuppressWarnings("unchecked") // annoType is the Class for A
|
||||
A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
|
||||
|
||||
// if direct && container, which is first?
|
||||
int insert = -1;
|
||||
int length = arr.length;
|
||||
if (directIndex >= 0 && containerIndex >= 0) {
|
||||
if (directIndex < containerIndex) {
|
||||
arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
insert = 1;
|
||||
} else {
|
||||
arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
insert = 0;
|
||||
length--;
|
||||
}
|
||||
} else if (directIndex >= 0) {
|
||||
arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
|
||||
return arr;
|
||||
} else {
|
||||
// Only container
|
||||
insert = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i + insert < length; i++)
|
||||
arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
// Needed to unpack the runtime view of containing annotations
|
||||
private static final Class<? extends Annotation> REPEATABLE_CLASS = initRepeatable();
|
||||
private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod();
|
||||
|
||||
private static Class<? extends Annotation> initRepeatable() {
|
||||
try {
|
||||
// Repeatable will not be available when bootstrapping on
|
||||
// JDK 7 so use a reflective lookup instead of a class
|
||||
// literal for Repeatable.class.
|
||||
return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
} catch (SecurityException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private static Method initValueElementMethod() {
|
||||
if (REPEATABLE_CLASS == null)
|
||||
return null;
|
||||
|
||||
Method m = null;
|
||||
try {
|
||||
m = REPEATABLE_CLASS.getMethod("value");
|
||||
if (m != null)
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to getAnnotations
|
||||
private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) {
|
||||
// Since we can not refer to java.lang.annotation.Repeatable until we are
|
||||
// bootstrapping with java 8 we need to get the Repeatable annotation using
|
||||
// reflective invocations instead of just using its type and element method.
|
||||
if (REPEATABLE_CLASS != null &&
|
||||
VALUE_ELEMENT_METHOD != null) {
|
||||
// Get the Repeatable instance on the annotations declaration
|
||||
Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS);
|
||||
if (repeatable != null) {
|
||||
try {
|
||||
// Get the value element, it should be a class
|
||||
// indicating the containing annotation type
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends Annotation> containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable);
|
||||
if (containerType == null)
|
||||
return null;
|
||||
|
||||
return containerType;
|
||||
} catch (ClassCastException e) {
|
||||
return null;
|
||||
} catch (IllegalAccessException e) {
|
||||
return null;
|
||||
} catch (InvocationTargetException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// Helper to getAnnotations
|
||||
private static Attribute[] unpackAttributes(Attribute.Compound container) {
|
||||
// We now have an instance of the container,
|
||||
// unpack it returning an instance of the
|
||||
// contained type or null
|
||||
return ((Attribute.Array)container.member(container.type.tsym.name.table.names.value)).values;
|
||||
}
|
||||
|
||||
public PackageSymbol getPackageElement(CharSequence name) {
|
||||
String strName = name.toString();
|
||||
if (strName.equals(""))
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package com.sun.tools.javac.model;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashSet;
|
||||
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.lang.model;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
import javax.lang.model.element.*;
|
||||
|
||||
/**
|
||||
* Represent a construct that can have annotations.
|
||||
*
|
||||
* When annotations are on an {@linkplain element.Element element},
|
||||
* the are on a <em>declaration</em>. When annotations are on a {@linkplain
|
||||
* type.TypeMirror type}, they are on a <em>use</em> of a type.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface AnnotatedConstruct {
|
||||
/**
|
||||
* Returns the annotations that are directly present on this
|
||||
* element or type use.
|
||||
*
|
||||
* @return the annotations directly present on this element or type use;
|
||||
* an empty list if there are none
|
||||
*/
|
||||
List<? extends AnnotationMirror> getAnnotationMirrors();
|
||||
|
||||
/**
|
||||
* Returns this element's or type use's annotation for the
|
||||
* specified type if such an annotation is present, else {@code
|
||||
* null}. The annotation may be either inherited or directly
|
||||
* present on this element.
|
||||
*
|
||||
* <p> The annotation returned by this method could contain an element
|
||||
* whose value is of type {@code Class}.
|
||||
* This value cannot be returned directly: information necessary to
|
||||
* locate and load a class (such as the class loader to use) is
|
||||
* not available, and the class might not be loadable at all.
|
||||
* Attempting to read a {@code Class} object by invoking the relevant
|
||||
* method on the returned annotation
|
||||
* will result in a {@link MirroredTypeException},
|
||||
* from which the corresponding {@link TypeMirror} may be extracted.
|
||||
* Similarly, attempting to read a {@code Class[]}-valued element
|
||||
* will result in a {@link MirroredTypesException}.
|
||||
*
|
||||
* <blockquote>
|
||||
* <i>Note:</i> This method is unlike others in this and related
|
||||
* interfaces. It operates on runtime reflective information —
|
||||
* representations of annotation types currently loaded into the
|
||||
* VM — rather than on the representations defined by and used
|
||||
* throughout these interfaces. Consequently, calling methods on
|
||||
* the returned annotation object can throw many of the exceptions
|
||||
* that can be thrown when calling methods on an annotation object
|
||||
* returned by core reflection. This method is intended for
|
||||
* callers that are written to operate on a known, fixed set of
|
||||
* annotation types.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param <A> the annotation type
|
||||
* @param annotationType the {@code Class} object corresponding to
|
||||
* the annotation type
|
||||
* @return this element's or type use's annotation for the
|
||||
* specified annotation type if present on this element, else
|
||||
* {@code null}
|
||||
*
|
||||
* @see #getAnnotationMirrors()
|
||||
* @see java.lang.reflect.AnnotatedElement#getAnnotation
|
||||
* @see EnumConstantNotPresentException
|
||||
* @see AnnotationTypeMismatchException
|
||||
* @see IncompleteAnnotationException
|
||||
* @see MirroredTypeException
|
||||
* @see MirroredTypesException
|
||||
*/
|
||||
<A extends Annotation> A getAnnotation(Class<A> annotationType);
|
||||
|
||||
/**
|
||||
* Returns annotations that are <em>present</em> on this element or type use.
|
||||
*
|
||||
* If there are no annotations <em>present</em> on this element or type use,
|
||||
* the return value is an array of length 0.
|
||||
*
|
||||
* The difference between this method and {@link #getAnnotation(Class)}
|
||||
* is that this method detects if its argument is a <em>repeatable
|
||||
* annotation type</em> (JLS 9.6), and if so, attempts to find one or more
|
||||
* annotations of that type by "looking through" a container annotation.
|
||||
*
|
||||
* <p> The annotations returned by this method could contain an element
|
||||
* whose value is of type {@code Class}.
|
||||
* This value cannot be returned directly: information necessary to
|
||||
* locate and load a class (such as the class loader to use) is
|
||||
* not available, and the class might not be loadable at all.
|
||||
* Attempting to read a {@code Class} object by invoking the relevant
|
||||
* method on the returned annotation
|
||||
* will result in a {@link MirroredTypeException},
|
||||
* from which the corresponding {@link TypeMirror} may be extracted.
|
||||
* Similarly, attempting to read a {@code Class[]}-valued element
|
||||
* will result in a {@link MirroredTypesException}.
|
||||
*
|
||||
* <blockquote>
|
||||
* <i>Note:</i> This method is unlike others in this and related
|
||||
* interfaces. It operates on runtime reflective information —
|
||||
* representations of annotation types currently loaded into the
|
||||
* VM — rather than on the representations defined by and used
|
||||
* throughout these interfaces. Consequently, calling methods on
|
||||
* the returned annotation object can throw many of the exceptions
|
||||
* that can be thrown when calling methods on an annotation object
|
||||
* returned by core reflection. This method is intended for
|
||||
* callers that are written to operate on a known, fixed set of
|
||||
* annotation types.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param <A> the annotation type
|
||||
* @param annotationType the {@code Class} object corresponding to
|
||||
* the annotation type
|
||||
* @return this element's annotations for the specified annotation
|
||||
* type if present on this element, else an empty array
|
||||
*
|
||||
* @see #getAnnotationMirrors()
|
||||
* @see #getAnnotation(java.lang.Class)
|
||||
* @see java.lang.reflect.AnnotatedElement#getAnnotationsByType
|
||||
* @see EnumConstantNotPresentException
|
||||
* @see AnnotationTypeMismatchException
|
||||
* @see IncompleteAnnotationException
|
||||
* @see MirroredTypeException
|
||||
* @see MirroredTypesException
|
||||
*/
|
||||
<A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType);
|
||||
}
|
@ -60,8 +60,7 @@ import javax.lang.model.util.*;
|
||||
* @see TypeMirror
|
||||
* @since 1.6
|
||||
*/
|
||||
public interface Element {
|
||||
|
||||
public interface Element extends javax.lang.model.AnnotatedConstruct {
|
||||
/**
|
||||
* Returns the type defined by this element.
|
||||
*
|
||||
@ -88,119 +87,6 @@ public interface Element {
|
||||
*/
|
||||
ElementKind getKind();
|
||||
|
||||
/**
|
||||
* Returns the annotations that are directly present on this element.
|
||||
*
|
||||
* <p> To get inherited annotations as well, use
|
||||
* {@link Elements#getAllAnnotationMirrors(Element) getAllAnnotationMirrors}.
|
||||
*
|
||||
* @see ElementFilter
|
||||
*
|
||||
* @return the annotations directly present on this element;
|
||||
* an empty list if there are none
|
||||
*/
|
||||
List<? extends AnnotationMirror> getAnnotationMirrors();
|
||||
|
||||
/**
|
||||
* Returns this element's annotation for the specified type if
|
||||
* such an annotation is present, else {@code null}. The
|
||||
* annotation may be either inherited or directly present on this
|
||||
* element.
|
||||
*
|
||||
* <p> The annotation returned by this method could contain an element
|
||||
* whose value is of type {@code Class}.
|
||||
* This value cannot be returned directly: information necessary to
|
||||
* locate and load a class (such as the class loader to use) is
|
||||
* not available, and the class might not be loadable at all.
|
||||
* Attempting to read a {@code Class} object by invoking the relevant
|
||||
* method on the returned annotation
|
||||
* will result in a {@link MirroredTypeException},
|
||||
* from which the corresponding {@link TypeMirror} may be extracted.
|
||||
* Similarly, attempting to read a {@code Class[]}-valued element
|
||||
* will result in a {@link MirroredTypesException}.
|
||||
*
|
||||
* <blockquote>
|
||||
* <i>Note:</i> This method is unlike others in this and related
|
||||
* interfaces. It operates on runtime reflective information —
|
||||
* representations of annotation types currently loaded into the
|
||||
* VM — rather than on the representations defined by and used
|
||||
* throughout these interfaces. Consequently, calling methods on
|
||||
* the returned annotation object can throw many of the exceptions
|
||||
* that can be thrown when calling methods on an annotation object
|
||||
* returned by core reflection. This method is intended for
|
||||
* callers that are written to operate on a known, fixed set of
|
||||
* annotation types.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param <A> the annotation type
|
||||
* @param annotationType the {@code Class} object corresponding to
|
||||
* the annotation type
|
||||
* @return this element's annotation for the specified annotation
|
||||
* type if present on this element, else {@code null}
|
||||
*
|
||||
* @see #getAnnotationMirrors()
|
||||
* @see java.lang.reflect.AnnotatedElement#getAnnotation
|
||||
* @see EnumConstantNotPresentException
|
||||
* @see AnnotationTypeMismatchException
|
||||
* @see IncompleteAnnotationException
|
||||
* @see MirroredTypeException
|
||||
* @see MirroredTypesException
|
||||
*/
|
||||
<A extends Annotation> A getAnnotation(Class<A> annotationType);
|
||||
|
||||
/**
|
||||
* Returns annotations that are <em>present</em> on this element.
|
||||
*
|
||||
* If there are no annotations <em>present</em> on this element, the return
|
||||
* value is an array of length 0.
|
||||
*
|
||||
* The difference between this method and {@link #getAnnotation(Class)}
|
||||
* is that this method detects if its argument is a <em>repeatable
|
||||
* annotation type</em> (JLS 9.6), and if so, attempts to find one or more
|
||||
* annotations of that type by "looking through" a container annotation.
|
||||
*
|
||||
* <p> The annotations returned by this method could contain an element
|
||||
* whose value is of type {@code Class}.
|
||||
* This value cannot be returned directly: information necessary to
|
||||
* locate and load a class (such as the class loader to use) is
|
||||
* not available, and the class might not be loadable at all.
|
||||
* Attempting to read a {@code Class} object by invoking the relevant
|
||||
* method on the returned annotation
|
||||
* will result in a {@link MirroredTypeException},
|
||||
* from which the corresponding {@link TypeMirror} may be extracted.
|
||||
* Similarly, attempting to read a {@code Class[]}-valued element
|
||||
* will result in a {@link MirroredTypesException}.
|
||||
*
|
||||
* <blockquote>
|
||||
* <i>Note:</i> This method is unlike others in this and related
|
||||
* interfaces. It operates on runtime reflective information —
|
||||
* representations of annotation types currently loaded into the
|
||||
* VM — rather than on the representations defined by and used
|
||||
* throughout these interfaces. Consequently, calling methods on
|
||||
* the returned annotation object can throw many of the exceptions
|
||||
* that can be thrown when calling methods on an annotation object
|
||||
* returned by core reflection. This method is intended for
|
||||
* callers that are written to operate on a known, fixed set of
|
||||
* annotation types.
|
||||
* </blockquote>
|
||||
*
|
||||
* @param <A> the annotation type
|
||||
* @param annotationType the {@code Class} object corresponding to
|
||||
* the annotation type
|
||||
* @return this element's annotations for the specified annotation
|
||||
* type if present on this element, else an empty array
|
||||
*
|
||||
* @see #getAnnotationMirrors()
|
||||
* @see #getAnnotation(java.lang.Class)
|
||||
* @see java.lang.reflect.AnnotatedElement#getAnnotationsByType
|
||||
* @see EnumConstantNotPresentException
|
||||
* @see AnnotationTypeMismatchException
|
||||
* @see IncompleteAnnotationException
|
||||
* @see MirroredTypeException
|
||||
* @see MirroredTypesException
|
||||
*/
|
||||
<A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType);
|
||||
|
||||
/**
|
||||
* Returns the modifiers of this element, excluding annotations.
|
||||
* Implicit modifiers, such as the {@code public} and {@code static}
|
||||
@ -325,6 +211,19 @@ public interface Element {
|
||||
*/
|
||||
int hashCode();
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p> To get inherited annotations as well, use {@link
|
||||
* Elements#getAllAnnotationMirrors(Element)
|
||||
* getAllAnnotationMirrors}.
|
||||
*
|
||||
* @see ElementFilter
|
||||
* @since 1.6
|
||||
*/
|
||||
@Override
|
||||
List<? extends AnnotationMirror> getAnnotationMirrors();
|
||||
/**
|
||||
* Applies a visitor to this element.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -68,6 +68,25 @@ public interface ExecutableElement extends Element, Parameterizable {
|
||||
*/
|
||||
List<? extends VariableElement> getParameters();
|
||||
|
||||
/**
|
||||
* Returns the receiver type of this executable,
|
||||
* or {@link javax.lang.model.type.NoType NoType} with
|
||||
* kind {@link javax.lang.model.type.TypeKind#NONE NONE}
|
||||
* if the executable has no receiver type.
|
||||
*
|
||||
* An executable which is an instance method, or a constructor of an
|
||||
* inner class, has a receiver type derived from the {@linkplain
|
||||
* #getEnclosingElement declaring type}.
|
||||
*
|
||||
* An executable which is a static method, or a constructor of a
|
||||
* non-inner class, or an initializer (static or instance), has no
|
||||
* receiver type.
|
||||
*
|
||||
* @return the receiver type of this executable
|
||||
* @since 1.8
|
||||
*/
|
||||
TypeMirror getReceiverType();
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this method or constructor accepts a variable
|
||||
* number of arguments and returns {@code false} otherwise.
|
||||
|
@ -77,6 +77,25 @@ public interface ExecutableType extends TypeMirror {
|
||||
*/
|
||||
List<? extends TypeMirror> getParameterTypes();
|
||||
|
||||
/**
|
||||
* Returns the receiver type of this executable,
|
||||
* or {@link javax.lang.model.type.NoType NoType} with
|
||||
* kind {@link javax.lang.model.type.TypeKind#NONE NONE}
|
||||
* if the executable has no receiver type.
|
||||
*
|
||||
* An executable which is an instance method, or a constructor of an
|
||||
* inner class, has a receiver type derived from the {@linkplain
|
||||
* #getEnclosingElement declaring type}.
|
||||
*
|
||||
* An executable which is a static method, or a constructor of a
|
||||
* non-inner class, or an initializer (static or instance), has no
|
||||
* receiver type.
|
||||
*
|
||||
* @return the receiver type of this executable
|
||||
* @since 1.8
|
||||
*/
|
||||
TypeMirror getReceiverType();
|
||||
|
||||
/**
|
||||
* Returns the exceptions and other throwables listed in this
|
||||
* executable's {@code throws} clause.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
package javax.lang.model.type;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
import javax.lang.model.element.*;
|
||||
import javax.lang.model.util.Types;
|
||||
|
||||
@ -55,7 +57,7 @@ import javax.lang.model.util.Types;
|
||||
* @see Types
|
||||
* @since 1.6
|
||||
*/
|
||||
public interface TypeMirror {
|
||||
public interface TypeMirror extends javax.lang.model.AnnotatedConstruct {
|
||||
|
||||
/**
|
||||
* Returns the {@code kind} of this type.
|
||||
|
@ -59,6 +59,13 @@ public interface Types {
|
||||
/**
|
||||
* Tests whether two {@code TypeMirror} objects represent the same type.
|
||||
*
|
||||
* <p>Since annotations are only meta-data associated with a type,
|
||||
* the set of annotations on either argument is <em>not</em> taken
|
||||
* into account when computing whether or not two {@code
|
||||
* TypeMirror} objects are the same type. In particular, two
|
||||
* {@code TypeMirror} objects can have different annotations and
|
||||
* still be considered the same.
|
||||
*
|
||||
* <p>Caveat: if either of the arguments to this method represents a
|
||||
* wildcard, this method will return false. As a consequence, a wildcard
|
||||
* is not the same type as itself. This might be surprising at first,
|
||||
|
Loading…
Reference in New Issue
Block a user