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

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

     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.tree.JCTree.JCLambda;
    31 import com.sun.tools.javac.util.*;
    33 /** A type annotation position.
    34 *
    35 *  <p><b>This is NOT part of any supported API.
    36 *  If you write code that depends on this, you do so at your own risk.
    37 *  This code and its internal interfaces are subject to change or
    38 *  deletion without notice.</b>
    39 */
    40 // Code duplicated in com.sun.tools.classfile.TypeAnnotation.Position
    41 public class TypeAnnotationPosition {
    43     public enum TypePathEntryKind {
    44         ARRAY(0),
    45         INNER_TYPE(1),
    46         WILDCARD(2),
    47         TYPE_ARGUMENT(3);
    49         public final int tag;
    51         private TypePathEntryKind(int tag) {
    52             this.tag = tag;
    53         }
    54     }
    56     public static class TypePathEntry {
    57         /** The fixed number of bytes per TypePathEntry. */
    58         public static final int bytesPerEntry = 2;
    60         public final TypePathEntryKind tag;
    61         public final int arg;
    63         public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY);
    64         public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE);
    65         public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD);
    67         private TypePathEntry(TypePathEntryKind tag) {
    68             Assert.check(tag == TypePathEntryKind.ARRAY ||
    69                     tag == TypePathEntryKind.INNER_TYPE ||
    70                     tag == TypePathEntryKind.WILDCARD,
    71                     "Invalid TypePathEntryKind: " + tag);
    72             this.tag = tag;
    73             this.arg = 0;
    74         }
    76         public TypePathEntry(TypePathEntryKind tag, int arg) {
    77             Assert.check(tag == TypePathEntryKind.TYPE_ARGUMENT,
    78                     "Invalid TypePathEntryKind: " + tag);
    79             this.tag = tag;
    80             this.arg = arg;
    81         }
    83         public static TypePathEntry fromBinary(int tag, int arg) {
    84             Assert.check(arg == 0 || tag == TypePathEntryKind.TYPE_ARGUMENT.tag,
    85                     "Invalid TypePathEntry tag/arg: " + tag + "/" + arg);
    86             switch (tag) {
    87             case 0:
    88                 return ARRAY;
    89             case 1:
    90                 return INNER_TYPE;
    91             case 2:
    92                 return WILDCARD;
    93             case 3:
    94                 return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg);
    95             default:
    96                 Assert.error("Invalid TypePathEntryKind tag: " + tag);
    97                 return null;
    98             }
    99         }
   101         @Override
   102         public String toString() {
   103             return tag.toString() +
   104                     (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : "");
   105         }
   107         @Override
   108         public boolean equals(Object other) {
   109             if (! (other instanceof TypePathEntry)) {
   110                 return false;
   111             }
   112             TypePathEntry tpe = (TypePathEntry) other;
   113             return this.tag == tpe.tag && this.arg == tpe.arg;
   114         }
   116         @Override
   117         public int hashCode() {
   118             return this.tag.hashCode() * 17 + this.arg;
   119         }
   120     }
   122     public TargetType type = TargetType.UNKNOWN;
   124     // For generic/array types.
   125     public List<TypePathEntry> location = List.nil();
   127     // Tree position.
   128     public int pos = -1;
   130     // For type casts, type tests, new, locals (as start_pc),
   131     // and method and constructor reference type arguments.
   132     public boolean isValidOffset = false;
   133     public int offset = -1;
   135     // For locals. arrays same length
   136     public int[] lvarOffset = null;
   137     public int[] lvarLength = null;
   138     public int[] lvarIndex = null;
   140     // For type parameter bound
   141     public int bound_index = Integer.MIN_VALUE;
   143     // For type parameter and method parameter
   144     public int parameter_index = Integer.MIN_VALUE;
   146     // For class extends, implements, and throws clauses
   147     public int type_index = Integer.MIN_VALUE;
   149     // For exception parameters, index into exception table.
   150     // In com.sun.tools.javac.jvm.Gen.genCatch we first set the type_index
   151     // to the catch type index - that value is only temporary.
   152     // Then in com.sun.tools.javac.jvm.Code.fillExceptionParameterPositions
   153     // we use that value to determine the exception table index.
   154     public int exception_index = Integer.MIN_VALUE;
   156     // If this type annotation is within a lambda expression,
   157     // store a pointer to the lambda expression tree in order
   158     // to allow a later translation to the right method.
   159     public JCLambda onLambda = null;
   161     public TypeAnnotationPosition() {}
   163     @Override
   164     public String toString() {
   165         StringBuilder sb = new StringBuilder();
   166         sb.append('[');
   167         sb.append(type);
   169         switch (type) {
   170         // instanceof
   171         case INSTANCEOF:
   172         // new expression
   173         case NEW:
   174         // constructor/method reference receiver
   175         case CONSTRUCTOR_REFERENCE:
   176         case METHOD_REFERENCE:
   177             sb.append(", offset = ");
   178             sb.append(offset);
   179             break;
   180         // local variable
   181         case LOCAL_VARIABLE:
   182         // resource variable
   183         case RESOURCE_VARIABLE:
   184             if (lvarOffset == null) {
   185                 sb.append(", lvarOffset is null!");
   186                 break;
   187             }
   188             sb.append(", {");
   189             for (int i = 0; i < lvarOffset.length; ++i) {
   190                 if (i != 0) sb.append("; ");
   191                 sb.append("start_pc = ");
   192                 sb.append(lvarOffset[i]);
   193                 sb.append(", length = ");
   194                 sb.append(lvarLength[i]);
   195                 sb.append(", index = ");
   196                 sb.append(lvarIndex[i]);
   197             }
   198             sb.append("}");
   199             break;
   200         // method receiver
   201         case METHOD_RECEIVER:
   202             // Do nothing
   203             break;
   204         // type parameter
   205         case CLASS_TYPE_PARAMETER:
   206         case METHOD_TYPE_PARAMETER:
   207             sb.append(", param_index = ");
   208             sb.append(parameter_index);
   209             break;
   210         // type parameter bound
   211         case CLASS_TYPE_PARAMETER_BOUND:
   212         case METHOD_TYPE_PARAMETER_BOUND:
   213             sb.append(", param_index = ");
   214             sb.append(parameter_index);
   215             sb.append(", bound_index = ");
   216             sb.append(bound_index);
   217             break;
   218         // class extends or implements clause
   219         case CLASS_EXTENDS:
   220             sb.append(", type_index = ");
   221             sb.append(type_index);
   222             break;
   223         // throws
   224         case THROWS:
   225             sb.append(", type_index = ");
   226             sb.append(type_index);
   227             break;
   228         // exception parameter
   229         case EXCEPTION_PARAMETER:
   230             sb.append(", exception_index = ");
   231             sb.append(exception_index);
   232             break;
   233         // method parameter
   234         case METHOD_FORMAL_PARAMETER:
   235             sb.append(", param_index = ");
   236             sb.append(parameter_index);
   237             break;
   238         // type cast
   239         case CAST:
   240         // method/constructor/reference type argument
   241         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
   242         case METHOD_INVOCATION_TYPE_ARGUMENT:
   243         case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
   244         case METHOD_REFERENCE_TYPE_ARGUMENT:
   245             sb.append(", offset = ");
   246             sb.append(offset);
   247             sb.append(", type_index = ");
   248             sb.append(type_index);
   249             break;
   250         // We don't need to worry about these
   251         case METHOD_RETURN:
   252         case FIELD:
   253             break;
   254         case UNKNOWN:
   255             sb.append(", position UNKNOWN!");
   256             break;
   257         default:
   258             Assert.error("Unknown target type: " + type);
   259         }
   261         // Append location data for generics/arrays.
   262         if (!location.isEmpty()) {
   263             sb.append(", location = (");
   264             sb.append(location);
   265             sb.append(")");
   266         }
   268         sb.append(", pos = ");
   269         sb.append(pos);
   271         if (onLambda != null) {
   272             sb.append(", onLambda hash = ");
   273             sb.append(onLambda.hashCode());
   274         }
   276         sb.append(']');
   277         return sb.toString();
   278     }
   280     /**
   281      * Indicates whether the target tree of the annotation has been optimized
   282      * away from classfile or not.
   283      * @return true if the target has not been optimized away
   284      */
   285     public boolean emitToClassfile() {
   286         return !type.isLocal() || isValidOffset;
   287     }
   290     public boolean matchesPos(int pos) {
   291         return this.pos == pos;
   292     }
   294     public void updatePosOffset(int to) {
   295         offset = to;
   296         lvarOffset = new int[]{to};
   297         isValidOffset = true;
   298     }
   300     /**
   301      * Decode the binary representation for a type path and set
   302      * the {@code location} field.
   303      *
   304      * @param list The bytecode representation of the type path.
   305      */
   306     public static List<TypePathEntry> getTypePathFromBinary(java.util.List<Integer> list) {
   307         ListBuffer<TypePathEntry> loc = new ListBuffer<>();
   308         Iterator<Integer> iter = list.iterator();
   309         while (iter.hasNext()) {
   310             Integer fst = iter.next();
   311             Assert.check(iter.hasNext(), "Could not decode type path: " + list);
   312             Integer snd = iter.next();
   313             loc = loc.append(TypePathEntry.fromBinary(fst, snd));
   314         }
   315         return loc.toList();
   316     }
   318     public static List<Integer> getBinaryFromTypePath(java.util.List<TypePathEntry> locs) {
   319         ListBuffer<Integer> loc = new ListBuffer<>();
   320         for (TypePathEntry tpe : locs) {
   321             loc = loc.append(tpe.tag.tag);
   322             loc = loc.append(tpe.arg);
   323         }
   324         return loc.toList();
   325     }
   326 }

mercurial