blob: d66338f3a979f8c6f17c269bd8f2fc386d5f6b85 [file] [log] [blame]
/*******************************************************************************
* 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" +
"}";
}