--- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java Mon Mar 18 18:33:13 2013 -0700
@@ -311,9 +311,9 @@
}
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("...");
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Mon Mar 18 18:33:13 2013 -0700
@@ -483,12 +483,12 @@
*/
@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 @@
}
/**
- * @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 @@
return v.visitMethodSymbol(this, p);
}
+ public Type getReceiverType() {
+ return asType().getReceiverType();
+ }
+
public Type getReturnType() {
return asType().getReturnType();
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Mon Mar 18 18:33:13 2013 -0700
@@ -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 @@
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 @@
}
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 @@
/** 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 @@
}
@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
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Mar 18 18:33:13 2013 -0700
@@ -4279,7 +4279,7 @@
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");
}
--- a/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Mon Mar 18 18:33:13 2013 -0700
@@ -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 @@
/**
* 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 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java Mon Mar 18 18:33:13 2013 -0700
@@ -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>
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Mon Mar 18 18:33:13 2013 -0700
@@ -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 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 @@
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(""))
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Mon Mar 18 18:33:13 2013 -0700
@@ -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;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java Mon Mar 18 18:33:13 2013 -0700
@@ -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);
+}
--- a/langtools/src/share/classes/javax/lang/model/element/Element.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/javax/lang/model/element/Element.java Mon Mar 18 18:33:13 2013 -0700
@@ -60,8 +60,7 @@
* @see TypeMirror
* @since 1.6
*/
-public interface Element {
-
+public interface Element extends javax.lang.model.AnnotatedConstruct {
/**
* Returns the type defined by this element.
*
@@ -89,119 +88,6 @@
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}
* modifiers of interface members, are included.
@@ -325,6 +211,19 @@
*/
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.
*
--- a/langtools/src/share/classes/javax/lang/model/element/ExecutableElement.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/javax/lang/model/element/ExecutableElement.java Mon Mar 18 18:33:13 2013 -0700
@@ -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
@@ -69,6 +69,25 @@
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.
*
--- a/langtools/src/share/classes/javax/lang/model/type/ExecutableType.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/javax/lang/model/type/ExecutableType.java Mon Mar 18 18:33:13 2013 -0700
@@ -78,6 +78,25 @@
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.
*
--- a/langtools/src/share/classes/javax/lang/model/type/TypeMirror.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/javax/lang/model/type/TypeMirror.java Mon Mar 18 18:33:13 2013 -0700
@@ -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 @@
* @see Types
* @since 1.6
*/
-public interface TypeMirror {
+public interface TypeMirror extends javax.lang.model.AnnotatedConstruct {
/**
* Returns the {@code kind} of this type.
--- a/langtools/src/share/classes/javax/lang/model/util/Types.java Mon Mar 18 14:40:32 2013 -0700
+++ b/langtools/src/share/classes/javax/lang/model/util/Types.java Mon Mar 18 18:33:13 2013 -0700
@@ -59,6 +59,13 @@
/**
* 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,