21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 |
23 |
24 /* |
24 /* |
25 * @test |
25 * @test |
26 * @bug 8013852 |
26 * @bug 8013852 8031744 |
27 * @summary Annotations on types |
27 * @summary Annotations on types |
28 * @library /tools/javac/lib |
28 * @library /tools/javac/lib |
29 * @ignore 8057688 type annotations in type argument position are lost |
|
30 * @ignore 8031744 Annotations on many Language Model elements are not returned |
|
31 * @build JavacTestingAbstractProcessor DPrinter BasicAnnoTests |
29 * @build JavacTestingAbstractProcessor DPrinter BasicAnnoTests |
32 * @compile/process -processor BasicAnnoTests -proc:only BasicAnnoTests.java |
30 * @compile/process -processor BasicAnnoTests -proc:only BasicAnnoTests.java |
33 */ |
31 */ |
34 |
32 |
35 import java.io.PrintWriter; |
33 import java.io.PrintWriter; |
|
34 import java.io.Serializable; |
36 import java.lang.annotation.Annotation; |
35 import java.lang.annotation.Annotation; |
37 import java.lang.annotation.ElementType; |
36 import java.lang.annotation.ElementType; |
|
37 import java.lang.annotation.Repeatable; |
38 import java.lang.annotation.Target; |
38 import java.lang.annotation.Target; |
|
39 import java.util.ArrayList; |
|
40 |
|
41 import java.util.HashSet; |
|
42 import java.util.List; |
39 import java.util.Map; |
43 import java.util.Map; |
|
44 import java.util.NavigableMap; |
40 import java.util.Set; |
45 import java.util.Set; |
|
46 import java.util.TreeMap; |
41 |
47 |
42 import javax.annotation.processing.ProcessingEnvironment; |
48 import javax.annotation.processing.ProcessingEnvironment; |
43 import javax.annotation.processing.RoundEnvironment; |
49 import javax.annotation.processing.RoundEnvironment; |
44 import javax.lang.model.AnnotatedConstruct; |
50 import javax.lang.model.AnnotatedConstruct; |
45 import javax.lang.model.element.AnnotationMirror; |
51 import javax.lang.model.element.AnnotationMirror; |
46 import javax.lang.model.element.AnnotationValue; |
52 import javax.lang.model.element.AnnotationValue; |
47 import javax.lang.model.element.Element; |
53 import javax.lang.model.element.Element; |
48 import javax.lang.model.element.ExecutableElement; |
54 import javax.lang.model.element.ExecutableElement; |
49 import javax.lang.model.element.TypeElement; |
55 import javax.lang.model.element.TypeElement; |
50 import javax.lang.model.type.ArrayType; |
56 import javax.lang.model.type.ArrayType; |
|
57 import javax.lang.model.type.DeclaredType; |
51 import javax.lang.model.type.ExecutableType; |
58 import javax.lang.model.type.ExecutableType; |
|
59 import javax.lang.model.type.IntersectionType; |
52 import javax.lang.model.type.TypeMirror; |
60 import javax.lang.model.type.TypeMirror; |
53 import javax.lang.model.type.TypeVariable; |
61 import javax.lang.model.type.TypeVariable; |
54 import javax.lang.model.type.WildcardType; |
62 import javax.lang.model.type.WildcardType; |
|
63 import javax.lang.model.util.Types; |
55 import javax.tools.Diagnostic.Kind; |
64 import javax.tools.Diagnostic.Kind; |
56 |
65 |
|
66 import com.sun.tools.javac.code.Attribute; |
57 import com.sun.tools.javac.code.Symbol; |
67 import com.sun.tools.javac.code.Symbol; |
58 import com.sun.tools.javac.code.Type; |
|
59 import com.sun.tools.javac.processing.JavacProcessingEnvironment; |
68 import com.sun.tools.javac.processing.JavacProcessingEnvironment; |
|
69 import com.sun.tools.javac.util.Name; |
|
70 |
|
71 import static com.sun.tools.javac.code.Attribute.Array; |
|
72 import static com.sun.tools.javac.code.Attribute.Constant; |
|
73 import static com.sun.tools.javac.code.Attribute.Compound; |
60 |
74 |
61 /** |
75 /** |
62 * The test scans this file looking for test cases annotated with @Test. |
76 * The test scans this file looking for test cases annotated with @Test. |
63 */ |
77 */ |
64 public class BasicAnnoTests extends JavacTestingAbstractProcessor { |
78 public class BasicAnnoTests extends JavacTestingAbstractProcessor { |
116 * Scan the type of an element, looking for an annotation |
130 * Scan the type of an element, looking for an annotation |
117 * to match the expected annotation specified in the @Test annotation. |
131 * to match the expected annotation specified in the @Test annotation. |
118 */ |
132 */ |
119 class TestTypeScanner extends TypeScanner<Void, Void> { |
133 class TestTypeScanner extends TypeScanner<Void, Void> { |
120 Element elem; |
134 Element elem; |
121 AnnotationMirror test; |
135 NavigableMap<Integer, AnnotationMirror> toBeFound; |
122 int count = 0; |
136 int count = 0; |
123 boolean found = false; |
137 Set<TypeMirror> seen = new HashSet<>(); |
124 |
138 |
125 TestTypeScanner(Element elem, AnnotationMirror test) { |
139 TestTypeScanner(Element elem, List<AnnotationMirror> tests, Types types) { |
|
140 super(types); |
126 this.elem = elem; |
141 this.elem = elem; |
127 this.test = test; |
142 |
|
143 NavigableMap<Integer, AnnotationMirror> testByPos = new TreeMap<>(); |
|
144 for (AnnotationMirror test : tests) { |
|
145 for (int pos : getPosn(test)) { |
|
146 testByPos.put(pos, test); |
|
147 } |
|
148 } |
|
149 this.toBeFound = testByPos; |
|
150 } |
|
151 |
|
152 public void test(TypeMirror t) { |
|
153 scan(t, null); |
128 } |
154 } |
129 |
155 |
130 @Override |
156 @Override |
131 Void scan(TypeMirror t, Void ignore) { |
157 Void scan(TypeMirror t, Void ignore) { |
132 if (t == null) |
158 if (t == null) |
133 return DEFAULT_VALUE; |
159 return DEFAULT_VALUE; |
134 if (verbose) |
160 |
135 out.println("scan " + count + ": " + t); |
161 if (!seen.contains(t)) { |
136 if (count == getPosn(test)) { |
162 try { |
137 String annoType = getAnnoType(test); |
163 seen.add(t); |
138 AnnotationMirror anno = getAnnotation(t, annoType); |
164 if (verbose) |
139 if (anno == null) { |
165 out.println("scan " + count + ": " + t); |
140 error(elem, "annotation not found on " + count + ": " + t); |
166 if (toBeFound.size() > 0) { |
141 } else { |
167 if (toBeFound.firstKey().equals(count)) { |
142 String v = getValue(anno, "value").toString(); |
168 AnnotationMirror test = toBeFound.pollFirstEntry().getValue(); |
143 if (v.equals(getExpect(test))) { |
169 String annoType = getAnnoType(test); |
144 out.println("found " + anno + " as expected"); |
170 AnnotationMirror anno = getAnnotation(t, annoType); |
145 found = true; |
171 if (anno == null) { |
|
172 error(elem, "annotation not found on " + count + ": " + t); |
|
173 } else { |
|
174 String v = getValue(anno, "value").toString(); |
|
175 if (v.equals(getExpect(test))) { |
|
176 out.println("found " + anno + " as expected"); |
|
177 } else { |
|
178 error(elem, "Unexpected value: " + v + ", expected: " + getExpect(test)); |
|
179 } |
|
180 } |
|
181 } else if (count > toBeFound.firstKey()) { |
|
182 rescue(); |
|
183 } else { |
|
184 List<? extends AnnotationMirror> annos = t.getAnnotationMirrors(); |
|
185 if (annos.size() > 0) { |
|
186 for (AnnotationMirror a : annos) |
|
187 error(elem, "annotation " + a + " found on " + count + ": " + t); |
|
188 } |
|
189 } |
146 } else { |
190 } else { |
147 error(elem, "Unexpected value: " + v + ", expected: " + getExpect(test)); |
191 List<? extends AnnotationMirror> annos = t.getAnnotationMirrors(); |
|
192 if (annos.size() > 0) { |
|
193 for (AnnotationMirror a : annos) |
|
194 error(elem, "annotation " + a + " found on " + count + ": " + t); |
|
195 } |
148 } |
196 } |
|
197 count++; |
|
198 return super.scan(t, ignore); |
|
199 |
|
200 } finally { |
|
201 seen.remove(t); |
149 } |
202 } |
150 } |
203 } |
151 count++; |
204 |
152 return super.scan(t, ignore); |
205 return DEFAULT_VALUE; |
153 } |
206 |
154 } |
207 } |
155 |
208 |
156 /** Get the position value from an @Test annotation mirror. */ |
209 private void rescue() { |
157 static int getPosn(AnnotationMirror test) { |
210 while (toBeFound.size() > 0 && toBeFound.firstKey() >= count) |
|
211 toBeFound.pollFirstEntry(); |
|
212 } |
|
213 } |
|
214 |
|
215 /** Get the position value from an element annotated with a @Test annotation mirror. */ |
|
216 static int[] getPosn(Element elem) { |
|
217 return elem.getAnnotation(Test.class).posn(); |
|
218 } |
|
219 |
|
220 /** Get the position value from a @Test annotation mirror. */ |
|
221 static Integer[] getPosn(AnnotationMirror test) { |
158 AnnotationValue v = getValue(test, "posn"); |
222 AnnotationValue v = getValue(test, "posn"); |
159 return (Integer) v.getValue(); |
223 Object value = v.getValue(); |
|
224 Integer i = 0; |
|
225 if (value instanceof Constant) { |
|
226 i = (Integer)((Constant)value).getValue(); |
|
227 Integer[] res = new Integer[1]; |
|
228 res[0] = i; |
|
229 return res; |
|
230 } else if (value instanceof List) { |
|
231 List<Constant> l = (List<Constant>)value; |
|
232 Integer[] res = new Integer[l.size()]; |
|
233 for (int c = 0; c < l.size(); c++) { |
|
234 res[c] = (Integer)l.get(c).getValue(); |
|
235 } |
|
236 return res; |
|
237 } |
|
238 return null; |
160 } |
239 } |
161 |
240 |
162 /** Get the expect value from an @Test annotation mirror. */ |
241 /** Get the expect value from an @Test annotation mirror. */ |
163 static String getExpect(AnnotationMirror test) { |
242 static String getExpect(AnnotationMirror test) { |
164 AnnotationValue v = getValue(test, "expect"); |
243 AnnotationValue v = getValue(test, "expect"); |
201 /** |
299 /** |
202 * The Language Model API does not provide a type scanner, so provide |
300 * The Language Model API does not provide a type scanner, so provide |
203 * one sufficient for our needs. |
301 * one sufficient for our needs. |
204 */ |
302 */ |
205 static class TypeScanner<R, P> extends SimpleTypeVisitor<R, P> { |
303 static class TypeScanner<R, P> extends SimpleTypeVisitor<R, P> { |
|
304 private Types types; |
|
305 |
|
306 public TypeScanner(Types types) { |
|
307 super(); |
|
308 this.types = types; |
|
309 } |
|
310 |
206 @Override |
311 @Override |
207 public R visitArray(ArrayType t, P p) { |
312 public R visitArray(ArrayType t, P p) { |
208 scan(t.getComponentType(), p); |
313 scan(t.getComponentType(), p); |
209 return super.visitArray(t, p); |
314 return super.visitArray(t, p); |
210 } |
315 } |
211 |
316 |
212 @Override |
317 @Override |
213 public R visitExecutable(ExecutableType t, P p) { |
318 public R visitExecutable(ExecutableType t, P p) { |
|
319 //out.println(" type parameters: " + t.getTypeVariables()); |
|
320 scan(t.getTypeVariables(), p); |
|
321 //out.println(" return: " + t.getReturnType()); |
|
322 scan(t.getReturnType(), p); |
|
323 //out.println(" receiver: " + t.getReceiverTypes()); |
214 scan(t.getReceiverType()); |
324 scan(t.getReceiverType()); |
215 //out.println(" params: " + t.getParameterTypes()); |
325 //out.println(" params: " + t.getParameterTypes()); |
216 scan(t.getParameterTypes(), p); |
326 scan(t.getParameterTypes(), p); |
217 //out.println(" return: " + t.getReturnType()); |
|
218 scan(t.getReturnType(), p); |
|
219 //out.println(" throws: " + t.getThrownTypes()); |
327 //out.println(" throws: " + t.getThrownTypes()); |
220 scan(t.getThrownTypes(), p); |
328 scan(t.getThrownTypes(), p); |
221 return super.visitExecutable(t, p); |
329 return super.visitExecutable(t, p); |
|
330 } |
|
331 |
|
332 @Override |
|
333 public R visitDeclared(DeclaredType t, P p) { |
|
334 scan(t.getTypeArguments(), p); |
|
335 // don't scan enclosing |
|
336 scan(types.directSupertypes(t), p); |
|
337 return super.visitDeclared(t, p); |
|
338 } |
|
339 |
|
340 @Override |
|
341 public R visitIntersection(IntersectionType t, P p) { |
|
342 scan(t.getBounds(), p); |
|
343 return super.visitIntersection(t, p); |
222 } |
344 } |
223 |
345 |
224 @Override |
346 @Override |
225 public R visitTypeVariable(TypeVariable t, P p) { |
347 public R visitTypeVariable(TypeVariable t, P p) { |
226 scan(t.getLowerBound(), p); |
348 scan(t.getLowerBound(), p); |
252 return result; |
374 return result; |
253 } |
375 } |
254 } |
376 } |
255 |
377 |
256 /** Annotation to identify test cases. */ |
378 /** Annotation to identify test cases. */ |
|
379 @Repeatable(Tests.class) |
257 @interface Test { |
380 @interface Test { |
258 /** Where to look for the annotation, expressed as a scan index. */ |
381 /** Where to look for the annotation, expressed as a scan index. */ |
259 int posn(); |
382 int[] posn(); |
260 /** The annotation to look for. */ |
383 /** The annotation to look for. */ |
261 Class<? extends Annotation> annoType(); |
384 Class<? extends Annotation> annoType(); |
262 /** The string representation of the annotation's value. */ |
385 /** The string representation of the annotation's value. */ |
263 String expect(); |
386 String expect(); |
264 } |
387 } |
265 |
388 |
|
389 @interface Tests { |
|
390 Test[] value(); |
|
391 } |
|
392 |
266 /** Type annotation to use in test cases. */ |
393 /** Type annotation to use in test cases. */ |
267 @Target(ElementType.TYPE_USE) |
394 @Target(ElementType.TYPE_USE) |
268 public @interface TA { |
395 public @interface TA { |
269 int value(); |
396 int value(); |
270 } |
397 } |
|
398 @Target(ElementType.TYPE_USE) |
|
399 public @interface TB { |
|
400 int value(); |
|
401 } |
|
402 |
|
403 // Test cases |
|
404 |
|
405 // TODO: add more cases for arrays |
|
406 // all annotated |
|
407 // all but one annotated |
|
408 // vary position of one not annotated |
|
409 // only one annotated |
|
410 // vary position of one annotated |
|
411 // the three above with the corner case of the ambiguos decl + type anno added |
271 |
412 |
272 @Test(posn=0, annoType=TA.class, expect="1") |
413 @Test(posn=0, annoType=TA.class, expect="1") |
273 public @TA(1) int f1; |
414 public @TA(1) int f1; |
274 |
415 |
|
416 @Test(posn=0, annoType=TA.class, expect="11") |
|
417 @TA(11) public int f11; |
|
418 |
|
419 @Test(posn=1, annoType=TA.class, expect="111") |
|
420 @TA(111) public int [] f111; |
|
421 |
|
422 @Test(posn=1, annoType=TA.class, expect="1120") |
|
423 @Test(posn=0, annoType=TB.class, expect="1121") |
|
424 @TA(1120) public int @TB(1121) [] f112; |
|
425 |
|
426 @Test(posn=0, annoType=TB.class, expect="11211") |
|
427 @Test(posn=1, annoType=TA.class, expect="11200") |
|
428 public @TA(11200) int @TB(11211) [] f112b; |
|
429 |
|
430 @Test(posn=1, annoType=TB.class, expect="1131") |
|
431 @Test(posn=2, annoType=TA.class, expect="1130") |
|
432 @TA(1130) public int [] @TB(1131) [] f113; |
|
433 |
|
434 @Test(posn=5, annoType=TA.class, expect="12") |
|
435 public @TA(12) int [] [] [] [] [] f12; |
|
436 |
|
437 @Test(posn=6, annoType=TA.class, expect="13") |
|
438 public @TA(13) int [] [] [] [] [] [] f13; |
|
439 |
|
440 @Test(posn=7, annoType=TA.class, expect="14") |
|
441 @TA(14) public int [] [] [] [] [] [] [] f14; |
|
442 |
|
443 @Test(posn=6, annoType=TA.class, expect="150") |
|
444 @Test(posn=7, annoType=TB.class, expect="151") |
|
445 @TB(151) public int [] [] [] [] [] [] @TA(150) [] f15; |
|
446 |
|
447 @Test(posn=0, annoType=TB.class, expect="1511") |
|
448 @Test(posn=3, annoType=TA.class, expect="1512") |
|
449 @Test(posn=6, annoType=TA.class, expect="150") |
|
450 @Test(posn=7, annoType=TB.class, expect="151") |
|
451 @TB(151) public int @TB(1511) [] [] [] @TA(1512) [] [] [] @TA(150) [] f15b; |
|
452 |
|
453 @Test(posn=0, annoType=TB.class, expect="1521") |
|
454 @Test(posn=3, annoType=TA.class, expect="1522") |
|
455 @Test(posn=6, annoType=TA.class, expect="152") |
|
456 public int @TB(1521) [] [] [] @TA(1522) [] [] [] @TA(152) [] f15c; |
|
457 |
|
458 @Test(posn=5, annoType=TA.class, expect="160") |
|
459 @Test(posn=6, annoType=TB.class, expect="161") |
|
460 public int [] [] [] [] [] @TA(160) [] @TB(161) [] f16; |
|
461 |
275 @Test(posn=0, annoType=TA.class, expect="2") |
462 @Test(posn=0, annoType=TA.class, expect="2") |
276 public int @TA(2) [] f2; |
463 public int @TA(2) [] f2; |
277 |
464 |
|
465 @Test(posn=0, annoType=TB.class, expect="33") |
278 @Test(posn=1, annoType=TA.class, expect="3") |
466 @Test(posn=1, annoType=TA.class, expect="3") |
279 public @TA(3) int [] f3; |
467 public @TA(3) int @TB(33) [] f3; |
280 |
468 |
281 @Test(posn=1, annoType=TA.class, expect="4") |
469 @Test(posn=2, annoType=TA.class, expect="4") |
282 public int m1(@TA(4) float a) throws Exception { return 0; } |
470 public int m1(@TA(4) float a) throws Exception { return 0; } |
283 |
471 |
284 @Test(posn=2, annoType=TA.class, expect="5") |
472 @Test(posn=1, annoType=TA.class, expect="5") |
285 public @TA(5) int m2(float a) throws Exception { return 0; } |
473 public @TA(5) int m2(float a) throws Exception { return 0; } |
286 |
474 |
287 @Test(posn=3, annoType=TA.class, expect="6") |
475 @Test(posn=3, annoType=TA.class, expect="6") |
288 public int m3(float a) throws @TA(6) Exception { return 0; } |
476 public int m3(float a) throws @TA(6) Exception { return 0; } |
|
477 |
|
478 // Also tests that a decl anno on a typevar doesn't show up on the Type |
|
479 @Test(posn=7, annoType=TA.class, expect="8") |
|
480 public <@TA(7) M> M m4(@TA(8) float a) throws Exception { return null; } |
|
481 |
|
482 // Also tests that a decl anno on a typevar doesn't show up on the Type |
|
483 @Test(posn=4, annoType=TA.class, expect="10") |
|
484 public class Inner1<@TA(9) S> extends @TA(10) Object implements Cloneable {} |
|
485 |
|
486 // Also tests that a decl anno on a typevar doesn't show up on the Type |
|
487 @Test(posn=5, annoType=TA.class, expect="12") |
|
488 public class Inner2<@TA(11) S> extends Object implements @TA(12) Cloneable {} |
|
489 |
|
490 @Test(posn={3,6}, annoType=TA.class, expect="13") |
|
491 public <M extends @TA(13) Object> M m5(float a) { return null; } |
|
492 |
|
493 @Test(posn=3, annoType=TA.class, expect="14") |
|
494 public class Inner3<QQQ extends @TA(14) Map> {} |
|
495 |
|
496 @Test(posn=4, annoType=TA.class, expect="15") |
|
497 public class Inner4<T extends @TA(15) Object & Cloneable & Serializable> {} |
|
498 |
|
499 @Test(posn=5, annoType=TA.class, expect="16") |
|
500 public class Inner5<T extends Object & @TA(16) Cloneable & Serializable> {} |
|
501 |
|
502 @Test(posn=7, annoType=TA.class, expect="17") |
|
503 public class Inner6<T extends Object & Cloneable & @TA(17) Serializable> {} |
|
504 |
|
505 // Test annotated bounds |
|
506 |
|
507 @Test(posn=1, annoType=TA.class, expect="18") |
|
508 public Set<@TA(18) ? extends Object> f4; |
|
509 |
|
510 @Test(posn=2, annoType=TA.class, expect="19") |
|
511 public Set<? extends @TA(19) Object> f5; |
|
512 |
|
513 @Test(posn=3, annoType=TA.class, expect="20") |
|
514 public Set<? extends Set<@TA(20) ? extends Object>> f6; |
|
515 |
|
516 @Test(posn=4, annoType=TA.class, expect="21") |
|
517 public Set<? extends Set<? extends @TA(21) Object>> f7; |
|
518 |
|
519 @Test(posn=1, annoType=TA.class, expect="22") |
|
520 public Set<@TA(22) ?> f8; |
|
521 |
|
522 @Test(posn=1, annoType=TA.class, expect="23") |
|
523 public Set<@TA(23) ? super Object> f9; |
|
524 |
|
525 // Test type use annotations on uses of type variables |
|
526 @Test(posn=5, annoType = TA.class, expect = "25") |
|
527 @Test(posn=5, annoType = TB.class, expect = "26") |
|
528 <T> void m6(@TA(25) @TB(26) T t) { } |
|
529 |
|
530 class Inner7<T> { |
|
531 @Test(posn=0, annoType = TA.class, expect = "30") |
|
532 @Test(posn=0, annoType = TB.class, expect = "31") |
|
533 @TA(30) @TB(31) T f; |
|
534 } |
|
535 |
|
536 // Test type use annotations on uses of type variables |
|
537 @Test(posn=5, annoType = TB.class, expect = "41") |
|
538 <@TA(40) T> void m7(@TB(41) T t) { } |
|
539 |
|
540 class Inner8<@TA(50) T> { |
|
541 @Test(posn=0, annoType = TB.class, expect = "51") |
|
542 @TB(51) T f; |
|
543 } |
|
544 |
|
545 // Test type use annotations on uses of Class types |
|
546 @Test(posn=5, annoType = TA.class, expect = "60") |
|
547 @Test(posn=5, annoType = TB.class, expect = "61") |
|
548 <T> void m60(@TA(60) @TB(61) String t) { } |
|
549 |
|
550 class Inner70<T> { |
|
551 @Test(posn=0, annoType = TA.class, expect = "70") |
|
552 @Test(posn=0, annoType = TB.class, expect = "71") |
|
553 @TA(70) @TB(71) String f; |
|
554 } |
|
555 |
|
556 // Test type use annotations on uses of type variables |
|
557 @Test(posn=5, annoType = TB.class, expect = "81") |
|
558 <@TA(80) T> void m80(@TB(81) String t) { } |
|
559 |
|
560 class Inner90<@TA(90) T> { |
|
561 @Test(posn=0, annoType = TB.class, expect = "91") |
|
562 @TB(91) String f; |
|
563 } |
|
564 |
|
565 // Recursive bound |
|
566 @Test(posn=4, annoType = TB.class, expect = "100") |
|
567 class Inner100<T extends Inner100<@TB(100) T>> { |
|
568 } |
289 } |
569 } |