author | jjg |
Wed, 23 Jan 2013 13:27:24 -0800 | |
changeset 15385 | ee1eebe7e210 |
parent 7681 | 1f0819a3341f |
child 15718 | 8e54c8e43d38 |
permissions | -rw-r--r-- |
3150 | 1 |
/* |
15385 | 2 |
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. |
3150 | 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 |
|
5520 | 7 |
* published by the Free Software Foundation. Oracle designates this |
3150 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5520 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
3150 | 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 |
* |
|
5520 | 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. |
|
3150 | 24 |
*/ |
25 |
||
26 |
package com.sun.tools.javac.code; |
|
27 |
||
15385 | 28 |
import java.util.Iterator; |
29 |
||
3150 | 30 |
import com.sun.tools.javac.util.*; |
31 |
||
32 |
/** A type annotation position. |
|
33 |
* |
|
5847
1908176fd6e3
6944312: Potential rebranding issues in openjdk/langtools repository sources
jjg
parents:
5520
diff
changeset
|
34 |
* <p><b>This is NOT part of any supported API. |
1908176fd6e3
6944312: Potential rebranding issues in openjdk/langtools repository sources
jjg
parents:
5520
diff
changeset
|
35 |
* If you write code that depends on this, you do so at your own risk. |
3150 | 36 |
* This code and its internal interfaces are subject to change or |
37 |
* deletion without notice.</b> |
|
38 |
*/ |
|
15385 | 39 |
// Code duplicated in com.sun.tools.classfile.TypeAnnotation.Position |
3150 | 40 |
public class TypeAnnotationPosition { |
41 |
||
15385 | 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 |
||
3150 | 121 |
public TargetType type = TargetType.UNKNOWN; |
122 |
||
123 |
// For generic/array types. |
|
15385 | 124 |
public List<TypePathEntry> location = List.nil(); |
3150 | 125 |
|
126 |
// Tree position. |
|
127 |
public int pos = -1; |
|
128 |
||
129 |
// For typecasts, type tests, new (and locals, as start_pc). |
|
3151
41800a86aad3
6854796: update JSR308 impl with latest code from type-annotations repo
jjg
parents:
3150
diff
changeset
|
130 |
public boolean isValidOffset = false; |
3150 | 131 |
public int offset = -1; |
132 |
||
133 |
// For locals. arrays same length |
|
4866
21f0ac9e5a20
6918127: improve handling of TypeAnnotationPosition fields
jjg
parents:
3300
diff
changeset
|
134 |
public int[] lvarOffset = null; |
21f0ac9e5a20
6918127: improve handling of TypeAnnotationPosition fields
jjg
parents:
3300
diff
changeset
|
135 |
public int[] lvarLength = null; |
21f0ac9e5a20
6918127: improve handling of TypeAnnotationPosition fields
jjg
parents:
3300
diff
changeset
|
136 |
public int[] lvarIndex = null; |
3150 | 137 |
|
138 |
// For type parameter bound |
|
4866
21f0ac9e5a20
6918127: improve handling of TypeAnnotationPosition fields
jjg
parents:
3300
diff
changeset
|
139 |
public int bound_index = Integer.MIN_VALUE; |
3150 | 140 |
|
141 |
// For type parameter and method parameter |
|
4866
21f0ac9e5a20
6918127: improve handling of TypeAnnotationPosition fields
jjg
parents:
3300
diff
changeset
|
142 |
public int parameter_index = Integer.MIN_VALUE; |
3150 | 143 |
|
15385 | 144 |
// For class extends, implements, and throws clauses |
4866
21f0ac9e5a20
6918127: improve handling of TypeAnnotationPosition fields
jjg
parents:
3300
diff
changeset
|
145 |
public int type_index = Integer.MIN_VALUE; |
3150 | 146 |
|
15385 | 147 |
// For exception parameters, index into exception table |
148 |
public int exception_index = Integer.MIN_VALUE; |
|
149 |
||
150 |
public TypeAnnotationPosition() {} |
|
3150 | 151 |
|
152 |
@Override |
|
153 |
public String toString() { |
|
154 |
StringBuilder sb = new StringBuilder(); |
|
155 |
sb.append('['); |
|
156 |
sb.append(type); |
|
157 |
||
158 |
switch (type) { |
|
15385 | 159 |
// type cast |
160 |
case CAST: |
|
161 |
// instanceof |
|
3150 | 162 |
case INSTANCEOF: |
15385 | 163 |
// new expression |
3150 | 164 |
case NEW: |
165 |
sb.append(", offset = "); |
|
166 |
sb.append(offset); |
|
167 |
break; |
|
15385 | 168 |
// local variable |
3150 | 169 |
case LOCAL_VARIABLE: |
15385 | 170 |
// resource variable |
171 |
case RESOURCE_VARIABLE: |
|
172 |
if (lvarOffset == null) { |
|
173 |
sb.append(", lvarOffset is null!"); |
|
174 |
break; |
|
175 |
} |
|
3150 | 176 |
sb.append(", {"); |
177 |
for (int i = 0; i < lvarOffset.length; ++i) { |
|
178 |
if (i != 0) sb.append("; "); |
|
15385 | 179 |
sb.append("start_pc = "); |
3150 | 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; |
|
15385 | 188 |
// method receiver |
3150 | 189 |
case METHOD_RECEIVER: |
190 |
// Do nothing |
|
191 |
break; |
|
15385 | 192 |
// type parameter |
3150 | 193 |
case CLASS_TYPE_PARAMETER: |
194 |
case METHOD_TYPE_PARAMETER: |
|
195 |
sb.append(", param_index = "); |
|
196 |
sb.append(parameter_index); |
|
197 |
break; |
|
15385 | 198 |
// type parameter bound |
3150 | 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; |
|
15385 | 206 |
// class extends or implements clause |
3150 | 207 |
case CLASS_EXTENDS: |
208 |
sb.append(", type_index = "); |
|
209 |
sb.append(type_index); |
|
210 |
break; |
|
15385 | 211 |
// throws |
3150 | 212 |
case THROWS: |
213 |
sb.append(", type_index = "); |
|
214 |
sb.append(type_index); |
|
215 |
break; |
|
15385 | 216 |
// exception parameter |
217 |
case EXCEPTION_PARAMETER: |
|
218 |
sb.append(", exception_index = "); |
|
219 |
sb.append(exception_index); |
|
3150 | 220 |
break; |
15385 | 221 |
// method parameter |
222 |
case METHOD_FORMAL_PARAMETER: |
|
3150 | 223 |
sb.append(", param_index = "); |
224 |
sb.append(parameter_index); |
|
225 |
break; |
|
15385 | 226 |
// method/constructor/reference type argument |
227 |
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: |
|
228 |
case METHOD_INVOCATION_TYPE_ARGUMENT: |
|
229 |
case METHOD_REFERENCE_TYPE_ARGUMENT: |
|
3150 | 230 |
sb.append(", offset = "); |
231 |
sb.append(offset); |
|
232 |
sb.append(", type_index = "); |
|
233 |
sb.append(type_index); |
|
234 |
break; |
|
15385 | 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); |
|
3150 | 244 |
break; |
245 |
case UNKNOWN: |
|
15385 | 246 |
sb.append(", position UNKNOWN!"); |
3150 | 247 |
break; |
248 |
default: |
|
15385 | 249 |
Assert.error("Unknown target type: " + type); |
3150 | 250 |
} |
251 |
||
252 |
// Append location data for generics/arrays. |
|
15385 | 253 |
if (!location.isEmpty()) { |
3150 | 254 |
sb.append(", location = ("); |
255 |
sb.append(location); |
|
256 |
sb.append(")"); |
|
257 |
} |
|
258 |
||
259 |
sb.append(", pos = "); |
|
260 |
sb.append(pos); |
|
261 |
||
262 |
sb.append(']'); |
|
263 |
return sb.toString(); |
|
264 |
} |
|
3151
41800a86aad3
6854796: update JSR308 impl with latest code from type-annotations repo
jjg
parents:
3150
diff
changeset
|
265 |
|
41800a86aad3
6854796: update JSR308 impl with latest code from type-annotations repo
jjg
parents:
3150
diff
changeset
|
266 |
/** |
41800a86aad3
6854796: update JSR308 impl with latest code from type-annotations repo
jjg
parents:
3150
diff
changeset
|
267 |
* Indicates whether the target tree of the annotation has been optimized |
41800a86aad3
6854796: update JSR308 impl with latest code from type-annotations repo
jjg
parents:
3150
diff
changeset
|
268 |
* away from classfile or not. |
41800a86aad3
6854796: update JSR308 impl with latest code from type-annotations repo
jjg
parents:
3150
diff
changeset
|
269 |
* @return true if the target has not been optimized away |
41800a86aad3
6854796: update JSR308 impl with latest code from type-annotations repo
jjg
parents:
3150
diff
changeset
|
270 |
*/ |
41800a86aad3
6854796: update JSR308 impl with latest code from type-annotations repo
jjg
parents:
3150
diff
changeset
|
271 |
public boolean emitToClassfile() { |
15385 | 272 |
return !type.isLocal() || isValidOffset; |
273 |
} |
|
274 |
||
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 |
} |
|
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(); |
|
3151
41800a86aad3
6854796: update JSR308 impl with latest code from type-annotations repo
jjg
parents:
3150
diff
changeset
|
300 |
} |
3150 | 301 |
} |