jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java
author alanb
Fri, 02 Nov 2012 15:50:11 +0000
changeset 14342 8435a30053c1
parent 10342 ca0984bc9d32
child 14676 985410ec95e3
permissions -rw-r--r--
7197491: update copyright year to match last edit in jdk8 jdk repository Reviewed-by: chegar, ksrini
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
14342
8435a30053c1 7197491: update copyright year to match last edit in jdk8 jdk repository
alanb
parents: 10342
diff changeset
     2
 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3959
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3959
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3959
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3959
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3959
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.reflect.annotation;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.lang.annotation.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.nio.ByteBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.nio.BufferUnderflowException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.lang.reflect.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import sun.reflect.ConstantPool;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import sun.reflect.generics.parser.SignatureParser;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import sun.reflect.generics.tree.TypeSignature;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import sun.reflect.generics.factory.GenericsFactory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import sun.reflect.generics.factory.CoreReflectionFactory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import sun.reflect.generics.visitor.Reifier;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import sun.reflect.generics.scope.ClassScope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * Parser for Java programming language annotations.  Translates
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * annotation byte streams emitted by compiler into annotation objects.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * @author  Josh Bloch
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * @since   1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
public class AnnotationParser {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
     * Parses the annotations described by the specified byte array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
     * resolving constant references in the specified constant pool.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
     * The array must contain an array of annotations as described
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
     * in the RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
     *   u2 num_annotations;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
     *   annotation annotations[num_annotations];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
     * @throws AnnotationFormatError if an annotation is found to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
     *         malformed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
     */
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
    62
    public static Map<Class<? extends Annotation>, Annotation> parseAnnotations(
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
                byte[] rawAnnotations,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
                ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
    65
                Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
        if (rawAnnotations == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
            return Collections.emptyMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
            return parseAnnotations2(rawAnnotations, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        } catch(BufferUnderflowException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
            throw new AnnotationFormatError("Unexpected end of annotations.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        } catch(IllegalArgumentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
            // Type mismatch in constant pool
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
            throw new AnnotationFormatError(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
    79
    private static Map<Class<? extends Annotation>, Annotation> parseAnnotations2(
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
                byte[] rawAnnotations,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
                ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
    82
                Class<?> container) {
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
    83
        Map<Class<? extends Annotation>, Annotation> result =
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
    84
            new LinkedHashMap<Class<? extends Annotation>, Annotation>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        int numAnnotations = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        for (int i = 0; i < numAnnotations; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
            Annotation a = parseAnnotation(buf, constPool, container, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
            if (a != null) {
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
    90
                Class<? extends Annotation> klass = a.annotationType();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
                AnnotationType type = AnnotationType.getInstance(klass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
                if (type.retention() == RetentionPolicy.RUNTIME)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
                    if (result.put(klass, a) != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
                        throw new AnnotationFormatError(
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
                            "Duplicate annotation for class: "+klass+": " + a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * Parses the parameter annotations described by the specified byte array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * resolving constant references in the specified constant pool.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * The array must contain an array of annotations as described
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     * in the RuntimeVisibleParameterAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     *    u1 num_parameters;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     *    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     *        u2 num_annotations;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     *        annotation annotations[num_annotations];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     *    } parameter_annotations[num_parameters];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     * Unlike parseAnnotations, rawAnnotations must not be null!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     * A null value must be handled by the caller.  This is so because
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * we cannot determine the number of parameters if rawAnnotations
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * is null.  Also, the caller should check that the number
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * of parameters indicated by the return value of this method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * matches the actual number of method parameters.  A mismatch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * indicates that an AnnotationFormatError should be thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * @throws AnnotationFormatError if an annotation is found to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     *         malformed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    public static Annotation[][] parseParameterAnnotations(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
                    byte[] rawAnnotations,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
                    ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   127
                    Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            return parseParameterAnnotations2(rawAnnotations, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        } catch(BufferUnderflowException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
            throw new AnnotationFormatError(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
                "Unexpected end of parameter annotations.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        } catch(IllegalArgumentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            // Type mismatch in constant pool
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            throw new AnnotationFormatError(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    private static Annotation[][] parseParameterAnnotations2(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                    byte[] rawAnnotations,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                    ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   142
                    Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        int numParameters = buf.get() & 0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        Annotation[][] result = new Annotation[numParameters][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        for (int i = 0; i < numParameters; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            int numAnnotations = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            List<Annotation> annotations =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                new ArrayList<Annotation>(numAnnotations);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            for (int j = 0; j < numAnnotations; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                Annotation a = parseAnnotation(buf, constPool, container, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
                if (a != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                    AnnotationType type = AnnotationType.getInstance(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                                              a.annotationType());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                    if (type.retention() == RetentionPolicy.RUNTIME)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
                        annotations.add(a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            result[i] = annotations.toArray(EMPTY_ANNOTATIONS_ARRAY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                    new Annotation[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * Parses the annotation at the current position in the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * byte buffer, resolving constant references in the specified constant
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * pool.  The cursor of the byte buffer must point to an "annotation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * structure" as described in the RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     * annotation {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     *    u2    type_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     *       u2    num_member_value_pairs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
     *       {    u2    member_name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     *             member_value value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
     *       }    member_value_pairs[num_member_value_pairs];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     *    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     * Returns the annotation, or null if the annotation's type cannot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     * be found by the VM, or is not a valid annotation type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * @param exceptionOnMissingAnnotationClass if true, throw
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     * TypeNotPresentException if a referenced annotation type is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     * available at runtime
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     */
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   190
    @SuppressWarnings("unchecked")
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    private static Annotation parseAnnotation(ByteBuffer buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
                                              ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   193
                                              Class<?> container,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                                              boolean exceptionOnMissingAnnotationClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        int typeIndex = buf.getShort() & 0xFFFF;
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   196
        Class<? extends Annotation> annotationClass = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        String sig = "[unknown]";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                sig = constPool.getUTF8At(typeIndex);
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   201
                annotationClass = (Class<? extends Annotation>)parseSig(sig, container);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            } catch (IllegalArgumentException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                // support obsolete early jsr175 format class files
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   204
                annotationClass = (Class<? extends Annotation>)constPool.getClassAt(typeIndex);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        } catch (NoClassDefFoundError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            if (exceptionOnMissingAnnotationClass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                // note: at this point sig is "[unknown]" or VM-style
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                // name instead of a binary name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                throw new TypeNotPresentException(sig, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            skipAnnotation(buf, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        catch (TypeNotPresentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            if (exceptionOnMissingAnnotationClass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            skipAnnotation(buf, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        AnnotationType type = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
            type = AnnotationType.getInstance(annotationClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        } catch (IllegalArgumentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            skipAnnotation(buf, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   228
        Map<String, Class<?>> memberTypes = type.memberTypes();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        Map<String, Object> memberValues =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            new LinkedHashMap<String, Object>(type.memberDefaults());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        int numMembers = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        for (int i = 0; i < numMembers; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
            int memberNameIndex = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            String memberName = constPool.getUTF8At(memberNameIndex);
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   236
            Class<?> memberType = memberTypes.get(memberName);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            if (memberType == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                // Member is no longer present in annotation type; ignore it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                skipMemberValue(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                Object value = parseMemberValue(memberType, buf, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                if (value instanceof AnnotationTypeMismatchExceptionProxy)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                    ((AnnotationTypeMismatchExceptionProxy) value).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                        setMember(type.members().get(memberName));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                memberValues.put(memberName, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        return annotationForMap(annotationClass, memberValues);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * Returns an annotation of the given type backed by the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     * member -> value map.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    public static Annotation annotationForMap(
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   257
        Class<? extends Annotation> type, Map<String, Object> memberValues)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        return (Annotation) Proxy.newProxyInstance(
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   260
            type.getClassLoader(), new Class<?>[] { type },
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            new AnnotationInvocationHandler(type, memberValues));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     * Parses the annotation member value at the current position in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
     * specified byte buffer, resolving constant references in the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
     * constant pool.  The cursor of the byte buffer must point to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     * "member_value structure" as described in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     * RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     *  member_value {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     *    u1 tag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     *    union {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     *       u2   const_value_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     *       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     *           u2   type_name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     *           u2   const_name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     *       } enum_const_value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     *       u2   class_info_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     *       annotation annotation_value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     *       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     *           u2    num_values;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
     *           member_value values[num_values];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
     *       } array_value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     *    } value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
     * }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * The member must be of the indicated type. If it is not, this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * method returns an AnnotationTypeMismatchExceptionProxy.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     */
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   291
    @SuppressWarnings("unchecked")
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   292
    public static Object parseMemberValue(Class<?> memberType,
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   293
                                          ByteBuffer buf,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                                          ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   295
                                          Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        Object result = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        int tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        switch(tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
          case 'e':
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   300
              return parseEnumValue((Class<? extends Enum<?>>)memberType, buf, constPool, container);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
          case 'c':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
              result = parseClassValue(buf, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
              break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
          case '@':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
              result = parseAnnotation(buf, constPool, container, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
              break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
          case '[':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
              return parseArray(memberType, buf, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
          default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
              result = parseConst(tag, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        if (!(result instanceof ExceptionProxy) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            !memberType.isInstance(result))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            result = new AnnotationTypeMismatchExceptionProxy(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                result.getClass() + "[" + result + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * Parses the primitive or String annotation member value indicated by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     * the specified tag byte at the current position in the specified byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     * buffer, resolving constant reference in the specified constant pool.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     * The cursor of the byte buffer must point to an annotation member value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * of the type indicated by the specified tag, as described in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     *       u2   const_value_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    private static Object parseConst(int tag,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                                     ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        int constIndex = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        switch(tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
          case 'B':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            return Byte.valueOf((byte) constPool.getIntAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
          case 'C':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            return Character.valueOf((char) constPool.getIntAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
          case 'D':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            return Double.valueOf(constPool.getDoubleAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
          case 'F':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            return Float.valueOf(constPool.getFloatAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
          case 'I':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            return Integer.valueOf(constPool.getIntAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
          case 'J':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            return Long.valueOf(constPool.getLongAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
          case 'S':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            return Short.valueOf((short) constPool.getIntAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
          case 'Z':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            return Boolean.valueOf(constPool.getIntAt(constIndex) != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
          case 's':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            return constPool.getUTF8At(constIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
          default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            throw new AnnotationFormatError(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                "Invalid member-value tag in annotation: " + tag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     * Parses the Class member value at the current position in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     * specified byte buffer, resolving constant references in the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     * constant pool.  The cursor of the byte buffer must point to a "class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * info index" as described in the RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     *       u2   class_info_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    private static Object parseClassValue(ByteBuffer buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                                          ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   368
                                          Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        int classIndex = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                String sig = constPool.getUTF8At(classIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                return parseSig(sig, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            } catch (IllegalArgumentException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                // support obsolete early jsr175 format class files
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                return constPool.getClassAt(classIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        } catch (NoClassDefFoundError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            return new TypeNotPresentExceptionProxy("[unknown]", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        catch (TypeNotPresentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            return new TypeNotPresentExceptionProxy(e.typeName(), e.getCause());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   386
    private static Class<?> parseSig(String sig, Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        if (sig.equals("V")) return void.class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        SignatureParser parser = SignatureParser.make();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        TypeSignature typeSig = parser.parseTypeSig(sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        GenericsFactory factory = CoreReflectionFactory.make(container, ClassScope.make(container));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        Reifier reify = Reifier.make(factory);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        typeSig.accept(reify);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        Type result = reify.getResult();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        return toClass(result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    }
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   396
    static Class<?> toClass(Type o) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        if (o instanceof GenericArrayType)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                                     0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                .getClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        return (Class)o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     * Parses the enum constant member value at the current position in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     * specified byte buffer, resolving constant references in the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     * constant pool.  The cursor of the byte buffer must point to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     * "enum_const_value structure" as described in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
     * RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     *       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
     *           u2   type_name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     *           u2   const_name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
     *       } enum_const_value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
     */
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   416
    @SuppressWarnings({"rawtypes", "unchecked"})
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   417
    private static Object parseEnumValue(Class<? extends Enum> enumType, ByteBuffer buf,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                                         ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   419
                                         Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        int typeNameIndex = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        String typeName  = constPool.getUTF8At(typeNameIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        int constNameIndex = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        String constName = constPool.getUTF8At(constNameIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        if (!typeName.endsWith(";")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
            // support now-obsolete early jsr175-format class files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
            if (!enumType.getName().equals(typeName))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            return new AnnotationTypeMismatchExceptionProxy(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
                typeName + "." + constName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        } else if (enumType != parseSig(typeName, container)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
            return new AnnotationTypeMismatchExceptionProxy(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
                typeName + "." + constName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            return  Enum.valueOf(enumType, constName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        } catch(IllegalArgumentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            return new EnumConstantNotPresentExceptionProxy(
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   439
                (Class<? extends Enum<?>>)enumType, constName);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
     * Parses the array value at the current position in the specified byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
     * buffer, resolving constant references in the specified constant pool.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
     * The cursor of the byte buffer must point to an array value struct
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
     * as specified in the RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     *       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     *           u2    num_values;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     *           member_value values[num_values];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     *       } array_value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     * If the array values do not match arrayType, an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     * AnnotationTypeMismatchExceptionProxy will be returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     */
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   457
    @SuppressWarnings("unchecked")
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   458
    private static Object parseArray(Class<?> arrayType,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                                     ByteBuffer buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                                     ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   461
                                     Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        int length = buf.getShort() & 0xFFFF;  // Number of array components
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   463
        Class<?> componentType = arrayType.getComponentType();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        if (componentType == byte.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
            return parseByteArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        } else if (componentType == char.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
            return parseCharArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        } else if (componentType == double.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
            return parseDoubleArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        } else if (componentType == float.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
            return parseFloatArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        } else if (componentType == int.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
            return parseIntArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        } else if (componentType == long.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
            return parseLongArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        } else if (componentType == short.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
            return parseShortArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        } else if (componentType == boolean.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
            return parseBooleanArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        } else if (componentType == String.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
            return parseStringArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        } else if (componentType == Class.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
            return parseClassArray(length, buf, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        } else if (componentType.isEnum()) {
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   486
            return parseEnumArray(length, (Class<? extends Enum<?>>)componentType, buf,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                                  constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
            assert componentType.isAnnotation();
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   490
            return parseAnnotationArray(length, (Class <? extends Annotation>)componentType, buf,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                                        constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    private static Object parseByteArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                                  ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        byte[] result = new byte[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
            if (tag == 'B') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                result[i] = (byte) constPool.getIntAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
    private static Object parseCharArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                                  ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        char[] result = new char[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        byte tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
            if (tag == 'C') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                result[i] = (char) constPool.getIntAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    private static Object parseDoubleArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                                    ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
        double[] result = new  double[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            if (tag == 'D') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                result[i] = constPool.getDoubleAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
    private static Object parseFloatArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                                   ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
        float[] result = new float[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            if (tag == 'F') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                result[i] = constPool.getFloatAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    private static Object parseIntArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                                 ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        int[] result = new  int[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
            if (tag == 'I') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                result[i] = constPool.getIntAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    private static Object parseLongArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                                  ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        long[] result = new long[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            if (tag == 'J') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                result[i] = constPool.getLongAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
    private static Object parseShortArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                                   ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        short[] result = new short[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
            if (tag == 'S') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
                result[i] = (short) constPool.getIntAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    private static Object parseBooleanArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                                     ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        boolean[] result = new boolean[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
            if (tag == 'Z') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                result[i] = (constPool.getIntAt(index) != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    private static Object parseStringArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                                    ByteBuffer buf,  ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        String[] result = new String[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
            if (tag == 's') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
                result[i] = constPool.getUTF8At(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    private static Object parseClassArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                                          ByteBuffer buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                                          ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   669
                                          Class<?> container) {
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   670
        Object[] result = new Class<?>[length];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
            if (tag == 'c') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                result[i] = parseClassValue(buf, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   686
    private static Object parseEnumArray(int length, Class<? extends Enum<?>> enumType,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
                                         ByteBuffer buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                                         ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   689
                                         Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        Object[] result = (Object[]) Array.newInstance(enumType, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
            if (tag == 'e') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
                result[i] = parseEnumValue(enumType, buf, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
    private static Object parseAnnotationArray(int length,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   707
                                               Class<? extends Annotation> annotationType,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                                               ByteBuffer buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                                               ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   710
                                               Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        Object[] result = (Object[]) Array.newInstance(annotationType, length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
            if (tag == '@') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
                result[i] = parseAnnotation(buf, constPool, container, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
     * Return an appropriate exception proxy for a mismatching array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
     * annotation where the erroneous array has the specified tag.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
    private static ExceptionProxy exceptionProxy(int tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
        return new AnnotationTypeMismatchExceptionProxy(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
            "Array with component tag: " + tag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
     * Skips the annotation at the current position in the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
     * byte buffer.  The cursor of the byte buffer must point to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
     * an "annotation structure" OR two bytes into an annotation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
     * structure (i.e., after the type index).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
     * @parameter complete true if the byte buffer points to the beginning
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
     *     of an annotation structure (rather than two bytes in).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
    private static void skipAnnotation(ByteBuffer buf, boolean complete) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        if (complete)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
            buf.getShort();   // Skip type index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        int numMembers = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        for (int i = 0; i < numMembers; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
            buf.getShort();   // Skip memberNameIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
            skipMemberValue(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
     * Skips the annotation member value at the current position in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
     * specified byte buffer.  The cursor of the byte buffer must point to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
     * "member_value structure."
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
    private static void skipMemberValue(ByteBuffer buf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        int tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
     * Skips the annotation member value at the current position in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
     * specified byte buffer.  The cursor of the byte buffer must point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
     * immediately after the tag in a "member_value structure."
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
    private static void skipMemberValue(int tag, ByteBuffer buf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
        switch(tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
          case 'e': // Enum value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            buf.getInt();  // (Two shorts, actually.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
          case '@':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
            skipAnnotation(buf, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
          case '[':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
            skipArray(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
          default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
            // Class, primitive, or String
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            buf.getShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
     * Skips the array value at the current position in the specified byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
     * buffer.  The cursor of the byte buffer must point to an array value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
     * struct.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    private static void skipArray(ByteBuffer buf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
        int length = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        for (int i = 0; i < length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
            skipMemberValue(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
    }
2174
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   797
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   798
    /*
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   799
     * This method converts the annotation map returned by the parseAnnotations()
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   800
     * method to an array.  It is called by Field.getDeclaredAnnotations(),
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   801
     * Method.getDeclaredAnnotations(), and Constructor.getDeclaredAnnotations().
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   802
     * This avoids the reflection classes to load the Annotation class until
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   803
     * it is needed.
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   804
     */
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   805
    private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   806
    public static Annotation[] toArray(Map<Class<? extends Annotation>, Annotation> annotations) {
2174
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   807
        return annotations.values().toArray(EMPTY_ANNOTATION_ARRAY);
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   808
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
}