| /******************************************************************************* |
| * 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" + |
| "}"; |
| } |