| /******************************************************************************* |
| * Copyright (c) 2005, 2012 BEA Systems, Inc. and others |
| * 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 |
| * IBM Corporation - Added test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=352949 |
| *******************************************************************************/ |
| |
| package org.eclipse.jdt.apt.tests; |
| |
| import java.util.Collection; |
| import java.util.Map; |
| |
| 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.core.env.EnvironmentFactory; |
| import org.eclipse.jdt.apt.tests.annotations.ProcessorTestStatus; |
| import org.eclipse.jdt.apt.tests.annotations.generic.AbstractGenericProcessor; |
| import org.eclipse.jdt.apt.tests.annotations.generic.GenericFactory; |
| import org.eclipse.jdt.apt.tests.annotations.mirrortest.MirrorDeclarationCodeExample; |
| import org.eclipse.jdt.apt.tests.annotations.mirrortest.SourceMirrorCodeExample; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| |
| import com.sun.mirror.apt.AnnotationProcessorEnvironment; |
| import com.sun.mirror.declaration.AnnotationMirror; |
| import com.sun.mirror.declaration.AnnotationTypeDeclaration; |
| import com.sun.mirror.declaration.AnnotationTypeElementDeclaration; |
| import com.sun.mirror.declaration.AnnotationValue; |
| import com.sun.mirror.declaration.Declaration; |
| import com.sun.mirror.declaration.TypeDeclaration; |
| import com.sun.mirror.util.SourcePosition; |
| |
| public class MirrorDeclarationTests extends APTTestBase { |
| |
| public MirrorDeclarationTests(final String name) |
| { |
| super(name); |
| } |
| |
| public static Test suite() |
| { |
| return new TestSuite(MirrorDeclarationTests.class); |
| } |
| |
| public void setUp() throws Exception |
| { |
| super.setUp(); |
| |
| IProject project = env.getProject( getProjectName() ); |
| IPath srcRoot = getSourcePath(); |
| String code = MirrorDeclarationCodeExample.CODE; |
| env.addClass(srcRoot, MirrorDeclarationCodeExample.CODE_PACKAGE, MirrorDeclarationCodeExample.CODE_CLASS_NAME, code); |
| fullBuild( project.getFullPath() ); |
| expectingNoProblems(); |
| } |
| |
| public void testMirrorDeclaration() throws Exception |
| { |
| assertEquals(ProcessorTestStatus.NO_ERRORS, ProcessorTestStatus.getErrors()); |
| } |
| |
| public void testFieldConstant() throws Exception |
| { |
| IProject project = env.getProject( getProjectName() ); |
| IPath srcRoot = getSourcePath(); |
| String codeTrigger = |
| "package test;\n" + |
| "public @interface Trigger{}"; |
| |
| env.addClass(srcRoot, "test", "Trigger", codeTrigger); |
| |
| String codeEntryPoint = "package test;\n" + |
| "@Trigger\n" + |
| "public class EntryPoint {\n" + |
| " ClassWithNestedAnnotation nestedAnno;\n}"; |
| |
| env.addClass(srcRoot, "test", "EntryPoint", codeEntryPoint); |
| |
| String codeClassWithNestedAnnotation = |
| "package test; \n" + |
| "public class ClassWithNestedAnnotation {\n" + |
| " public final int FOUR = 4; \n " + |
| "}"; |
| |
| env.addClass(srcRoot, "test", "ClassWithNestedAnnotation", codeClassWithNestedAnnotation); |
| fullBuild( project.getFullPath() ); |
| expectingNoProblems(); |
| } |
| |
| // TODO: Disabled due to Bugzilla 124388 -theodora |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=124388 |
| public void DISABLED_testDefault() throws Exception |
| { |
| IProject project = env.getProject( getProjectName() ); |
| IPath srcRoot = getSourcePath(); |
| String codeTrigger = |
| "package test;\n" + |
| "public @interface Trigger{}"; |
| |
| env.addClass(srcRoot, "test", "Trigger", codeTrigger); |
| |
| String codeEntryPoint = "package test;\n" + |
| "@Trigger\n" + |
| "public class EntryPoint {\n" + |
| " ClassWithNestedAnnotation nestedAnno;\n}"; |
| |
| env.addClass(srcRoot, "test", "EntryPoint", codeEntryPoint); |
| |
| String codeClassWithNestedAnnotation = |
| "package test; \n" + |
| "public class ClassWithNestedAnnotation {\n" + |
| " public @interface NestedAnnotation{\n" + |
| " public enum Character{ \n" + |
| " Winnie, Tiger, Piglet, Eore; \n" + |
| " }\n"+ |
| " Character value() default Character.Eore; \n" + |
| " }\n" + |
| "}"; |
| |
| env.addClass(srcRoot, "test", "ClassWithNestedAnnotation", codeClassWithNestedAnnotation); |
| fullBuild( project.getFullPath() ); |
| expectingNoProblems(); |
| } |
| |
| /** |
| * Test AST based mirror implementation and binding based mirror implementation. |
| * Specifically, |
| * (i) method declaration with unresolvable return type. |
| * (ii) constructor declaration with unresolvable parameter |
| * (iii) field declaration with unresolvable type. |
| * |
| * This test focus on declarations from file in context. |
| * |
| * @throws Exception |
| */ |
| public void testUnresolvableDeclarations0() |
| throws Exception |
| { |
| IProject project = env.getProject( getProjectName() ); |
| IPath srcRoot = getSourcePath(); |
| String declAnno = |
| "package test;\n" + |
| "public @interface DeclarationAnno{}"; |
| |
| env.addClass(srcRoot, "test", "DeclarationAnno", declAnno); |
| |
| String codeFoo = |
| "package test;\n" + |
| "@DeclarationAnno\n" + |
| "public class Foo {\n" + |
| " int field0;\n " + |
| " UnknownType field1;\n " + |
| " public Foo(UnknownType type){} \n" + |
| " public void voidMethod(){} \n " + |
| " public UnknownType getType(){}\n " + |
| " public class Inner{} \n" + |
| "}"; |
| |
| final IPath fooPath = env.addClass(srcRoot, "test", "Foo", codeFoo); |
| fullBuild( project.getFullPath() ); |
| |
| expectingOnlySpecificProblemsFor(fooPath, new ExpectedProblem[]{ |
| new ExpectedProblem("", "UnknownType cannot be resolved to a type", fooPath), |
| new ExpectedProblem("", "UnknownType cannot be resolved to a type", fooPath), |
| new ExpectedProblem("", "UnknownType cannot be resolved to a type", fooPath)} |
| ); |
| } |
| |
| /** |
| * Test AST based mirror implementation and binding based mirror implementation. |
| * Specifically, |
| * (i) method declaration with unresolvable return type. |
| * (ii) constructor declaration with unresolvable parameter |
| * (iii) field declaration with unresolvable type. |
| * |
| * This test focus on declarations from file outside of processor |
| * environment context. |
| * |
| * @throws Exception |
| */ |
| public void testUnresolvableDeclarations1() |
| throws Exception |
| { |
| IProject project = env.getProject( getProjectName() ); |
| IPath srcRoot = getSourcePath(); |
| String declAnno = |
| "package test;\n" + |
| "public @interface DeclarationAnno{}"; |
| |
| env.addClass(srcRoot, "test", "DeclarationAnno", declAnno); |
| |
| String codeBar = |
| "package test;\n" + |
| "@DeclarationAnno\n" + |
| "public class Bar {}"; |
| env.addClass(srcRoot, "test", "Bar", codeBar); |
| |
| String codeFoo = |
| "package test;\n" + |
| "@DeclarationAnno\n" + |
| "public class Foo {\n" + |
| " int field0;\n " + |
| " UnknownType field1;\n " + |
| " public Foo(UnknownType type){} \n" + |
| " public void voidMethod(){} \n " + |
| " public UnknownType getType(){}\n " + |
| " public class Inner{} \n" + |
| "}"; |
| |
| final IPath fooPath = env.addClass(srcRoot, "test", "Foo", codeFoo); |
| |
| fullBuild( project.getFullPath() ); |
| expectingOnlySpecificProblemsFor(fooPath, new ExpectedProblem[]{ |
| new ExpectedProblem("", "UnknownType cannot be resolved to a type", fooPath), |
| new ExpectedProblem("", "UnknownType cannot be resolved to a type", fooPath), |
| new ExpectedProblem("", "UnknownType cannot be resolved to a type", fooPath)} |
| ); |
| } |
| |
| public void testLocation() { |
| |
| TestLocationProc p = new TestLocationProc(); |
| GenericFactory.setProcessor(p); |
| |
| IProject project = env.getProject( getProjectName() ); |
| IPath srcRoot = getSourcePath(); |
| String x = |
| "package test;\n" + |
| "import org.eclipse.jdt.apt.tests.annotations.generic.*;\n" + |
| "@GenericAnnotation public class X {}"; |
| |
| env.addClass(srcRoot, "test", "X", x); |
| |
| fullBuild( project.getFullPath() ); |
| expectingNoProblems(); |
| |
| assertTrue("Processor not invoked", p.called); |
| } |
| |
| public void testSourceMirror() { |
| |
| TestSourceMirrorProc p = new TestSourceMirrorProc(); |
| GenericFactory.setProcessor(p); |
| |
| IProject project = env.getProject( getProjectName() ); |
| IPath srcRoot = getSourcePath(); |
| env.addClass(srcRoot, SourceMirrorCodeExample.CODE_PACKAGE, SourceMirrorCodeExample.ANNO_CODE_CLASS_NAME, SourceMirrorCodeExample.ANNO_CODE); |
| env.addClass(srcRoot, SourceMirrorCodeExample.CODE_PACKAGE, SourceMirrorCodeExample.CODE_CLASS_NAME, SourceMirrorCodeExample.CODE); |
| |
| fullBuild( project.getFullPath() ); |
| expectingNoProblems(); |
| |
| assertTrue("Processor not invoked", p.called); |
| } |
| |
| public void testPackageInfo() { |
| PackageInfoProc p = new PackageInfoProc(); |
| GenericFactory.setProcessor(p); |
| |
| IProject project = env.getProject( getProjectName() ); |
| IPath srcRoot = getSourcePath(); |
| IPath pkg = env.addPackage(srcRoot, "pkg"); |
| String contents = "@PkgAnnotation\n" + |
| "@GenericAnnotation\n" + |
| "package pkg;\n" + |
| "import org.eclipse.jdt.apt.tests.annotations.generic.*;"; |
| env.addFile(pkg, "package-info.java", contents); |
| String annContents = |
| "package pkg;\n" + |
| "\n" + |
| "@interface PkgAnnotation {\n" + |
| " String value() default \"def\";\n" + |
| "}\n"; |
| env.addClass(srcRoot, "pkg", "pkgAnnotation", annContents); |
| fullBuild( project.getFullPath() ); |
| expectingNoProblems(); |
| |
| assertTrue("Processor not invoked", p.called); |
| } |
| |
| static class TestLocationProc extends AbstractGenericProcessor { |
| |
| boolean called; |
| |
| public void _process() { |
| called = true; |
| assertTrue(decls.size() == 1); |
| |
| Declaration d = decls.iterator().next(); |
| SourcePosition p = d.getPosition(); |
| |
| assertTrue(p.column() == 32); |
| assertTrue(p.line() == 3); |
| } |
| } |
| |
| static class TestSourceMirrorProc extends AbstractGenericProcessor { |
| |
| boolean called; |
| |
| public void _process() { |
| called = true; |
| TypeDeclaration tdCode = env.getTypeDeclaration(SourceMirrorCodeExample.CODE_PACKAGE + "." + SourceMirrorCodeExample.CODE_CLASS_NAME); |
| for (AnnotationMirror am : tdCode.getAnnotationMirrors()) { |
| if ("GenericAnnotation".equals(am.getAnnotationType().getDeclaration().getSimpleName())) { |
| continue; |
| } |
| assertTrue(null != am.getPosition()); |
| AnnotationTypeDeclaration atd = am.getAnnotationType().getDeclaration(); |
| assertTrue(null != atd.getPosition()); |
| for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> entry : am.getElementValues().entrySet()) { |
| assertNotNull(entry.getKey().getPosition()); |
| assertNotNull(entry.getKey().getDefaultValue().getPosition()); |
| } |
| } |
| } |
| } |
| |
| static class PackageInfoProc extends AbstractGenericProcessor { |
| |
| boolean called; |
| |
| public void _process() { |
| called = true; |
| AnnotationTypeDeclaration annoDecl = (AnnotationTypeDeclaration)env.getTypeDeclaration("pkg.PkgAnnotation"); |
| assertTrue(null != annoDecl); |
| // get the annotated declarations |
| Collection<Declaration> annotatedDecls = env.getDeclarationsAnnotatedWith(annoDecl); |
| // don't return the package declaration - well, apt is doing that.. |
| assertTrue(annotatedDecls == null || annotatedDecls.size() == 0); |
| |
| //TODO: test to support package annotation |
| // PackageDeclaration pdCode = env.getPackage("pkg"); |
| // for (AnnotationMirror am : pdCode.getAnnotationMirrors()) { |
| // if ("GenericAnnotation".equals(am.getAnnotationType().getDeclaration().getSimpleName())) { |
| // continue; |
| // } |
| // assertTrue(null != am.getPosition()); |
| // AnnotationTypeDeclaration atd = am.getAnnotationType().getDeclaration(); |
| // assertTrue(null != atd.getPosition()); |
| // for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> entry : am.getElementValues().entrySet()) { |
| // assertNotNull(entry.getKey().getPosition()); |
| // assertNotNull(entry.getKey().getDefaultValue().getPosition()); |
| // } |
| // } |
| } |
| } |
| |
| public void testEnvFactory() throws JavaModelException { |
| |
| IProject project = env.getProject(getProjectName()); |
| IPath srcRoot = getSourcePath(); |
| String x = "package test;\n" + "import org.eclipse.jdt.apt.tests.annotations.generic.*;\n" |
| + "@GenericAnnotation public class X {}"; |
| |
| IPath path = env.addClass(srcRoot, "test", "X", x); |
| IPath tail = path.removeFirstSegments(2); |
| IJavaProject p = JavaCore.create(project); |
| ICompilationUnit cu = (ICompilationUnit) p.findElement(tail); |
| assertTrue("Could not find cu", cu != null); |
| |
| AnnotationProcessorEnvironment env = EnvironmentFactory.getEnvironment(cu, p); |
| TypeDeclaration t = env.getTypeDeclaration("test.X"); |
| |
| SourcePosition pos = t.getPosition(); |
| |
| assertTrue(pos.column() == 32); |
| assertTrue(pos.line() == 3); |
| |
| // Bad type should gracefully return null |
| TypeDeclaration tBad = env.getTypeDeclaration("test.XYZ"); |
| assertTrue(null == tBad); |
| } |
| |
| } |