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

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.javac.code;
aoqi@0 27
aoqi@0 28 import java.util.Iterator;
aoqi@0 29
aoqi@0 30 import com.sun.tools.javac.tree.JCTree.JCLambda;
aoqi@0 31 import com.sun.tools.javac.util.*;
aoqi@0 32
aoqi@0 33 /** A type annotation position.
aoqi@0 34 *
aoqi@0 35 * <p><b>This is NOT part of any supported API.
aoqi@0 36 * If you write code that depends on this, you do so at your own risk.
aoqi@0 37 * This code and its internal interfaces are subject to change or
aoqi@0 38 * deletion without notice.</b>
aoqi@0 39 */
aoqi@0 40 // Code duplicated in com.sun.tools.classfile.TypeAnnotation.Position
aoqi@0 41 public class TypeAnnotationPosition {
aoqi@0 42
aoqi@0 43 public enum TypePathEntryKind {
aoqi@0 44 ARRAY(0),
aoqi@0 45 INNER_TYPE(1),
aoqi@0 46 WILDCARD(2),
aoqi@0 47 TYPE_ARGUMENT(3);
aoqi@0 48
aoqi@0 49 public final int tag;
aoqi@0 50
aoqi@0 51 private TypePathEntryKind(int tag) {
aoqi@0 52 this.tag = tag;
aoqi@0 53 }
aoqi@0 54 }
aoqi@0 55
aoqi@0 56 public static class TypePathEntry {
aoqi@0 57 /** The fixed number of bytes per TypePathEntry. */
aoqi@0 58 public static final int bytesPerEntry = 2;
aoqi@0 59
aoqi@0 60 public final TypePathEntryKind tag;
aoqi@0 61 public final int arg;
aoqi@0 62
aoqi@0 63 public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY);
aoqi@0 64 public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE);
aoqi@0 65 public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD);
aoqi@0 66
aoqi@0 67 private TypePathEntry(TypePathEntryKind tag) {
aoqi@0 68 Assert.check(tag == TypePathEntryKind.ARRAY ||
aoqi@0 69 tag == TypePathEntryKind.INNER_TYPE ||
aoqi@0 70 tag == TypePathEntryKind.WILDCARD,
aoqi@0 71 "Invalid TypePathEntryKind: " + tag);
aoqi@0 72 this.tag = tag;
aoqi@0 73 this.arg = 0;
aoqi@0 74 }
aoqi@0 75
aoqi@0 76 public TypePathEntry(TypePathEntryKind tag, int arg) {
aoqi@0 77 Assert.check(tag == TypePathEntryKind.TYPE_ARGUMENT,
aoqi@0 78 "Invalid TypePathEntryKind: " + tag);
aoqi@0 79 this.tag = tag;
aoqi@0 80 this.arg = arg;
aoqi@0 81 }
aoqi@0 82
aoqi@0 83 public static TypePathEntry fromBinary(int tag, int arg) {
aoqi@0 84 Assert.check(arg == 0 || tag == TypePathEntryKind.TYPE_ARGUMENT.tag,
aoqi@0 85 "Invalid TypePathEntry tag/arg: " + tag + "/" + arg);
aoqi@0 86 switch (tag) {
aoqi@0 87 case 0:
aoqi@0 88 return ARRAY;
aoqi@0 89 case 1:
aoqi@0 90 return INNER_TYPE;
aoqi@0 91 case 2:
aoqi@0 92 return WILDCARD;
aoqi@0 93 case 3:
aoqi@0 94 return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg);
aoqi@0 95 default:
aoqi@0 96 Assert.error("Invalid TypePathEntryKind tag: " + tag);
aoqi@0 97 return null;
aoqi@0 98 }
aoqi@0 99 }
aoqi@0 100
aoqi@0 101 @Override
aoqi@0 102 public String toString() {
aoqi@0 103 return tag.toString() +
aoqi@0 104 (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : "");
aoqi@0 105 }
aoqi@0 106
aoqi@0 107 @Override
aoqi@0 108 public boolean equals(Object other) {
aoqi@0 109 if (! (other instanceof TypePathEntry)) {
aoqi@0 110 return false;
aoqi@0 111 }
aoqi@0 112 TypePathEntry tpe = (TypePathEntry) other;
aoqi@0 113 return this.tag == tpe.tag && this.arg == tpe.arg;
aoqi@0 114 }
aoqi@0 115
aoqi@0 116 @Override
aoqi@0 117 public int hashCode() {
aoqi@0 118 return this.tag.hashCode() * 17 + this.arg;
aoqi@0 119 }
aoqi@0 120 }
aoqi@0 121
aoqi@0 122 public TargetType type = TargetType.UNKNOWN;
aoqi@0 123
aoqi@0 124 // For generic/array types.
aoqi@0 125 public List<TypePathEntry> location = List.nil();
aoqi@0 126
aoqi@0 127 // Tree position.
aoqi@0 128 public int pos = -1;
aoqi@0 129
aoqi@0 130 // For type casts, type tests, new, locals (as start_pc),
aoqi@0 131 // and method and constructor reference type arguments.
aoqi@0 132 public boolean isValidOffset = false;
aoqi@0 133 public int offset = -1;
aoqi@0 134
aoqi@0 135 // For locals. arrays same length
aoqi@0 136 public int[] lvarOffset = null;
aoqi@0 137 public int[] lvarLength = null;
aoqi@0 138 public int[] lvarIndex = null;
aoqi@0 139
aoqi@0 140 // For type parameter bound
aoqi@0 141 public int bound_index = Integer.MIN_VALUE;
aoqi@0 142
aoqi@0 143 // For type parameter and method parameter
aoqi@0 144 public int parameter_index = Integer.MIN_VALUE;
aoqi@0 145
aoqi@0 146 // For class extends, implements, and throws clauses
aoqi@0 147 public int type_index = Integer.MIN_VALUE;
aoqi@0 148
aoqi@0 149 // For exception parameters, index into exception table.
aoqi@0 150 // In com.sun.tools.javac.jvm.Gen.genCatch we first set the type_index
aoqi@0 151 // to the catch type index - that value is only temporary.
aoqi@0 152 // Then in com.sun.tools.javac.jvm.Code.fillExceptionParameterPositions
aoqi@0 153 // we use that value to determine the exception table index.
aoqi@0 154 public int exception_index = Integer.MIN_VALUE;
aoqi@0 155
aoqi@0 156 // If this type annotation is within a lambda expression,
aoqi@0 157 // store a pointer to the lambda expression tree in order
aoqi@0 158 // to allow a later translation to the right method.
aoqi@0 159 public JCLambda onLambda = null;
aoqi@0 160
aoqi@0 161 public TypeAnnotationPosition() {}
aoqi@0 162
aoqi@0 163 @Override
aoqi@0 164 public String toString() {
aoqi@0 165 StringBuilder sb = new StringBuilder();
aoqi@0 166 sb.append('[');
aoqi@0 167 sb.append(type);
aoqi@0 168
aoqi@0 169 switch (type) {
aoqi@0 170 // instanceof
aoqi@0 171 case INSTANCEOF:
aoqi@0 172 // new expression
aoqi@0 173 case NEW:
aoqi@0 174 // constructor/method reference receiver
aoqi@0 175 case CONSTRUCTOR_REFERENCE:
aoqi@0 176 case METHOD_REFERENCE:
aoqi@0 177 sb.append(", offset = ");
aoqi@0 178 sb.append(offset);
aoqi@0 179 break;
aoqi@0 180 // local variable
aoqi@0 181 case LOCAL_VARIABLE:
aoqi@0 182 // resource variable
aoqi@0 183 case RESOURCE_VARIABLE:
aoqi@0 184 if (lvarOffset == null) {
aoqi@0 185 sb.append(", lvarOffset is null!");
aoqi@0 186 break;
aoqi@0 187 }
aoqi@0 188 sb.append(", {");
aoqi@0 189 for (int i = 0; i < lvarOffset.length; ++i) {
aoqi@0 190 if (i != 0) sb.append("; ");
aoqi@0 191 sb.append("start_pc = ");
aoqi@0 192 sb.append(lvarOffset[i]);
aoqi@0 193 sb.append(", length = ");
aoqi@0 194 sb.append(lvarLength[i]);
aoqi@0 195 sb.append(", index = ");
aoqi@0 196 sb.append(lvarIndex[i]);
aoqi@0 197 }
aoqi@0 198 sb.append("}");
aoqi@0 199 break;
aoqi@0 200 // method receiver
aoqi@0 201 case METHOD_RECEIVER:
aoqi@0 202 // Do nothing
aoqi@0 203 break;
aoqi@0 204 // type parameter
aoqi@0 205 case CLASS_TYPE_PARAMETER:
aoqi@0 206 case METHOD_TYPE_PARAMETER:
aoqi@0 207 sb.append(", param_index = ");
aoqi@0 208 sb.append(parameter_index);
aoqi@0 209 break;
aoqi@0 210 // type parameter bound
aoqi@0 211 case CLASS_TYPE_PARAMETER_BOUND:
aoqi@0 212 case METHOD_TYPE_PARAMETER_BOUND:
aoqi@0 213 sb.append(", param_index = ");
aoqi@0 214 sb.append(parameter_index);
aoqi@0 215 sb.append(", bound_index = ");
aoqi@0 216 sb.append(bound_index);
aoqi@0 217 break;
aoqi@0 218 // class extends or implements clause
aoqi@0 219 case CLASS_EXTENDS:
aoqi@0 220 sb.append(", type_index = ");
aoqi@0 221 sb.append(type_index);
aoqi@0 222 break;
aoqi@0 223 // throws
aoqi@0 224 case THROWS:
aoqi@0 225 sb.append(", type_index = ");
aoqi@0 226 sb.append(type_index);
aoqi@0 227 break;
aoqi@0 228 // exception parameter
aoqi@0 229 case EXCEPTION_PARAMETER:
aoqi@0 230 sb.append(", exception_index = ");
aoqi@0 231 sb.append(exception_index);
aoqi@0 232 break;
aoqi@0 233 // method parameter
aoqi@0 234 case METHOD_FORMAL_PARAMETER:
aoqi@0 235 sb.append(", param_index = ");
aoqi@0 236 sb.append(parameter_index);
aoqi@0 237 break;
aoqi@0 238 // type cast
aoqi@0 239 case CAST:
aoqi@0 240 // method/constructor/reference type argument
aoqi@0 241 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
aoqi@0 242 case METHOD_INVOCATION_TYPE_ARGUMENT:
aoqi@0 243 case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
aoqi@0 244 case METHOD_REFERENCE_TYPE_ARGUMENT:
aoqi@0 245 sb.append(", offset = ");
aoqi@0 246 sb.append(offset);
aoqi@0 247 sb.append(", type_index = ");
aoqi@0 248 sb.append(type_index);
aoqi@0 249 break;
aoqi@0 250 // We don't need to worry about these
aoqi@0 251 case METHOD_RETURN:
aoqi@0 252 case FIELD:
aoqi@0 253 break;
aoqi@0 254 case UNKNOWN:
aoqi@0 255 sb.append(", position UNKNOWN!");
aoqi@0 256 break;
aoqi@0 257 default:
aoqi@0 258 Assert.error("Unknown target type: " + type);
aoqi@0 259 }
aoqi@0 260
aoqi@0 261 // Append location data for generics/arrays.
aoqi@0 262 if (!location.isEmpty()) {
aoqi@0 263 sb.append(", location = (");
aoqi@0 264 sb.append(location);
aoqi@0 265 sb.append(")");
aoqi@0 266 }
aoqi@0 267
aoqi@0 268 sb.append(", pos = ");
aoqi@0 269 sb.append(pos);
aoqi@0 270
aoqi@0 271 if (onLambda != null) {
aoqi@0 272 sb.append(", onLambda hash = ");
aoqi@0 273 sb.append(onLambda.hashCode());
aoqi@0 274 }
aoqi@0 275
aoqi@0 276 sb.append(']');
aoqi@0 277 return sb.toString();
aoqi@0 278 }
aoqi@0 279
aoqi@0 280 /**
aoqi@0 281 * Indicates whether the target tree of the annotation has been optimized
aoqi@0 282 * away from classfile or not.
aoqi@0 283 * @return true if the target has not been optimized away
aoqi@0 284 */
aoqi@0 285 public boolean emitToClassfile() {
aoqi@0 286 return !type.isLocal() || isValidOffset;
aoqi@0 287 }
aoqi@0 288
aoqi@0 289
aoqi@0 290 public boolean matchesPos(int pos) {
aoqi@0 291 return this.pos == pos;
aoqi@0 292 }
aoqi@0 293
aoqi@0 294 public void updatePosOffset(int to) {
aoqi@0 295 offset = to;
aoqi@0 296 lvarOffset = new int[]{to};
aoqi@0 297 isValidOffset = true;
aoqi@0 298 }
aoqi@0 299
aoqi@0 300 /**
aoqi@0 301 * Decode the binary representation for a type path and set
aoqi@0 302 * the {@code location} field.
aoqi@0 303 *
aoqi@0 304 * @param list The bytecode representation of the type path.
aoqi@0 305 */
aoqi@0 306 public static List<TypePathEntry> getTypePathFromBinary(java.util.List<Integer> list) {
aoqi@0 307 ListBuffer<TypePathEntry> loc = new ListBuffer<>();
aoqi@0 308 Iterator<Integer> iter = list.iterator();
aoqi@0 309 while (iter.hasNext()) {
aoqi@0 310 Integer fst = iter.next();
aoqi@0 311 Assert.check(iter.hasNext(), "Could not decode type path: " + list);
aoqi@0 312 Integer snd = iter.next();
aoqi@0 313 loc = loc.append(TypePathEntry.fromBinary(fst, snd));
aoqi@0 314 }
aoqi@0 315 return loc.toList();
aoqi@0 316 }
aoqi@0 317
aoqi@0 318 public static List<Integer> getBinaryFromTypePath(java.util.List<TypePathEntry> locs) {
aoqi@0 319 ListBuffer<Integer> loc = new ListBuffer<>();
aoqi@0 320 for (TypePathEntry tpe : locs) {
aoqi@0 321 loc = loc.append(tpe.tag.tag);
aoqi@0 322 loc = loc.append(tpe.arg);
aoqi@0 323 }
aoqi@0 324 return loc.toList();
aoqi@0 325 }
aoqi@0 326 }

mercurial