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 that the interaction between annotated and unannotated jjg@1521: * array levels jjg@1521: */ jjg@1521: jjg@1521: import com.sun.tools.javac.api.JavacTool; jjg@1521: import java.lang.annotation.*; 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 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 ArrayPositionConsistency { 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, "ArrayPositionConsistency.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: int foundAnnotations = 0; jjg@1521: public Void visitCompilationUnit(CompilationUnitTree node, Void ignore) { jjg@1521: super.visitCompilationUnit(node, ignore); jjg@1521: if (foundAnnotations != expectedAnnotations) { jjg@1521: throw new AssertionError("Expected " + expectedAnnotations + jjg@1521: " annotations but found: " + foundAnnotations); 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: foundAnnotations++; jjg@1521: jjg@1521: int expected = -1; jjg@1521: if (annotation.equals("@A()")) jjg@1521: expected = 0; jjg@1521: else if (annotation.equals("@B()")) jjg@1521: expected = 1; jjg@1521: else if (annotation.equals("@C()")) jjg@1521: expected = 2; jjg@1521: else jjg@1521: throw new AssertionError("found an unexpected annotation: " + annotation); jjg@1521: if (found != expected) { jjg@1521: throw new AssertionError("Unexpected found length" + jjg@1521: ", found " + found + " but expected " + expected); jjg@1521: } 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: static int expectedAnnotations = 23; jjg@1521: jjg@1521: // visited code jjg@1521: @A String @C [] @B [] field1; jjg@1521: @A String @C [] [] field2; jjg@1521: @A String [] @B [] field3; jjg@1521: String [] @B [] field4; jjg@1521: jjg@1521: @A List @C [] @B [] genfield1; jjg@1521: @A List @C [] [] genfield2; jjg@1521: @A List [] @B [] genfield3; jjg@1521: List [] @B [] genfield4; jjg@1521: jjg@1521: List<@A String @C [] @B []> typearg1; jjg@1521: List<@A String @C [] []> typearg2; jjg@1521: List<@A String [] @B []> typearg3; jjg@1521: List< String [] @B []> typearg4; jjg@1521: jjg@1521: void vararg1(@A String @C [] @B ... arg) {} jjg@1521: void vararg2(@A String @C [] ... arg) {} jjg@1521: void vararg3(@A String [] @B ... arg) {} jjg@1521: void vararg4( String [] @B ... arg) {} 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: }