39 public class ReferenceInfoUtil { |
39 public class ReferenceInfoUtil { |
40 |
40 |
41 public static final int IGNORE_VALUE = -321; |
41 public static final int IGNORE_VALUE = -321; |
42 |
42 |
43 public static List<TypeAnnotation> extendedAnnotationsOf(ClassFile cf) { |
43 public static List<TypeAnnotation> extendedAnnotationsOf(ClassFile cf) { |
44 List<TypeAnnotation> annos = new ArrayList<TypeAnnotation>(); |
44 List<TypeAnnotation> annos = new ArrayList<>(); |
45 findAnnotations(cf, annos); |
45 findAnnotations(cf, annos); |
46 return annos; |
46 return annos; |
47 } |
47 } |
48 |
48 |
49 /////////////////// Extract type annotations ////////////////// |
49 /////////////////// Extract type annotations ////////////////// |
117 RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; |
117 RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; |
118 annos.addAll(Arrays.asList(tAttr.annotations)); |
118 annos.addAll(Arrays.asList(tAttr.annotations)); |
119 } |
119 } |
120 } |
120 } |
121 |
121 |
122 /////////////////// TA Position Builder /////////////////////// |
|
123 /* TODO: comment out this dead code. Was this unfinished code that was |
|
124 * supposed to be used somewhere? The tests pass without this. |
|
125 private static class TAPositionBuilder { |
|
126 private TypeAnnotation.Position pos = new TypeAnnotation.Position(); |
|
127 |
|
128 private TAPositionBuilder() { } |
|
129 |
|
130 public TypeAnnotation.Position build() { return pos; } |
|
131 |
|
132 public static TAPositionBuilder ofType(TypeAnnotation.TargetType type) { |
|
133 TAPositionBuilder builder = new TAPositionBuilder(); |
|
134 builder.pos.type = type; |
|
135 return builder; |
|
136 } |
|
137 |
|
138 public TAPositionBuilder atOffset(int offset) { |
|
139 switch (pos.type) { |
|
140 // type cast |
|
141 case TYPECAST: |
|
142 // instanceof |
|
143 case INSTANCEOF: |
|
144 // new expression |
|
145 case NEW: |
|
146 pos.offset = offset; |
|
147 break; |
|
148 default: |
|
149 throw new IllegalArgumentException("invalid field for given type: " + pos.type); |
|
150 } |
|
151 return this; |
|
152 } |
|
153 |
|
154 public TAPositionBuilder atLocalPosition(int offset, int length, int index) { |
|
155 switch (pos.type) { |
|
156 // local variable |
|
157 case LOCAL_VARIABLE: |
|
158 pos.lvarOffset = new int[] { offset }; |
|
159 pos.lvarLength = new int[] { length }; |
|
160 pos.lvarIndex = new int[] { index }; |
|
161 break; |
|
162 default: |
|
163 throw new IllegalArgumentException("invalid field for given type: " + pos.type); |
|
164 } |
|
165 return this; |
|
166 } |
|
167 |
|
168 public TAPositionBuilder atParameterIndex(int index) { |
|
169 switch (pos.type) { |
|
170 // type parameters |
|
171 case CLASS_TYPE_PARAMETER: |
|
172 case METHOD_TYPE_PARAMETER: |
|
173 // method parameter |
|
174 case METHOD_FORMAL_PARAMETER: |
|
175 pos.parameter_index = index; |
|
176 break; |
|
177 default: |
|
178 throw new IllegalArgumentException("invalid field for given type: " + pos.type); |
|
179 } |
|
180 return this; |
|
181 } |
|
182 |
|
183 public TAPositionBuilder atParamBound(int param, int bound) { |
|
184 switch (pos.type) { |
|
185 // type parameters bounds |
|
186 case CLASS_TYPE_PARAMETER_BOUND: |
|
187 case METHOD_TYPE_PARAMETER_BOUND: |
|
188 pos.parameter_index = param; |
|
189 pos.bound_index = bound; |
|
190 break; |
|
191 default: |
|
192 throw new IllegalArgumentException("invalid field for given type: " + pos.type); |
|
193 } |
|
194 return this; |
|
195 } |
|
196 |
|
197 public TAPositionBuilder atWildcardPosition(TypeAnnotation.Position pos) { |
|
198 switch (pos.type) { |
|
199 // wildcards |
|
200 case WILDCARD_BOUND: |
|
201 pos.wildcard_position = pos; |
|
202 break; |
|
203 default: |
|
204 throw new IllegalArgumentException("invalid field for given type: " + pos.type); |
|
205 } |
|
206 return this; |
|
207 } |
|
208 |
|
209 public TAPositionBuilder atTypeIndex(int index) { |
|
210 switch (pos.type) { |
|
211 // class extends or implements clauses |
|
212 case CLASS_EXTENDS: |
|
213 // throws |
|
214 case THROWS: |
|
215 pos.type_index = index; |
|
216 break; |
|
217 default: |
|
218 throw new IllegalArgumentException("invalid field for given type: " + pos.type); |
|
219 } |
|
220 return this; |
|
221 } |
|
222 |
|
223 public TAPositionBuilder atOffsetWithIndex(int offset, int index) { |
|
224 switch (pos.type) { |
|
225 // method type argument: wasn't specified |
|
226 case NEW_TYPE_ARGUMENT: |
|
227 case METHOD_TYPE_ARGUMENT: |
|
228 pos.offset = offset; |
|
229 pos.type_index = index; |
|
230 break; |
|
231 default: |
|
232 throw new IllegalArgumentException("invalid field for given type: " + pos.type); |
|
233 } |
|
234 return this; |
|
235 } |
|
236 |
|
237 public TAPositionBuilder atGenericLocation(Integer ...loc) { |
|
238 pos.location = Arrays.asList(loc); |
|
239 pos.type = pos.type.getGenericComplement(); |
|
240 return this; |
|
241 } |
|
242 }*/ |
|
243 |
|
244 /////////////////////// Equality testing ///////////////////// |
122 /////////////////////// Equality testing ///////////////////// |
245 private static boolean areEquals(int a, int b) { |
123 private static boolean areEquals(int a, int b) { |
246 return a == b || a == IGNORE_VALUE || b == IGNORE_VALUE; |
124 return a == b || a == IGNORE_VALUE || b == IGNORE_VALUE; |
247 } |
125 } |
248 |
126 |
262 |
140 |
263 return true; |
141 return true; |
264 } |
142 } |
265 |
143 |
266 public static boolean areEquals(TypeAnnotation.Position p1, TypeAnnotation.Position p2) { |
144 public static boolean areEquals(TypeAnnotation.Position p1, TypeAnnotation.Position p2) { |
267 if (p1 == p2) |
145 return p1 == p2 || !(p1 == null || p2 == null) && |
268 return true; |
146 p1.type == p2.type && |
269 if (p1 == null || p2 == null) |
147 (p1.location.equals(p2.location)) && |
270 return false; |
148 areEquals(p1.offset, p2.offset) && |
271 |
149 areEquals(p1.lvarOffset, p2.lvarOffset) && |
272 return ((p1.type == p2.type) |
150 areEquals(p1.lvarLength, p2.lvarLength) && |
273 && (p1.location.equals(p2.location)) |
151 areEquals(p1.lvarIndex, p2.lvarIndex) && |
274 && areEquals(p1.offset, p2.offset) |
152 areEquals(p1.bound_index, p2.bound_index) && |
275 && areEquals(p1.lvarOffset, p2.lvarOffset) |
153 areEquals(p1.parameter_index, p2.parameter_index) && |
276 && areEquals(p1.lvarLength, p2.lvarLength) |
154 areEquals(p1.type_index, p2.type_index) && |
277 && areEquals(p1.lvarIndex, p2.lvarIndex) |
155 areEquals(p1.exception_index, p2.exception_index); |
278 && areEquals(p1.bound_index, p2.bound_index) |
156 |
279 && areEquals(p1.parameter_index, p2.parameter_index) |
|
280 && areEquals(p1.type_index, p2.type_index) |
|
281 && areEquals(p1.exception_index, p2.exception_index)); |
|
282 } |
157 } |
283 |
158 |
284 private static TypeAnnotation findAnnotation(String name, List<TypeAnnotation> annotations, ClassFile cf) throws InvalidIndex, UnexpectedEntry { |
159 private static TypeAnnotation findAnnotation(String name, List<TypeAnnotation> annotations, ClassFile cf) throws InvalidIndex, UnexpectedEntry { |
285 String properName = "L" + name + ";"; |
160 String properName = "L" + name + ";"; |
286 for (TypeAnnotation anno : annotations) { |
161 for (TypeAnnotation anno : annotations) { |
304 TypeAnnotation.Position expected = e.getValue(); |
179 TypeAnnotation.Position expected = e.getValue(); |
305 TypeAnnotation actual = findAnnotation(aName, actualAnnos, cf); |
180 TypeAnnotation actual = findAnnotation(aName, actualAnnos, cf); |
306 if (actual == null) |
181 if (actual == null) |
307 throw new ComparisionException("Expected annotation not found: " + aName); |
182 throw new ComparisionException("Expected annotation not found: " + aName); |
308 |
183 |
309 // TODO: you currently get an exception if the test case does not use all necessary |
|
310 // annotation attributes, e.g. forgetting the offset for a local variable. |
|
311 // It would be nicer to give an understandable warning instead. |
|
312 if (!areEquals(expected, actual.position)) { |
184 if (!areEquals(expected, actual.position)) { |
313 throw new ComparisionException("Unexpected position for annotation : " + aName + |
185 throw new ComparisionException("Unexpected position for annotation : " + aName + |
314 "\n Expected: " + expected.toString() + |
186 "\n Expected: " + expected.toString() + |
315 "\n Found: " + actual.position.toString()); |
187 "\n Found: " + actual.position.toString()); |
316 } |
188 } |