| package org.eclipse.jdt.apt.tests; |
| |
| import java.io.File; |
| import java.util.HashSet; |
| import junit.framework.Test; |
| import junit.framework.TestCase; |
| import junit.framework.TestSuite; |
| |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jdt.apt.tests.annotations.ProcessorTestStatus; |
| import org.eclipse.jdt.apt.tests.annotations.readannotation.CodeExample; |
| import org.eclipse.jdt.apt.tests.plugin.AptTestsPlugin; |
| import org.eclipse.jdt.core.BindingKey; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.dom.ASTParser; |
| import org.eclipse.jdt.core.dom.ASTRequestor; |
| import org.eclipse.jdt.core.dom.IBinding; |
| import org.eclipse.jdt.core.dom.IMethodBinding; |
| import org.eclipse.jdt.core.dom.IResolvedAnnotation; |
| import org.eclipse.jdt.core.dom.ITypeBinding; |
| import org.eclipse.jdt.core.dom.IVariableBinding; |
| import org.eclipse.jdt.core.tests.builder.Tests; |
| import org.eclipse.jdt.core.tests.util.Util; |
| |
| /** |
| * This test the dom layer of annotation support. No APT involved. |
| * @author tyeung |
| */ |
| public class ReadAnnotationTests2 extends Tests { |
| |
| private String[] NO_ANNOTATIONS = new String[0]; |
| private ICompilationUnit[] NO_UNIT = new ICompilationUnit[0]; |
| private int counter = 0; |
| private String projectName = null; |
| public ReadAnnotationTests2(final String name) { |
| super( name ); |
| } |
| |
| public static Test suite() { |
| return new TestSuite( ReadAnnotationTests2.class ); |
| } |
| |
| public String getProjectName() { |
| return projectName; |
| } |
| |
| public String getUniqueProjectName(){ |
| projectName = ReadAnnotationTests.class.getName() + "Project" + counter; //$NON-NLS-1$ |
| counter ++; |
| return projectName; |
| } |
| |
| |
| public IPath getSourcePath() { |
| IProject project = env.getProject( getProjectName() ); |
| IFolder srcFolder = project.getFolder( "src" ); //$NON-NLS-1$ |
| IPath srcRoot = srcFolder.getFullPath(); |
| return srcRoot; |
| } |
| |
| public IPath getBinaryPath(){ |
| IProject project = env.getProject( getProjectName() ); |
| IFolder srcFolder = project.getFolder( "binary" ); //$NON-NLS-1$ |
| IPath lib = srcFolder.getFullPath(); |
| return lib; |
| } |
| |
| public IPath getOutputPath(){ |
| IProject project = env.getProject( getProjectName() ); |
| IFolder binFolder = project.getFolder( "bin" ); //$NON-NLS-1$ |
| IPath bin = binFolder.getFullPath(); |
| return bin; |
| } |
| |
| private void addAllSources() |
| { |
| IPath srcRoot = getSourcePath(); |
| // SimpleAnnotation.java |
| env.addClass( |
| srcRoot, |
| CodeExample.PACKAGE_QUESTION, |
| CodeExample.SIMPLE_ANNOTATION_CLASS, |
| CodeExample.SIMPLE_ANNOTATION_CODE ); |
| |
| // RTVisibleAnnotation.java |
| env.addClass( |
| srcRoot, |
| CodeExample.PACKAGE_QUESTION, |
| CodeExample.RTVISIBLE_CLASS, |
| CodeExample.RTVISIBLE_ANNOTATION_CODE); |
| |
| // RTInvisibleAnnotation.java |
| env.addClass( |
| srcRoot, |
| CodeExample.PACKAGE_QUESTION, |
| CodeExample.RTINVISIBLE_CLASS, |
| CodeExample.RTINVISIBLE_ANNOTATION_CODE); |
| |
| // package-info.java |
| env.addClass( |
| srcRoot, |
| CodeExample.PACKAGE_QUESTION, |
| CodeExample.PACKAGE_INFO_CLASS, |
| CodeExample.PACKAGE_INFO_CODE); |
| |
| // Color.java |
| env.addClass( |
| srcRoot, |
| CodeExample.PACKAGE_QUESTION, |
| CodeExample.COLOR_CLASS, |
| CodeExample.COLOR_CODE); |
| |
| // AnnotationTest.java |
| env.addClass( |
| srcRoot, |
| CodeExample.PACKAGE_QUESTION, |
| CodeExample.ANNOTATION_TEST_CLASS, |
| CodeExample.ANNOTATION_TEST_CODE); |
| } |
| |
| private IProject setupTest() throws Exception |
| { |
| ProcessorTestStatus.reset(); |
| // project will be deleted by super-class's tearDown() method |
| IPath projectPath = env.addProject( getUniqueProjectName(), "1.5" ); //$NON-NLS-1$ |
| env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$ |
| env.addExternalJars( projectPath, Util.getJavaClassLibs() ); |
| fullBuild( projectPath ); |
| |
| // remove old package fragment root so that names don't collide |
| env.removePackageFragmentRoot( projectPath, "" ); //$NON-NLS-1$ |
| |
| env.addPackageFragmentRoot( projectPath, "src" ); //$NON-NLS-1$ |
| return env.getProject(getProjectName()); |
| } |
| |
| /** |
| * Set up all the source files for testing. |
| * Runs the AnnotationReaderProcessor, which contains |
| * the actual testing. |
| */ |
| public void testSourceAnnotation() throws Exception { |
| // reset the error reset the error; |
| IProject project = setupTest(); |
| addAllSources(); |
| fullBuild( project.getFullPath() ); |
| expectingNoProblems(); |
| _testAnnotations(); |
| } |
| |
| /** |
| * Set up the jar file for testing. |
| * Runs the AnnotationReaderProcessor, which contains |
| * the actual testing. |
| */ |
| public void testBindingAnnotation() throws Exception |
| { |
| IProject project = setupTest(); |
| final File jar = |
| TestUtil.getFileInPlugin(AptTestsPlugin.getDefault(), |
| new Path("/src/org/eclipse/jdt/apt/tests/annotations/readannotation/lib/question.jar")); //$NON-NLS-1$ |
| final String path = jar.getAbsolutePath(); |
| env.addExternalJar(project.getFullPath(), path); |
| fullBuild( project.getFullPath() ); |
| expectingNoProblems(); |
| _testAnnotations(); |
| } |
| |
| private ITypeBinding getTypeBinding(final String key, final IJavaProject javaProj) |
| { |
| class BindingRequestor extends ASTRequestor |
| { |
| private ITypeBinding _result = null; |
| public void acceptBinding(String bindingKey, IBinding binding) |
| { |
| if( binding != null && binding.getKind() == IBinding.TYPE ) |
| _result = (ITypeBinding)binding; |
| } |
| } |
| |
| final BindingRequestor requestor = new BindingRequestor(); |
| final ASTParser parser = ASTParser.newParser(AST.JLS3); |
| parser.setResolveBindings(true); |
| parser.setProject(javaProj); |
| parser.createASTs(NO_UNIT, new String[]{key}, requestor, null); |
| return requestor._result; |
| } |
| |
| @SuppressWarnings("nls") |
| public void _testAnnotations() |
| { |
| final String typeKey = BindingKey.createTypeBindingKey("question.AnnotationTest"); |
| final ITypeBinding typeBinding = getTypeBinding(typeKey, env.getJavaProject(getProjectName())); |
| |
| TestCase.assertNotNull("failed to locate 'question.AnnotationTest'", typeBinding); |
| TestCase.assertEquals("Type name mismatch", "question.AnnotationTest", typeBinding.getQualifiedName()); |
| |
| // test package annotation |
| final String[] expectedPkgAnnos = new String[]{ "@Deprecated()" }; |
| assertAnnotation(expectedPkgAnnos, typeBinding.getPackage().getAnnotations() ); |
| |
| // test annotation on type. |
| final String[] expectedTypeAnnos = new String[]{ "@Deprecated()", |
| "@RTVisibleAnno(anno = @SimpleAnnotation(value = test), clazzes = {})", |
| "@RTInvisibleAnno(value = question)" }; |
| |
| assertAnnotation(expectedTypeAnnos, typeBinding.getAnnotations()); |
| |
| final IVariableBinding[] fieldBindings = typeBinding.getDeclaredFields(); |
| int counter = 0; |
| TestCase.assertEquals(5, fieldBindings.length); |
| for(IVariableBinding fieldDecl : fieldBindings ){ |
| final String name = "field" + counter; |
| |
| TestCase.assertEquals("field name mismatch", name, fieldDecl.getName()); |
| final String[] expected; |
| switch(counter){ |
| case 0: |
| expected = new String[] { "@RTVisibleAnno(name = Foundation, boolValue = false, byteValue = 16, charValue = c, doubleValue = 99.0, floatValue = 9.0, intValue = 999, longValue = 3333, shortValue = 3, colors = {question.Color RED, question.Color BLUE}, anno = @SimpleAnnotation(value = core), simpleAnnos = {@SimpleAnnotation(value = org), @SimpleAnnotation(value = eclipse), @SimpleAnnotation(value = jdt)}, clazzes = {Object.class, String.class}, clazz = Object.class)", |
| "@RTInvisibleAnno(value = org.eclipse.jdt.core)", |
| "@Deprecated()" }; |
| break; |
| case 1: |
| expected = new String[] { "@Deprecated()" }; |
| break; |
| case 2: |
| expected = new String[] { "@RTVisibleAnno(anno = @SimpleAnnotation(value = field), clazzes = {})", |
| "@RTInvisibleAnno(value = 2)" }; |
| break; |
| case 3: |
| expected = new String[] { "@RTInvisibleAnno(value = 3)" }; |
| break; |
| case 4: |
| expected = new String[] { "@SimpleAnnotation(value = 4)" }; |
| break; |
| default: |
| expected = NO_ANNOTATIONS; |
| } |
| |
| assertAnnotation(expected, fieldDecl.getAnnotations()); |
| counter ++; |
| } |
| |
| |
| final IMethodBinding[] methodBindings = typeBinding.getDeclaredMethods(); |
| counter = 0; |
| TestCase.assertEquals(7, methodBindings.length); |
| for(IMethodBinding methodDecl : methodBindings ){ |
| final String name = "method" + counter; |
| |
| TestCase.assertEquals("method name mismatch", name, methodDecl.getName()); |
| final String[] expected; |
| switch(counter) |
| { |
| case 0: |
| expected = new String[] { "@RTVisibleAnno(anno = @SimpleAnnotation(value = method0), clazzes = {})", |
| "@RTInvisibleAnno(value = 0)", |
| "@Deprecated()" }; |
| break; |
| case 1: |
| expected = new String[] { "@Deprecated()" }; |
| break; |
| case 2: |
| expected = new String[] { "@RTVisibleAnno(anno = @SimpleAnnotation(value = method2), clazzes = {})", |
| "@RTInvisibleAnno(value = 2)" }; |
| break; |
| case 3: |
| expected = new String[] { "@RTInvisibleAnno(value = 3)" }; |
| break; |
| case 4: |
| expected = new String[] { "@SimpleAnnotation(value = method4)" }; |
| break; |
| case 5: |
| case 6: |
| default: |
| expected = NO_ANNOTATIONS; |
| } |
| |
| assertAnnotation(expected, methodDecl.getAnnotations()); |
| |
| if( counter == 5 ){ |
| final int numParameters = methodDecl.getParameterTypes().length; |
| for( int pCounter=0; pCounter<numParameters; pCounter++ ){ |
| final String[] expectedParamAnnotations; |
| switch( pCounter ) |
| { |
| case 1: |
| expectedParamAnnotations = new String[] { "@Deprecated()" }; |
| break; |
| case 2: |
| expectedParamAnnotations = new String[] { "@RTVisibleAnno(anno = @SimpleAnnotation(value = param2), clazzes = {})", |
| "@RTInvisibleAnno(value = 2)" }; |
| break; |
| default: |
| expectedParamAnnotations = NO_ANNOTATIONS; |
| } |
| assertAnnotation(expectedParamAnnotations, methodDecl.getParameterAnnotations(pCounter)); |
| } |
| |
| } |
| counter ++; |
| } |
| } |
| |
| private void assertAnnotation(final String[] expected, IResolvedAnnotation[] annotations) |
| { |
| final int expectedLen = expected.length; |
| TestCase.assertEquals("annotation number mismatch", expected.length, annotations.length); //$NON-NLS-1$ |
| |
| final HashSet<String> expectedSet = new HashSet<String>(expectedLen * 4 / 3 + 1); |
| for( int i=0; i<expectedLen; i++ ) |
| expectedSet.add(expected[i]); |
| |
| int counter = 0; |
| for( IResolvedAnnotation mirror : annotations ){ |
| if( counter >= expectedLen ) |
| TestCase.assertEquals("", mirror.toString()); //$NON-NLS-1$ |
| else{ |
| final String mirrorToString = mirror.toString(); |
| final boolean contains = expectedSet.contains(mirrorToString); |
| if( !contains ){ |
| System.err.println(mirrorToString); |
| System.err.println(expectedSet); |
| } |
| TestCase.assertTrue("unexpected annotation " + mirrorToString, contains); //$NON-NLS-1$ |
| expectedSet.remove(mirrorToString); |
| } |
| counter ++; |
| } |
| } |
| |
| |
| } |