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

Mon, 04 Feb 2013 18:08:53 -0500

author
dholmes
date
Mon, 04 Feb 2013 18:08:53 -0500
changeset 1570
f91144b7da75
parent 1521
71f35e4b93a5
child 1563
bc456436c613
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 typecasts, type tests, new (and locals, as start_pc).
   130     public boolean isValidOffset = false;
   131     public int offset = -1;
   133     // For locals. arrays same length
   134     public int[] lvarOffset = null;
   135     public int[] lvarLength = null;
   136     public int[] lvarIndex = null;
   138     // For type parameter bound
   139     public int bound_index = Integer.MIN_VALUE;
   141     // For type parameter and method parameter
   142     public int parameter_index = Integer.MIN_VALUE;
   144     // For class extends, implements, and throws clauses
   145     public int type_index = Integer.MIN_VALUE;
   147     // For exception parameters, index into exception table
   148     public int exception_index = Integer.MIN_VALUE;
   150     public TypeAnnotationPosition() {}
   152     @Override
   153     public String toString() {
   154         StringBuilder sb = new StringBuilder();
   155         sb.append('[');
   156         sb.append(type);
   158         switch (type) {
   159         // type cast
   160         case CAST:
   161         // instanceof
   162         case INSTANCEOF:
   163         // new expression
   164         case NEW:
   165             sb.append(", offset = ");
   166             sb.append(offset);
   167             break;
   168         // local variable
   169         case LOCAL_VARIABLE:
   170         // resource variable
   171         case RESOURCE_VARIABLE:
   172             if (lvarOffset == null) {
   173                 sb.append(", lvarOffset is null!");
   174                 break;
   175             }
   176             sb.append(", {");
   177             for (int i = 0; i < lvarOffset.length; ++i) {
   178                 if (i != 0) sb.append("; ");
   179                 sb.append("start_pc = ");
   180                 sb.append(lvarOffset[i]);
   181                 sb.append(", length = ");
   182                 sb.append(lvarLength[i]);
   183                 sb.append(", index = ");
   184                 sb.append(lvarIndex[i]);
   185             }
   186             sb.append("}");
   187             break;
   188         // method receiver
   189         case METHOD_RECEIVER:
   190             // Do nothing
   191             break;
   192         // type parameter
   193         case CLASS_TYPE_PARAMETER:
   194         case METHOD_TYPE_PARAMETER:
   195             sb.append(", param_index = ");
   196             sb.append(parameter_index);
   197             break;
   198         // type parameter bound
   199         case CLASS_TYPE_PARAMETER_BOUND:
   200         case METHOD_TYPE_PARAMETER_BOUND:
   201             sb.append(", param_index = ");
   202             sb.append(parameter_index);
   203             sb.append(", bound_index = ");
   204             sb.append(bound_index);
   205             break;
   206         // class extends or implements clause
   207         case CLASS_EXTENDS:
   208             sb.append(", type_index = ");
   209             sb.append(type_index);
   210             break;
   211         // throws
   212         case THROWS:
   213             sb.append(", type_index = ");
   214             sb.append(type_index);
   215             break;
   216         // exception parameter
   217         case EXCEPTION_PARAMETER:
   218             sb.append(", exception_index = ");
   219             sb.append(exception_index);
   220             break;
   221         // method parameter
   222         case METHOD_FORMAL_PARAMETER:
   223             sb.append(", param_index = ");
   224             sb.append(parameter_index);
   225             break;
   226         // method/constructor/reference type argument
   227         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
   228         case METHOD_INVOCATION_TYPE_ARGUMENT:
   229         case METHOD_REFERENCE_TYPE_ARGUMENT:
   230             sb.append(", offset = ");
   231             sb.append(offset);
   232             sb.append(", type_index = ");
   233             sb.append(type_index);
   234             break;
   235         // We don't need to worry about these
   236         case METHOD_RETURN:
   237         case FIELD:
   238             break;
   239         // lambda formal parameter
   240         case LAMBDA_FORMAL_PARAMETER:
   241             // TODO: also needs an offset?
   242             sb.append(", param_index = ");
   243             sb.append(parameter_index);
   244             break;
   245         case UNKNOWN:
   246             sb.append(", position UNKNOWN!");
   247             break;
   248         default:
   249             Assert.error("Unknown target type: " + type);
   250         }
   252         // Append location data for generics/arrays.
   253         if (!location.isEmpty()) {
   254             sb.append(", location = (");
   255             sb.append(location);
   256             sb.append(")");
   257         }
   259         sb.append(", pos = ");
   260         sb.append(pos);
   262         sb.append(']');
   263         return sb.toString();
   264     }
   266     /**
   267      * Indicates whether the target tree of the annotation has been optimized
   268      * away from classfile or not.
   269      * @return true if the target has not been optimized away
   270      */
   271     public boolean emitToClassfile() {
   272         return !type.isLocal() || isValidOffset;
   273     }
   275     /**
   276      * Decode the binary representation for a type path and set
   277      * the {@code location} field.
   278      *
   279      * @param list The bytecode representation of the type path.
   280      */
   281     public static List<TypePathEntry> getTypePathFromBinary(java.util.List<Integer> list) {
   282         ListBuffer<TypePathEntry> loc = ListBuffer.lb();
   283         Iterator<Integer> iter = list.iterator();
   284         while (iter.hasNext()) {
   285             Integer fst = iter.next();
   286             Assert.check(iter.hasNext(), "Could not decode type path: " + list);
   287             Integer snd = iter.next();
   288             loc = loc.append(TypePathEntry.fromBinary(fst, snd));
   289         }
   290         return loc.toList();
   291     }
   293     public static List<Integer> getBinaryFromTypePath(java.util.List<TypePathEntry> locs) {
   294         ListBuffer<Integer> loc = ListBuffer.lb();
   295         for (TypePathEntry tpe : locs) {
   296             loc = loc.append(tpe.tag.tag);
   297             loc = loc.append(tpe.arg);
   298         }
   299         return loc.toList();
   300     }
   301 }

mercurial