langtools/src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java
changeset 8050 4b78c27c217f
parent 8030 0074833e36c6
parent 8049 6f996a6c9b02
child 8051 85a8fae9d6e0
equal deleted inserted replaced
8030:0074833e36c6 8050:4b78c27c217f
     1 /*
       
     2  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package com.sun.tools.classfile;
       
    27 
       
    28 import java.io.IOException;
       
    29 import java.util.ArrayList;
       
    30 import java.util.EnumSet;
       
    31 import java.util.List;
       
    32 import java.util.Set;
       
    33 
       
    34 import static com.sun.tools.classfile.ExtendedAnnotation.TargetAttribute.*;
       
    35 
       
    36 /**
       
    37  * See JSR 308 specification, section 4.1
       
    38  *
       
    39  *  <p><b>This is NOT part of any supported API.
       
    40  *  If you write code that depends on this, you do so at your own risk.
       
    41  *  This code and its internal interfaces are subject to change or
       
    42  *  deletion without notice.</b>
       
    43  */
       
    44 public class ExtendedAnnotation {
       
    45     ExtendedAnnotation(ClassReader cr) throws IOException, Annotation.InvalidAnnotation {
       
    46         annotation = new Annotation(cr);
       
    47         position = read_position(cr);
       
    48     }
       
    49 
       
    50     public ExtendedAnnotation(ConstantPool constant_pool,
       
    51             Annotation annotation, Position position) {
       
    52         this.annotation = annotation;
       
    53         this.position = position;
       
    54     }
       
    55 
       
    56     public int length() {
       
    57         int n = annotation.length();
       
    58         n += position_length(position);
       
    59         return n;
       
    60     }
       
    61 
       
    62     public final Annotation annotation;
       
    63     public final Position position;
       
    64 
       
    65     private static Position read_position(ClassReader cr) throws IOException, Annotation.InvalidAnnotation {
       
    66         // Copied from ClassReader
       
    67         int tag = (byte)cr.readUnsignedByte();  // cast to introduce signedness
       
    68         if (!TargetType.isValidTargetTypeValue(tag))
       
    69             throw new Annotation.InvalidAnnotation("invalid type annotation target type value: " + tag);
       
    70 
       
    71         TargetType type = TargetType.fromTargetTypeValue(tag);
       
    72 
       
    73         Position position = new Position();
       
    74         position.type = type;
       
    75 
       
    76         switch (type) {
       
    77         // type case
       
    78         case TYPECAST:
       
    79         case TYPECAST_GENERIC_OR_ARRAY:
       
    80         // object creation
       
    81         case INSTANCEOF:
       
    82         case INSTANCEOF_GENERIC_OR_ARRAY:
       
    83         // new expression
       
    84         case NEW:
       
    85         case NEW_GENERIC_OR_ARRAY:
       
    86             position.offset = cr.readUnsignedShort();
       
    87             break;
       
    88          // local variable
       
    89         case LOCAL_VARIABLE:
       
    90         case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
       
    91             int table_length = cr.readUnsignedShort();
       
    92             position.lvarOffset = new int[table_length];
       
    93             position.lvarLength = new int[table_length];
       
    94             position.lvarIndex = new int[table_length];
       
    95             for (int i = 0; i < table_length; ++i) {
       
    96                 position.lvarOffset[i] = cr.readUnsignedShort();
       
    97                 position.lvarLength[i] = cr.readUnsignedShort();
       
    98                 position.lvarIndex[i] = cr.readUnsignedShort();
       
    99             }
       
   100             break;
       
   101          // method receiver
       
   102         case METHOD_RECEIVER:
       
   103             // Do nothing
       
   104             break;
       
   105         // type parameters
       
   106         case CLASS_TYPE_PARAMETER:
       
   107         case METHOD_TYPE_PARAMETER:
       
   108             position.parameter_index = cr.readUnsignedByte();
       
   109             break;
       
   110         // type parameter bounds
       
   111         case CLASS_TYPE_PARAMETER_BOUND:
       
   112         case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
       
   113         case METHOD_TYPE_PARAMETER_BOUND:
       
   114         case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
       
   115             position.parameter_index = cr.readUnsignedByte();
       
   116             position.bound_index = cr.readUnsignedByte();
       
   117             break;
       
   118          // wildcards
       
   119         case WILDCARD_BOUND:
       
   120         case WILDCARD_BOUND_GENERIC_OR_ARRAY:
       
   121             position.wildcard_position = read_position(cr);
       
   122             break;
       
   123          // Class extends and implements clauses
       
   124         case CLASS_EXTENDS:
       
   125         case CLASS_EXTENDS_GENERIC_OR_ARRAY:
       
   126             int in = cr.readUnsignedShort();
       
   127             if (in == 0xFFFF)
       
   128                 in = -1;
       
   129             position.type_index = in;
       
   130             break;
       
   131         // throws
       
   132         case THROWS:
       
   133             position.type_index = cr.readUnsignedShort();
       
   134             break;
       
   135         case CLASS_LITERAL:
       
   136         case CLASS_LITERAL_GENERIC_OR_ARRAY:
       
   137             position.offset = cr.readUnsignedShort();
       
   138             break;
       
   139         // method parameter: not specified
       
   140         case METHOD_PARAMETER_GENERIC_OR_ARRAY:
       
   141             position.parameter_index = cr.readUnsignedByte();
       
   142             break;
       
   143         // method type argument: wasn't specified
       
   144         case NEW_TYPE_ARGUMENT:
       
   145         case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
       
   146         case METHOD_TYPE_ARGUMENT:
       
   147         case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
       
   148             position.offset = cr.readUnsignedShort();
       
   149             position.type_index = cr.readUnsignedByte();
       
   150             break;
       
   151         // We don't need to worry abut these
       
   152         case METHOD_RETURN_GENERIC_OR_ARRAY:
       
   153         case FIELD_GENERIC_OR_ARRAY:
       
   154             break;
       
   155         case UNKNOWN:
       
   156             break;
       
   157         default:
       
   158             throw new AssertionError("Cannot be here");
       
   159         }
       
   160 
       
   161         if (type.hasLocation()) {
       
   162             int len = cr.readUnsignedShort();
       
   163             List<Integer> loc = new ArrayList<Integer>(len);
       
   164             for (int i = 0; i < len; i++)
       
   165                 loc.add(cr.readUnsignedByte());
       
   166             position.location = loc;
       
   167         }
       
   168         return position;
       
   169     }
       
   170 
       
   171     private static int position_length(Position pos) {
       
   172         int n = 0;
       
   173         n += 1; // target_type
       
   174         switch (pos.type) {
       
   175         // type case
       
   176         case TYPECAST:
       
   177         case TYPECAST_GENERIC_OR_ARRAY:
       
   178         // object creation
       
   179         case INSTANCEOF:
       
   180         case INSTANCEOF_GENERIC_OR_ARRAY:
       
   181         // new expression
       
   182         case NEW:
       
   183         case NEW_GENERIC_OR_ARRAY:
       
   184             n += 2;
       
   185             break;
       
   186          // local variable
       
   187         case LOCAL_VARIABLE:
       
   188         case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
       
   189             n += 2; // table_length;
       
   190             int table_length = pos.lvarOffset.length;
       
   191             n += 2 * table_length; // offset
       
   192             n += 2 * table_length; // length;
       
   193             n += 2 * table_length; // index
       
   194             break;
       
   195          // method receiver
       
   196         case METHOD_RECEIVER:
       
   197             // Do nothing
       
   198             break;
       
   199         // type parameters
       
   200         case CLASS_TYPE_PARAMETER:
       
   201         case METHOD_TYPE_PARAMETER:
       
   202             n += 1; // parameter_index;
       
   203             break;
       
   204         // type parameter bounds
       
   205         case CLASS_TYPE_PARAMETER_BOUND:
       
   206         case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
       
   207         case METHOD_TYPE_PARAMETER_BOUND:
       
   208         case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
       
   209             n += 1; // parameter_index
       
   210             n += 1; // bound_index
       
   211             break;
       
   212         case WILDCARD_BOUND:
       
   213         case WILDCARD_BOUND_GENERIC_OR_ARRAY:
       
   214             n += position_length(pos.wildcard_position);
       
   215             break;
       
   216          // Class extends and implements clauses
       
   217         case CLASS_EXTENDS:
       
   218         case CLASS_EXTENDS_GENERIC_OR_ARRAY:
       
   219             n += 2; // type_index
       
   220             break;
       
   221         // throws
       
   222         case THROWS:
       
   223             n += 2; // type_index
       
   224             break;
       
   225         case CLASS_LITERAL:
       
   226         case CLASS_LITERAL_GENERIC_OR_ARRAY:
       
   227             n += 1; // offset
       
   228             break;
       
   229         // method parameter: not specified
       
   230         case METHOD_PARAMETER_GENERIC_OR_ARRAY:
       
   231             n += 1; // parameter_index
       
   232             break;
       
   233         // method type argument: wasn't specified
       
   234         case NEW_TYPE_ARGUMENT:
       
   235         case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
       
   236         case METHOD_TYPE_ARGUMENT:
       
   237         case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
       
   238             n += 2; // offset
       
   239             n += 1; // type index
       
   240             break;
       
   241         // We don't need to worry abut these
       
   242         case METHOD_RETURN_GENERIC_OR_ARRAY:
       
   243         case FIELD_GENERIC_OR_ARRAY:
       
   244             break;
       
   245         case UNKNOWN:
       
   246             break;
       
   247         default:
       
   248         }
       
   249 
       
   250         if (pos.type.hasLocation()) {
       
   251             n += 2; // length
       
   252             n += 1 * pos.location.size(); // actual array size
       
   253         }
       
   254 
       
   255         return n;
       
   256     }
       
   257 
       
   258     // Code duplicated from com.sun.tools.javac.code.TypeAnnotations.Position
       
   259     public static class Position {
       
   260 
       
   261         public TargetType type = TargetType.UNKNOWN;
       
   262 
       
   263         // For generic/array types.
       
   264         public List<Integer> location = new ArrayList<Integer>();
       
   265 
       
   266         // For typecasts, type tests, new (and locals, as start_pc).
       
   267         public int offset = -1;
       
   268 
       
   269         // For locals.
       
   270         public int[] lvarOffset = null;
       
   271         public int[] lvarLength = null;
       
   272         public int[] lvarIndex = null;
       
   273 
       
   274         // For type parameter bound
       
   275         public int bound_index = Integer.MIN_VALUE;
       
   276 
       
   277         // For type parameter and method parameter
       
   278         public int parameter_index = Integer.MIN_VALUE;
       
   279 
       
   280         // For class extends, implements, and throws classes
       
   281         public int type_index = Integer.MIN_VALUE;
       
   282 
       
   283         // For wildcards
       
   284         public Position wildcard_position = null;
       
   285 
       
   286         @Override
       
   287         public String toString() {
       
   288             StringBuilder sb = new StringBuilder();
       
   289             sb.append('[');
       
   290             sb.append(type);
       
   291 
       
   292             switch (type) {
       
   293             // type case
       
   294             case TYPECAST:
       
   295             case TYPECAST_GENERIC_OR_ARRAY:
       
   296             // object creation
       
   297             case INSTANCEOF:
       
   298             case INSTANCEOF_GENERIC_OR_ARRAY:
       
   299             // new expression
       
   300             case NEW:
       
   301             case NEW_GENERIC_OR_ARRAY:
       
   302             case NEW_TYPE_ARGUMENT:
       
   303             case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
       
   304                 sb.append(", offset = ");
       
   305                 sb.append(offset);
       
   306                 break;
       
   307              // local variable
       
   308             case LOCAL_VARIABLE:
       
   309             case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
       
   310                 sb.append(", {");
       
   311                 for (int i = 0; i < lvarOffset.length; ++i) {
       
   312                     if (i != 0) sb.append("; ");
       
   313                     sb.append(", start_pc = ");
       
   314                     sb.append(lvarOffset[i]);
       
   315                     sb.append(", length = ");
       
   316                     sb.append(lvarLength[i]);
       
   317                     sb.append(", index = ");
       
   318                     sb.append(lvarIndex[i]);
       
   319                 }
       
   320                 sb.append("}");
       
   321                 break;
       
   322              // method receiver
       
   323             case METHOD_RECEIVER:
       
   324                 // Do nothing
       
   325                 break;
       
   326             // type parameters
       
   327             case CLASS_TYPE_PARAMETER:
       
   328             case METHOD_TYPE_PARAMETER:
       
   329                 sb.append(", param_index = ");
       
   330                 sb.append(parameter_index);
       
   331                 break;
       
   332             // type parameters bound
       
   333             case CLASS_TYPE_PARAMETER_BOUND:
       
   334             case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
       
   335             case METHOD_TYPE_PARAMETER_BOUND:
       
   336             case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
       
   337                 sb.append(", param_index = ");
       
   338                 sb.append(parameter_index);
       
   339                 sb.append(", bound_index = ");
       
   340                 sb.append(bound_index);
       
   341                 break;
       
   342              // wildcard
       
   343             case WILDCARD_BOUND:
       
   344             case WILDCARD_BOUND_GENERIC_OR_ARRAY:
       
   345                 sb.append(", wild_card = ");
       
   346                 sb.append(wildcard_position);
       
   347                 break;
       
   348              // Class extends and implements clauses
       
   349             case CLASS_EXTENDS:
       
   350             case CLASS_EXTENDS_GENERIC_OR_ARRAY:
       
   351                 sb.append(", type_index = ");
       
   352                 sb.append(type_index);
       
   353                 break;
       
   354             // throws
       
   355             case THROWS:
       
   356                 sb.append(", type_index = ");
       
   357                 sb.append(type_index);
       
   358                 break;
       
   359             case CLASS_LITERAL:
       
   360             case CLASS_LITERAL_GENERIC_OR_ARRAY:
       
   361                 sb.append(", offset = ");
       
   362                 sb.append(offset);
       
   363                 break;
       
   364             // method parameter: not specified
       
   365             case METHOD_PARAMETER_GENERIC_OR_ARRAY:
       
   366                 sb.append(", param_index = ");
       
   367                 sb.append(parameter_index);
       
   368                 break;
       
   369             // method type argument: wasn't specified
       
   370             case METHOD_TYPE_ARGUMENT:
       
   371             case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
       
   372                 sb.append(", offset = ");
       
   373                 sb.append(offset);
       
   374                 sb.append(", type_index = ");
       
   375                 sb.append(type_index);
       
   376                 break;
       
   377             // We don't need to worry abut these
       
   378             case METHOD_RETURN_GENERIC_OR_ARRAY:
       
   379             case FIELD_GENERIC_OR_ARRAY:
       
   380                 break;
       
   381             case UNKNOWN:
       
   382                 break;
       
   383             default:
       
   384                 throw new AssertionError("unknown type: " + type);
       
   385             }
       
   386 
       
   387             // Append location data for generics/arrays.
       
   388             if (type.hasLocation()) {
       
   389                 sb.append(", location = (");
       
   390                 sb.append(location);
       
   391                 sb.append(")");
       
   392             }
       
   393 
       
   394             sb.append(']');
       
   395             return sb.toString();
       
   396         }
       
   397     }
       
   398 
       
   399     // Code duplicated from com.sun.tools.javac.comp.TargetType
       
   400     public enum TargetType {
       
   401 
       
   402         /** For annotations on typecasts. */
       
   403         TYPECAST(0x00),
       
   404 
       
   405         /** For annotations on a type argument or nested array of a typecast. */
       
   406         TYPECAST_GENERIC_OR_ARRAY(0x01, HasLocation),
       
   407 
       
   408         /** For annotations on type tests. */
       
   409         INSTANCEOF(0x02),
       
   410 
       
   411         /** For annotations on a type argument or nested array of a type test. */
       
   412         INSTANCEOF_GENERIC_OR_ARRAY(0x03, HasLocation),
       
   413 
       
   414         /** For annotations on object creation expressions. */
       
   415         NEW(0x04),
       
   416 
       
   417         /**
       
   418          * For annotations on a type argument or nested array of an object creation
       
   419          * expression.
       
   420          */
       
   421         NEW_GENERIC_OR_ARRAY(0x05, HasLocation),
       
   422 
       
   423 
       
   424         /** For annotations on the method receiver. */
       
   425         METHOD_RECEIVER(0x06),
       
   426 
       
   427         // invalid location
       
   428         // METHOD_RECEIVER_GENERIC_OR_ARRAY(0x07, HasLocation),
       
   429 
       
   430         /** For annotations on local variables. */
       
   431         LOCAL_VARIABLE(0x08),
       
   432 
       
   433         /** For annotations on a type argument or nested array of a local. */
       
   434         LOCAL_VARIABLE_GENERIC_OR_ARRAY(0x09, HasLocation),
       
   435 
       
   436         // already handled by regular annotations
       
   437         // METHOD_RETURN(0x0A),
       
   438 
       
   439         /**
       
   440          * For annotations on a type argument or nested array of a method return
       
   441          * type.
       
   442          */
       
   443         METHOD_RETURN_GENERIC_OR_ARRAY(0x0B, HasLocation),
       
   444 
       
   445         // already handled by regular annotations
       
   446         // METHOD_PARAMETER(0x0C),
       
   447 
       
   448         /** For annotations on a type argument or nested array of a method parameter. */
       
   449         METHOD_PARAMETER_GENERIC_OR_ARRAY(0x0D, HasLocation),
       
   450 
       
   451         // already handled by regular annotations
       
   452         // FIELD(0x0E),
       
   453 
       
   454         /** For annotations on a type argument or nested array of a field. */
       
   455         FIELD_GENERIC_OR_ARRAY(0x0F, HasLocation),
       
   456 
       
   457         /** For annotations on a bound of a type parameter of a class. */
       
   458         CLASS_TYPE_PARAMETER_BOUND(0x10, HasBound, HasParameter),
       
   459 
       
   460         /**
       
   461          * For annotations on a type argument or nested array of a bound of a type
       
   462          * parameter of a class.
       
   463          */
       
   464         CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY(0x11, HasBound, HasLocation, HasParameter),
       
   465 
       
   466         /** For annotations on a bound of a type parameter of a method. */
       
   467         METHOD_TYPE_PARAMETER_BOUND(0x12, HasBound, HasParameter),
       
   468 
       
   469         /**
       
   470          * For annotations on a type argument or nested array of a bound of a type
       
   471          * parameter of a method.
       
   472          */
       
   473         METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY(0x13, HasBound, HasLocation, HasParameter),
       
   474 
       
   475         /** For annotations on the type of an "extends" or "implements" clause. */
       
   476         CLASS_EXTENDS(0x14),
       
   477 
       
   478         /** For annotations on the inner type of an "extends" or "implements" clause. */
       
   479         CLASS_EXTENDS_GENERIC_OR_ARRAY(0x15, HasLocation),
       
   480 
       
   481         /** For annotations on a throws clause in a method declaration. */
       
   482         THROWS(0x16),
       
   483 
       
   484         // invalid location
       
   485         // THROWS_GENERIC_OR_ARRAY(0x17, HasLocation),
       
   486 
       
   487         /** For annotations in type arguments of object creation expressions. */
       
   488         NEW_TYPE_ARGUMENT(0x18),
       
   489         NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x19, HasLocation),
       
   490 
       
   491         METHOD_TYPE_ARGUMENT(0x1A),
       
   492         METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x1B, HasLocation),
       
   493 
       
   494         WILDCARD_BOUND(0x1C, HasBound),
       
   495         WILDCARD_BOUND_GENERIC_OR_ARRAY(0x1D, HasBound, HasLocation),
       
   496 
       
   497         CLASS_LITERAL(0x1E),
       
   498         CLASS_LITERAL_GENERIC_OR_ARRAY(0x1F, HasLocation),
       
   499 
       
   500         METHOD_TYPE_PARAMETER(0x20, HasParameter),
       
   501 
       
   502         // invalid location
       
   503         // METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x21, HasLocation, HasParameter),
       
   504 
       
   505         CLASS_TYPE_PARAMETER(0x22, HasParameter),
       
   506 
       
   507         // invalid location
       
   508         // CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x23, HasLocation, HasParameter),
       
   509 
       
   510         /** For annotations with an unknown target. */
       
   511         UNKNOWN(-1);
       
   512 
       
   513         static final int MAXIMUM_TARGET_TYPE_VALUE = 0x22;
       
   514 
       
   515         private final int targetTypeValue;
       
   516         private Set<TargetAttribute> flags;
       
   517 
       
   518         TargetType(int targetTypeValue, TargetAttribute... attrs) {
       
   519             if (targetTypeValue < Byte.MIN_VALUE
       
   520                 || targetTypeValue > Byte.MAX_VALUE)
       
   521                 throw new AssertionError("attribute type value needs to be a byte: " + targetTypeValue);
       
   522             this.targetTypeValue = (byte)targetTypeValue;
       
   523             this.flags = EnumSet.noneOf(TargetAttribute.class);
       
   524             for (TargetAttribute attr : attrs)
       
   525                 this.flags.add(attr);
       
   526         }
       
   527 
       
   528         /**
       
   529          * Returns whether or not this TargetType represents an annotation whose
       
   530          * target is an inner type of a generic or array type.
       
   531          *
       
   532          * @return true if this TargetType represents an annotation on an inner
       
   533          *         type, false otherwise
       
   534          */
       
   535         public boolean hasLocation() {
       
   536             return flags.contains(HasLocation);
       
   537         }
       
   538 
       
   539         public TargetType getGenericComplement() {
       
   540             if (hasLocation())
       
   541                 return this;
       
   542             else
       
   543                 return fromTargetTypeValue(targetTypeValue() + 1);
       
   544         }
       
   545 
       
   546         /**
       
   547          * Returns whether or not this TargetType represents an annotation whose
       
   548          * target has a parameter index.
       
   549          *
       
   550          * @return true if this TargetType has a parameter index,
       
   551          *         false otherwise
       
   552          */
       
   553         public boolean hasParameter() {
       
   554             return flags.contains(HasParameter);
       
   555         }
       
   556 
       
   557         /**
       
   558          * Returns whether or not this TargetType represents an annotation whose
       
   559          * target is a type parameter bound.
       
   560          *
       
   561          * @return true if this TargetType represents an type parameter bound
       
   562          *         annotation, false otherwise
       
   563          */
       
   564         public boolean hasBound() {
       
   565             return flags.contains(HasBound);
       
   566         }
       
   567 
       
   568         public int targetTypeValue() {
       
   569             return this.targetTypeValue;
       
   570         }
       
   571 
       
   572         private static TargetType[] targets = null;
       
   573 
       
   574         private static TargetType[] buildTargets() {
       
   575             TargetType[] targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
       
   576             TargetType[] alltargets = values();
       
   577             for (TargetType target : alltargets)
       
   578                 if (target.targetTypeValue >= 0)
       
   579                     targets[target.targetTypeValue] = target;
       
   580             for (int i = 0; i <= MAXIMUM_TARGET_TYPE_VALUE; ++i)
       
   581                 if (targets[i] == null)
       
   582                     targets[i] = UNKNOWN;
       
   583             return targets;
       
   584         }
       
   585 
       
   586         public static boolean isValidTargetTypeValue(int tag) {
       
   587             if (targets == null)
       
   588                 targets = buildTargets();
       
   589 
       
   590             if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
       
   591                 return true;
       
   592 
       
   593             return (tag >= 0 && tag < targets.length);
       
   594         }
       
   595 
       
   596         public static TargetType fromTargetTypeValue(int tag) {
       
   597             if (targets == null)
       
   598                 targets = buildTargets();
       
   599 
       
   600             if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
       
   601                 return UNKNOWN;
       
   602 
       
   603             if (tag < 0 || tag >= targets.length)
       
   604                 throw new IllegalArgumentException("Unknown TargetType: " + tag);
       
   605             return targets[tag];
       
   606         }
       
   607     }
       
   608 
       
   609     static enum TargetAttribute {
       
   610         HasLocation, HasParameter, HasBound;
       
   611     }
       
   612 }