/******************************************************************************* * Copyright (c) 2006 BEA Systems, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * sbandow@bea.com - initial API and implementation * *******************************************************************************/ package org.eclipse.jdt.apt.tests; import java.util.ArrayList; import java.util.Collection; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.apt.tests.annotations.generic.AbstractGenericProcessor; import org.eclipse.jdt.apt.tests.annotations.generic.GenericFactory; import com.sun.mirror.declaration.AnnotationMirror; import com.sun.mirror.declaration.ClassDeclaration; import com.sun.mirror.declaration.FieldDeclaration; import com.sun.mirror.declaration.MethodDeclaration; import com.sun.mirror.declaration.TypeDeclaration; import com.sun.mirror.declaration.TypeParameterDeclaration; import com.sun.mirror.type.AnnotationType; import com.sun.mirror.type.ArrayType; import com.sun.mirror.type.ClassType; import com.sun.mirror.type.DeclaredType; import com.sun.mirror.type.EnumType; import com.sun.mirror.type.InterfaceType; import com.sun.mirror.type.PrimitiveType; import com.sun.mirror.type.ReferenceType; import com.sun.mirror.type.TypeMirror; import com.sun.mirror.type.TypeVariable; import com.sun.mirror.type.VoidType; import com.sun.mirror.type.WildcardType; import com.sun.mirror.util.TypeVisitor; import com.sun.mirror.util.Types; /** * Tests for the JDT-APT implementation of Type Visitors */ public class TypeVisitorTests extends APTTestBase { public TypeVisitorTests(final String name) { super(name); } public static Test suite() { return new TestSuite(TypeVisitorTests.class); } public void testPrimitiveTypeVisitor() { testCaseIdentifier = Cases.PrimitiveType; runProcessorBasedTest(); } public void testVoidTypeVisitor() { testCaseIdentifier = Cases.VoidType; runProcessorBasedTest(); } public void testClassTypeVisitor() { testCaseIdentifier = Cases.ClassType; runProcessorBasedTest(); } public void testEnumTypeVisitor() { testCaseIdentifier = Cases.EnumType; runProcessorBasedTest(); } public void testInterfaceTypeVisitor() { testCaseIdentifier = Cases.InterfaceType; runProcessorBasedTest(); } public void testAnnotationTypeVisitor() { testCaseIdentifier = Cases.AnnotationType; runProcessorBasedTest(); } public void testArrayTypeVisitor() { testCaseIdentifier = Cases.ArrayType; runProcessorBasedTest(); } public void testTypeVariableVisitor() { testCaseIdentifier = Cases.TypeVariable; runProcessorBasedTest(); } public void testWildcardTypeVisitor() { testCaseIdentifier = Cases.WildcardType; runProcessorBasedTest(); } /** * Instantiate the AnnotationProcessor to run the actual tests */ void runProcessorBasedTest() { TypeVisitorProc p = new TypeVisitorProc(); GenericFactory.PROCESSOR = p; IProject project = env.getProject(getProjectName()); IPath srcRoot = getSourcePath(); env.addClass(srcRoot, "test", "Test", code); fullBuild( project.getFullPath() ); expectingNoProblems(); assertTrue("Processor not invoked", p.called); } /** * Annotation Processor containing the actual tests */ class TypeVisitorProc extends AbstractGenericProcessor { boolean called; public void _process() { called = true; assertTrue(decls.size() == 1); initTypeVisitList(); TypeDeclaration typeDecl = env.getTypeDeclarations().iterator().next(); Collection<TypeDeclaration> nestedTypes = typeDecl.getNestedTypes(); Collection<FieldDeclaration> fieldDecls = typeDecl.getFields(); ClassDeclaration classDecl = null; FieldDeclaration fieldDecl = null; PrimitiveType primitiveType = null; AnnotationMirror annoMirror = null; Types typesUtil = env.getTypeUtils(); switch (testCaseIdentifier) { case PrimitiveType : for(FieldDeclaration tempDecl : fieldDecls) { if(tempDecl.getSimpleName().equals("j")) { fieldDecl = tempDecl; } } primitiveType = (PrimitiveType)fieldDecl.getType(); primitiveType.accept(new TypeVisitorImpl()); assertEquals("Expect one visitor", 1, typesVisited.size()); assertEquals("Expected PrimitiveType visitor", "PrimitiveTypeImpl", typesVisited.get(0).getClass().getSimpleName()); break; case VoidType : MethodDeclaration methodDecl = typeDecl.getMethods().iterator().next(); VoidType voidType = (VoidType)methodDecl.getReturnType(); voidType.accept(new TypeVisitorImpl()); assertEquals("Expect one visitor", 1, typesVisited.size()); assertEquals("Expected VoidType visitor", "VoidTypeImpl", typesVisited.get(0).getClass().getSimpleName()); break; case ClassType : for(TypeDeclaration tempDecl : nestedTypes) { if(tempDecl.getSimpleName().equals("C")) { classDecl = (ClassDeclaration)tempDecl; } } ClassType classType = classDecl.getSuperclass(); classType.accept(new TypeVisitorImpl()); assertEquals("Expect one visitor", 1, typesVisited.size()); assertEquals("Expected ClassType visitor", "ClassDeclarationImpl", typesVisited.get(0).getClass().getSimpleName()); break; case EnumType : for(FieldDeclaration tempDecl : fieldDecls) { if(tempDecl.getSimpleName().equals("s")) { fieldDecl = tempDecl; } } annoMirror = fieldDecl.getAnnotationMirrors().iterator().next(); EnumType enumType = (EnumType)annoMirror.getElementValues().keySet().iterator().next().getReturnType(); enumType.accept(new TypeVisitorImpl()); assertEquals("Expect one visitor", 1, typesVisited.size()); assertEquals("Expected EnumType visitor", "EnumDeclarationImpl", typesVisited.get(0).getClass().getSimpleName()); break; case InterfaceType : for(TypeDeclaration tempDecl : nestedTypes) { if(tempDecl.getSimpleName().equals("D")) { classDecl = (ClassDeclaration)tempDecl; } } InterfaceType interfaceType = classDecl.getSuperinterfaces().iterator().next(); interfaceType.accept(new TypeVisitorImpl()); assertEquals("Expect one visitor", 1, typesVisited.size()); assertEquals("Expected InterfaceType visitor", "InterfaceDeclarationImpl", typesVisited.get(0).getClass().getSimpleName()); break; case AnnotationType : for(FieldDeclaration tempDecl : fieldDecls) { if(tempDecl.getSimpleName().equals("s")) { fieldDecl = tempDecl; } } annoMirror = fieldDecl.getAnnotationMirrors().iterator().next(); AnnotationType annoType = annoMirror.getAnnotationType(); annoType.accept(new TypeVisitorImpl()); assertEquals("Expect one visitor", 1, typesVisited.size()); assertEquals("Expected AnnotationType visitor", "AnnotationDeclarationImpl", typesVisited.get(0).getClass().getSimpleName()); break; case ArrayType : for(FieldDeclaration tempDecl : fieldDecls) { if(tempDecl.getSimpleName().equals("k")) { fieldDecl = tempDecl; } } ArrayType arrayType = (ArrayType)fieldDecl.getType(); arrayType.accept(new TypeVisitorImpl()); assertEquals("Expect one visitor", 1, typesVisited.size()); assertEquals("Expected ArrayType visitor", "ArrayTypeImpl", typesVisited.get(0).getClass().getSimpleName()); break; case TypeVariable : for(TypeDeclaration tempDecl : nestedTypes) { if(tempDecl.getSimpleName().equals("P")) { classDecl = (ClassDeclaration)tempDecl; } } TypeParameterDeclaration typeParamDecl = classDecl.getFormalTypeParameters().iterator().next(); TypeVariable typeVariable = typesUtil.getTypeVariable(typeParamDecl); typeVariable.accept(new TypeVisitorImpl()); assertEquals("Expect one visitor", 1, typesVisited.size()); assertEquals("Expected TypeVariable visitor", "TypeParameterDeclarationImpl", typesVisited.get(0).getClass().getSimpleName()); break; case WildcardType : for(FieldDeclaration tempDecl : fieldDecls) { if(tempDecl.getSimpleName().equals("ln")) { fieldDecl = tempDecl; } } InterfaceType wildcardList = (InterfaceType)fieldDecl.getType(); WildcardType wildcardType = (WildcardType)wildcardList.getActualTypeArguments().iterator().next(); wildcardType.accept(new TypeVisitorImpl()); assertEquals("Expect one visitor", 1, typesVisited.size()); assertEquals("Expected WildcardType visitor", "WildcardTypeImpl", typesVisited.get(0).getClass().getSimpleName()); break; } } } /** * TypeVisitor implementation for the purposes of these tests */ class TypeVisitorImpl implements TypeVisitor { public void visitTypeMirror(TypeMirror t) { fail("Should never visit a TypeMirror, only a subclass: " + t); } public void visitPrimitiveType(PrimitiveType t) { typeVisited(t); } public void visitVoidType(VoidType t) { typeVisited(t); } public void visitReferenceType(ReferenceType t) { fail("Should never visit a ReferenceType, only a subclass: " + t); } public void visitDeclaredType(DeclaredType t) { fail("Should never visit a DeclaredType, only a subclass: " + t); } public void visitClassType(ClassType t) { typeVisited(t); } public void visitEnumType(EnumType t) { typeVisited(t); } public void visitInterfaceType(InterfaceType t) { typeVisited(t); } public void visitAnnotationType(AnnotationType t) { typeVisited(t); } public void visitArrayType(ArrayType t) { typeVisited(t); } public void visitTypeVariable(TypeVariable t) { typeVisited(t); } public void visitWildcardType(WildcardType t) { typeVisited(t); } } /* * Utilities for running the TypeVisitor tests */ enum Cases { PrimitiveType, VoidType, ClassType, EnumType, InterfaceType, AnnotationType, ArrayType, TypeVariable, WildcardType } Cases testCaseIdentifier; ArrayList<TypeMirror> typesVisited = new ArrayList<TypeMirror>(); void typeVisited(TypeMirror t) { typesVisited.add(t); } void initTypeVisitList() { if(typesVisited.size() > 0) { typesVisited.clear(); } } final String code = "package test;" + "\n" + "import org.eclipse.jdt.apt.tests.annotations.generic.*;" + "\n" + "import java.util.List;" + "\n" + "@GenericAnnotation public class Test" + "\n" + "{" + "\n" + " int j;" + "\n" + " int k[];" + "\n" + " List<? extends Number> ln;" + "\n" + " class C {}" + "\n" + " class P<T> { }" + "\n" + " class D implements Runnable { public void run () {} }" + "\n" + " void m() {}" + "\n" + " enum E { elephant }" + "\n" + " @interface B { E e(); }" + "\n" + " @B(e = E.elephant)" + "\n" + " String s;" + "\n" + "}"; }