MakeTypeTest.java revision 3294:9adfb22ff08f
134355Sjb/* 234355Sjb * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. 389985Sbde * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4171210Speter * 534355Sjb * This code is free software; you can redistribute it and/or modify it 634355Sjb * under the terms of the GNU General Public License version 2 only, as 764002Speter * published by the Free Software Foundation. 834355Sjb * 934355Sjb * This code is distributed in the hope that it will be useful, but WITHOUT 1034355Sjb * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1134355Sjb * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1234355Sjb * version 2 for more details (a copy is included in the LICENSE file that 1334355Sjb * accompanied this code). 1434355Sjb * 1534355Sjb * You should have received a copy of the GNU General Public License version 1634355Sjb * 2 along with this work; if not, write to the Free Software Foundation, 1734355Sjb * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1834355Sjb * 1934355Sjb * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2034355Sjb * or visit www.oracle.com if you need additional information or have any 2134355Sjb * questions. 22171210Speter */ 2334355Sjb 2434355Sjb/* 2534355Sjb * @test 2634355Sjb * @bug 8042239 2734355Sjb * @summary Verify that TreeMaker.Type(Type) can handle all reasonable types 2834355Sjb * @library /tools/javac/lib 2934355Sjb * @modules jdk.compiler/com.sun.tools.javac.api 3034355Sjb * jdk.compiler/com.sun.tools.javac.code 3134355Sjb * jdk.compiler/com.sun.tools.javac.processing 3234355Sjb * jdk.compiler/com.sun.tools.javac.tree 3334355Sjb * jdk.compiler/com.sun.tools.javac.util 3434355Sjb * @build JavacTestingAbstractProcessor MakeTypeTest 3534355Sjb * @compile/process/ref=MakeTypeTest.out -XDaccessInternalAPI -processor MakeTypeTest MakeTypeTest.java 3634355Sjb */ 3734355Sjb 3834355Sjbimport java.lang.annotation.*; 3934355Sjbimport java.util.*; 4034355Sjb 4134355Sjbimport javax.annotation.processing.RoundEnvironment; 4234355Sjbimport javax.lang.model.element.*; 4334355Sjbimport javax.lang.model.type.*; 4434355Sjb 4534355Sjbimport com.sun.source.tree.*; 4634355Sjbimport com.sun.source.util.*; 4734355Sjbimport com.sun.tools.javac.api.JavacTrees; 4834355Sjbimport com.sun.tools.javac.code.Type; 4934355Sjbimport com.sun.tools.javac.code.Type.ClassType; 5034355Sjbimport com.sun.tools.javac.processing.JavacProcessingEnvironment; 5134355Sjbimport com.sun.tools.javac.tree.JCTree.JCExpression; 5234355Sjbimport com.sun.tools.javac.tree.TreeMaker; 5334355Sjbimport com.sun.tools.javac.util.*; 5434355Sjbimport com.sun.tools.javac.util.List; 5534355Sjb 5634355Sjbpublic class MakeTypeTest extends JavacTestingAbstractProcessor { 5734355Sjb @Override 5834355Sjb public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 5934355Sjb if (!roundEnv.processingOver()) 6034355Sjb return false; 6134355Sjb 6234355Sjb JavacTask.instance(processingEnv).addTaskListener(new TaskListener() { 6334355Sjb @Override 6434355Sjb public void started(TaskEvent e) { 6534355Sjb } 6634355Sjb @Override 6734355Sjb public void finished(TaskEvent e) { 6834355Sjb if (e.getKind() == TaskEvent.Kind.ANALYZE && 6934355Sjb e.getTypeElement().getQualifiedName().contentEquals("MakeTypeTest")) { 7034355Sjb doTest(); 7134355Sjb } 7234355Sjb } 7334355Sjb }); 7434355Sjb 7534355Sjb return false; 7634355Sjb } 7734355Sjb 7834355Sjb void doTest() { 7934355Sjb //go through this file, look for @TestType and verify TreeMaker.Type behavior: 8034355Sjb Context ctx = ((JavacProcessingEnvironment) processingEnv).getContext(); 8134355Sjb JavacTrees trees = JavacTrees.instance(ctx); 8234355Sjb TypeElement testType = processingEnv.getElementUtils().getTypeElement("MakeTypeTest"); 8334355Sjb TreePath path = trees.getPath(testType); 8434355Sjb 8534355Sjb Set<TypeKind> unseenTypeKinds = EnumSet.allOf(TypeKind.class); 8634355Sjb 8734355Sjb new TreePathScanner<Void, Void>() { 8834355Sjb @Override 8934355Sjb public Void visitVariable(VariableTree node, Void p) { 9034355Sjb handleDecl(new TreePath(getCurrentPath(), node.getType())); 9134355Sjb return super.visitVariable(node, p); 9234355Sjb } 9334355Sjb 9434355Sjb @Override 9534355Sjb public Void visitMethod(MethodTree node, Void p) { 9634355Sjb if (node.getReturnType() != null) 9734355Sjb handleDecl(new TreePath(getCurrentPath(), node.getReturnType())); 9834355Sjb return super.visitMethod(node, p); 9934355Sjb } 10034355Sjb 10134355Sjb @Override 10234355Sjb public Void visitTypeParameter(TypeParameterTree node, Void p) { 10334355Sjb TypeVariable type = (TypeVariable) trees.getTypeMirror(getCurrentPath()); 10434355Sjb TreePath aBoundPath = new TreePath(getCurrentPath(), node.getBounds().get(0)); 10534355Sjb handleDecl(aBoundPath, (Type) type.getUpperBound()); 10634355Sjb return super.visitTypeParameter(node, p); 10734355Sjb } 10834355Sjb 10934355Sjb void handleDecl(TreePath typePath) { 11034355Sjb handleDecl(typePath, (Type) trees.getTypeMirror(typePath)); 111171210Speter } 112171210Speter 113127891Sdfr void handleDecl(TreePath typePath, Type type) { 11434355Sjb Element decl = trees.getElement(typePath.getParentPath()); 11534355Sjb TestType testType = decl.getAnnotation(TestType.class); 11634355Sjb 11734355Sjb if (testType == null) return ; 11834355Sjb 11934355Sjb if (testType.nested() >= 0) { 12034355Sjb ClassType ct = (ClassType) type; 12134355Sjb type = ct.getTypeArguments().get(testType.nested()); 12234355Sjb } 123171210Speter 124171210Speter JCExpression typeExpr = TreeMaker.instance(ctx).Type(type); 12534355Sjb 12634355Sjb if (!typeExpr.getKind().equals(testType.expectedKind())) { 12734355Sjb throw new IllegalStateException("was=" + typeExpr + ", kind=" + 12834355Sjb typeExpr.getKind() + "; expected kind: " + 12934355Sjb testType.expectedKind() + "; type=" + type); 13034355Sjb } 13134355Sjb unseenTypeKinds.remove(type.getKind()); 13234355Sjb } 13334355Sjb 13434355Sjb }.scan(path, null); 13534355Sjb 13634355Sjb unseenTypeKinds.removeAll(Arrays.asList(TypeKind.NONE, TypeKind.NULL, TypeKind.ERROR, 137171210Speter TypeKind.PACKAGE, TypeKind.EXECUTABLE, TypeKind.OTHER, TypeKind.MODULE)); 13834355Sjb 139171210Speter if (!unseenTypeKinds.isEmpty()) 140171210Speter throw new IllegalStateException("Unhandled types=" + unseenTypeKinds); 141171210Speter 14234355Sjb System.err.println("done."); 14334355Sjb } 14434355Sjb 14534355Sjb //the following defines the Types that should be passed into TreeMaker.Type and 14635938Sdyson //the expected resulting Tree kind: 14734355Sjb 14834355Sjb @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE) 14934355Sjb boolean f1; 15034355Sjb @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE) 15134355Sjb byte f2; 15234355Sjb @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE) 15334355Sjb char f3; 15434355Sjb @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE) 15534355Sjb double f4; 15634355Sjb @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE) 15734355Sjb float f5; 15834355Sjb @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE) 15934355Sjb int f6; 16034355Sjb @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE) 16134355Sjb long f7; 16234355Sjb @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE) 163156138Sdavidxu short f8; 164156138Sdavidxu @TestType(expectedKind=Tree.Kind.PARAMETERIZED_TYPE) 165156138Sdavidxu List<? extends String> f9; 166156138Sdavidxu @TestType(expectedKind=Tree.Kind.ARRAY_TYPE) 167156138Sdavidxu int[] fa; 16834355Sjb @TestType(expectedKind=Tree.Kind.EXTENDS_WILDCARD, nested = 0) 169137875Smarks List<? extends String> fb; 17034355Sjb @TestType(expectedKind=Tree.Kind.SUPER_WILDCARD, nested = 0) 17134355Sjb List<? super String> fc; 17234355Sjb @TestType(expectedKind=Tree.Kind.UNBOUNDED_WILDCARD, nested = 0) 17334355Sjb List<?> fd; 17434355Sjb 175151868Sdavidxu @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE) 176151868Sdavidxu void voidMethod() { 177151868Sdavidxu try { 17835938Sdyson voidMethod(); 17935938Sdyson } catch (@TestType(expectedKind=Tree.Kind.UNION_TYPE) NullPointerException | 18035938Sdyson IllegalStateException ex) { 18135938Sdyson } 18235938Sdyson } 18335938Sdyson 18435938Sdyson class WithTypeParam<@TestType(expectedKind=Tree.Kind.INTERSECTION_TYPE) 18535938Sdyson T extends CharSequence & Runnable> { 186147814Sjhb @TestType(expectedKind=Tree.Kind.IDENTIFIER) 187147814Sjhb T voidMethod() { 188171210Speter return null; 18951138Salfred } 19051138Salfred } 19134355Sjb 19234355Sjb} 19334355Sjb 19434355Sjb//TreeMaker.Type will be tested for the type the element annotated by this annotation 19534355Sjb@Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.METHOD, 19634355Sjb ElementType.PARAMETER, ElementType.TYPE_PARAMETER}) 19734355Sjb@interface TestType { 19834355Sjb //the expected Tree kind of the Tree that will be returned from TreeMaker.Type for the type 19934355Sjb public Tree.Kind expectedKind(); 20034355Sjb //if >=0, the current type will be interpreted as a ClassType and the type to test will be 20134355Sjb //the given type argument: 20256115Speter public int nested() default -1; 20356115Speter} 20434355Sjb