BasicAnnoTests.java revision 2877:62e285806e83
1275970Scy/*
2275970Scy * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
3275970Scy * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4275970Scy *
5275970Scy * This code is free software; you can redistribute it and/or modify it
6275970Scy * under the terms of the GNU General Public License version 2 only, as
7275970Scy * published by the Free Software Foundation.
8275970Scy *
9275970Scy * This code is distributed in the hope that it will be useful, but WITHOUT
10275970Scy * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11275970Scy * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12275970Scy * version 2 for more details (a copy is included in the LICENSE file that
13275970Scy * accompanied this code).
14275970Scy *
15275970Scy * You should have received a copy of the GNU General Public License version
16275970Scy * 2 along with this work; if not, write to the Free Software Foundation,
17275970Scy * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18275970Scy *
19275970Scy * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20275970Scy * or visit www.oracle.com if you need additional information or have any
21275970Scy * questions.
22275970Scy */
23275970Scy
24275970Scy/*
25275970Scy * @test
26275970Scy * @bug 8013852 8031744
27275970Scy * @summary Annotations on types
28275970Scy * @library /tools/javac/lib
29275970Scy * @build JavacTestingAbstractProcessor DPrinter BasicAnnoTests
30275970Scy * @compile/process -processor BasicAnnoTests -proc:only BasicAnnoTests.java
31275970Scy */
32275970Scy
33275970Scyimport java.io.PrintWriter;
34275970Scyimport java.io.Serializable;
35275970Scyimport java.lang.annotation.Annotation;
36275970Scyimport java.lang.annotation.ElementType;
37275970Scyimport java.lang.annotation.Repeatable;
38275970Scyimport java.lang.annotation.Target;
39275970Scyimport java.util.ArrayList;
40275970Scy
41275970Scyimport java.util.HashSet;
42275970Scyimport java.util.List;
43275970Scyimport java.util.Map;
44275970Scyimport java.util.NavigableMap;
45275970Scyimport java.util.Set;
46275970Scyimport java.util.TreeMap;
47275970Scy
48275970Scyimport javax.annotation.processing.ProcessingEnvironment;
49275970Scyimport javax.annotation.processing.RoundEnvironment;
50275970Scyimport javax.lang.model.AnnotatedConstruct;
51275970Scyimport javax.lang.model.element.AnnotationMirror;
52275970Scyimport javax.lang.model.element.AnnotationValue;
53275970Scyimport javax.lang.model.element.Element;
54275970Scyimport javax.lang.model.element.ExecutableElement;
55275970Scyimport javax.lang.model.element.TypeElement;
56275970Scyimport javax.lang.model.type.ArrayType;
57275970Scyimport javax.lang.model.type.DeclaredType;
58275970Scyimport javax.lang.model.type.ExecutableType;
59275970Scyimport javax.lang.model.type.IntersectionType;
60275970Scyimport javax.lang.model.type.TypeMirror;
61275970Scyimport javax.lang.model.type.TypeVariable;
62275970Scyimport javax.lang.model.type.WildcardType;
63275970Scyimport javax.lang.model.util.Types;
64275970Scyimport javax.tools.Diagnostic.Kind;
65275970Scy
66275970Scyimport com.sun.tools.javac.code.Attribute;
67275970Scyimport com.sun.tools.javac.code.Symbol;
68275970Scyimport com.sun.tools.javac.processing.JavacProcessingEnvironment;
69275970Scyimport com.sun.tools.javac.util.Name;
70275970Scy
71275970Scyimport static com.sun.tools.javac.code.Attribute.Array;
72275970Scyimport static com.sun.tools.javac.code.Attribute.Constant;
73275970Scyimport static com.sun.tools.javac.code.Attribute.Compound;
74275970Scy
75275970Scy/**
76275970Scy * The test scans this file looking for test cases annotated with @Test.
77275970Scy */
78275970Scypublic class BasicAnnoTests extends JavacTestingAbstractProcessor {
79275970Scy    DPrinter dprinter;
80275970Scy    PrintWriter out;
81275970Scy    boolean verbose = true;
82275970Scy
83275970Scy    @Override
84275970Scy    public void init(ProcessingEnvironment pEnv) {
85275970Scy        super.init(pEnv);
86275970Scy        dprinter = new DPrinter(((JavacProcessingEnvironment) pEnv).getContext());
87275970Scy        out = dprinter.out;
88275970Scy    }
89275970Scy
90275970Scy    @Override
91275970Scy    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
92275970Scy        TestElementScanner s = new TestElementScanner();
93275970Scy        for (Element e: roundEnv.getRootElements()) {
94275970Scy            s.scan(e, null);
95275970Scy        }
96275970Scy        return true;
97275970Scy    }
98275970Scy
99275970Scy    void error(Element e, String msg) {
100275970Scy        messager.printMessage(Kind.ERROR, msg, e);
101275970Scy        errors++;
102275970Scy    }
103275970Scy
104275970Scy    int errors;
105275970Scy
106275970Scy    /**
107275970Scy     * Scan an element looking for declarations annotated with @Test.
108275970Scy     * Run a TestTypeScanner on the annotations that are found.
109275970Scy     */
110275970Scy    class TestElementScanner extends ElementScanner<Void,Void> {
111275970Scy        public Void scan(Element elem, Void ignore) {
112275970Scy            List<AnnotationMirror> tests = new ArrayList<>();
113275970Scy            AnnotationMirror test = getAnnotation(elem, Test.class.getName().replace('$', '.'));
114275970Scy            if (test != null) {
115275970Scy                tests.add(test);
116275970Scy            }
117275970Scy            tests.addAll(getAnnotations(elem, Tests.class.getName().replace('$', '.')));
118275970Scy
119275970Scy            if (tests.size() > 0) {
120275970Scy                out.println("Test: " + elem + " " + test);
121275970Scy                TestTypeScanner s = new TestTypeScanner(elem, tests, types);
122275970Scy                s.test(elem.asType());
123275970Scy                out.println();
124275970Scy            }
125275970Scy            return super.scan(elem, ignore);
126275970Scy        }
127275970Scy    }
128275970Scy
129275970Scy    /**
130275970Scy     * Scan the type of an element, looking for an annotation
131275970Scy     * to match the expected annotation specified in the @Test annotation.
132275970Scy     */
133275970Scy    class TestTypeScanner extends TypeScanner<Void, Void> {
134275970Scy        Element elem;
135275970Scy        NavigableMap<Integer, AnnotationMirror> toBeFound;
136275970Scy        int count = 0;
137275970Scy        Set<TypeMirror> seen = new HashSet<>();
138275970Scy
139275970Scy        TestTypeScanner(Element elem, List<AnnotationMirror> tests, Types types) {
140275970Scy            super(types);
141275970Scy            this.elem = elem;
142275970Scy
143275970Scy            NavigableMap<Integer, AnnotationMirror> testByPos = new TreeMap<>();
144275970Scy            for (AnnotationMirror test : tests) {
145275970Scy                for (int pos : getPosn(test)) {
146275970Scy                    testByPos.put(pos, test);
147275970Scy                }
148275970Scy            }
149275970Scy            this.toBeFound = testByPos;
150275970Scy        }
151275970Scy
152275970Scy        public void test(TypeMirror t) {
153275970Scy            scan(t, null);
154275970Scy        }
155275970Scy
156275970Scy        @Override
157275970Scy        Void scan(TypeMirror t, Void ignore) {
158275970Scy            if (t == null)
159275970Scy                return DEFAULT_VALUE;
160275970Scy
161275970Scy            if (!seen.contains(t)) {
162275970Scy                try {
163275970Scy                    seen.add(t);
164275970Scy                    if (verbose)
165275970Scy                        out.println("scan " + count + ": " + t);
166275970Scy                    if (toBeFound.size() > 0) {
167275970Scy                        if (toBeFound.firstKey().equals(count)) {
168275970Scy                            AnnotationMirror test = toBeFound.pollFirstEntry().getValue();
169275970Scy                            String annoType = getAnnoType(test);
170275970Scy                            AnnotationMirror anno = getAnnotation(t, annoType);
171275970Scy                            if (anno == null) {
172275970Scy                                error(elem, "annotation not found on " + count + ": " + t);
173275970Scy                            } else {
174275970Scy                                String v = getValue(anno, "value").toString();
175275970Scy                                if (v.equals(getExpect(test))) {
176275970Scy                                    out.println("found " + anno + " as expected");
177275970Scy                                } else {
178275970Scy                                    error(elem, "Unexpected value: " + v + ", expected: " + getExpect(test));
179275970Scy                                }
180275970Scy                            }
181275970Scy                        } else if (count > toBeFound.firstKey()) {
182275970Scy                            rescue();
183275970Scy                        } else {
184275970Scy                            List<? extends AnnotationMirror> annos = t.getAnnotationMirrors();
185275970Scy                            if (annos.size() > 0) {
186275970Scy                                for (AnnotationMirror a : annos)
187275970Scy                                    error(elem, "annotation " + a + " found on " + count + ": " + t);
188275970Scy                            }
189275970Scy                        }
190275970Scy                    } else {
191275970Scy                        List<? extends AnnotationMirror> annos = t.getAnnotationMirrors();
192275970Scy                        if (annos.size() > 0) {
193275970Scy                            for (AnnotationMirror a : annos)
194275970Scy                                error(elem, "annotation " + a + " found on " + count + ": " + t);
195275970Scy                        }
196275970Scy                    }
197275970Scy                    count++;
198275970Scy                    return super.scan(t, ignore);
199275970Scy
200275970Scy                } finally {
201275970Scy                    seen.remove(t);
202275970Scy                }
203275970Scy            }
204275970Scy
205275970Scy            return DEFAULT_VALUE;
206275970Scy
207275970Scy        }
208275970Scy
209275970Scy        private void rescue() {
210275970Scy            while (toBeFound.size() > 0 && toBeFound.firstKey() >= count)
211275970Scy                toBeFound.pollFirstEntry();
212275970Scy        }
213275970Scy    }
214275970Scy
215275970Scy    /** Get the position value from an element annotated with a @Test annotation mirror. */
216275970Scy    static int[] getPosn(Element elem) {
217275970Scy        return elem.getAnnotation(Test.class).posn();
218275970Scy    }
219275970Scy
220275970Scy    /** Get the position value from a @Test annotation mirror. */
221275970Scy    static Integer[] getPosn(AnnotationMirror test) {
222275970Scy        AnnotationValue v = getValue(test, "posn");
223275970Scy        Object value = v.getValue();
224275970Scy        Integer i = 0;
225275970Scy        if (value instanceof Constant) {
226275970Scy            i = (Integer)((Constant)value).getValue();
227275970Scy            Integer[] res = new Integer[1];
228275970Scy            res[0] = i;
229275970Scy            return res;
230275970Scy        } else if (value instanceof List) {
231275970Scy            List<Constant> l = (List<Constant>)value;
232275970Scy            Integer[] res = new Integer[l.size()];
233275970Scy            for (int c = 0; c < l.size(); c++) {
234275970Scy                res[c] = (Integer)l.get(c).getValue();
235275970Scy            }
236275970Scy            return res;
237275970Scy        }
238275970Scy        return null;
239275970Scy    }
240275970Scy
241275970Scy    /** Get the expect value from an @Test annotation mirror. */
242275970Scy    static String getExpect(AnnotationMirror test) {
243275970Scy        AnnotationValue v = getValue(test, "expect");
244275970Scy        return (String) v.getValue();
245275970Scy    }
246275970Scy
247275970Scy    /** Get the annoType value from an @Test annotation mirror. */
248275970Scy    static String getAnnoType(AnnotationMirror test) {
249275970Scy        AnnotationValue v = getValue(test, "annoType");
250275970Scy        TypeMirror m = (TypeMirror) v.getValue();
251275970Scy        return m.toString();
252275970Scy    }
253275970Scy
254275970Scy    /**
255275970Scy     * Get a specific annotation mirror from an annotated construct.
256275970Scy     */
257275970Scy    static AnnotationMirror getAnnotation(AnnotatedConstruct e, String name) {
258275970Scy        for (AnnotationMirror m: e.getAnnotationMirrors()) {
259275970Scy            TypeElement te = (TypeElement) m.getAnnotationType().asElement();
260275970Scy            if (te.getQualifiedName().contentEquals(name)) {
261275970Scy                return m;
262275970Scy            }
263275970Scy        }
264275970Scy        return null;
265275970Scy    }
266275970Scy
267275970Scy    static List<AnnotationMirror> getAnnotations(Element e, String name) {
268275970Scy        Name valueName = ((Symbol)e).getSimpleName().table.names.value;
269275970Scy        List<AnnotationMirror> res = new ArrayList<>();
270275970Scy
271275970Scy        for (AnnotationMirror m : e.getAnnotationMirrors()) {
272275970Scy            TypeElement te = (TypeElement) m.getAnnotationType().asElement();
273275970Scy            if (te.getQualifiedName().contentEquals(name)) {
274275970Scy                Compound theAnno = (Compound)m;
275275970Scy                Array valueArray = (Array)theAnno.member(valueName);
276275970Scy                for (Attribute a : valueArray.getValue()) {
277275970Scy                    AnnotationMirror theMirror = (AnnotationMirror) a;
278275970Scy
279275970Scy                    res.add(theMirror);
280275970Scy                }
281275970Scy            }
282275970Scy        }
283275970Scy        return res;
284275970Scy    }
285275970Scy
286275970Scy    /**
287275970Scy     * Get a specific value from an annotation mirror.
288275970Scy     */
289275970Scy    static AnnotationValue getValue(AnnotationMirror anno, String name) {
290275970Scy        Map<? extends ExecutableElement, ? extends AnnotationValue> map = anno.getElementValues();
291275970Scy        for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> e: map.entrySet()) {
292275970Scy            if (e.getKey().getSimpleName().contentEquals(name)) {
293275970Scy                return e.getValue();
294275970Scy            }
295275970Scy        }
296275970Scy        return null;
297275970Scy    }
298275970Scy
299275970Scy    /**
300275970Scy     * The Language Model API does not provide a type scanner, so provide
301275970Scy     * one sufficient for our needs.
302275970Scy     */
303275970Scy    static class TypeScanner<R, P> extends SimpleTypeVisitor<R, P> {
304275970Scy        private Types types;
305275970Scy
306275970Scy        public TypeScanner(Types types) {
307275970Scy            super();
308275970Scy            this.types = types;
309275970Scy        }
310275970Scy
311275970Scy        @Override
312275970Scy        public R visitArray(ArrayType t, P p) {
313275970Scy            scan(t.getComponentType(), p);
314275970Scy            return super.visitArray(t, p);
315275970Scy        }
316275970Scy
317275970Scy        @Override
318275970Scy        public R visitExecutable(ExecutableType t, P p) {
319275970Scy            //out.println("  type parameters: " + t.getTypeVariables());
320275970Scy            scan(t.getTypeVariables(), p);
321275970Scy            //out.println("  return: " + t.getReturnType());
322275970Scy            scan(t.getReturnType(), p);
323275970Scy            //out.println("  receiver: " + t.getReceiverTypes());
324275970Scy            scan(t.getReceiverType());
325275970Scy            //out.println("  params: " + t.getParameterTypes());
326275970Scy            scan(t.getParameterTypes(), p);
327275970Scy            //out.println("  throws: " + t.getThrownTypes());
328275970Scy            scan(t.getThrownTypes(), p);
329275970Scy            return super.visitExecutable(t, p);
330275970Scy        }
331275970Scy
332275970Scy        @Override
333275970Scy        public R visitDeclared(DeclaredType t, P p) {
334275970Scy            scan(t.getTypeArguments(), p);
335275970Scy            // don't scan enclosing
336275970Scy            scan(types.directSupertypes(t), p);
337275970Scy            return super.visitDeclared(t, p);
338275970Scy        }
339275970Scy
340275970Scy        @Override
341275970Scy        public R visitIntersection(IntersectionType t, P p) {
342275970Scy            scan(t.getBounds(), p);
343275970Scy            return super.visitIntersection(t, p);
344275970Scy        }
345275970Scy
346275970Scy        @Override
347275970Scy        public R visitTypeVariable(TypeVariable t, P p) {
348275970Scy            scan(t.getLowerBound(), p);
349275970Scy            scan(t.getUpperBound(), p);
350275970Scy            return super.visitTypeVariable(t, p);
351275970Scy        }
352275970Scy
353275970Scy        @Override
354275970Scy        public R visitWildcard(WildcardType t, P p) {
355275970Scy            scan(t.getExtendsBound(), p);
356275970Scy            scan(t.getSuperBound(), p);
357275970Scy            return super.visitWildcard(t, p);
358275970Scy        }
359275970Scy
360275970Scy        R scan(TypeMirror t) {
361275970Scy            return scan(t, null);
362275970Scy        }
363275970Scy
364275970Scy        R scan(TypeMirror t, P p) {
365275970Scy            return (t == null) ? DEFAULT_VALUE : t.accept(this, p);
366275970Scy        }
367275970Scy
368275970Scy        R scan(Iterable<? extends TypeMirror> iter, P p) {
369275970Scy            if (iter == null)
370275970Scy                return DEFAULT_VALUE;
371275970Scy            R result = DEFAULT_VALUE;
372275970Scy            for (TypeMirror t: iter)
373275970Scy                result = scan(t, p);
374275970Scy            return result;
375275970Scy        }
376275970Scy    }
377275970Scy
378275970Scy    /** Annotation to identify test cases. */
379275970Scy    @Repeatable(Tests.class)
380275970Scy    @interface Test {
381275970Scy        /** Where to look for the annotation, expressed as a scan index. */
382275970Scy        int[] posn();
383275970Scy        /** The annotation to look for. */
384275970Scy        Class<? extends Annotation> annoType();
385275970Scy        /** The string representation of the annotation's value. */
386275970Scy        String expect();
387275970Scy    }
388275970Scy
389275970Scy    @interface Tests {
390275970Scy        Test[] value();
391275970Scy    }
392275970Scy
393275970Scy    /** Type annotation to use in test cases. */
394275970Scy    @Target(ElementType.TYPE_USE)
395275970Scy    public @interface TA {
396275970Scy        int value();
397275970Scy    }
398275970Scy    @Target(ElementType.TYPE_USE)
399275970Scy    public @interface TB {
400275970Scy        int value();
401275970Scy    }
402275970Scy
403275970Scy    // Test cases
404275970Scy
405275970Scy    // TODO: add more cases for arrays
406275970Scy    //       all annotated
407275970Scy    //       all but one annotated
408275970Scy    //             vary position of one not annotated
409275970Scy    //       only one annotated
410275970Scy    //             vary position of one annotated
411275970Scy    //       the three above with the corner case of the ambiguos decl + type anno added
412275970Scy
413275970Scy    @Test(posn=0, annoType=TA.class, expect="1")
414275970Scy    public @TA(1) int f1;
415275970Scy
416275970Scy    @Test(posn=0, annoType=TA.class, expect="11")
417275970Scy    @TA(11) public int f11;
418275970Scy
419275970Scy    @Test(posn=1, annoType=TA.class, expect="111")
420275970Scy    @TA(111) public int [] f111;
421275970Scy
422275970Scy    @Test(posn=1, annoType=TA.class, expect="1120")
423275970Scy    @Test(posn=0, annoType=TB.class, expect="1121")
424275970Scy    @TA(1120) public int @TB(1121) [] f112;
425275970Scy
426275970Scy    @Test(posn=0, annoType=TB.class, expect="11211")
427275970Scy    @Test(posn=1, annoType=TA.class, expect="11200")
428275970Scy    public @TA(11200) int @TB(11211) [] f112b;
429275970Scy
430275970Scy    @Test(posn=1, annoType=TB.class, expect="1131")
431275970Scy    @Test(posn=2, annoType=TA.class, expect="1130")
432275970Scy    @TA(1130) public int [] @TB(1131) [] f113;
433275970Scy
434275970Scy    @Test(posn=5, annoType=TA.class, expect="12")
435275970Scy    public @TA(12) int [] [] [] [] [] f12;
436275970Scy
437275970Scy    @Test(posn=6, annoType=TA.class, expect="13")
438275970Scy    public @TA(13) int [] [] [] [] [] [] f13;
439275970Scy
440275970Scy    @Test(posn=7, annoType=TA.class, expect="14")
441275970Scy    @TA(14) public int [] [] [] [] [] [] [] f14;
442275970Scy
443275970Scy    @Test(posn=6, annoType=TA.class, expect="150")
444275970Scy    @Test(posn=7, annoType=TB.class, expect="151")
445275970Scy    @TB(151) public int [] [] [] [] [] [] @TA(150) [] f15;
446275970Scy
447275970Scy    @Test(posn=0, annoType=TB.class, expect="1511")
448275970Scy    @Test(posn=3, annoType=TA.class, expect="1512")
449275970Scy    @Test(posn=6, annoType=TA.class, expect="150")
450275970Scy    @Test(posn=7, annoType=TB.class, expect="151")
451275970Scy    @TB(151) public int @TB(1511) [] [] [] @TA(1512) [] [] [] @TA(150) [] f15b;
452275970Scy
453275970Scy    @Test(posn=0, annoType=TB.class, expect="1521")
454275970Scy    @Test(posn=3, annoType=TA.class, expect="1522")
455275970Scy    @Test(posn=6, annoType=TA.class, expect="152")
456275970Scy    public int @TB(1521) [] [] [] @TA(1522) [] [] [] @TA(152) [] f15c;
457275970Scy
458275970Scy    @Test(posn=5, annoType=TA.class, expect="160")
459275970Scy    @Test(posn=6, annoType=TB.class, expect="161")
460275970Scy    public int [] [] [] [] [] @TA(160) [] @TB(161) [] f16;
461275970Scy
462275970Scy    @Test(posn=0, annoType=TA.class, expect="2")
463275970Scy    public int @TA(2) [] f2;
464275970Scy
465275970Scy    @Test(posn=0, annoType=TB.class, expect="33")
466275970Scy    @Test(posn=1, annoType=TA.class, expect="3")
467275970Scy    public @TA(3) int @TB(33) [] f3;
468275970Scy
469275970Scy    @Test(posn=2, annoType=TA.class, expect="4")
470275970Scy    public int m1(@TA(4) float a) throws Exception { return 0; }
471275970Scy
472275970Scy    @Test(posn=1, annoType=TA.class, expect="5")
473275970Scy    public @TA(5) int m2(float a) throws Exception { return 0; }
474275970Scy
475275970Scy    @Test(posn=3, annoType=TA.class, expect="6")
476275970Scy    public int m3(float a) throws @TA(6) Exception { return 0; }
477275970Scy
478275970Scy    // Also tests that a decl anno on a typevar doesn't show up on the Type
479275970Scy    @Test(posn=7, annoType=TA.class, expect="8")
480275970Scy    public <@TA(7) M> M m4(@TA(8) float a) throws Exception { return null; }
481275970Scy
482275970Scy    // Also tests that a decl anno on a typevar doesn't show up on the Type
483275970Scy    @Test(posn=4, annoType=TA.class, expect="10")
484275970Scy    public class Inner1<@TA(9) S> extends @TA(10) Object implements Cloneable {}
485275970Scy
486275970Scy    // Also tests that a decl anno on a typevar doesn't show up on the Type
487275970Scy    @Test(posn=5, annoType=TA.class, expect="12")
488275970Scy    public class Inner2<@TA(11) S> extends Object implements @TA(12) Cloneable {}
489275970Scy
490275970Scy    @Test(posn={3,6}, annoType=TA.class, expect="13")
491275970Scy    public <M extends @TA(13) Object> M m5(float a) { return null; }
492275970Scy
493275970Scy    @Test(posn=3, annoType=TA.class, expect="14")
494275970Scy    public class Inner3<QQQ extends @TA(14) Map> {}
495275970Scy
496275970Scy    @Test(posn=4, annoType=TA.class, expect="15")
497275970Scy    public class Inner4<T extends @TA(15) Object & Cloneable & Serializable> {}
498275970Scy
499275970Scy    @Test(posn=5, annoType=TA.class, expect="16")
500275970Scy    public class Inner5<T extends Object & @TA(16) Cloneable & Serializable> {}
501275970Scy
502275970Scy    @Test(posn=7, annoType=TA.class, expect="17")
503275970Scy    public class Inner6<T extends Object & Cloneable & @TA(17) Serializable> {}
504275970Scy
505275970Scy    // Test annotated bounds
506275970Scy
507275970Scy    @Test(posn=1, annoType=TA.class, expect="18")
508275970Scy    public Set<@TA(18) ? extends Object> f4;
509275970Scy
510275970Scy    @Test(posn=2, annoType=TA.class, expect="19")
511275970Scy    public Set<? extends @TA(19) Object> f5;
512275970Scy
513275970Scy    @Test(posn=3, annoType=TA.class, expect="20")
514275970Scy    public Set<? extends Set<@TA(20) ? extends Object>> f6;
515275970Scy
516275970Scy    @Test(posn=4, annoType=TA.class, expect="21")
517275970Scy    public Set<? extends Set<? extends @TA(21) Object>> f7;
518275970Scy
519275970Scy    @Test(posn=1, annoType=TA.class, expect="22")
520275970Scy    public Set<@TA(22) ?> f8;
521275970Scy
522275970Scy    @Test(posn=1, annoType=TA.class, expect="23")
523275970Scy    public Set<@TA(23) ? super Object> f9;
524275970Scy
525275970Scy    // Test type use annotations on uses of type variables
526275970Scy    @Test(posn=5, annoType = TA.class, expect = "25")
527275970Scy    @Test(posn=5, annoType = TB.class, expect = "26")
528275970Scy    <T> void m6(@TA(25) @TB(26) T t) { }
529275970Scy
530275970Scy    class Inner7<T> {
531275970Scy        @Test(posn=0, annoType = TA.class, expect = "30")
532275970Scy        @Test(posn=0, annoType = TB.class, expect = "31")
533275970Scy        @TA(30) @TB(31) T f;
534275970Scy    }
535275970Scy
536275970Scy    // Test type use annotations on uses of type variables
537275970Scy    @Test(posn=5, annoType = TB.class, expect = "41")
538275970Scy    <@TA(40) T> void m7(@TB(41) T t) { }
539275970Scy
540275970Scy    class Inner8<@TA(50) T> {
541275970Scy        @Test(posn=0, annoType = TB.class, expect = "51")
542275970Scy        @TB(51) T f;
543275970Scy    }
544275970Scy
545275970Scy    // Test type use annotations on uses of Class types
546275970Scy    @Test(posn=5, annoType = TA.class, expect = "60")
547275970Scy    @Test(posn=5, annoType = TB.class, expect = "61")
548275970Scy    <T> void m60(@TA(60) @TB(61) String t) { }
549275970Scy
550275970Scy    class Inner70<T> {
551275970Scy        @Test(posn=0, annoType = TA.class, expect = "70")
552275970Scy        @Test(posn=0, annoType = TB.class, expect = "71")
553275970Scy        @TA(70) @TB(71) String f;
554275970Scy    }
555275970Scy
556275970Scy    // Test type use annotations on uses of type variables
557275970Scy    @Test(posn=5, annoType = TB.class, expect = "81")
558275970Scy    <@TA(80) T> void m80(@TB(81) String t) { }
559275970Scy
560275970Scy    class Inner90<@TA(90) T> {
561275970Scy        @Test(posn=0, annoType = TB.class, expect = "91")
562275970Scy        @TB(91) String f;
563275970Scy    }
564275970Scy
565275970Scy    // Recursive bound
566275970Scy    @Test(posn=4, annoType = TB.class, expect = "100")
567275970Scy    class Inner100<T extends Inner100<@TB(100) T>> {
568275970Scy    }
569275970Scy}
570275970Scy