### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.builder Index: src/org/eclipse/jdt/core/tests/builder/BuilderTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BuilderTests.java,v retrieving revision 1.17 diff -u -r1.17 BuilderTests.java --- src/org/eclipse/jdt/core/tests/builder/BuilderTests.java 2 Dec 2008 15:48:40 -0000 1.17 +++ src/org/eclipse/jdt/core/tests/builder/BuilderTests.java 4 Jan 2009 07:58:55 -0000 @@ -521,10 +521,11 @@ if ((AbstractCompilerTest.getPossibleComplianceLevels() & AbstractCompilerTest.F_1_5) != 0) { int length = classes.length; - System.arraycopy(classes, 0, classes = new Class[length+3], 0, length); + System.arraycopy(classes, 0, classes = new Class[length+4], 0, length); classes[length++] = Java50Tests.class; classes[length++] = PackageInfoTest.class; classes[length++] = ParticipantBuildTests.class; + classes[length++] = AnnotationDependencyTests.class; } return classes; } Index: src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java =================================================================== RCS file: src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java diff -N src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2009, Walter Harley 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: + * Walter Harley (eclipse@cafewalter.com) - initial implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.builder; + +import junit.framework.Test; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.jdt.core.tests.util.Util; + +/** + * Tests to verify that annotation changes cause recompilation of dependent types. + * See http://bugs.eclipse.org/149768 + */ +public class AnnotationDependencyTests extends BuilderTests { + private IPath srcRoot = null; + private IPath projectPath = null; + + public AnnotationDependencyTests(String name) { + super(name); + } + + public static Test suite() { + return buildTestSuite(AnnotationDependencyTests.class); + } + + public void setUp() throws Exception { + super.setUp(); + + this.projectPath = env.addProject("Project", "1.5"); //$NON-NLS-1$ + env.addExternalJars(this.projectPath, Util.getJavaClassLibs()); + + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(this.projectPath,""); //$NON-NLS-1$ + + this.srcRoot = env.addPackageFragmentRoot(this.projectPath, "src"); //$NON-NLS-1$ + env.setOutputFolder(this.projectPath, "bin"); //$NON-NLS-1$ + } + + protected void tearDown() throws Exception { + this.projectPath = null; + this.srcRoot = null; + + super.tearDown(); + } + + private void addAnnotationType() { + String annoCode = "package p1;\n" + + "@interface Anno {\n" + + "String value();\n" + + "}\n"; + env.addClass(this.srcRoot, "p1", "Anno", annoCode); + } + + /** + * This test makes sure that changing an annotation on type A causes type B + * to be recompiled, if B references A. See http://bugs.eclipse.org/149768 + */ + public void testTypeAnnotationDependency() throws Exception + { + String a1Code = "package p1; " + "\n" + + "@Anno(\"A1\")" + "\n" + + "public class A {}"; + String a2Code = "package p1; " + "\n" + + "@Anno(\"A2\")" + "\n" + + "public class A {}"; + String bCode = "package p1; " + "\n" + + "public class B {" + "\n" + + " public A a;" + "\n" + + "}"; + + env.addClass( this.srcRoot, "p1", "A", a1Code ); + env.addClass( this.srcRoot, "p1", "B", bCode ); + addAnnotationType(); + + fullBuild( this.projectPath ); + expectingNoProblems(); + + // edit annotation in A + env.addClass( this.srcRoot, "p1", "A", a2Code ); + incrementalBuild( this.projectPath ); + expectingNoProblems(); + + // verify that B was recompiled + expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" }); + } + + /** + * This test makes sure that changing an annotation on a field within type A + * causes type B to be recompiled, if B references A. + * See http://bugs.eclipse.org/149768 + */ + public void testFieldAnnotationDependency() throws Exception + { + String a1Code = "package p1; " + "\n" + + "public class A {" + "\n" + + " @Anno(\"A1\")" + "\n" + + " protected int f;" + "\n" + + "}"; + String a2Code = "package p1; " + "\n" + + "public class A {" + "\n" + + " @Anno(\"A2\")" + "\n" + + " protected int f;" + "\n" + + "}"; + String bCode = "package p1; " + "\n" + + "public class B {" + "\n" + + " public A a;" + "\n" + + "}"; + + env.addClass( this.srcRoot, "p1", "A", a1Code ); + env.addClass( this.srcRoot, "p1", "B", bCode ); + addAnnotationType(); + + fullBuild( this.projectPath ); + expectingNoProblems(); + + // edit annotation in A + env.addClass( this.srcRoot, "p1", "A", a2Code ); + incrementalBuild( this.projectPath ); + expectingNoProblems(); + + // verify that B was recompiled + expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" }); + } + + /** + * This test makes sure that changing an annotation on a method within type A + * causes type B to be recompiled, if B references A. + * See http://bugs.eclipse.org/149768 + */ + public void testMethodAnnotationDependency() throws Exception + { + String a1Code = "package p1; " + "\n" + + "public class A {" + "\n" + + " @Anno(\"A1\")" + "\n" + + " protected int f() { return 0; }" + "\n" + + "}"; + String a2Code = "package p1; " + "\n" + + "public class A {" + "\n" + + " @Anno(\"A2\")" + "\n" + + " protected int f() { return 0; }" + "\n" + + "}"; + String bCode = "package p1; " + "\n" + + "public class B {" + "\n" + + " public A a;" + "\n" + + "}"; + + env.addClass( this.srcRoot, "p1", "A", a1Code ); + env.addClass( this.srcRoot, "p1", "B", bCode ); + addAnnotationType(); + + fullBuild( this.projectPath ); + expectingNoProblems(); + + // edit annotation in A + env.addClass( this.srcRoot, "p1", "A", a2Code ); + incrementalBuild( this.projectPath ); + expectingNoProblems(); + + // verify that B was recompiled + expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" }); + } + + /** + * This test makes sure that changing an annotation on an inner type X within type A + * causes type B to be recompiled, if B references A. + * Note that B does not directly reference A.X, only A. + * See http://bugs.eclipse.org/149768 + */ + public void testInnerTypeAnnotationDependency() throws Exception + { + String a1Code = "package p1; " + "\n" + + "public class A {" + "\n" + + " @Anno(\"A1\")" + "\n" + + " public class X { }" + "\n" + + "}"; + String a2Code = "package p1; " + "\n" + + "public class A {" + "\n" + + " @Anno(\"A2\")" + "\n" + + " public class X { }" + "\n" + + "}"; + String bCode = "package p1; " + "\n" + + "public class B {" + "\n" + + " public A a;" + "\n" + + "}"; + + env.addClass( this.srcRoot, "p1", "A", a1Code ); + env.addClass( this.srcRoot, "p1", "B", bCode ); + addAnnotationType(); + + fullBuild( this.projectPath ); + expectingNoProblems(); + + // edit annotation in A + env.addClass( this.srcRoot, "p1", "A", a2Code ); + incrementalBuild( this.projectPath ); + expectingNoProblems(); + + // verify that B was recompiled + expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.A$X", "p1.B" }); + } + + /** + * This test makes sure that changing an annotation on a type A + * does not cause type B to be recompiled, if B does not reference A. + * See http://bugs.eclipse.org/149768 + */ + public void testUnrelatedTypeAnnotationDependency() throws Exception + { + String a1Code = "package p1; " + "\n" + + "@Anno(\"A1\")" + "\n" + + "public class A {}"; + String a2Code = "package p1; " + "\n" + + "@Anno(\"A2\")" + "\n" + + "public class A {}"; + String bCode = "package p1; " + "\n" + + "public class B {" + "\n" + + "}"; + + env.addClass( this.srcRoot, "p1", "A", a1Code ); + env.addClass( this.srcRoot, "p1", "B", bCode ); + addAnnotationType(); + + fullBuild( this.projectPath ); + expectingNoProblems(); + + // edit annotation in A + env.addClass( this.srcRoot, "p1", "A", a2Code ); + incrementalBuild( this.projectPath ); + expectingNoProblems(); + + // verify that B was not recompiled + expectingUniqueCompiledClasses(new String[] { "p1.A" }); + } + +}