test/tools/javac/processing/model/element/TestTypeParameterAnnotations.java

Wed, 18 Jun 2014 10:44:16 +0200

author
jlahoda
date
Wed, 18 Jun 2014 10:44:16 +0200
changeset 2427
a3ad6e2ede44
parent 1709
bae8387d16aa
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8046916: Type parameter annotations don't work with multiple type parameters
Summary: When reading type variable's annotations out of the owner's type annotations, use the type variable's index in owner to exclude annotations belonging to other type variables.
Reviewed-by: jfranck, emc

jfranck@1709 1 /*
jlahoda@2427 2 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
jfranck@1709 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jfranck@1709 4 *
jfranck@1709 5 * This code is free software; you can redistribute it and/or modify it
jfranck@1709 6 * under the terms of the GNU General Public License version 2 only, as
jfranck@1709 7 * published by the Free Software Foundation.
jfranck@1709 8 *
jfranck@1709 9 * This code is distributed in the hope that it will be useful, but WITHOUT
jfranck@1709 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jfranck@1709 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jfranck@1709 12 * version 2 for more details (a copy is included in the LICENSE file that
jfranck@1709 13 * accompanied this code).
jfranck@1709 14 *
jfranck@1709 15 * You should have received a copy of the GNU General Public License version
jfranck@1709 16 * 2 along with this work; if not, write to the Free Software Foundation,
jfranck@1709 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jfranck@1709 18 *
jfranck@1709 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jfranck@1709 20 * or visit www.oracle.com if you need additional information or have any
jfranck@1709 21 * questions.
jfranck@1709 22 */
jfranck@1709 23
jfranck@1709 24 /*
jfranck@1709 25 * @test
jlahoda@2427 26 * @bug 8011027 8046916
jfranck@1709 27 * @library /tools/javac/lib
jfranck@1709 28 * @build JavacTestingAbstractProcessor TestTypeParameterAnnotations
jfranck@1709 29 * @compile -processor TestTypeParameterAnnotations -proc:only TestTypeParameterAnnotations.java
jfranck@1709 30 */
jfranck@1709 31
jfranck@1709 32 import java.util.*;
jfranck@1709 33 import java.lang.annotation.*;
jfranck@1709 34 import javax.annotation.processing.*;
jfranck@1709 35 import javax.lang.model.element.*;
jfranck@1709 36 import javax.tools.*;
jfranck@1709 37
jlahoda@2427 38 @ExpectedTypeParameterAnnotations(typeParameterName="T1",
jlahoda@2427 39 annotations={"Foo1", "Bar1", "Baz1"})
jlahoda@2427 40 @ExpectedTypeParameterAnnotations(typeParameterName="T2", annotations={})
jlahoda@2427 41 @ExpectedTypeParameterAnnotations(typeParameterName="T3",
jlahoda@2427 42 annotations={"Foo2", "Bar2", "Baz2"})
jlahoda@2427 43 @ExpectedTypeParameterAnnotations(typeParameterName="T4", annotations={})
jlahoda@2427 44 public class TestTypeParameterAnnotations<@Foo1 @Bar1 @Baz1 T1, T2, @Foo2 @Bar2 @Baz2 T3, T4> extends
jlahoda@2427 45 JavacTestingAbstractProcessor {
jfranck@1709 46 int round = 0;
jfranck@1709 47
jfranck@1709 48 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
jfranck@1709 49 if (++round == 1) {
jfranck@1709 50 int found = (new Scanner()).scan(roundEnv.getRootElements(), null);
jfranck@1709 51 if (found == expect) {
jfranck@1709 52 ; //nop
jfranck@1709 53 } else {
jfranck@1709 54 error("unexpected number of results: expected " + expect
jfranck@1709 55 + ", found " + found);
jfranck@1709 56 }
jfranck@1709 57
jfranck@1709 58 }
jfranck@1709 59 return true;
jfranck@1709 60 }
jfranck@1709 61
jfranck@1709 62 class Scanner extends JavacTestingAbstractProcessor.ElementScanner<Integer,Void> {
jfranck@1709 63 @Override
jfranck@1709 64 public Integer visitExecutable(ExecutableElement e, Void p) {
jfranck@1709 65 super.visitExecutable(e, p);
jfranck@1709 66 found += check(e, e.getTypeParameters());
jfranck@1709 67 return found;
jfranck@1709 68 }
jfranck@1709 69
jfranck@1709 70 @Override
jfranck@1709 71 public Integer visitType(TypeElement e, Void p) {
jfranck@1709 72 super.visitType(e, p);
jfranck@1709 73 found += check(e, e.getTypeParameters());
jfranck@1709 74 return found;
jfranck@1709 75 }
jfranck@1709 76
jfranck@1709 77 int found;
jfranck@1709 78 }
jfranck@1709 79
jfranck@1709 80 int check(Element e, List<? extends TypeParameterElement> typarams) {
jfranck@1709 81 if (typarams.isEmpty())
jfranck@1709 82 return 0;
jfranck@1709 83
jlahoda@2427 84 for (TypeParameterElement tpe : typarams) {
jlahoda@2427 85 ExpectedTypeParameterAnnotations expected = null;
jlahoda@2427 86 for (ExpectedTypeParameterAnnotations a : e.getAnnotationsByType(ExpectedTypeParameterAnnotations.class)) {
jlahoda@2427 87 if (tpe.getSimpleName().contentEquals(a.typeParameterName())) {
jlahoda@2427 88 expected = a;
jlahoda@2427 89 break;
jlahoda@2427 90 }
jlahoda@2427 91 }
jlahoda@2427 92 if (expected == null) {
jlahoda@2427 93 throw new IllegalStateException("Does not have expected values annotation.");
jlahoda@2427 94 }
jlahoda@2427 95 checkAnnotationMirrors(tpe, tpe.getAnnotationMirrors(), expected);
jlahoda@2427 96 checkAnnotationMirrors(tpe, elements.getAllAnnotationMirrors(tpe), expected);
jlahoda@2427 97 checkGetAnnotation(tpe, expected);
jlahoda@2427 98 checkGetAnnotations(tpe, expected);
jfranck@1709 99 }
jlahoda@2427 100
jlahoda@2427 101 return typarams.size();
jfranck@1709 102 }
jfranck@1709 103
jlahoda@2427 104 void checkAnnotationMirrors(TypeParameterElement tpe, List<? extends AnnotationMirror> l, ExpectedTypeParameterAnnotations expected) {
jlahoda@2427 105 String[] expectedAnnotations = expected.annotations();
jlahoda@2427 106
jlahoda@2427 107 if (l.size() != expectedAnnotations.length) {
jlahoda@2427 108 error("Incorrect number of annotations, got " + l.size() +
jlahoda@2427 109 ", should be " + expectedAnnotations.length, tpe);
jlahoda@2427 110 return ;
jfranck@1709 111 }
jfranck@1709 112
jlahoda@2427 113 for (int i = 0; i < expectedAnnotations.length; i++) {
jlahoda@2427 114 AnnotationMirror m = l.get(i);
jlahoda@2427 115 if (!m.getAnnotationType().asElement().equals(elements.getTypeElement(expectedAnnotations[i]))) {
jlahoda@2427 116 error("Wrong type of annotation, was expecting @Foo", m.getAnnotationType().asElement());
jlahoda@2427 117 return ;
jlahoda@2427 118 }
jfranck@1709 119 }
jfranck@1709 120 }
jfranck@1709 121
jlahoda@2427 122 void checkGetAnnotation(TypeParameterElement tpe, ExpectedTypeParameterAnnotations expected) {
jlahoda@2427 123 List<String> expectedAnnotations = Arrays.asList(expected.annotations());
jfranck@1709 124
jlahoda@2427 125 for (Class<? extends Annotation> c : ALL_ANNOTATIONS) {
jlahoda@2427 126 Object a = tpe.getAnnotation(c);
jfranck@1709 127
jlahoda@2427 128 if (a != null ^ expectedAnnotations.indexOf(c.getName()) != (-1)) {
jlahoda@2427 129 error("Unexpected behavior for " + c.getName(), tpe);
jlahoda@2427 130 return ;
jlahoda@2427 131 }
jlahoda@2427 132 }
jfranck@1709 133 }
jfranck@1709 134
jlahoda@2427 135 void checkGetAnnotations(TypeParameterElement tpe, ExpectedTypeParameterAnnotations expected) {
jlahoda@2427 136 List<String> expectedAnnotations = Arrays.asList(expected.annotations());
jlahoda@2427 137
jlahoda@2427 138 for (Class<? extends Annotation> c : ALL_ANNOTATIONS) {
jlahoda@2427 139 Object[] a = tpe.getAnnotationsByType(c);
jlahoda@2427 140
jlahoda@2427 141 if (a.length > 0 ^ expectedAnnotations.indexOf(c.getName()) != (-1)) {
jlahoda@2427 142 error("Unexpected behavior for " + c.getName(), tpe);
jlahoda@2427 143 return ;
jlahoda@2427 144 }
jfranck@1709 145 }
jfranck@1709 146 }
jfranck@1709 147
jfranck@1709 148 void note(String msg) {
jfranck@1709 149 messager.printMessage(Diagnostic.Kind.NOTE, msg);
jfranck@1709 150 }
jfranck@1709 151
jfranck@1709 152 void note(String msg, Element e) {
jfranck@1709 153 messager.printMessage(Diagnostic.Kind.NOTE, msg, e);
jfranck@1709 154 }
jfranck@1709 155
jfranck@1709 156 void error(String msg, Element e) {
jfranck@1709 157 messager.printMessage(Diagnostic.Kind.ERROR, msg, e);
jfranck@1709 158 }
jfranck@1709 159
jfranck@1709 160 void error(String msg) {
jfranck@1709 161 messager.printMessage(Diagnostic.Kind.ERROR, msg);
jfranck@1709 162 }
jfranck@1709 163
jlahoda@2427 164 Class<? extends Annotation>[] ALL_ANNOTATIONS = new Class[] {
jlahoda@2427 165 Foo1.class, Bar1.class, Baz1.class,
jlahoda@2427 166 Foo2.class, Bar2.class, Baz2.class,
jlahoda@2427 167 };
jlahoda@2427 168
jfranck@1709 169 // additional generic elements to test
jlahoda@2427 170 @ExpectedTypeParameterAnnotations(typeParameterName="W",
jlahoda@2427 171 annotations={"Foo1", "Bar1", "Baz1"})
jlahoda@2427 172 @ExpectedTypeParameterAnnotations(typeParameterName="X", annotations={})
jlahoda@2427 173 @ExpectedTypeParameterAnnotations(typeParameterName="Y",
jlahoda@2427 174 annotations={"Foo2", "Bar2", "Baz2"})
jlahoda@2427 175 @ExpectedTypeParameterAnnotations(typeParameterName="Z", annotations={})
jlahoda@2427 176 <@Foo1 @Bar1 @Baz1 W, X, @Foo2 @Bar2 @Baz2 Y, Z> X m(X x) { return x; }
jfranck@1709 177
jlahoda@2427 178 @ExpectedTypeParameterAnnotations(typeParameterName="W",
jlahoda@2427 179 annotations={"Foo1", "Bar1", "Baz1"})
jlahoda@2427 180 @ExpectedTypeParameterAnnotations(typeParameterName="X", annotations={})
jlahoda@2427 181 @ExpectedTypeParameterAnnotations(typeParameterName="Y",
jlahoda@2427 182 annotations={"Foo2", "Bar2", "Baz2"})
jlahoda@2427 183 @ExpectedTypeParameterAnnotations(typeParameterName="Z", annotations={})
jlahoda@2427 184 interface Intf<@Foo1 @Bar1 @Baz1 W, X, @Foo2 @Bar2 @Baz2 Y, Z> { X m() ; }
jfranck@1709 185
jlahoda@2427 186 @ExpectedTypeParameterAnnotations(typeParameterName="W",
jlahoda@2427 187 annotations={"Foo1", "Bar1", "Baz1"})
jlahoda@2427 188 @ExpectedTypeParameterAnnotations(typeParameterName="X", annotations={})
jlahoda@2427 189 @ExpectedTypeParameterAnnotations(typeParameterName="Y",
jlahoda@2427 190 annotations={"Foo2", "Bar2", "Baz2"})
jlahoda@2427 191 @ExpectedTypeParameterAnnotations(typeParameterName="Z", annotations={})
jlahoda@2427 192 class Clazz<@Foo1 @Bar1 @Baz1 W, X, @Foo2 @Bar2 @Baz2 Y, Z> {
jlahoda@2427 193 @ExpectedTypeParameterAnnotations(typeParameterName="W",
jlahoda@2427 194 annotations={"Foo1", "Bar1", "Baz1"})
jlahoda@2427 195 @ExpectedTypeParameterAnnotations(typeParameterName="X", annotations={})
jlahoda@2427 196 @ExpectedTypeParameterAnnotations(typeParameterName="Y",
jlahoda@2427 197 annotations={"Foo2", "Bar2", "Baz2"})
jlahoda@2427 198 @ExpectedTypeParameterAnnotations(typeParameterName="Z", annotations={})
jlahoda@2427 199 <@Foo1 @Bar1 @Baz1 W, X, @Foo2 @Bar2 @Baz2 Y, Z> Clazz() { }
jfranck@1709 200 }
jfranck@1709 201
jlahoda@2427 202 final int expect = 5 * 4; // top level class, plus preceding examples, 4 type variables each
jfranck@1709 203 }
jfranck@1709 204
jfranck@1709 205 @Target(ElementType.TYPE_PARAMETER)
jlahoda@2427 206 @interface Foo1 {}
jfranck@1709 207
jfranck@1709 208 @Target(ElementType.TYPE_PARAMETER)
jlahoda@2427 209 @interface Bar1 {}
jfranck@1709 210
jfranck@1709 211 @Target(ElementType.TYPE_PARAMETER)
jlahoda@2427 212 @interface Baz1 {}
jlahoda@2427 213
jlahoda@2427 214 @Target(ElementType.TYPE_PARAMETER)
jlahoda@2427 215 @interface Foo2 {}
jlahoda@2427 216
jlahoda@2427 217 @Target(ElementType.TYPE_PARAMETER)
jlahoda@2427 218 @interface Bar2 {}
jlahoda@2427 219
jlahoda@2427 220 @Target(ElementType.TYPE_PARAMETER)
jlahoda@2427 221 @interface Baz2 {}
jlahoda@2427 222
jlahoda@2427 223 @Repeatable(ExpectedTypeParameterAnnotationsCollection.class)
jlahoda@2427 224 @interface ExpectedTypeParameterAnnotations {
jlahoda@2427 225 public String typeParameterName();
jlahoda@2427 226 public String[] annotations();
jlahoda@2427 227 }
jlahoda@2427 228
jlahoda@2427 229 @interface ExpectedTypeParameterAnnotationsCollection {
jlahoda@2427 230 public ExpectedTypeParameterAnnotations[] value();
jlahoda@2427 231 }

mercurial