jjg@1521: /* darcy@1534: * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. jjg@1521: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jjg@1521: * jjg@1521: * This code is free software; you can redistribute it and/or modify it jjg@1521: * under the terms of the GNU General Public License version 2 only, as jjg@1521: * published by the Free Software Foundation. jjg@1521: * jjg@1521: * This code is distributed in the hope that it will be useful, but WITHOUT jjg@1521: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jjg@1521: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jjg@1521: * version 2 for more details (a copy is included in the LICENSE file that jjg@1521: * accompanied this code). jjg@1521: * jjg@1521: * You should have received a copy of the GNU General Public License version jjg@1521: * 2 along with this work; if not, write to the Free Software Foundation, jjg@1521: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jjg@1521: * jjg@1521: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA jjg@1521: * or visit www.oracle.com if you need additional information or have any jjg@1521: * questions. jjg@1521: */ jjg@1521: jjg@1521: /* jjg@1521: * @test jjg@1521: * @summary Checks the annotation types targeting array types jjg@1521: */ jjg@1521: jjg@1521: import com.sun.tools.javac.api.JavacTool; jjg@1521: import java.io.File; jjg@1521: import java.io.PrintWriter; jjg@1521: import java.util.Arrays; jjg@1521: import java.util.List; jjg@1521: import java.util.Map; jjg@1521: import java.util.HashMap; jjg@1521: import java.lang.annotation.*; jjg@1521: import javax.tools.JavaFileManager; jjg@1521: import javax.tools.JavaFileObject; jjg@1521: import com.sun.source.tree.*; jjg@1521: import com.sun.source.util.JavacTask; jjg@1521: import com.sun.source.util.TreeScanner; jjg@1521: import javax.tools.StandardJavaFileManager; jjg@1521: jjg@1521: jjg@1521: public class AnnotatedArrayOrder { jjg@1521: public static void main(String[] args) throws Exception { jjg@1521: PrintWriter out = new PrintWriter(System.out, true); jjg@1521: JavacTool tool = JavacTool.create(); jjg@1521: StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); jjg@1521: File testSrc = new File(System.getProperty("test.src")); jjg@1521: Iterable f = jjg@1521: fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "AnnotatedArrayOrder.java"))); jjg@1521: JavacTask task = tool.getTask(out, fm, null, null, null, f); jjg@1521: Iterable trees = task.parse(); jjg@1521: out.flush(); jjg@1521: jjg@1521: Scanner s = new Scanner(); jjg@1521: for (CompilationUnitTree t: trees) jjg@1521: s.scan(t, null); jjg@1521: jjg@1521: } jjg@1521: jjg@1521: private static class Scanner extends TreeScanner { jjg@1521: public Void visitCompilationUnit(CompilationUnitTree node, Void ignore) { jjg@1521: super.visitCompilationUnit(node, ignore); jjg@1521: if (!expectedLocations.isEmpty()) { jjg@1521: throw new AssertionError("Didn't found all annotations: " + expectedLocations); jjg@1521: } jjg@1521: return null; jjg@1521: } jjg@1521: jjg@1521: private void testAnnotations(List annos, int found) { jjg@1521: String annotation = annos.get(0).toString(); jjg@1521: jjg@1521: if (!expectedLocations.containsKey(annotation)) jjg@1521: throw new AssertionError("Found unexpected annotation: " + annotation + expectedLocations); jjg@1521: jjg@1521: int expected = expectedLocations.get(annotation); jjg@1521: if (found != expected) jjg@1521: throw new AssertionError("The expected array length for this error doesn't match"); jjg@1521: jjg@1521: expectedLocations.remove(annotation); jjg@1521: } jjg@1521: jjg@1521: public Void visitAnnotatedType(AnnotatedTypeTree node, Void ignore) { jjg@1521: testAnnotations(node.getAnnotations(), arrayLength(node)); jjg@1521: return super.visitAnnotatedType(node, ignore); jjg@1521: } jjg@1521: jjg@1521: private int arrayLength(Tree tree) { jjg@1521: switch (tree.getKind()) { jjg@1521: case ARRAY_TYPE: jjg@1521: return 1 + arrayLength(((ArrayTypeTree)tree).getType()); jjg@1521: case ANNOTATED_TYPE: jjg@1521: return arrayLength(((AnnotatedTypeTree)tree).getUnderlyingType()); jjg@1521: default: jjg@1521: return 0; jjg@1521: } jjg@1521: } jjg@1521: } jjg@1521: jjg@1521: // expectedLocations values: jjg@1521: static Map expectedLocations = new HashMap(); jjg@1521: jjg@1521: // visited code jjg@1521: @A String @C [] @B [] field; jjg@1521: static { jjg@1521: // Shouldn't find @A(), as it is field annotation jjg@1521: expectedLocations.put("@B()", 1); jjg@1521: expectedLocations.put("@C()", 2); jjg@1521: } jjg@1521: jjg@1521: List<@D String @F [] @E []> typearg; jjg@1521: static { jjg@1521: expectedLocations.put("@D()", 0); jjg@1521: expectedLocations.put("@E()", 1); jjg@1521: expectedLocations.put("@F()", 2); jjg@1521: } jjg@1521: jjg@1521: void varargSimple(@G String @H ... vararg1) { } jjg@1521: static { jjg@1521: // Shouldn't find @G(), as it is a parameter annotation jjg@1521: expectedLocations.put("@H()", 1); jjg@1521: } jjg@1521: jjg@1521: void varargLong(@I String @L [] @K [] @J ... vararg2) { } jjg@1521: static { jjg@1521: // Shouldn't find @I(), as it is a parameter annotation jjg@1521: expectedLocations.put("@J()", 1); jjg@1521: expectedLocations.put("@K()", 2); jjg@1521: expectedLocations.put("@L()", 3); jjg@1521: } jjg@1521: jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface A {} jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface B {} jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface C {} jjg@1521: jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface D {} jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface E {} jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface F {} jjg@1521: jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface G {} jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface H {} jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface I {} jjg@1521: jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface J {} jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface K {} jjg@1521: @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) jjg@1521: @interface L {} jjg@1521: }