jjg@1969: /* jjg@1969: * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. jjg@1969: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jjg@1969: * jjg@1969: * This code is free software; you can redistribute it and/or modify it jjg@1969: * under the terms of the GNU General Public License version 2 only, as jjg@1969: * published by the Free Software Foundation. jjg@1969: * jjg@1969: * This code is distributed in the hope that it will be useful, but WITHOUT jjg@1969: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jjg@1969: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jjg@1969: * version 2 for more details (a copy is included in the LICENSE file that jjg@1969: * accompanied this code). jjg@1969: * jjg@1969: * You should have received a copy of the GNU General Public License version jjg@1969: * 2 along with this work; if not, write to the Free Software Foundation, jjg@1969: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jjg@1969: * jjg@1969: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA jjg@1969: * or visit www.oracle.com if you need additional information or have any jjg@1969: * questions. jjg@1969: */ jjg@1969: jjg@1969: /* jjg@1969: * @test jjg@1969: * @bug 1234567 jjg@1969: * @summary test Pretty print of type annotations jjg@1969: * @author wmdietl jjg@1969: */ jjg@1969: jjg@1969: import com.sun.source.tree.ClassTree; jjg@1969: import com.sun.source.tree.CompilationUnitTree; jjg@1969: import com.sun.tools.javac.api.JavacTaskImpl; jjg@1969: import com.sun.tools.javac.tree.JCTree; jjg@1969: jjg@1969: import java.io.IOException; jjg@1969: import java.net.URI; jjg@1969: import java.util.Arrays; jjg@1969: import java.util.List; jjg@1969: import java.util.LinkedList; jjg@1969: jjg@1969: import javax.tools.JavaCompiler; jjg@1969: import javax.tools.JavaFileObject; jjg@1969: import javax.tools.SimpleJavaFileObject; jjg@1969: import javax.tools.ToolProvider; jjg@1969: jjg@1969: public class TypeAnnotationsPretty { jjg@1969: private final JavaCompiler tool; jjg@1969: jjg@1969: TypeAnnotationsPretty() { jjg@1969: tool = ToolProvider.getSystemJavaCompiler(); jjg@1969: } jjg@1969: jjg@1969: private List matches = new LinkedList(); jjg@1969: private List mismatches = new LinkedList(); jjg@1969: jjg@1969: public static void main(String... args) throws Exception { jjg@1969: TypeAnnotationsPretty tap = new TypeAnnotationsPretty(); jjg@1969: jjg@1969: tap.runField("@TA()\nObject cls = null"); jjg@1969: tap.runField("@TA()\nObject cls = new @TA() Object()"); jjg@1969: jjg@1969: tap.runField("@TA()\nList<@TB() Object> cls = null"); jjg@1969: tap.runField("@TA()\nList<@TB() Object> cls = new @TA() LinkedList<@TB() Object>()"); jjg@1969: jjg@1969: tap.runField("Class[] cls = null"); jjg@1969: tap.runField("@TA()\nClass[] cls = null"); jjg@1969: tap.runField("Class @TA() [] cls = null"); jjg@1969: tap.runField("@TA()\nClass @TB() [] cls = null"); jjg@1969: jjg@1969: tap.runField("Class[] cls = new Class[]{Object.class}"); jjg@1969: tap.runField("@TA()\nClass[] cls = new @TA() Class[]{Object.class}"); jjg@1969: tap.runField("Class @TB() [] cls = new Class @TB() []{Object.class}"); jjg@1969: tap.runField("@TA()\nClass @TB() [] cls = new @TA() Class @TB() []{Object.class}"); jjg@1969: tap.runField("@TA()\nClass @TB() [] @TC() [] cls = new @TA() Class @TB() [10] @TC() []"); jjg@1969: tap.runField("Class @TB() [] @TC() [] cls = new Class @TB() [10] @TC() []"); jjg@1969: tap.runField("@TA()\nClass @TB() [] @TC() [] @TD() [] cls = new @TA() Class @TB() [10] @TC() [] @TD() []"); jjg@1969: jjg@1969: tap.runMethod("\n@TA()\nObject test(@TB()\nList<@TC() String> p) {\n" + jjg@1969: " return null;\n" + jjg@1969: "}"); jjg@1969: jjg@1969: jjg@1969: if (!tap.matches.isEmpty()) { jjg@1969: for (String m : tap.matches) jjg@1969: System.out.println(m); jjg@1969: } jjg@1969: if (!tap.mismatches.isEmpty()) { jjg@1969: for (String mm : tap.mismatches) jjg@1969: System.err.println(mm + "\n"); jjg@1969: throw new RuntimeException("Tests failed!"); jjg@1969: } jjg@1969: } jjg@1969: jjg@1969: private static final String prefix = jjg@1969: "import java.lang.annotation.*;" + jjg@1969: "import java.util.*;" + jjg@1969: "public class Test {"; jjg@1969: jjg@1969: private static final String postfix = jjg@1969: "@Target(ElementType.TYPE_USE)" + jjg@1969: "@interface TA {}" + jjg@1969: "@Target(ElementType.TYPE_USE)" + jjg@1969: "@interface TB {}" + jjg@1969: "@Target(ElementType.TYPE_USE)" + jjg@1969: "@interface TC {}" + jjg@1969: "@Target(ElementType.TYPE_USE)" + jjg@1969: "@interface TD {}"; jjg@1969: jjg@1969: jjg@1969: private void runField(String code) throws IOException { jjg@1969: String src = prefix + jjg@1969: code + "; }" + jjg@1969: postfix; jjg@1969: jjg@1969: JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, jjg@1969: null, Arrays.asList(new MyFileObject(src))); jjg@1969: jjg@1969: jjg@1969: for (CompilationUnitTree cut : ct.parse()) { jjg@1969: JCTree.JCVariableDecl var = jjg@1969: (JCTree.JCVariableDecl) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0); jjg@1969: jjg@1969: if (!code.equals(var.toString())) { jjg@1969: mismatches.add("Expected: " + code + jjg@1969: "\nObtained: " + var.toString()); jjg@1969: } else { jjg@1969: matches.add("Passed: " + code); jjg@1969: } jjg@1969: } jjg@1969: } jjg@1969: jjg@1969: private void runMethod(String code) throws IOException { jjg@1969: String src = prefix + jjg@1969: code + "}" + jjg@1969: postfix; jjg@1969: jjg@1969: JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, jjg@1969: null, Arrays.asList(new MyFileObject(src))); jjg@1969: jjg@1969: jjg@1969: for (CompilationUnitTree cut : ct.parse()) { jjg@1969: JCTree.JCMethodDecl var = jjg@1969: (JCTree.JCMethodDecl) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0); jjg@1969: jjg@1969: if (!code.equals(var.toString())) { jjg@1969: mismatches.add("Expected: " + code + jjg@1969: "\nObtained: " + var.toString()); jjg@1969: } else { jjg@1969: matches.add("Passed: " + code); jjg@1969: } jjg@1969: } jjg@1969: } jjg@1969: } jjg@1969: jjg@1969: jjg@1969: class MyFileObject extends SimpleJavaFileObject { jjg@1969: jjg@1969: private String text; jjg@1969: jjg@1969: public MyFileObject(String text) { jjg@1969: super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); jjg@1969: this.text = text; jjg@1969: } jjg@1969: jjg@1969: @Override jjg@1969: public CharSequence getCharContent(boolean ignoreEncodingErrors) { jjg@1969: return text; jjg@1969: } jjg@1969: }