src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java

Sun, 17 Feb 2013 16:44:55 -0500

author
dholmes
date
Sun, 17 Feb 2013 16:44:55 -0500
changeset 1571
af8417e590f4
parent 1563
bc456436c613
child 1755
ddb4a2bfcd82
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright (c) 2003, 2013, 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  */
    26 package com.sun.tools.javac.code;
    28 import java.util.Iterator;
    30 import com.sun.tools.javac.util.*;
    32 /** A type annotation position.
    33 *
    34 *  <p><b>This is NOT part of any supported API.
    35 *  If you write code that depends on this, you do so at your own risk.
    36 *  This code and its internal interfaces are subject to change or
    37 *  deletion without notice.</b>
    38 */
    39 // Code duplicated in com.sun.tools.classfile.TypeAnnotation.Position
    40 public class TypeAnnotationPosition {
    42     public enum TypePathEntryKind {
    43         ARRAY(0),
    44         INNER_TYPE(1),
    45         WILDCARD(2),
    46         TYPE_ARGUMENT(3);
    48         public final int tag;
    50         private TypePathEntryKind(int tag) {
    51             this.tag = tag;
    52         }
    53     }
    55     public static class TypePathEntry {
    56         /** The fixed number of bytes per TypePathEntry. */
    57         public static final int bytesPerEntry = 2;
    59         public final TypePathEntryKind tag;
    60         public final int arg;
    62         public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY);
    63         public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE);
    64         public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD);
    66         private TypePathEntry(TypePathEntryKind tag) {
    67             Assert.check(tag == TypePathEntryKind.ARRAY ||
    68                     tag == TypePathEntryKind.INNER_TYPE ||
    69                     tag == TypePathEntryKind.WILDCARD,
    70                     "Invalid TypePathEntryKind: " + tag);
    71             this.tag = tag;
    72             this.arg = 0;
    73         }
    75         public TypePathEntry(TypePathEntryKind tag, int arg) {
    76             Assert.check(tag == TypePathEntryKind.TYPE_ARGUMENT,
    77                     "Invalid TypePathEntryKind: " + tag);
    78             this.tag = tag;
    79             this.arg = arg;
    80         }
    82         public static TypePathEntry fromBinary(int tag, int arg) {
    83             Assert.check(arg == 0 || tag == TypePathEntryKind.TYPE_ARGUMENT.tag,
    84                     "Invalid TypePathEntry tag/arg: " + tag + "/" + arg);
    85             switch (tag) {
    86             case 0:
    87                 return ARRAY;
    88             case 1:
    89                 return INNER_TYPE;
    90             case 2:
    91                 return WILDCARD;
    92             case 3:
    93                 return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg);
    94             default:
    95                 Assert.error("Invalid TypePathEntryKind tag: " + tag);
    96                 return null;
    97             }
    98         }
   100         @Override
   101         public String toString() {
   102             return tag.toString() +
   103                     (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : "");
   104         }
   106         @Override
   107         public boolean equals(Object other) {
   108             if (! (other instanceof TypePathEntry)) {
   109                 return false;
   110             }
   111             TypePathEntry tpe = (TypePathEntry) other;
   112             return this.tag == tpe.tag && this.arg == tpe.arg;
   113         }
   115         @Override
   116         public int hashCode() {
   117             return this.tag.hashCode() * 17 + this.arg;
   118         }
   119     }
   121     public TargetType type = TargetType.UNKNOWN;
   123     // For generic/array types.
   124     public List<TypePathEntry> location = List.nil();
   126     // Tree position.
   127     public int pos = -1;
   129     // For type casts, type tests, new, locals (as start_pc),
   130     // and method and constructor reference type arguments.
   131     public boolean isValidOffset = false;
   132     public int offset = -1;
   134     // For locals. arrays same length
   135     public int[] lvarOffset = null;
   136     public int[] lvarLength = null;
   137     public int[] lvarIndex = null;
   139     // For type parameter bound
   140     public int bound_index = Integer.MIN_VALUE;
   142     // For type parameter and method parameter
   143     public int parameter_index = Integer.MIN_VALUE;
   145     // For class extends, implements, and throws clauses
   146     public int type_index = Integer.MIN_VALUE;
   148     // For exception parameters, index into exception table
   149     public int exception_index = Integer.MIN_VALUE;
   151     public TypeAnnotationPosition() {}
   153     @Override
   154     public String toString() {
   155         StringBuilder sb = new StringBuilder();
   156         sb.append('[');
   157         sb.append(type);
   159         switch (type) {
   160         // instanceof
   161         case INSTANCEOF:
   162         // new expression
   163         case NEW:
   164         // constructor/method reference receiver
   165         case CONSTRUCTOR_REFERENCE:
   166         case METHOD_REFERENCE:
   167             sb.append(", offset = ");
   168             sb.append(offset);
   169             break;
   170         // local variable
   171         case LOCAL_VARIABLE:
   172         // resource variable
   173         case RESOURCE_VARIABLE:
   174             if (lvarOffset == null) {
   175                 sb.append(", lvarOffset is null!");
   176                 break;
   177             }
   178             sb.append(", {");
   179             for (int i = 0; i < lvarOffset.length; ++i) {
   180                 if (i != 0) sb.append("; ");
   181                 sb.append("start_pc = ");
   182                 sb.append(lvarOffset[i]);
   183                 sb.append(", length = ");
   184                 sb.append(lvarLength[i]);
   185                 sb.append(", index = ");
   186                 sb.append(lvarIndex[i]);
   187             }
   188             sb.append("}");
   189             break;
   190         // method receiver
   191         case METHOD_RECEIVER:
   192             // Do nothing
   193             break;
   194         // type parameter
   195         case CLASS_TYPE_PARAMETER:
   196         case METHOD_TYPE_PARAMETER:
   197             sb.append(", param_index = ");
   198             sb.append(parameter_index);
   199             break;
   200         // type parameter bound
   201         case CLASS_TYPE_PARAMETER_BOUND:
   202         case METHOD_TYPE_PARAMETER_BOUND:
   203             sb.append(", param_index = ");
   204             sb.append(parameter_index);
   205             sb.append(", bound_index = ");
   206             sb.append(bound_index);
   207             break;
   208         // class extends or implements clause
   209         case CLASS_EXTENDS:
   210             sb.append(", type_index = ");
   211             sb.append(type_index);
   212             break;
   213         // throws
   214         case THROWS:
   215             sb.append(", type_index = ");
   216             sb.append(type_index);
   217             break;
   218         // exception parameter
   219         case EXCEPTION_PARAMETER:
   220             sb.append(", exception_index = ");
   221             sb.append(exception_index);
   222             break;
   223         // method parameter
   224         case METHOD_FORMAL_PARAMETER:
   225             sb.append(", param_index = ");
   226             sb.append(parameter_index);
   227             break;
   228         // type cast
   229         case CAST:
   230         // method/constructor/reference type argument
   231         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
   232         case METHOD_INVOCATION_TYPE_ARGUMENT:
   233         case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
   234         case METHOD_REFERENCE_TYPE_ARGUMENT:
   235             sb.append(", offset = ");
   236             sb.append(offset);
   237             sb.append(", type_index = ");
   238             sb.append(type_index);
   239             break;
   240         // We don't need to worry about these
   241         case METHOD_RETURN:
   242         case FIELD:
   243             break;
   244         case UNKNOWN:
   245             sb.append(", position UNKNOWN!");
   246             break;
   247         default:
   248             Assert.error("Unknown target type: " + type);
   249         }
   251         // Append location data for generics/arrays.
   252         if (!location.isEmpty()) {
   253             sb.append(", location = (");
   254             sb.append(location);
   255             sb.append(")");
   256         }
   258         sb.append(", pos = ");
   259         sb.append(pos);
   261         sb.append(']');
   262         return sb.toString();
   263     }
   265     /**
   266      * Indicates whether the target tree of the annotation has been optimized
   267      * away from classfile or not.
   268      * @return true if the target has not been optimized away
   269      */
   270     public boolean emitToClassfile() {
   271         return !type.isLocal() || isValidOffset;
   272     }
   274     /**
   275      * Decode the binary representation for a type path and set
   276      * the {@code location} field.
   277      *
   278      * @param list The bytecode representation of the type path.
   279      */
   280     public static List<TypePathEntry> getTypePathFromBinary(java.util.List<Integer> list) {
   281         ListBuffer<TypePathEntry> loc = ListBuffer.lb();
   282         Iterator<Integer> iter = list.iterator();
   283         while (iter.hasNext()) {
   284             Integer fst = iter.next();
   285             Assert.check(iter.hasNext(), "Could not decode type path: " + list);
   286             Integer snd = iter.next();
   287             loc = loc.append(TypePathEntry.fromBinary(fst, snd));
   288         }
   289         return loc.toList();
   290     }
   292     public static List<Integer> getBinaryFromTypePath(java.util.List<TypePathEntry> locs) {
   293         ListBuffer<Integer> loc = ListBuffer.lb();
   294         for (TypePathEntry tpe : locs) {
   295             loc = loc.append(tpe.tag.tag);
   296             loc = loc.append(tpe.arg);
   297         }
   298         return loc.toList();
   299     }
   300 }

mercurial