BasicAnnoTests.java revision 3294:9adfb22ff08f
1189251Ssam/*
2189251Ssam * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
3189251Ssam * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4189251Ssam *
5189251Ssam * This code is free software; you can redistribute it and/or modify it
6189251Ssam * under the terms of the GNU General Public License version 2 only, as
7189251Ssam * published by the Free Software Foundation.
8189251Ssam *
9189251Ssam * This code is distributed in the hope that it will be useful, but WITHOUT
10189251Ssam * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11189251Ssam * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12189251Ssam * version 2 for more details (a copy is included in the LICENSE file that
13189251Ssam * accompanied this code).
14189251Ssam *
15189251Ssam * You should have received a copy of the GNU General Public License version
16189251Ssam * 2 along with this work; if not, write to the Free Software Foundation,
17189251Ssam * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18189251Ssam *
19189251Ssam * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20189251Ssam * or visit www.oracle.com if you need additional information or have any
21189251Ssam * questions.
22189251Ssam */
23189251Ssam
24189251Ssam/*
25189251Ssam * @test
26189251Ssam * @bug 8013852 8031744
27189251Ssam * @summary Annotations on types
28189251Ssam * @library /tools/javac/lib
29189251Ssam * @modules jdk.compiler/com.sun.tools.javac.api
30189251Ssam *          jdk.compiler/com.sun.tools.javac.code
31189251Ssam *          jdk.compiler/com.sun.tools.javac.processing
32189251Ssam *          jdk.compiler/com.sun.tools.javac.tree
33189251Ssam *          jdk.compiler/com.sun.tools.javac.util
34189251Ssam * @build JavacTestingAbstractProcessor DPrinter BasicAnnoTests
35189251Ssam * @compile/process -XDaccessInternalAPI -processor BasicAnnoTests -proc:only BasicAnnoTests.java
36189251Ssam */
37189251Ssam
38189251Ssamimport java.io.PrintWriter;
39189251Ssamimport java.io.Serializable;
40189251Ssamimport java.lang.annotation.Annotation;
41189251Ssamimport java.lang.annotation.ElementType;
42189251Ssamimport java.lang.annotation.Repeatable;
43189251Ssamimport java.lang.annotation.Target;
44189251Ssamimport java.util.ArrayList;
45189251Ssam
46189251Ssamimport java.util.HashSet;
47189251Ssamimport java.util.List;
48189251Ssamimport java.util.Map;
49189251Ssamimport java.util.NavigableMap;
50189251Ssamimport java.util.Set;
51189251Ssamimport java.util.TreeMap;
52189251Ssam
53189251Ssamimport javax.annotation.processing.ProcessingEnvironment;
54189251Ssamimport javax.annotation.processing.RoundEnvironment;
55189251Ssamimport javax.lang.model.AnnotatedConstruct;
56189251Ssamimport javax.lang.model.element.AnnotationMirror;
57189251Ssamimport javax.lang.model.element.AnnotationValue;
58189251Ssamimport javax.lang.model.element.Element;
59189251Ssamimport javax.lang.model.element.ExecutableElement;
60189251Ssamimport javax.lang.model.element.TypeElement;
61189251Ssamimport javax.lang.model.type.ArrayType;
62189251Ssamimport javax.lang.model.type.DeclaredType;
63189251Ssamimport javax.lang.model.type.ExecutableType;
64189251Ssamimport javax.lang.model.type.IntersectionType;
65189251Ssamimport javax.lang.model.type.TypeMirror;
66189251Ssamimport javax.lang.model.type.TypeVariable;
67189251Ssamimport javax.lang.model.type.WildcardType;
68189251Ssamimport javax.lang.model.util.Types;
69189251Ssamimport javax.tools.Diagnostic.Kind;
70189251Ssam
71189251Ssamimport com.sun.tools.javac.code.Attribute;
72189251Ssamimport com.sun.tools.javac.code.Symbol;
73189251Ssamimport com.sun.tools.javac.processing.JavacProcessingEnvironment;
74189251Ssamimport com.sun.tools.javac.util.Name;
75189251Ssam
76189251Ssamimport static com.sun.tools.javac.code.Attribute.Array;
77189251Ssamimport static com.sun.tools.javac.code.Attribute.Constant;
78189251Ssamimport static com.sun.tools.javac.code.Attribute.Compound;
79189251Ssam
80189251Ssam/**
81189251Ssam * The test scans this file looking for test cases annotated with @Test.
82189251Ssam */
83189251Ssampublic class BasicAnnoTests extends JavacTestingAbstractProcessor {
84189251Ssam    DPrinter dprinter;
85189251Ssam    PrintWriter out;
86189251Ssam    boolean verbose = true;
87189251Ssam
88189251Ssam    @Override
89189251Ssam    public void init(ProcessingEnvironment pEnv) {
90189251Ssam        super.init(pEnv);
91189251Ssam        dprinter = new DPrinter(((JavacProcessingEnvironment) pEnv).getContext());
92189251Ssam        out = dprinter.out;
93189251Ssam    }
94189251Ssam
95189251Ssam    @Override
96189251Ssam    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
97189251Ssam        TestElementScanner s = new TestElementScanner();
98189251Ssam        for (Element e: roundEnv.getRootElements()) {
99189251Ssam            s.scan(e, null);
100189251Ssam        }
101189251Ssam        return true;
102189251Ssam    }
103189251Ssam
104189251Ssam    void error(Element e, String msg) {
105189251Ssam        messager.printMessage(Kind.ERROR, msg, e);
106189251Ssam        errors++;
107189251Ssam    }
108189251Ssam
109189251Ssam    int errors;
110189251Ssam
111189251Ssam    /**
112189251Ssam     * Scan an element looking for declarations annotated with @Test.
113189251Ssam     * Run a TestTypeScanner on the annotations that are found.
114189251Ssam     */
115189251Ssam    class TestElementScanner extends ElementScanner<Void,Void> {
116189251Ssam        public Void scan(Element elem, Void ignore) {
117189251Ssam            List<AnnotationMirror> tests = new ArrayList<>();
118189251Ssam            AnnotationMirror test = getAnnotation(elem, Test.class.getName().replace('$', '.'));
119189251Ssam            if (test != null) {
120189251Ssam                tests.add(test);
121189251Ssam            }
122189251Ssam            tests.addAll(getAnnotations(elem, Tests.class.getName().replace('$', '.')));
123189251Ssam
124189251Ssam            if (tests.size() > 0) {
125189251Ssam                out.println("Test: " + elem + " " + test);
126189251Ssam                TestTypeScanner s = new TestTypeScanner(elem, tests, types);
127189251Ssam                s.test(elem.asType());
128189251Ssam                out.println();
129189251Ssam            }
130189251Ssam            return super.scan(elem, ignore);
131189251Ssam        }
132189251Ssam    }
133189251Ssam
134189251Ssam    /**
135189251Ssam     * Scan the type of an element, looking for an annotation
136189251Ssam     * to match the expected annotation specified in the @Test annotation.
137189251Ssam     */
138189251Ssam    class TestTypeScanner extends TypeScanner<Void, Void> {
139189251Ssam        Element elem;
140189251Ssam        NavigableMap<Integer, AnnotationMirror> toBeFound;
141189251Ssam        int count = 0;
142189251Ssam        Set<TypeMirror> seen = new HashSet<>();
143189251Ssam
144189251Ssam        TestTypeScanner(Element elem, List<AnnotationMirror> tests, Types types) {
145189251Ssam            super(types);
146189251Ssam            this.elem = elem;
147189251Ssam
148189251Ssam            NavigableMap<Integer, AnnotationMirror> testByPos = new TreeMap<>();
149189251Ssam            for (AnnotationMirror test : tests) {
150189251Ssam                for (int pos : getPosn(test)) {
151189251Ssam                    testByPos.put(pos, test);
152189251Ssam                }
153189251Ssam            }
154189251Ssam            this.toBeFound = testByPos;
155189251Ssam        }
156189251Ssam
157189251Ssam        public void test(TypeMirror t) {
158189251Ssam            scan(t, null);
159189251Ssam        }
160189251Ssam
161189251Ssam        @Override
162189251Ssam        Void scan(TypeMirror t, Void ignore) {
163189251Ssam            if (t == null)
164189251Ssam                return DEFAULT_VALUE;
165189251Ssam
166189251Ssam            if (!seen.contains(t)) {
167189251Ssam                try {
168189251Ssam                    seen.add(t);
169189251Ssam                    if (verbose)
170189251Ssam                        out.println("scan " + count + ": " + t);
171189251Ssam                    if (toBeFound.size() > 0) {
172189251Ssam                        if (toBeFound.firstKey().equals(count)) {
173189251Ssam                            AnnotationMirror test = toBeFound.pollFirstEntry().getValue();
174189251Ssam                            String annoType = getAnnoType(test);
175189251Ssam                            AnnotationMirror anno = getAnnotation(t, annoType);
176189251Ssam                            if (anno == null) {
177189251Ssam                                error(elem, "annotation not found on " + count + ": " + t);
178189251Ssam                            } else {
179189251Ssam                                String v = getValue(anno, "value").toString();
180189251Ssam                                if (v.equals(getExpect(test))) {
181189251Ssam                                    out.println("found " + anno + " as expected");
182189251Ssam                                } else {
183189251Ssam                                    error(elem, "Unexpected value: " + v + ", expected: " + getExpect(test));
184189251Ssam                                }
185189251Ssam                            }
186189251Ssam                        } else if (count > toBeFound.firstKey()) {
187189251Ssam                            rescue();
188189251Ssam                        } else {
189189251Ssam                            List<? extends AnnotationMirror> annos = t.getAnnotationMirrors();
190189251Ssam                            if (annos.size() > 0) {
191189251Ssam                                for (AnnotationMirror a : annos)
192189251Ssam                                    error(elem, "annotation " + a + " found on " + count + ": " + t);
193189251Ssam                            }
194189251Ssam                        }
195189251Ssam                    } else {
196189251Ssam                        List<? extends AnnotationMirror> annos = t.getAnnotationMirrors();
197189251Ssam                        if (annos.size() > 0) {
198189251Ssam                            for (AnnotationMirror a : annos)
199189251Ssam                                error(elem, "annotation " + a + " found on " + count + ": " + t);
200189251Ssam                        }
201189251Ssam                    }
202189251Ssam                    count++;
203189251Ssam                    return super.scan(t, ignore);
204189251Ssam
205189251Ssam                } finally {
206189251Ssam                    seen.remove(t);
207189251Ssam                }
208189251Ssam            }
209189251Ssam
210189251Ssam            return DEFAULT_VALUE;
211189251Ssam
212189251Ssam        }
213189251Ssam
214189251Ssam        private void rescue() {
215189251Ssam            while (toBeFound.size() > 0 && toBeFound.firstKey() >= count)
216189251Ssam                toBeFound.pollFirstEntry();
217189251Ssam        }
218189251Ssam    }
219189251Ssam
220189251Ssam    /** Get the position value from an element annotated with a @Test annotation mirror. */
221189251Ssam    static int[] getPosn(Element elem) {
222189251Ssam        return elem.getAnnotation(Test.class).posn();
223189251Ssam    }
224189251Ssam
225189251Ssam    /** Get the position value from a @Test annotation mirror. */
226189251Ssam    static Integer[] getPosn(AnnotationMirror test) {
227189251Ssam        AnnotationValue v = getValue(test, "posn");
228189251Ssam        Object value = v.getValue();
229189251Ssam        Integer i = 0;
230189251Ssam        if (value instanceof Constant) {
231189251Ssam            i = (Integer)((Constant)value).getValue();
232189251Ssam            Integer[] res = new Integer[1];
233189251Ssam            res[0] = i;
234189251Ssam            return res;
235189251Ssam        } else if (value instanceof List) {
236189251Ssam            List<Constant> l = (List<Constant>)value;
237189251Ssam            Integer[] res = new Integer[l.size()];
238189251Ssam            for (int c = 0; c < l.size(); c++) {
239189251Ssam                res[c] = (Integer)l.get(c).getValue();
240189251Ssam            }
241189251Ssam            return res;
242189251Ssam        }
243189251Ssam        return null;
244189251Ssam    }
245189251Ssam
246189251Ssam    /** Get the expect value from an @Test annotation mirror. */
247189251Ssam    static String getExpect(AnnotationMirror test) {
248189251Ssam        AnnotationValue v = getValue(test, "expect");
249189251Ssam        return (String) v.getValue();
250189251Ssam    }
251189251Ssam
252189251Ssam    /** Get the annoType value from an @Test annotation mirror. */
253189251Ssam    static String getAnnoType(AnnotationMirror test) {
254189251Ssam        AnnotationValue v = getValue(test, "annoType");
255189251Ssam        TypeMirror m = (TypeMirror) v.getValue();
256189251Ssam        return m.toString();
257189251Ssam    }
258189251Ssam
259189251Ssam    /**
260189251Ssam     * Get a specific annotation mirror from an annotated construct.
261189251Ssam     */
262189251Ssam    static AnnotationMirror getAnnotation(AnnotatedConstruct e, String name) {
263189251Ssam        for (AnnotationMirror m: e.getAnnotationMirrors()) {
264189251Ssam            TypeElement te = (TypeElement) m.getAnnotationType().asElement();
265189251Ssam            if (te.getQualifiedName().contentEquals(name)) {
266189251Ssam                return m;
267189251Ssam            }
268189251Ssam        }
269189251Ssam        return null;
270189251Ssam    }
271189251Ssam
272189251Ssam    static List<AnnotationMirror> getAnnotations(Element e, String name) {
273189251Ssam        Name valueName = ((Symbol)e).getSimpleName().table.names.value;
274189251Ssam        List<AnnotationMirror> res = new ArrayList<>();
275189251Ssam
276189251Ssam        for (AnnotationMirror m : e.getAnnotationMirrors()) {
277189251Ssam            TypeElement te = (TypeElement) m.getAnnotationType().asElement();
278189251Ssam            if (te.getQualifiedName().contentEquals(name)) {
279189251Ssam                Compound theAnno = (Compound)m;
280189251Ssam                Array valueArray = (Array)theAnno.member(valueName);
281189251Ssam                for (Attribute a : valueArray.getValue()) {
282189251Ssam                    AnnotationMirror theMirror = (AnnotationMirror) a;
283189251Ssam
284189251Ssam                    res.add(theMirror);
285189251Ssam                }
286189251Ssam            }
287189251Ssam        }
288189251Ssam        return res;
289189251Ssam    }
290189251Ssam
291189251Ssam    /**
292189251Ssam     * Get a specific value from an annotation mirror.
293189251Ssam     */
294189251Ssam    static AnnotationValue getValue(AnnotationMirror anno, String name) {
295189251Ssam        Map<? extends ExecutableElement, ? extends AnnotationValue> map = anno.getElementValues();
296189251Ssam        for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> e: map.entrySet()) {
297189251Ssam            if (e.getKey().getSimpleName().contentEquals(name)) {
298189251Ssam                return e.getValue();
299189251Ssam            }
300189251Ssam        }
301189251Ssam        return null;
302189251Ssam    }
303189251Ssam
304189251Ssam    /**
305189251Ssam     * The Language Model API does not provide a type scanner, so provide
306189251Ssam     * one sufficient for our needs.
307189251Ssam     */
308189251Ssam    static class TypeScanner<R, P> extends SimpleTypeVisitor<R, P> {
309189251Ssam        private Types types;
310189251Ssam
311189251Ssam        public TypeScanner(Types types) {
312189251Ssam            super();
313189251Ssam            this.types = types;
314189251Ssam        }
315189251Ssam
316189251Ssam        @Override
317189251Ssam        public R visitArray(ArrayType t, P p) {
318189251Ssam            scan(t.getComponentType(), p);
319189251Ssam            return super.visitArray(t, p);
320189251Ssam        }
321189251Ssam
322189251Ssam        @Override
323189251Ssam        public R visitExecutable(ExecutableType t, P p) {
324189251Ssam            //out.println("  type parameters: " + t.getTypeVariables());
325189251Ssam            scan(t.getTypeVariables(), p);
326189251Ssam            //out.println("  return: " + t.getReturnType());
327189251Ssam            scan(t.getReturnType(), p);
328189251Ssam            //out.println("  receiver: " + t.getReceiverTypes());
329189251Ssam            scan(t.getReceiverType());
330189251Ssam            //out.println("  params: " + t.getParameterTypes());
331189251Ssam            scan(t.getParameterTypes(), p);
332189251Ssam            //out.println("  throws: " + t.getThrownTypes());
333189251Ssam            scan(t.getThrownTypes(), p);
334189251Ssam            return super.visitExecutable(t, p);
335189251Ssam        }
336189251Ssam
337189251Ssam        @Override
338189251Ssam        public R visitDeclared(DeclaredType t, P p) {
339189251Ssam            scan(t.getTypeArguments(), p);
340189251Ssam            // don't scan enclosing
341189251Ssam            scan(types.directSupertypes(t), p);
342189251Ssam            return super.visitDeclared(t, p);
343189251Ssam        }
344189251Ssam
345189251Ssam        @Override
346189251Ssam        public R visitIntersection(IntersectionType t, P p) {
347189251Ssam            scan(t.getBounds(), p);
348189251Ssam            return super.visitIntersection(t, p);
349189251Ssam        }
350189251Ssam
351189251Ssam        @Override
352189251Ssam        public R visitTypeVariable(TypeVariable t, P p) {
353189251Ssam            scan(t.getLowerBound(), p);
354189251Ssam            scan(t.getUpperBound(), p);
355189251Ssam            return super.visitTypeVariable(t, p);
356189251Ssam        }
357189251Ssam
358189251Ssam        @Override
359189251Ssam        public R visitWildcard(WildcardType t, P p) {
360189251Ssam            scan(t.getExtendsBound(), p);
361189251Ssam            scan(t.getSuperBound(), p);
362189251Ssam            return super.visitWildcard(t, p);
363189251Ssam        }
364189251Ssam
365189251Ssam        R scan(TypeMirror t) {
366189251Ssam            return scan(t, null);
367189251Ssam        }
368189251Ssam
369189251Ssam        R scan(TypeMirror t, P p) {
370189251Ssam            return (t == null) ? DEFAULT_VALUE : t.accept(this, p);
371189251Ssam        }
372189251Ssam
373189251Ssam        R scan(Iterable<? extends TypeMirror> iter, P p) {
374189251Ssam            if (iter == null)
375189251Ssam                return DEFAULT_VALUE;
376189251Ssam            R result = DEFAULT_VALUE;
377189251Ssam            for (TypeMirror t: iter)
378189251Ssam                result = scan(t, p);
379189251Ssam            return result;
380189251Ssam        }
381189251Ssam    }
382189251Ssam
383189251Ssam    /** Annotation to identify test cases. */
384189251Ssam    @Repeatable(Tests.class)
385189251Ssam    @interface Test {
386189251Ssam        /** Where to look for the annotation, expressed as a scan index. */
387189251Ssam        int[] posn();
388189251Ssam        /** The annotation to look for. */
389189251Ssam        Class<? extends Annotation> annoType();
390189251Ssam        /** The string representation of the annotation's value. */
391189251Ssam        String expect();
392189251Ssam    }
393189251Ssam
394189251Ssam    @interface Tests {
395189251Ssam        Test[] value();
396189251Ssam    }
397189251Ssam
398189251Ssam    /** Type annotation to use in test cases. */
399189251Ssam    @Target(ElementType.TYPE_USE)
400189251Ssam    public @interface TA {
401189251Ssam        int value();
402189251Ssam    }
403189251Ssam    @Target(ElementType.TYPE_USE)
404189251Ssam    public @interface TB {
405189251Ssam        int value();
406189251Ssam    }
407189251Ssam
408189251Ssam    // Test cases
409189251Ssam
410189251Ssam    // TODO: add more cases for arrays
411189251Ssam    //       all annotated
412189251Ssam    //       all but one annotated
413189251Ssam    //             vary position of one not annotated
414189251Ssam    //       only one annotated
415189251Ssam    //             vary position of one annotated
416189251Ssam    //       the three above with the corner case of the ambiguos decl + type anno added
417189251Ssam
418189251Ssam    @Test(posn=0, annoType=TA.class, expect="1")
419189251Ssam    public @TA(1) int f1;
420189251Ssam
421189251Ssam    @Test(posn=0, annoType=TA.class, expect="11")
422189251Ssam    @TA(11) public int f11;
423189251Ssam
424189251Ssam    @Test(posn=1, annoType=TA.class, expect="111")
425189251Ssam    @TA(111) public int [] f111;
426189251Ssam
427189251Ssam    @Test(posn=1, annoType=TA.class, expect="1120")
428189251Ssam    @Test(posn=0, annoType=TB.class, expect="1121")
429189251Ssam    @TA(1120) public int @TB(1121) [] f112;
430189251Ssam
431189251Ssam    @Test(posn=0, annoType=TB.class, expect="11211")
432189251Ssam    @Test(posn=1, annoType=TA.class, expect="11200")
433189251Ssam    public @TA(11200) int @TB(11211) [] f112b;
434189251Ssam
435189251Ssam    @Test(posn=1, annoType=TB.class, expect="1131")
436189251Ssam    @Test(posn=2, annoType=TA.class, expect="1130")
437189251Ssam    @TA(1130) public int [] @TB(1131) [] f113;
438189251Ssam
439189251Ssam    @Test(posn=5, annoType=TA.class, expect="12")
440189251Ssam    public @TA(12) int [] [] [] [] [] f12;
441189251Ssam
442189251Ssam    @Test(posn=6, annoType=TA.class, expect="13")
443189251Ssam    public @TA(13) int [] [] [] [] [] [] f13;
444189251Ssam
445189251Ssam    @Test(posn=7, annoType=TA.class, expect="14")
446189251Ssam    @TA(14) public int [] [] [] [] [] [] [] f14;
447189251Ssam
448189251Ssam    @Test(posn=6, annoType=TA.class, expect="150")
449189251Ssam    @Test(posn=7, annoType=TB.class, expect="151")
450189251Ssam    @TB(151) public int [] [] [] [] [] [] @TA(150) [] f15;
451189251Ssam
452189251Ssam    @Test(posn=0, annoType=TB.class, expect="1511")
453189251Ssam    @Test(posn=3, annoType=TA.class, expect="1512")
454189251Ssam    @Test(posn=6, annoType=TA.class, expect="150")
455189251Ssam    @Test(posn=7, annoType=TB.class, expect="151")
456189251Ssam    @TB(151) public int @TB(1511) [] [] [] @TA(1512) [] [] [] @TA(150) [] f15b;
457189251Ssam
458189251Ssam    @Test(posn=0, annoType=TB.class, expect="1521")
459189251Ssam    @Test(posn=3, annoType=TA.class, expect="1522")
460189251Ssam    @Test(posn=6, annoType=TA.class, expect="152")
461189251Ssam    public int @TB(1521) [] [] [] @TA(1522) [] [] [] @TA(152) [] f15c;
462189251Ssam
463189251Ssam    @Test(posn=5, annoType=TA.class, expect="160")
464189251Ssam    @Test(posn=6, annoType=TB.class, expect="161")
465189251Ssam    public int [] [] [] [] [] @TA(160) [] @TB(161) [] f16;
466189251Ssam
467189251Ssam    @Test(posn=0, annoType=TA.class, expect="2")
468189251Ssam    public int @TA(2) [] f2;
469189251Ssam
470189251Ssam    @Test(posn=0, annoType=TB.class, expect="33")
471189251Ssam    @Test(posn=1, annoType=TA.class, expect="3")
472189251Ssam    public @TA(3) int @TB(33) [] f3;
473189251Ssam
474189251Ssam    @Test(posn=2, annoType=TA.class, expect="4")
475189251Ssam    public int m1(@TA(4) float a) throws Exception { return 0; }
476189251Ssam
477189251Ssam    @Test(posn=1, annoType=TA.class, expect="5")
478189251Ssam    public @TA(5) int m2(float a) throws Exception { return 0; }
479189251Ssam
480189251Ssam    @Test(posn=3, annoType=TA.class, expect="6")
481189251Ssam    public int m3(float a) throws @TA(6) Exception { return 0; }
482189251Ssam
483189251Ssam    // Also tests that a decl anno on a typevar doesn't show up on the Type
484189251Ssam    @Test(posn=7, annoType=TA.class, expect="8")
485189251Ssam    public <@TA(7) M> M m4(@TA(8) float a) throws Exception { return null; }
486189251Ssam
487189251Ssam    // Also tests that a decl anno on a typevar doesn't show up on the Type
488189251Ssam    @Test(posn=4, annoType=TA.class, expect="10")
489189251Ssam    public class Inner1<@TA(9) S> extends @TA(10) Object implements Cloneable {}
490189251Ssam
491189251Ssam    // Also tests that a decl anno on a typevar doesn't show up on the Type
492189251Ssam    @Test(posn=5, annoType=TA.class, expect="12")
493189251Ssam    public class Inner2<@TA(11) S> extends Object implements @TA(12) Cloneable {}
494189251Ssam
495189251Ssam    @Test(posn={3,6}, annoType=TA.class, expect="13")
496189251Ssam    public <M extends @TA(13) Object> M m5(float a) { return null; }
497189251Ssam
498189251Ssam    @Test(posn=3, annoType=TA.class, expect="14")
499189251Ssam    public class Inner3<QQQ extends @TA(14) Map> {}
500189251Ssam
501189251Ssam    @Test(posn=4, annoType=TA.class, expect="15")
502189251Ssam    public class Inner4<T extends @TA(15) Object & Cloneable & Serializable> {}
503189251Ssam
504189251Ssam    @Test(posn=5, annoType=TA.class, expect="16")
505189251Ssam    public class Inner5<T extends Object & @TA(16) Cloneable & Serializable> {}
506189251Ssam
507189251Ssam    @Test(posn=7, annoType=TA.class, expect="17")
508189251Ssam    public class Inner6<T extends Object & Cloneable & @TA(17) Serializable> {}
509189251Ssam
510189251Ssam    // Test annotated bounds
511189251Ssam
512189251Ssam    @Test(posn=1, annoType=TA.class, expect="18")
513189251Ssam    public Set<@TA(18) ? extends Object> f4;
514189251Ssam
515189251Ssam    @Test(posn=2, annoType=TA.class, expect="19")
516189251Ssam    public Set<? extends @TA(19) Object> f5;
517189251Ssam
518189251Ssam    @Test(posn=3, annoType=TA.class, expect="20")
519189251Ssam    public Set<? extends Set<@TA(20) ? extends Object>> f6;
520189251Ssam
521189251Ssam    @Test(posn=4, annoType=TA.class, expect="21")
522189251Ssam    public Set<? extends Set<? extends @TA(21) Object>> f7;
523189251Ssam
524189251Ssam    @Test(posn=1, annoType=TA.class, expect="22")
525189251Ssam    public Set<@TA(22) ?> f8;
526189251Ssam
527189251Ssam    @Test(posn=1, annoType=TA.class, expect="23")
528189251Ssam    public Set<@TA(23) ? super Object> f9;
529189251Ssam
530189251Ssam    // Test type use annotations on uses of type variables
531189251Ssam    @Test(posn=5, annoType = TA.class, expect = "25")
532189251Ssam    @Test(posn=5, annoType = TB.class, expect = "26")
533189251Ssam    <T> void m6(@TA(25) @TB(26) T t) { }
534189251Ssam
535189251Ssam    class Inner7<T> {
536189251Ssam        @Test(posn=0, annoType = TA.class, expect = "30")
537189251Ssam        @Test(posn=0, annoType = TB.class, expect = "31")
538189251Ssam        @TA(30) @TB(31) T f;
539189251Ssam    }
540189251Ssam
541189251Ssam    // Test type use annotations on uses of type variables
542189251Ssam    @Test(posn=5, annoType = TB.class, expect = "41")
543189251Ssam    <@TA(40) T> void m7(@TB(41) T t) { }
544189251Ssam
545189251Ssam    class Inner8<@TA(50) T> {
546189251Ssam        @Test(posn=0, annoType = TB.class, expect = "51")
547189251Ssam        @TB(51) T f;
548189251Ssam    }
549189251Ssam
550189251Ssam    // Test type use annotations on uses of Class types
551189251Ssam    @Test(posn=5, annoType = TA.class, expect = "60")
552189251Ssam    @Test(posn=5, annoType = TB.class, expect = "61")
553189251Ssam    <T> void m60(@TA(60) @TB(61) String t) { }
554189251Ssam
555189251Ssam    class Inner70<T> {
556189251Ssam        @Test(posn=0, annoType = TA.class, expect = "70")
557189251Ssam        @Test(posn=0, annoType = TB.class, expect = "71")
558189251Ssam        @TA(70) @TB(71) String f;
559189251Ssam    }
560189251Ssam
561189251Ssam    // Test type use annotations on uses of type variables
562189251Ssam    @Test(posn=5, annoType = TB.class, expect = "81")
563189251Ssam    <@TA(80) T> void m80(@TB(81) String t) { }
564189251Ssam
565189251Ssam    class Inner90<@TA(90) T> {
566189251Ssam        @Test(posn=0, annoType = TB.class, expect = "91")
567189251Ssam        @TB(91) String f;
568189251Ssam    }
569189251Ssam
570189251Ssam    // Recursive bound
571189251Ssam    @Test(posn=4, annoType = TB.class, expect = "100")
572189251Ssam    class Inner100<T extends Inner100<@TB(100) T>> {
573189251Ssam    }
574189251Ssam}
575189251Ssam