src/share/classes/com/sun/tools/javac/model/JavacElements.java

changeset 1645
97f6839673d6
parent 1559
01af1b5c631d
child 1709
bae8387d16aa
     1.1 --- a/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Mon Mar 18 14:40:32 2013 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Mon Mar 18 18:33:13 2013 -0700
     1.3 @@ -25,10 +25,6 @@
     1.4  
     1.5  package com.sun.tools.javac.model;
     1.6  
     1.7 -import java.lang.annotation.Annotation;
     1.8 -import java.lang.annotation.Inherited;
     1.9 -import java.lang.reflect.InvocationTargetException;
    1.10 -import java.lang.reflect.Method;
    1.11  import java.util.Map;
    1.12  
    1.13  import javax.lang.model.SourceVersion;
    1.14 @@ -40,7 +36,6 @@
    1.15  
    1.16  import com.sun.tools.javac.code.*;
    1.17  import com.sun.tools.javac.code.Symbol.*;
    1.18 -import com.sun.tools.javac.code.TypeTag;
    1.19  import com.sun.tools.javac.comp.AttrContext;
    1.20  import com.sun.tools.javac.comp.Enter;
    1.21  import com.sun.tools.javac.comp.Env;
    1.22 @@ -98,237 +93,6 @@
    1.23          enter = Enter.instance(context);
    1.24      }
    1.25  
    1.26 -    /**
    1.27 -     * An internal-use utility that creates a runtime view of an
    1.28 -     * annotation. This is the implementation of
    1.29 -     * Element.getAnnotation(Class).
    1.30 -     */
    1.31 -    public static <A extends Annotation> A getAnnotation(Symbol annotated,
    1.32 -                                                         Class<A> annoType) {
    1.33 -        if (!annoType.isAnnotation())
    1.34 -            throw new IllegalArgumentException("Not an annotation type: "
    1.35 -                                               + annoType);
    1.36 -        Attribute.Compound c;
    1.37 -        if (annotated.kind == Kinds.TYP && annotated instanceof ClassSymbol) {
    1.38 -            c = getAttributeOnClass((ClassSymbol)annotated, annoType);
    1.39 -        } else {
    1.40 -            c = getAttribute(annotated, annoType);
    1.41 -        }
    1.42 -        return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType);
    1.43 -    }
    1.44 -
    1.45 -    // Helper to getAnnotation[s]
    1.46 -    private static <A extends Annotation> Attribute.Compound getAttribute(Symbol annotated,
    1.47 -                                                                          Class<A> annoType) {
    1.48 -        String name = annoType.getName();
    1.49 -
    1.50 -        for (Attribute.Compound anno : annotated.getRawAttributes())
    1.51 -            if (name.equals(anno.type.tsym.flatName().toString()))
    1.52 -                return anno;
    1.53 -
    1.54 -        return null;
    1.55 -    }
    1.56 -    // Helper to getAnnotation[s]
    1.57 -    private static <A extends Annotation> Attribute.Compound getAttributeOnClass(ClassSymbol annotated,
    1.58 -                                                                Class<A> annoType) {
    1.59 -        boolean inherited = annoType.isAnnotationPresent(Inherited.class);
    1.60 -        Attribute.Compound result = null;
    1.61 -        while (annotated.name != annotated.name.table.names.java_lang_Object) {
    1.62 -            result = getAttribute(annotated, annoType);
    1.63 -            if (result != null || !inherited)
    1.64 -                break;
    1.65 -            Type sup = annotated.getSuperclass();
    1.66 -            if (!sup.hasTag(CLASS) || sup.isErroneous())
    1.67 -                break;
    1.68 -            annotated = (ClassSymbol) sup.tsym;
    1.69 -        }
    1.70 -        return result;
    1.71 -    }
    1.72 -
    1.73 -    /**
    1.74 -     * An internal-use utility that creates a runtime view of
    1.75 -     * annotations. This is the implementation of
    1.76 -     * Element.getAnnotations(Class).
    1.77 -     */
    1.78 -    public static <A extends Annotation> A[] getAnnotations(Symbol annotated,
    1.79 -                                                            Class<A> annoType) {
    1.80 -        if (!annoType.isAnnotation())
    1.81 -            throw new IllegalArgumentException("Not an annotation type: "
    1.82 -                                               + annoType);
    1.83 -        // If annoType does not declare a container this is equivalent to wrapping
    1.84 -        // getAnnotation(...) in an array.
    1.85 -        Class <? extends Annotation> containerType = getContainer(annoType);
    1.86 -        if (containerType == null) {
    1.87 -            A res = getAnnotation(annotated, annoType);
    1.88 -            int size;
    1.89 -            if (res == null) {
    1.90 -                size = 0;
    1.91 -            } else {
    1.92 -                size = 1;
    1.93 -            }
    1.94 -            @SuppressWarnings("unchecked") // annoType is the Class for A
    1.95 -            A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
    1.96 -            if (res != null)
    1.97 -                arr[0] = res;
    1.98 -            return arr;
    1.99 -        }
   1.100 -
   1.101 -        // So we have a containing type
   1.102 -        String name = annoType.getName();
   1.103 -        String annoTypeName = annoType.getSimpleName();
   1.104 -        String containerTypeName = containerType.getSimpleName();
   1.105 -        int directIndex = -1, containerIndex = -1;
   1.106 -        Attribute.Compound direct = null, container = null;
   1.107 -        Attribute.Compound[] rawAttributes = annotated.getRawAttributes().toArray(new Attribute.Compound[0]);
   1.108 -
   1.109 -        // Find directly present annotations
   1.110 -        for (int i = 0; i < rawAttributes.length; i++) {
   1.111 -            if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
   1.112 -                directIndex = i;
   1.113 -                direct = rawAttributes[i];
   1.114 -            } else if(containerTypeName != null &&
   1.115 -                      containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
   1.116 -                containerIndex = i;
   1.117 -                container = rawAttributes[i];
   1.118 -            }
   1.119 -        }
   1.120 -        // Deal with inherited annotations
   1.121 -        if (annotated.kind == Kinds.TYP &&
   1.122 -                (annotated instanceof ClassSymbol)) {
   1.123 -            ClassSymbol s = (ClassSymbol)annotated;
   1.124 -            if (direct == null && container == null) {
   1.125 -                direct = getAttributeOnClass(s, annoType);
   1.126 -                container = getAttributeOnClass(s, containerType);
   1.127 -
   1.128 -                // both are inherited and found, put container last
   1.129 -                if (direct != null && container != null) {
   1.130 -                    directIndex = 0;
   1.131 -                    containerIndex = 1;
   1.132 -                } else if (direct != null) {
   1.133 -                    directIndex = 0;
   1.134 -                } else {
   1.135 -                    containerIndex = 0;
   1.136 -                }
   1.137 -            } else if (direct == null) {
   1.138 -                direct = getAttributeOnClass(s, annoType);
   1.139 -                if (direct != null)
   1.140 -                    directIndex = containerIndex + 1;
   1.141 -            } else if (container == null) {
   1.142 -                container = getAttributeOnClass(s, containerType);
   1.143 -                if (container != null)
   1.144 -                    containerIndex = directIndex + 1;
   1.145 -            }
   1.146 -        }
   1.147 -
   1.148 -        // Pack them in an array
   1.149 -        Attribute[] contained0 = new Attribute[0];
   1.150 -        if (container != null)
   1.151 -            contained0 = unpackAttributes(container);
   1.152 -        ListBuffer<Attribute.Compound> compounds = ListBuffer.lb();
   1.153 -        for (Attribute a : contained0)
   1.154 -            if (a instanceof Attribute.Compound)
   1.155 -                compounds = compounds.append((Attribute.Compound)a);
   1.156 -        Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]);
   1.157 -
   1.158 -        int size = (direct == null ? 0 : 1) + contained.length;
   1.159 -        @SuppressWarnings("unchecked") // annoType is the Class for A
   1.160 -        A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
   1.161 -
   1.162 -        // if direct && container, which is first?
   1.163 -        int insert = -1;
   1.164 -        int length = arr.length;
   1.165 -        if (directIndex >= 0 && containerIndex >= 0) {
   1.166 -            if (directIndex < containerIndex) {
   1.167 -                arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
   1.168 -                insert = 1;
   1.169 -            } else {
   1.170 -                arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
   1.171 -                insert = 0;
   1.172 -                length--;
   1.173 -            }
   1.174 -        } else if (directIndex >= 0) {
   1.175 -            arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
   1.176 -            return arr;
   1.177 -        } else {
   1.178 -            // Only container
   1.179 -            insert = 0;
   1.180 -        }
   1.181 -
   1.182 -        for (int i = 0; i + insert < length; i++)
   1.183 -            arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType);
   1.184 -
   1.185 -        return arr;
   1.186 -    }
   1.187 -
   1.188 -    // Needed to unpack the runtime view of containing annotations
   1.189 -    private static final Class<? extends Annotation> REPEATABLE_CLASS = initRepeatable();
   1.190 -    private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod();
   1.191 -
   1.192 -    private static Class<? extends Annotation> initRepeatable() {
   1.193 -        try {
   1.194 -            // Repeatable will not be available when bootstrapping on
   1.195 -            // JDK 7 so use a reflective lookup instead of a class
   1.196 -            // literal for Repeatable.class.
   1.197 -            return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class);
   1.198 -        } catch (ClassNotFoundException e) {
   1.199 -            return null;
   1.200 -        } catch (SecurityException e) {
   1.201 -            return null;
   1.202 -        }
   1.203 -    }
   1.204 -    private static Method initValueElementMethod() {
   1.205 -        if (REPEATABLE_CLASS == null)
   1.206 -            return null;
   1.207 -
   1.208 -        Method m = null;
   1.209 -        try {
   1.210 -            m = REPEATABLE_CLASS.getMethod("value");
   1.211 -            if (m != null)
   1.212 -                m.setAccessible(true);
   1.213 -            return m;
   1.214 -        } catch (NoSuchMethodException e) {
   1.215 -            return null;
   1.216 -        }
   1.217 -    }
   1.218 -
   1.219 -    // Helper to getAnnotations
   1.220 -    private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) {
   1.221 -        // Since we can not refer to java.lang.annotation.Repeatable until we are
   1.222 -        // bootstrapping with java 8 we need to get the Repeatable annotation using
   1.223 -        // reflective invocations instead of just using its type and element method.
   1.224 -        if (REPEATABLE_CLASS != null &&
   1.225 -            VALUE_ELEMENT_METHOD != null) {
   1.226 -            // Get the Repeatable instance on the annotations declaration
   1.227 -            Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS);
   1.228 -            if (repeatable != null) {
   1.229 -                try {
   1.230 -                    // Get the value element, it should be a class
   1.231 -                    // indicating the containing annotation type
   1.232 -                    @SuppressWarnings("unchecked")
   1.233 -                    Class<? extends Annotation> containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable);
   1.234 -                    if (containerType == null)
   1.235 -                        return null;
   1.236 -
   1.237 -                    return containerType;
   1.238 -                } catch (ClassCastException e) {
   1.239 -                    return null;
   1.240 -                } catch (IllegalAccessException e) {
   1.241 -                    return null;
   1.242 -                } catch (InvocationTargetException e ) {
   1.243 -                    return null;
   1.244 -                }
   1.245 -            }
   1.246 -        }
   1.247 -        return null;
   1.248 -    }
   1.249 -    // Helper to getAnnotations
   1.250 -    private static Attribute[] unpackAttributes(Attribute.Compound container) {
   1.251 -        // We now have an instance of the container,
   1.252 -        // unpack it returning an instance of the
   1.253 -        // contained type or null
   1.254 -        return ((Attribute.Array)container.member(container.type.tsym.name.table.names.value)).values;
   1.255 -    }
   1.256 -
   1.257      public PackageSymbol getPackageElement(CharSequence name) {
   1.258          String strName = name.toString();
   1.259          if (strName.equals(""))

mercurial