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

Wed, 19 Mar 2014 16:44:49 +0000

author
vromero
date
Wed, 19 Mar 2014 16:44:49 +0000
changeset 2301
27a3026256cd
parent 2047
5f915a0c9615
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8034924: Incorrect inheritance of inaccessible static method
Reviewed-by: jjg, jlahoda

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

mercurial