src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java
author cushon
Mon, 18 Jun 2018 18:49:34 -0700
changeset 50620 2b7714a592a1
parent 50591 9f4c08c444e8
permissions -rw-r--r--
8198669: Refactor annotation array value parsing to reduce duplication Reviewed-by: psandoz, darcy
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
15510
898d924a7efd 8004698: Implement Core Reflection for Type Annotations
jfranck
parents: 14676
diff changeset
     2
 * Copyright (c) 2003, 2013, 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.*;
50620
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
    29
import java.lang.reflect.*;
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
    30
import java.nio.BufferUnderflowException;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.nio.ByteBuffer;
50620
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
    32
import java.util.*;
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
    33
import java.util.function.Supplier;
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 15510
diff changeset
    34
import java.security.AccessController;
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 15510
diff changeset
    35
import java.security.PrivilegedAction;
37363
329dba26ffd2 8137058: Clear out all non-Critical APIs from sun.reflect
chegar
parents: 31061
diff changeset
    36
import jdk.internal.reflect.ConstantPool;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import sun.reflect.generics.parser.SignatureParser;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import sun.reflect.generics.tree.TypeSignature;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import sun.reflect.generics.factory.GenericsFactory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import sun.reflect.generics.factory.CoreReflectionFactory;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import sun.reflect.generics.visitor.Reifier;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import sun.reflect.generics.scope.ClassScope;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * Parser for Java programming language annotations.  Translates
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * annotation byte streams emitted by compiler into annotation objects.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * @author  Josh Bloch
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * @since   1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
public class AnnotationParser {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
     * Parses the annotations described by the specified byte array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
     * resolving constant references in the specified constant pool.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
     * The array must contain an array of annotations as described
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
     * in the RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
     *   u2 num_annotations;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
     *   annotation annotations[num_annotations];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
     * @throws AnnotationFormatError if an annotation is found to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     *         malformed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
     */
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
    65
    public static Map<Class<? extends Annotation>, Annotation> parseAnnotations(
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
                byte[] rawAnnotations,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
                ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
    68
                Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
        if (rawAnnotations == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
            return Collections.emptyMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        try {
18827
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    73
            return parseAnnotations2(rawAnnotations, constPool, container, null);
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    74
        } catch(BufferUnderflowException e) {
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    75
            throw new AnnotationFormatError("Unexpected end of annotations.");
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    76
        } catch(IllegalArgumentException e) {
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    77
            // Type mismatch in constant pool
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    78
            throw new AnnotationFormatError(e);
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    79
        }
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    80
    }
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    81
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    82
    /**
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    83
     * Like {@link #parseAnnotations(byte[], sun.reflect.ConstantPool, Class)}
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    84
     * with an additional parameter {@code selectAnnotationClasses} which selects the
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    85
     * annotation types to parse (other than selected are quickly skipped).<p>
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    86
     * This method is only used to parse select meta annotations in the construction
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    87
     * phase of {@link AnnotationType} instances to prevent infinite recursion.
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    88
     *
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    89
     * @param selectAnnotationClasses an array of annotation types to select when parsing
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    90
     */
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    91
    @SafeVarargs
19199
4dfcc94aa1f2 8022190: Fix varargs lint warnings in the JDK
darcy
parents: 18827
diff changeset
    92
    @SuppressWarnings("varargs") // selectAnnotationClasses is used safely
18827
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    93
    static Map<Class<? extends Annotation>, Annotation> parseSelectAnnotations(
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    94
                byte[] rawAnnotations,
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    95
                ConstantPool constPool,
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    96
                Class<?> container,
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    97
                Class<? extends Annotation> ... selectAnnotationClasses) {
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    98
        if (rawAnnotations == null)
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
    99
            return Collections.emptyMap();
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   100
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   101
        try {
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   102
            return parseAnnotations2(rawAnnotations, constPool, container, selectAnnotationClasses);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        } catch(BufferUnderflowException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
            throw new AnnotationFormatError("Unexpected end of annotations.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        } catch(IllegalArgumentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
            // Type mismatch in constant pool
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
            throw new AnnotationFormatError(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   111
    private static Map<Class<? extends Annotation>, Annotation> parseAnnotations2(
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
                byte[] rawAnnotations,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                ConstantPool constPool,
18827
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   114
                Class<?> container,
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   115
                Class<? extends Annotation>[] selectAnnotationClasses) {
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   116
        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
   117
            new LinkedHashMap<Class<? extends Annotation>, Annotation>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        int numAnnotations = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        for (int i = 0; i < numAnnotations; i++) {
18827
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   121
            Annotation a = parseAnnotation2(buf, constPool, container, false, selectAnnotationClasses);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
            if (a != null) {
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   123
                Class<? extends Annotation> klass = a.annotationType();
18827
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   124
                if (AnnotationType.getInstance(klass).retention() == RetentionPolicy.RUNTIME &&
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   125
                    result.put(klass, a) != null) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
                        throw new AnnotationFormatError(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                            "Duplicate annotation for class: "+klass+": " + a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        }
18827
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   130
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     * Parses the parameter annotations described by the specified byte array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     * resolving constant references in the specified constant pool.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * The array must contain an array of annotations as described
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * in the RuntimeVisibleParameterAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     *    u1 num_parameters;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     *    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     *        u2 num_annotations;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     *        annotation annotations[num_annotations];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     *    } parameter_annotations[num_parameters];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * Unlike parseAnnotations, rawAnnotations must not be null!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * A null value must be handled by the caller.  This is so because
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * we cannot determine the number of parameters if rawAnnotations
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * is null.  Also, the caller should check that the number
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * of parameters indicated by the return value of this method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     * matches the actual number of method parameters.  A mismatch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * indicates that an AnnotationFormatError should be thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * @throws AnnotationFormatError if an annotation is found to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     *         malformed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    public static Annotation[][] parseParameterAnnotations(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                    byte[] rawAnnotations,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                    ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   160
                    Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
            return parseParameterAnnotations2(rawAnnotations, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        } catch(BufferUnderflowException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            throw new AnnotationFormatError(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                "Unexpected end of parameter annotations.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        } catch(IllegalArgumentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            // Type mismatch in constant pool
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            throw new AnnotationFormatError(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    private static Annotation[][] parseParameterAnnotations2(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
                    byte[] rawAnnotations,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
                    ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   175
                    Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        int numParameters = buf.get() & 0xFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        Annotation[][] result = new Annotation[numParameters][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        for (int i = 0; i < numParameters; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            int numAnnotations = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            List<Annotation> annotations =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
                new ArrayList<Annotation>(numAnnotations);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            for (int j = 0; j < numAnnotations; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
                Annotation a = parseAnnotation(buf, constPool, container, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
                if (a != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
                    AnnotationType type = AnnotationType.getInstance(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
                                              a.annotationType());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                    if (type.retention() == RetentionPolicy.RUNTIME)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                        annotations.add(a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            result[i] = annotations.toArray(EMPTY_ANNOTATIONS_ARRAY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                    new Annotation[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
     * Parses the annotation at the current position in the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
     * byte buffer, resolving constant references in the specified constant
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
     * pool.  The cursor of the byte buffer must point to an "annotation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     * structure" as described in the RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * annotation {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     *    u2    type_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     *       u2    num_member_value_pairs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
     *       {    u2    member_name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
     *             member_value value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     *       }    member_value_pairs[num_member_value_pairs];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     *    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     * }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     * Returns the annotation, or null if the annotation's type cannot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     * be found by the VM, or is not a valid annotation type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
     * @param exceptionOnMissingAnnotationClass if true, throw
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
     * TypeNotPresentException if a referenced annotation type is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     * available at runtime
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
     */
15510
898d924a7efd 8004698: Implement Core Reflection for Type Annotations
jfranck
parents: 14676
diff changeset
   223
    static Annotation parseAnnotation(ByteBuffer buf,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                                              ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   225
                                              Class<?> container,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                                              boolean exceptionOnMissingAnnotationClass) {
18827
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   227
       return parseAnnotation2(buf, constPool, container, exceptionOnMissingAnnotationClass, null);
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   228
    }
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   229
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   230
    @SuppressWarnings("unchecked")
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   231
    private static Annotation parseAnnotation2(ByteBuffer buf,
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   232
                                              ConstantPool constPool,
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   233
                                              Class<?> container,
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   234
                                              boolean exceptionOnMissingAnnotationClass,
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   235
                                              Class<? extends Annotation>[] selectAnnotationClasses) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        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
   237
        Class<? extends Annotation> annotationClass = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        String sig = "[unknown]";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                sig = constPool.getUTF8At(typeIndex);
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   242
                annotationClass = (Class<? extends Annotation>)parseSig(sig, container);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
            } catch (IllegalArgumentException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                // 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
   245
                annotationClass = (Class<? extends Annotation>)constPool.getClassAt(typeIndex);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        } catch (NoClassDefFoundError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
            if (exceptionOnMissingAnnotationClass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                // note: at this point sig is "[unknown]" or VM-style
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
                // name instead of a binary name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                throw new TypeNotPresentException(sig, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            skipAnnotation(buf, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        catch (TypeNotPresentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            if (exceptionOnMissingAnnotationClass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            skipAnnotation(buf, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        }
18827
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   261
        if (selectAnnotationClasses != null && !contains(selectAnnotationClasses, annotationClass)) {
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   262
            skipAnnotation(buf, false);
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   263
            return null;
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   264
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        AnnotationType type = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            type = AnnotationType.getInstance(annotationClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        } catch (IllegalArgumentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            skipAnnotation(buf, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   273
        Map<String, Class<?>> memberTypes = type.memberTypes();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        Map<String, Object> memberValues =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
            new LinkedHashMap<String, Object>(type.memberDefaults());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        int numMembers = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        for (int i = 0; i < numMembers; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            int memberNameIndex = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            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
   281
            Class<?> memberType = memberTypes.get(memberName);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            if (memberType == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                // Member is no longer present in annotation type; ignore it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                skipMemberValue(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                Object value = parseMemberValue(memberType, buf, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                if (value instanceof AnnotationTypeMismatchExceptionProxy)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                    ((AnnotationTypeMismatchExceptionProxy) value).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                        setMember(type.members().get(memberName));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                memberValues.put(memberName, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        return annotationForMap(annotationClass, memberValues);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     * Returns an annotation of the given type backed by the given
31061
fead7d86d75f 8081517: minor cleanup for docs
avstepan
parents: 28056
diff changeset
   299
     * member {@literal ->} value map.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     */
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 15510
diff changeset
   301
    public static Annotation annotationForMap(final Class<? extends Annotation> type,
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 15510
diff changeset
   302
                                              final Map<String, Object> memberValues)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    {
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 15510
diff changeset
   304
        return AccessController.doPrivileged(new PrivilegedAction<Annotation>() {
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 15510
diff changeset
   305
            public Annotation run() {
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 15510
diff changeset
   306
                return (Annotation) Proxy.newProxyInstance(
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 15510
diff changeset
   307
                    type.getClassLoader(), new Class<?>[] { type },
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 15510
diff changeset
   308
                    new AnnotationInvocationHandler(type, memberValues));
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 15510
diff changeset
   309
            }});
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     * Parses the annotation member value at the current position in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     * specified byte buffer, resolving constant references in the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     * constant pool.  The cursor of the byte buffer must point to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     * "member_value structure" as described in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     * RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     *  member_value {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     *    u1 tag;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     *    union {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     *       u2   const_value_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     *       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     *           u2   type_name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     *           u2   const_name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     *       } enum_const_value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     *       u2   class_info_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     *       annotation annotation_value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     *       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     *           u2    num_values;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     *           member_value values[num_values];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     *       } array_value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
     *    } value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
     * }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
     * The member must be of the indicated type. If it is not, this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
     * method returns an AnnotationTypeMismatchExceptionProxy.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
     */
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   339
    @SuppressWarnings("unchecked")
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   340
    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
   341
                                          ByteBuffer buf,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                                          ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   343
                                          Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        Object result = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        int tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        switch(tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
          case 'e':
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   348
              return parseEnumValue((Class<? extends Enum<?>>)memberType, buf, constPool, container);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
          case 'c':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
              result = parseClassValue(buf, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
              break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
          case '@':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
              result = parseAnnotation(buf, constPool, container, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
              break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
          case '[':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
              return parseArray(memberType, buf, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
          default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
              result = parseConst(tag, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        if (!(result instanceof ExceptionProxy) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
            !memberType.isInstance(result))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            result = new AnnotationTypeMismatchExceptionProxy(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                result.getClass() + "[" + result + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
     * Parses the primitive or String annotation member value indicated by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
     * the specified tag byte at the current position in the specified byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     * buffer, resolving constant reference in the specified constant pool.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     * The cursor of the byte buffer must point to an annotation member value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     * of the type indicated by the specified tag, as described in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     * RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     *       u2   const_value_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    private static Object parseConst(int tag,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                                     ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        int constIndex = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        switch(tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
          case 'B':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
            return Byte.valueOf((byte) constPool.getIntAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
          case 'C':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            return Character.valueOf((char) constPool.getIntAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
          case 'D':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            return Double.valueOf(constPool.getDoubleAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
          case 'F':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            return Float.valueOf(constPool.getFloatAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
          case 'I':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
            return Integer.valueOf(constPool.getIntAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
          case 'J':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            return Long.valueOf(constPool.getLongAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
          case 'S':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            return Short.valueOf((short) constPool.getIntAt(constIndex));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
          case 'Z':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            return Boolean.valueOf(constPool.getIntAt(constIndex) != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
          case 's':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
            return constPool.getUTF8At(constIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
          default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            throw new AnnotationFormatError(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                "Invalid member-value tag in annotation: " + tag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     * Parses the Class member value at the current position in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     * specified byte buffer, resolving constant references in the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
     * constant pool.  The cursor of the byte buffer must point to a "class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
     * info index" as described in the RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
     *       u2   class_info_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    private static Object parseClassValue(ByteBuffer buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                                          ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   416
                                          Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        int classIndex = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                String sig = constPool.getUTF8At(classIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                return parseSig(sig, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            } catch (IllegalArgumentException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                // support obsolete early jsr175 format class files
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                return constPool.getClassAt(classIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        } catch (NoClassDefFoundError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
            return new TypeNotPresentExceptionProxy("[unknown]", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        catch (TypeNotPresentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
            return new TypeNotPresentExceptionProxy(e.typeName(), e.getCause());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   434
    private static Class<?> parseSig(String sig, Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        if (sig.equals("V")) return void.class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        SignatureParser parser = SignatureParser.make();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        TypeSignature typeSig = parser.parseTypeSig(sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        GenericsFactory factory = CoreReflectionFactory.make(container, ClassScope.make(container));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        Reifier reify = Reifier.make(factory);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        typeSig.accept(reify);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        Type result = reify.getResult();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        return toClass(result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
    }
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   444
    static Class<?> toClass(Type o) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        if (o instanceof GenericArrayType)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
            return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                                     0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                .getClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        return (Class)o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     * Parses the enum constant member value at the current position in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     * specified byte buffer, resolving constant references in the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     * constant pool.  The cursor of the byte buffer must point to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     * "enum_const_value structure" as described in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     * RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     *       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     *           u2   type_name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     *           u2   const_name_index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     *       } enum_const_value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     */
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   464
    @SuppressWarnings({"rawtypes", "unchecked"})
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   465
    private static Object parseEnumValue(Class<? extends Enum> enumType, ByteBuffer buf,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                                         ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   467
                                         Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        int typeNameIndex = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        String typeName  = constPool.getUTF8At(typeNameIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        int constNameIndex = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        String constName = constPool.getUTF8At(constNameIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        if (!typeName.endsWith(";")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
            // support now-obsolete early jsr175-format class files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            if (!enumType.getName().equals(typeName))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
            return new AnnotationTypeMismatchExceptionProxy(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                typeName + "." + constName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        } else if (enumType != parseSig(typeName, container)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            return new AnnotationTypeMismatchExceptionProxy(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                typeName + "." + constName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
            return  Enum.valueOf(enumType, constName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        } catch(IllegalArgumentException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            return new EnumConstantNotPresentExceptionProxy(
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   487
                (Class<? extends Enum<?>>)enumType, constName);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
     * Parses the array value at the current position in the specified byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
     * buffer, resolving constant references in the specified constant pool.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
     * The cursor of the byte buffer must point to an array value struct
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     * as specified in the RuntimeVisibleAnnotations_attribute:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
     *       {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
     *           u2    num_values;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
     *           member_value values[num_values];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
     *       } array_value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
     * If the array values do not match arrayType, an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
     * AnnotationTypeMismatchExceptionProxy will be returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
     */
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   505
    @SuppressWarnings("unchecked")
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   506
    private static Object parseArray(Class<?> arrayType,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                                     ByteBuffer buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                                     ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   509
                                     Class<?> container) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        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
   511
        Class<?> componentType = arrayType.getComponentType();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        if (componentType == byte.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
            return parseByteArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        } else if (componentType == char.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
            return parseCharArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        } else if (componentType == double.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            return parseDoubleArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        } else if (componentType == float.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
            return parseFloatArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        } else if (componentType == int.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
            return parseIntArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        } else if (componentType == long.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            return parseLongArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        } else if (componentType == short.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            return parseShortArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        } else if (componentType == boolean.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            return parseBooleanArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        } else if (componentType == String.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            return parseStringArray(length, buf, constPool);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        } else if (componentType == Class.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            return parseClassArray(length, buf, constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        } else if (componentType.isEnum()) {
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   534
            return parseEnumArray(length, (Class<? extends Enum<?>>)componentType, buf,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                                  constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            assert componentType.isAnnotation();
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   538
            return parseAnnotationArray(length, (Class <? extends Annotation>)componentType, buf,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                                        constPool, container);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
    private static Object parseByteArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                                  ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
        byte[] result = new byte[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            if (tag == 'B') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                result[i] = (byte) constPool.getIntAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    private static Object parseCharArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                                  ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
        char[] result = new char[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        byte tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
            if (tag == 'C') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                result[i] = (char) constPool.getIntAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
    private static Object parseDoubleArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                                    ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        double[] result = new  double[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            if (tag == 'D') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                result[i] = constPool.getDoubleAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
    private static Object parseFloatArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                                   ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        float[] result = new float[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
            if (tag == 'F') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                result[i] = constPool.getFloatAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
    private static Object parseIntArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                                 ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
        int[] result = new  int[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
            if (tag == 'I') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                result[i] = constPool.getIntAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
    private static Object parseLongArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
                                  ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        long[] result = new long[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
            if (tag == 'J') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                result[i] = constPool.getLongAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    private static Object parseShortArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                                   ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        short[] result = new short[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            if (tag == 'S') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                result[i] = (short) constPool.getIntAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
    private static Object parseBooleanArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                                     ByteBuffer buf, ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        boolean[] result = new boolean[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            if (tag == 'Z') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                result[i] = (constPool.getIntAt(index) != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
    private static Object parseStringArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
                                    ByteBuffer buf,  ConstantPool constPool) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        String[] result = new String[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        boolean typeMismatch = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        int tag = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
            tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            if (tag == 's') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
                int index = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
                result[i] = constPool.getUTF8At(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
                skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                typeMismatch = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        return typeMismatch ? exceptionProxy(tag) : result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
    private static Object parseClassArray(int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                                          ByteBuffer buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
                                          ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   717
                                          Class<?> container) {
50620
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   718
        return parseArrayElements(new Class<?>[length],
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   719
                buf, 'c', () -> parseClassValue(buf, constPool, container));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
10342
ca0984bc9d32 7077389: Reflection classes do not build with javac -Xlint:all -Werror
jjg
parents: 5506
diff changeset
   722
    private static Object parseEnumArray(int length, Class<? extends Enum<?>> enumType,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                                         ByteBuffer buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                                         ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   725
                                         Class<?> container) {
50620
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   726
        return parseArrayElements((Object[]) Array.newInstance(enumType, length),
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   727
                buf, 'e', () -> parseEnumValue(enumType, buf, constPool, container));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
    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
   731
                                               Class<? extends Annotation> annotationType,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
                                               ByteBuffer buf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
                                               ConstantPool constPool,
3959
05a07c0a273b 5062288: (reflect) Core reflection uses raw types when it could be using wildcards
darcy
parents: 2174
diff changeset
   734
                                               Class<?> container) {
50620
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   735
        return parseArrayElements((Object[]) Array.newInstance(annotationType, length),
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   736
                buf, '@', () -> parseAnnotation(buf, constPool, container, true));
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   737
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
50620
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   739
    private static Object parseArrayElements(Object[] result,
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   740
                                             ByteBuffer buf,
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   741
                                             int expectedTag,
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   742
                                             Supplier<Object> parseElement) {
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   743
        Object exceptionProxy = null;
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   744
        for (int i = 0; i < result.length; i++) {
50591
9f4c08c444e8 7183985: (ann) Class.getAnnotation() throws an ArrayStoreException when the annotation class not present
cushon
parents: 47216
diff changeset
   745
            int tag = buf.get();
50620
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   746
            if (tag == expectedTag) {
2b7714a592a1 8198669: Refactor annotation array value parsing to reduce duplication
cushon
parents: 50591
diff changeset
   747
                Object value = parseElement.get();
50591
9f4c08c444e8 7183985: (ann) Class.getAnnotation() throws an ArrayStoreException when the annotation class not present
cushon
parents: 47216
diff changeset
   748
                if (value instanceof ExceptionProxy) {
9f4c08c444e8 7183985: (ann) Class.getAnnotation() throws an ArrayStoreException when the annotation class not present
cushon
parents: 47216
diff changeset
   749
                    if (exceptionProxy == null) exceptionProxy = (ExceptionProxy) value;
9f4c08c444e8 7183985: (ann) Class.getAnnotation() throws an ArrayStoreException when the annotation class not present
cushon
parents: 47216
diff changeset
   750
                } else {
9f4c08c444e8 7183985: (ann) Class.getAnnotation() throws an ArrayStoreException when the annotation class not present
cushon
parents: 47216
diff changeset
   751
                    result[i] = value;
9f4c08c444e8 7183985: (ann) Class.getAnnotation() throws an ArrayStoreException when the annotation class not present
cushon
parents: 47216
diff changeset
   752
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                skipMemberValue(tag, buf);
50591
9f4c08c444e8 7183985: (ann) Class.getAnnotation() throws an ArrayStoreException when the annotation class not present
cushon
parents: 47216
diff changeset
   755
                if (exceptionProxy == null) exceptionProxy = exceptionProxy(tag);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        }
50591
9f4c08c444e8 7183985: (ann) Class.getAnnotation() throws an ArrayStoreException when the annotation class not present
cushon
parents: 47216
diff changeset
   758
        return (exceptionProxy != null) ? exceptionProxy : result;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
    /**
28056
0cab6eb92852 8065172: More core reflection final and volatile annotations
martin
parents: 25859
diff changeset
   762
     * Returns an appropriate exception proxy for a mismatching array
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
     * annotation where the erroneous array has the specified tag.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
    private static ExceptionProxy exceptionProxy(int tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        return new AnnotationTypeMismatchExceptionProxy(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            "Array with component tag: " + tag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
     * Skips the annotation at the current position in the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
     * byte buffer.  The cursor of the byte buffer must point to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
     * an "annotation structure" OR two bytes into an annotation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
     * structure (i.e., after the type index).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
     * @parameter complete true if the byte buffer points to the beginning
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
     *     of an annotation structure (rather than two bytes in).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
    private static void skipAnnotation(ByteBuffer buf, boolean complete) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
        if (complete)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
            buf.getShort();   // Skip type index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        int numMembers = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
        for (int i = 0; i < numMembers; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
            buf.getShort();   // Skip memberNameIndex
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            skipMemberValue(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
     * Skips the annotation member value at the current position in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
     * specified byte buffer.  The cursor of the byte buffer must point to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
     * "member_value structure."
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
    private static void skipMemberValue(ByteBuffer buf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        int tag = buf.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        skipMemberValue(tag, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
     * Skips the annotation member value at the current position in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
     * specified byte buffer.  The cursor of the byte buffer must point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
     * immediately after the tag in a "member_value structure."
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
    private static void skipMemberValue(int tag, ByteBuffer buf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
        switch(tag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
          case 'e': // Enum value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
            buf.getInt();  // (Two shorts, actually.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
          case '@':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            skipAnnotation(buf, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
          case '[':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
            skipArray(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
          default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
            // Class, primitive, or String
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
            buf.getShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
     * Skips the array value at the current position in the specified byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
     * buffer.  The cursor of the byte buffer must point to an array value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
     * struct.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
    private static void skipArray(ByteBuffer buf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
        int length = buf.getShort() & 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
        for (int i = 0; i < length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
            skipMemberValue(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
    }
2174
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   831
18827
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   832
    /**
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   833
     * Searches for given {@code element} in given {@code array} by identity.
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   834
     * Returns {@code true} if found {@code false} if not.
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   835
     */
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   836
    private static boolean contains(Object[] array, Object element) {
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   837
        for (Object e : array)
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   838
            if (e == element)
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   839
                return true;
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   840
        return false;
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   841
    }
ecbd9c8bef12 7122142: (ann) Race condition between isAnnotationPresent and getAnnotations
plevart
parents: 16923
diff changeset
   842
2174
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   843
    /*
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   844
     * This method converts the annotation map returned by the parseAnnotations()
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   845
     * method to an array.  It is called by Field.getDeclaredAnnotations(),
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   846
     * Method.getDeclaredAnnotations(), and Constructor.getDeclaredAnnotations().
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   847
     * 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
   848
     * it is needed.
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   849
     */
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   850
    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
   851
    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
   852
        return annotations.values().toArray(EMPTY_ANNOTATION_ARRAY);
0ffce164e4a4 6799230: Lazily load java.lang.annotation.Annotation class
mchung
parents: 2
diff changeset
   853
    }
14676
985410ec95e3 7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents: 14342
diff changeset
   854
985410ec95e3 7154390: Add support for repeating annotations in j.l.r.AnnotatedElement
jfranck
parents: 14342
diff changeset
   855
    static Annotation[] getEmptyAnnotationArray() { return EMPTY_ANNOTATION_ARRAY; }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
}