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

changeset 1570
f91144b7da75
parent 1521
71f35e4b93a5
child 1563
bc456436c613
equal deleted inserted replaced
1569:475eb15dfdad 1570:f91144b7da75
1 /* 1 /*
2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 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. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this 7 * published by the Free Software Foundation. Oracle designates this
23 * questions. 23 * questions.
24 */ 24 */
25 25
26 package com.sun.tools.javac.code; 26 package com.sun.tools.javac.code;
27 27
28 import java.util.Iterator;
29
28 import com.sun.tools.javac.util.*; 30 import com.sun.tools.javac.util.*;
29 31
30 /** A type annotation position. 32 /** A type annotation position.
31 * 33 *
32 * <p><b>This is NOT part of any supported API. 34 * <p><b>This is NOT part of any supported API.
33 * If you write code that depends on this, you do so at your own risk. 35 * If you write code that depends on this, you do so at your own risk.
34 * This code and its internal interfaces are subject to change or 36 * This code and its internal interfaces are subject to change or
35 * deletion without notice.</b> 37 * deletion without notice.</b>
36 */ 38 */
39 // Code duplicated in com.sun.tools.classfile.TypeAnnotation.Position
37 public class TypeAnnotationPosition { 40 public class TypeAnnotationPosition {
38 41
42 public enum TypePathEntryKind {
43 ARRAY(0),
44 INNER_TYPE(1),
45 WILDCARD(2),
46 TYPE_ARGUMENT(3);
47
48 public final int tag;
49
50 private TypePathEntryKind(int tag) {
51 this.tag = tag;
52 }
53 }
54
55 public static class TypePathEntry {
56 /** The fixed number of bytes per TypePathEntry. */
57 public static final int bytesPerEntry = 2;
58
59 public final TypePathEntryKind tag;
60 public final int arg;
61
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);
65
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 }
74
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 }
81
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 }
99
100 @Override
101 public String toString() {
102 return tag.toString() +
103 (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : "");
104 }
105
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 }
114
115 @Override
116 public int hashCode() {
117 return this.tag.hashCode() * 17 + this.arg;
118 }
119 }
120
39 public TargetType type = TargetType.UNKNOWN; 121 public TargetType type = TargetType.UNKNOWN;
40 122
41 // For generic/array types. 123 // For generic/array types.
42 public List<Integer> location = List.nil(); 124 public List<TypePathEntry> location = List.nil();
43 125
44 // Tree position. 126 // Tree position.
45 public int pos = -1; 127 public int pos = -1;
46 128
47 // For typecasts, type tests, new (and locals, as start_pc). 129 // For typecasts, type tests, new (and locals, as start_pc).
57 public int bound_index = Integer.MIN_VALUE; 139 public int bound_index = Integer.MIN_VALUE;
58 140
59 // For type parameter and method parameter 141 // For type parameter and method parameter
60 public int parameter_index = Integer.MIN_VALUE; 142 public int parameter_index = Integer.MIN_VALUE;
61 143
62 // For class extends, implements, and throws classes 144 // For class extends, implements, and throws clauses
63 public int type_index = Integer.MIN_VALUE; 145 public int type_index = Integer.MIN_VALUE;
64 146
65 // For wildcards 147 // For exception parameters, index into exception table
66 public TypeAnnotationPosition wildcard_position = null; 148 public int exception_index = Integer.MIN_VALUE;
149
150 public TypeAnnotationPosition() {}
67 151
68 @Override 152 @Override
69 public String toString() { 153 public String toString() {
70 StringBuilder sb = new StringBuilder(); 154 StringBuilder sb = new StringBuilder();
71 sb.append('['); 155 sb.append('[');
72 sb.append(type); 156 sb.append(type);
73 157
74 switch (type) { 158 switch (type) {
75 // type case 159 // type cast
76 case TYPECAST: 160 case CAST:
77 case TYPECAST_GENERIC_OR_ARRAY: 161 // instanceof
78 // object creation
79 case INSTANCEOF: 162 case INSTANCEOF:
80 case INSTANCEOF_GENERIC_OR_ARRAY: 163 // new expression
81 // new expression
82 case NEW: 164 case NEW:
83 case NEW_GENERIC_OR_ARRAY:
84 case NEW_TYPE_ARGUMENT:
85 case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
86 sb.append(", offset = "); 165 sb.append(", offset = ");
87 sb.append(offset); 166 sb.append(offset);
88 break; 167 break;
89 // local variable 168 // local variable
90 case LOCAL_VARIABLE: 169 case LOCAL_VARIABLE:
91 case LOCAL_VARIABLE_GENERIC_OR_ARRAY: 170 // resource variable
171 case RESOURCE_VARIABLE:
172 if (lvarOffset == null) {
173 sb.append(", lvarOffset is null!");
174 break;
175 }
92 sb.append(", {"); 176 sb.append(", {");
93 for (int i = 0; i < lvarOffset.length; ++i) { 177 for (int i = 0; i < lvarOffset.length; ++i) {
94 if (i != 0) sb.append("; "); 178 if (i != 0) sb.append("; ");
95 sb.append(", start_pc = "); 179 sb.append("start_pc = ");
96 sb.append(lvarOffset[i]); 180 sb.append(lvarOffset[i]);
97 sb.append(", length = "); 181 sb.append(", length = ");
98 sb.append(lvarLength[i]); 182 sb.append(lvarLength[i]);
99 sb.append(", index = "); 183 sb.append(", index = ");
100 sb.append(lvarIndex[i]); 184 sb.append(lvarIndex[i]);
101 } 185 }
102 sb.append("}"); 186 sb.append("}");
103 break; 187 break;
104 // method receiver 188 // method receiver
105 case METHOD_RECEIVER: 189 case METHOD_RECEIVER:
106 // Do nothing 190 // Do nothing
107 break; 191 break;
108 // type parameters 192 // type parameter
109 case CLASS_TYPE_PARAMETER: 193 case CLASS_TYPE_PARAMETER:
110 case METHOD_TYPE_PARAMETER: 194 case METHOD_TYPE_PARAMETER:
111 sb.append(", param_index = "); 195 sb.append(", param_index = ");
112 sb.append(parameter_index); 196 sb.append(parameter_index);
113 break; 197 break;
114 // type parameters bound 198 // type parameter bound
115 case CLASS_TYPE_PARAMETER_BOUND: 199 case CLASS_TYPE_PARAMETER_BOUND:
116 case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
117 case METHOD_TYPE_PARAMETER_BOUND: 200 case METHOD_TYPE_PARAMETER_BOUND:
118 case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
119 sb.append(", param_index = "); 201 sb.append(", param_index = ");
120 sb.append(parameter_index); 202 sb.append(parameter_index);
121 sb.append(", bound_index = "); 203 sb.append(", bound_index = ");
122 sb.append(bound_index); 204 sb.append(bound_index);
123 break; 205 break;
124 // wildcard 206 // class extends or implements clause
125 case WILDCARD_BOUND:
126 case WILDCARD_BOUND_GENERIC_OR_ARRAY:
127 sb.append(", wild_card = ");
128 sb.append(wildcard_position);
129 break;
130 // Class extends and implements clauses
131 case CLASS_EXTENDS: 207 case CLASS_EXTENDS:
132 case CLASS_EXTENDS_GENERIC_OR_ARRAY:
133 sb.append(", type_index = "); 208 sb.append(", type_index = ");
134 sb.append(type_index); 209 sb.append(type_index);
135 break; 210 break;
136 // throws 211 // throws
137 case THROWS: 212 case THROWS:
138 sb.append(", type_index = "); 213 sb.append(", type_index = ");
139 sb.append(type_index); 214 sb.append(type_index);
140 break; 215 break;
141 case CLASS_LITERAL: 216 // exception parameter
142 case CLASS_LITERAL_GENERIC_OR_ARRAY: 217 case EXCEPTION_PARAMETER:
143 sb.append(", offset = "); 218 sb.append(", exception_index = ");
144 sb.append(offset); 219 sb.append(exception_index);
145 break; 220 break;
146 // method parameter: not specified 221 // method parameter
147 case METHOD_PARAMETER_GENERIC_OR_ARRAY: 222 case METHOD_FORMAL_PARAMETER:
148 sb.append(", param_index = "); 223 sb.append(", param_index = ");
149 sb.append(parameter_index); 224 sb.append(parameter_index);
150 break; 225 break;
151 // method type argument: wasn't specified 226 // method/constructor/reference type argument
152 case METHOD_TYPE_ARGUMENT: 227 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
153 case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY: 228 case METHOD_INVOCATION_TYPE_ARGUMENT:
229 case METHOD_REFERENCE_TYPE_ARGUMENT:
154 sb.append(", offset = "); 230 sb.append(", offset = ");
155 sb.append(offset); 231 sb.append(offset);
156 sb.append(", type_index = "); 232 sb.append(", type_index = ");
157 sb.append(type_index); 233 sb.append(type_index);
158 break; 234 break;
159 // We don't need to worry abut these 235 // We don't need to worry about these
160 case METHOD_RETURN_GENERIC_OR_ARRAY: 236 case METHOD_RETURN:
161 case FIELD_GENERIC_OR_ARRAY: 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);
162 break; 244 break;
163 case UNKNOWN: 245 case UNKNOWN:
246 sb.append(", position UNKNOWN!");
164 break; 247 break;
165 default: 248 default:
166 // throw new AssertionError("unknown type: " + type); 249 Assert.error("Unknown target type: " + type);
167 } 250 }
168 251
169 // Append location data for generics/arrays. 252 // Append location data for generics/arrays.
170 if (type.hasLocation()) { 253 if (!location.isEmpty()) {
171 sb.append(", location = ("); 254 sb.append(", location = (");
172 sb.append(location); 255 sb.append(location);
173 sb.append(")"); 256 sb.append(")");
174 } 257 }
175 258
184 * Indicates whether the target tree of the annotation has been optimized 267 * Indicates whether the target tree of the annotation has been optimized
185 * away from classfile or not. 268 * away from classfile or not.
186 * @return true if the target has not been optimized away 269 * @return true if the target has not been optimized away
187 */ 270 */
188 public boolean emitToClassfile() { 271 public boolean emitToClassfile() {
189 if (type == TargetType.WILDCARD_BOUND 272 return !type.isLocal() || isValidOffset;
190 || type == TargetType.WILDCARD_BOUND_GENERIC_OR_ARRAY) 273 }
191 return wildcard_position.isValidOffset; 274
192 else 275 /**
193 return !type.isLocal() || isValidOffset; 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 }
292
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();
194 } 300 }
195 } 301 }

mercurial