### Eclipse Workspace Patch 1.0 #P org.eclipse.ajdt.ui.tests Index: src/org/eclipse/ajdt/ui/tests/UITestCase.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.ui.tests/src/org/eclipse/ajdt/ui/tests/UITestCase.java,v retrieving revision 1.19 diff -u -r1.19 UITestCase.java --- src/org/eclipse/ajdt/ui/tests/UITestCase.java 11 Aug 2008 23:15:51 -0000 1.19 +++ src/org/eclipse/ajdt/ui/tests/UITestCase.java 6 Sep 2008 04:39:49 -0000 @@ -28,6 +28,7 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; @@ -251,6 +252,18 @@ } } + /** + * Returns the IWorkspace this test suite is running on. + */ + public IWorkspace getWorkspace() { + return ResourcesPlugin.getWorkspace(); + } + + public IWorkspaceRoot getWorkspaceRoot() { + return getWorkspace().getRoot(); + } + + protected void waitForJobsToComplete(){ SynchronizationUtils.joinBackgroudActivities(); } Index: src/org/eclipse/ajdt/ui/tests/ErrorsTest.aj =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.ui.tests/src/org/eclipse/ajdt/ui/tests/ErrorsTest.aj,v retrieving revision 1.9 diff -u -r1.9 ErrorsTest.aj --- src/org/eclipse/ajdt/ui/tests/ErrorsTest.aj 31 Jul 2008 15:33:55 -0000 1.9 +++ src/org/eclipse/ajdt/ui/tests/ErrorsTest.aj 6 Sep 2008 04:39:47 -0000 @@ -52,7 +52,10 @@ for (int i = 0; i < numAdded; i++) { // New entries are always added at the start LogEntry entry = (LogEntry) logs[i]; if(entry.getSeverity() == IStatus.ERROR || entry.getSeverity() == IStatus.WARNING) { - failureText += "The test added errors to the log: " + entry.getMessage() + "\n" + entry.getStack() + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (entry.getMessage().indexOf("org.eclipse.core.tests.UnknownProvider") == -1) {//$NON-NLS-1$ + // ignore warnings that are regarding a known missing class. + failureText += "The test added errors to the log: " + entry.getMessage() + "\n" + entry.getStack() + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } } } if (failureText.length() > 0) { Index: AllUITests_MaxPermSize.launch =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.ui.tests/AllUITests_MaxPermSize.launch,v retrieving revision 1.3 diff -u -r1.3 AllUITests_MaxPermSize.launch --- AllUITests_MaxPermSize.launch 18 Dec 2006 12:53:02 -0000 1.3 +++ AllUITests_MaxPermSize.launch 6 Sep 2008 04:39:47 -0000 @@ -1,35 +1,37 @@ - + + + - - + + + + + + + + + + + - + + - - - - - - + + - - - - - + - + + + + + - - - - - - - - + + Index: src/org/eclipse/ajdt/ui/tests/builder/BuildPathNavigationTests.java =================================================================== RCS file: src/org/eclipse/ajdt/ui/tests/builder/BuildPathNavigationTests.java diff -N src/org/eclipse/ajdt/ui/tests/builder/BuildPathNavigationTests.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ajdt/ui/tests/builder/BuildPathNavigationTests.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,128 @@ +package org.eclipse.ajdt.ui.tests.builder; + +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.ajdt.core.AspectJCorePreferences; +import org.eclipse.ajdt.ui.AspectJUIPlugin; +import org.eclipse.ajdt.ui.tests.UITestCase; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.core.IClasspathAttribute; +import org.eclipse.jdt.core.IClasspathContainer; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.JavaCore; + +public class BuildPathNavigationTests extends UITestCase { + IClasspathContainer container; + protected void setUp() throws Exception { + super.setUp(); + final IProject containerProj = createPredefinedProject("PathTesting-ContainerOnAspectPath"); //$NON-NLS-1$ + createPredefinedProject("PathTesting-JarOnAspectPath"); //$NON-NLS-1$ + createPredefinedProject("PathTesting-ProjectOnAspectPath"); //$NON-NLS-1$ + IProject varProj = createPredefinedProject("PathTesting-VariableOnAspectPath"); //$NON-NLS-1$ + JavaCore.setClasspathVariable("Aspect_Path_Var", varProj.getFullPath(), null); //$NON-NLS-1$ + IClasspathAttribute[] attribute = new IClasspathAttribute[] {AspectJCorePreferences.ASPECTPATH_ATTRIBUTE }; + final IClasspathEntry entry = + JavaCore.newProjectEntry( + containerProj.getFullPath(), + null, false, + attribute, + false); + + container = new IClasspathContainer() { + public IClasspathEntry[] getClasspathEntries() { + return new IClasspathEntry[] { entry }; + } + public String getDescription() { + return "org.eclipse.jdt.USER_LIBRARY/Aspect_Path_Lib"; //$NON-NLS-1$ + } + public int getKind() { + return IClasspathContainer.K_APPLICATION; + } + public IPath getPath() { + return new Path("org.eclipse.jdt.USER_LIBRARY/Aspect_Path_Lib"); //$NON-NLS-1$ + } + }; + } + + + /** + * Test to see that the extra location attributes are associated with advice markers for inpaths + * + * This attribute has the format FFFF:::NNNN:::NNNN:::NNNN + * - The FFFF is the file which contains the source of the advice or ITD in affect + * - The other three NNNN fields are integers indicating (in order) the + * start line number of the advice in that file, the end line number of the + * advice in that file and the column number for the advice. + */ + public void testInpathMarkers() throws Exception { + try { + IProject inpathProj = createPredefinedProject("PathTesting-HasInpath"); //$NON-NLS-1$ + JavaCore.setClasspathContainer(container.getPath(), new IJavaProject[] { JavaCore.create(inpathProj) }, + new IClasspathContainer[] { container }, null); + + getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); + waitForJobsToComplete(); + IFile aspectFile = inpathProj.getFile("src/aspects/AdviseClassOnInpath.aj"); //$NON-NLS-1$ + + IMarker[] markers = aspectFile.findMarkers(IMarker.MARKER, true, 2); + + // should have one marker for each advice (ie- 5) + assertEquals("Invalid number of markers on file " + aspectFile, 5, markers.length); //$NON-NLS-1$ + + // each marker should have extra information attached to it + for (int i = 0; i < markers.length; i++) { + IMarker marker = markers[i]; + String loc = (String) marker.getAttribute(AspectJUIPlugin.RELATED_LOCATIONS_ATTRIBUTE_PREFIX + 0); + assertNotNull("No location attached to marker number " + i, loc); //$NON-NLS-1$ + + String[] s = loc.split(":::"); //$NON-NLS-1$ + assertEquals("Invalid extra location attribute format\n " + loc, 4, s.length); //$NON-NLS-1$ + } + } catch (CoreException e) { + fail(); + } + } + + /** + * Test to see that the extra location attributes are associated with advice markers for aspect paths + * + * This attribute has the format FFFF:::NNNN:::NNNN:::NNNN + * - The FFFF is the file which contains the source of the advice or ITD in affect + * - The other three NNNN fields are integers indicating (in order) the + * start line number of the advice in that file, the end line number of the + * advice in that file and the column number for the advice. + */ + public void testAspectPathMarkers() { + try { + IProject aspectPathProj = createPredefinedProject("PathTesting-HasAspectPath"); //$NON-NLS-1$ + JavaCore.setClasspathContainer(container.getPath(), new IJavaProject[] { JavaCore.create(aspectPathProj) }, + new IClasspathContainer[] { container }, null); + + getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); + waitForJobsToComplete(); + IFile aspectFile = aspectPathProj.getFile("src/main/Main.java"); //$NON-NLS-1$ + + IMarker[] markers = aspectFile.findMarkers(IMarker.MARKER, true, 2); + + System.out.println(getAllProblemViewMarkers()[0].getAttribute(IMarker.MESSAGE)); + // should have one marker for each advised method (ie- 4) + assertEquals("Invalid number of markers on file " + aspectFile, 4, markers.length); //$NON-NLS-1$ + // each marker should have extra information attached to it + for (int i = 0; i < markers.length; i++) { + IMarker marker = markers[i]; + String loc = (String) marker.getAttribute(AspectJUIPlugin.RELATED_LOCATIONS_ATTRIBUTE_PREFIX + 0); + assertNotNull("No location attached to marker number " + i, loc); //$NON-NLS-1$ + + String[] s = loc.split(":::"); //$NON-NLS-1$ + assertEquals("Invalid extra location attribute format\n " + loc, 4, s.length); //$NON-NLS-1$ + } + } catch (CoreException e) { + fail(); + } + } +} #P org.eclipse.ajdt.core.tests Index: src/org/eclipse/ajdt/core/tests/AllCoreTests.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.core.tests/src/org/eclipse/ajdt/core/tests/AllCoreTests.java,v retrieving revision 1.23 diff -u -r1.23 AllCoreTests.java --- src/org/eclipse/ajdt/core/tests/AllCoreTests.java 12 Aug 2008 21:45:34 -0000 1.23 +++ src/org/eclipse/ajdt/core/tests/AllCoreTests.java 6 Sep 2008 04:40:18 -0000 @@ -14,12 +14,15 @@ import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.ajdt.core.tests.ajde.CoreCompilerConfigurationTests; +import org.eclipse.ajdt.core.tests.ajde.CoreCompilerConfigurationTests2; +import org.eclipse.ajdt.core.tests.ajde.CoreCompilerFactoryTests; import org.eclipse.ajdt.core.tests.builder.AJBuilderTest; import org.eclipse.ajdt.core.tests.builder.AJBuilderTest2; import org.eclipse.ajdt.core.tests.builder.AspectPathTests; import org.eclipse.ajdt.core.tests.builder.Bug159197Test; -import org.eclipse.ajdt.core.tests.builder.Bug99133Test; import org.eclipse.ajdt.core.tests.builder.Bug43711Test; +import org.eclipse.ajdt.core.tests.builder.Bug99133Test; import org.eclipse.ajdt.core.tests.builder.CoreOutputLocationManagerTest; import org.eclipse.ajdt.core.tests.codeconversion.AspectsConvertingParserTest; import org.eclipse.ajdt.core.tests.codeconversion.CodeCheckerTest; @@ -77,6 +80,11 @@ suite.addTest(new TestSuite(AJRelationshipManagerTest.class)); suite.addTest(new TestSuite(BinaryWeavingSupportTest.class)); + // core compiler configuration + suite.addTest(new TestSuite(CoreCompilerConfigurationTests.class)); + suite.addTest(new TestSuite(CoreCompilerConfigurationTests2.class)); + suite.addTest(new TestSuite(CoreCompilerFactoryTests.class)); + // Java Element tests suite.addTest(new TestSuite(AspectElementTests.class)); Index: src/org/eclipse/ajdt/core/tests/testutils/TestLogger.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.core.tests/src/org/eclipse/ajdt/core/tests/testutils/TestLogger.java,v retrieving revision 1.9 diff -u -r1.9 TestLogger.java --- src/org/eclipse/ajdt/core/tests/testutils/TestLogger.java 19 Jul 2008 00:19:59 -0000 1.9 +++ src/org/eclipse/ajdt/core/tests/testutils/TestLogger.java 6 Sep 2008 04:40:21 -0000 @@ -133,11 +133,13 @@ * Clears the log */ public void clearLog() { - log.clear(); + if (log != null) { + log.clear(); + } } public boolean isEmpty() { - return log.isEmpty(); + return log != null && log.isEmpty(); } /** Index: src/org/eclipse/ajdt/core/tests/builder/AJBuilderTest.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.core.tests/src/org/eclipse/ajdt/core/tests/builder/AJBuilderTest.java,v retrieving revision 1.16 diff -u -r1.16 AJBuilderTest.java --- src/org/eclipse/ajdt/core/tests/builder/AJBuilderTest.java 19 Jul 2008 00:19:58 -0000 1.16 +++ src/org/eclipse/ajdt/core/tests/builder/AJBuilderTest.java 6 Sep 2008 04:40:21 -0000 @@ -400,7 +400,7 @@ assertTrue( "AJDT should have found no source file changes and decided not to build", //$NON-NLS-1$ listContainsString(buildLog, "build: Examined delta - no " + //$NON-NLS-1$ - "source file changes for project bug99133b")); //$NON-NLS-1$ + "source file or classpath changes for project bug99133b")); //$NON-NLS-1$ assertFalse("There should be no errors in the build log", //$NON-NLS-1$ listContainsString(buildLog, "error")); //$NON-NLS-1$ @@ -471,7 +471,7 @@ assertTrue( "AJDT should have found no source file changes and decided not to build", //$NON-NLS-1$ listContainsString(buildLog, "build: Examined delta - no " + //$NON-NLS-1$ - "source file changes for project bug99133b")); //$NON-NLS-1$ + "source file or classpath changes for project bug99133b")); //$NON-NLS-1$ assertFalse("There should be no errors in the build log", //$NON-NLS-1$ listContainsString(buildLog, "error")); //$NON-NLS-1$ @@ -550,7 +550,7 @@ assertTrue( "AJDT should have found no source file changes and decided not to build", //$NON-NLS-1$ listContainsString(buildLogB, "build: Examined delta - no " + //$NON-NLS-1$ - "source file changes for project bug99133b")); //$NON-NLS-1$ + "source file or classpath changes for project bug99133b")); //$NON-NLS-1$ // by checking that we don't have the following messages in the // log (and the previous checking for no errors) we know that Index: workspace/AspectProj2-On AspectPath/.project =================================================================== RCS file: workspace/AspectProj2-On AspectPath/.project diff -N workspace/AspectProj2-On AspectPath/.project --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProj2-On AspectPath/.project 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,18 @@ + + + AspectProj2-On AspectPath + + + + + + org.eclipse.ajdt.core.ajbuilder + + + + + + org.eclipse.ajdt.ui.ajnature + org.eclipse.jdt.core.javanature + + Index: workspace/AspectProj1/.project =================================================================== RCS file: workspace/AspectProj1/.project diff -N workspace/AspectProj1/.project --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProj1/.project 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,18 @@ + + + AspectProj1 + + + + + + org.eclipse.ajdt.core.ajbuilder + + + + + + org.eclipse.ajdt.ui.ajnature + org.eclipse.jdt.core.javanature + + Index: workspace/AspectProj3-Has Outjar/.classpath =================================================================== RCS file: workspace/AspectProj3-Has Outjar/.classpath diff -N workspace/AspectProj3-Has Outjar/.classpath --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProj3-Has Outjar/.classpath 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,7 @@ + + + + + + + Index: workspace/AspectProj2-On AspectPath/.classpath =================================================================== RCS file: workspace/AspectProj2-On AspectPath/.classpath diff -N workspace/AspectProj2-On AspectPath/.classpath --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProj2-On AspectPath/.classpath 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,7 @@ + + + + + + + Index: workspace/AspectProjWeCareAbout/.project =================================================================== RCS file: workspace/AspectProjWeCareAbout/.project diff -N workspace/AspectProjWeCareAbout/.project --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProjWeCareAbout/.project 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,18 @@ + + + AspectProjWeCareAbout + + + + + + org.eclipse.ajdt.core.ajbuilder + + + + + + org.eclipse.ajdt.ui.ajnature + org.eclipse.jdt.core.javanature + + Index: workspace/AspectProj2-On AspectPath/src/b/B.java =================================================================== RCS file: workspace/AspectProj2-On AspectPath/src/b/B.java diff -N workspace/AspectProj2-On AspectPath/src/b/B.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProj2-On AspectPath/src/b/B.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,5 @@ +package b; + +public class B { + +} Index: workspace/AspectProjWeCareAbout/.classpath =================================================================== RCS file: workspace/AspectProjWeCareAbout/.classpath diff -N workspace/AspectProjWeCareAbout/.classpath --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProjWeCareAbout/.classpath 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + Index: workspace/JavaProj2-On Inpath/.project =================================================================== RCS file: workspace/JavaProj2-On Inpath/.project diff -N workspace/JavaProj2-On Inpath/.project --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/JavaProj2-On Inpath/.project 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,17 @@ + + + JavaProj2-On Inpath + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + Index: workspace/AspectProjWeCareAbout/src/a/B.java =================================================================== RCS file: workspace/AspectProjWeCareAbout/src/a/B.java diff -N workspace/AspectProjWeCareAbout/src/a/B.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProjWeCareAbout/src/a/B.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,5 @@ +package a; + +public class B { + +} Index: workspace/AspectProj3-Has Outjar/.project =================================================================== RCS file: workspace/AspectProj3-Has Outjar/.project diff -N workspace/AspectProj3-Has Outjar/.project --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProj3-Has Outjar/.project 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,18 @@ + + + AspectProj3-Has Outjar + + + + + + org.eclipse.ajdt.core.ajbuilder + + + + + + org.eclipse.ajdt.ui.ajnature + org.eclipse.jdt.core.javanature + + Index: workspace/JavaProj3-ClassFolder/.classpath =================================================================== RCS file: workspace/JavaProj3-ClassFolder/.classpath diff -N workspace/JavaProj3-ClassFolder/.classpath --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/JavaProj3-ClassFolder/.classpath 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,6 @@ + + + + + + Index: workspace/AspectProj1/.classpath =================================================================== RCS file: workspace/AspectProj1/.classpath diff -N workspace/AspectProj1/.classpath --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProj1/.classpath 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,7 @@ + + + + + + + Index: workspace/JavaProj1/bin/c/D.class =================================================================== RCS file: workspace/JavaProj1/bin/c/D.class diff -N workspace/JavaProj1/bin/c/D.class --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/JavaProj1/bin/c/D.class 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,7 @@ +1c/Djava/lang/Object()VCode + LineNumberTableLocalVariableTablethisLc/D;x()I +SourceFileD.java!/* +  +-  +  + Index: workspace/AspectProj3-Has Outjar/src/f/OnOutJar.java =================================================================== RCS file: workspace/AspectProj3-Has Outjar/src/f/OnOutJar.java diff -N workspace/AspectProj3-Has Outjar/src/f/OnOutJar.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProj3-Has Outjar/src/f/OnOutJar.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,5 @@ +package f; + +public class OnOutJar { + +} Index: workspace/JavaProj1/.classpath =================================================================== RCS file: workspace/JavaProj1/.classpath diff -N workspace/JavaProj1/.classpath --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/JavaProj1/.classpath 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,6 @@ + + + + + + Index: workspace/AspectProj3-Has Outjar/.settings/org.eclipse.ajdt.ui.prefs =================================================================== RCS file: workspace/AspectProj3-Has Outjar/.settings/org.eclipse.ajdt.ui.prefs diff -N workspace/AspectProj3-Has Outjar/.settings/org.eclipse.ajdt.ui.prefs --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProj3-Has Outjar/.settings/org.eclipse.ajdt.ui.prefs 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,3 @@ +#Thu Sep 04 11:34:44 PDT 2008 +eclipse.preferences.version=1 +org.eclipse.ajdt.ui.outJar=output.jar Index: src/org/eclipse/ajdt/core/tests/ajde/CoreCompilerConfigurationTests.java =================================================================== RCS file: src/org/eclipse/ajdt/core/tests/ajde/CoreCompilerConfigurationTests.java diff -N src/org/eclipse/ajdt/core/tests/ajde/CoreCompilerConfigurationTests.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ajdt/core/tests/ajde/CoreCompilerConfigurationTests.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,280 @@ +package org.eclipse.ajdt.core.tests.ajde; + +import java.io.StringReader; + +import org.eclipse.ajdt.core.AspectJCorePreferences; +import org.eclipse.ajdt.core.AspectJPlugin; +import org.eclipse.ajdt.core.tests.AJDTCoreTestCase; +import org.eclipse.ajdt.core.tests.testutils.ReaderInputStream; +import org.eclipse.ajdt.core.tests.testutils.TestLogger; +import org.eclipse.ajdt.core.tests.testutils.Utils; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IncrementalProjectBuilder; + + +/** + * This class tests Bug 245566. The use of ICompilerConfiguration's + * api should reduce overhead in preparing for incremenental builds + */ +public class CoreCompilerConfigurationTests extends AJDTCoreTestCase { + private TestLogger testLog; + + protected void setUp() throws Exception { + super.setUp(); + Utils.setAutobuilding(false); + testLog = new TestLogger(); + AspectJPlugin.getDefault().setAJLogger(testLog); + AspectJCorePreferences.setIncrementalCompilationOptimizationsEnabled(true); + } + + protected void tearDown() throws Exception { + super.tearDown(); + Utils.setAutobuilding(true); + AspectJCorePreferences.setIncrementalCompilationOptimizationsEnabled(false); + } + + // test to ensure that when the switch is turned off, optimization does not occur + public void testIncrementalCompilationOptimizationsEnabled() throws Exception { + + assertTrue(AspectJCorePreferences.isIncrementalCompilationOptimizationsEnabled()); + AspectJCorePreferences.setIncrementalCompilationOptimizationsEnabled(false); + assertFalse(AspectJCorePreferences.isIncrementalCompilationOptimizationsEnabled()); + + // load project and full build + IProject proj = createPredefinedProject("Bean Example"); + + testLog.clearLog(); + + proj.getFile("src/bean/Point.java").touch(null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // ensure that the classpath entries list has not been set + assertEquals(0, testLog.numberOfEntriesForMessage("Setting list of classpath elements with modified contents:")); + assertEquals(1, testLog.numberOfEntriesForMessage("Optimizations turned off, so assuming all parts of configuration have changed")); + assertEquals(1, testLog.numberOfEntriesForMessage("Configuration was []")); + assertEquals(1, testLog.numberOfEntriesForMessage("Resetting list of modified source files. Was [/Users/andrew/Eclipse/Workspaces/junit-workspace/Bean Example/src/bean/Point.java]")); + } + + + public void testChangeSourceFiles() throws Exception { + + // load project and full build + IProject proj = createPredefinedProject("Bean Example"); + + // touch source files (one Java and one AJ) + proj.getFile("src/bean/Point.java").touch(null); + proj.getFile("src/bean/BoundPoint.aj").touch(null); + + testLog.clearLog(); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // look at AJDT Event trace + // when build is determining which source files have changed + assertEquals(1, testLog.numberOfEntriesForMessage("File: /Users/andrew/Eclipse/Workspaces/junit-workspace/Bean Example/src/bean/Point.java has changed.")); + assertEquals(1, testLog.numberOfEntriesForMessage("File: /Users/andrew/Eclipse/Workspaces/junit-workspace/Bean Example/src/bean/BoundPoint.aj has changed.")); + + // should not happen. this line should only be logged when a file is added or deleted + assertEquals(0, testLog.numberOfEntriesForMessage("CoreCompilerConfiguration for project Bean Example registered a configuration change: [PROJECTSOURCEFILES_CHANGED]")); + + // during a callback from ajc + assertEquals(1, testLog.numberOfEntriesForMessage("build: Examined delta - 2 changed, 0 added, and 0 deleted source files in required project Bean Example")); + + // after compilation can reset configuration + assertEquals(1, testLog.numberOfEntriesForMessage("Resetting list of modified source files. Was [/Users/andrew/Eclipse/Workspaces/junit-workspace/Bean Example/src/bean/BoundPoint.aj, /Users/andrew/Eclipse/Workspaces/junit-workspace/Bean Example/src/bean/Point.java]")); + + // when the configuration is being reset + assertEquals(1, testLog.numberOfEntriesForMessage("Configuration was []")); + } + + // also test creating and deleting source files and resources + public void testAddDeleteSourceFiles() throws Exception { + // load project and full build + IProject proj = createPredefinedProject("Bean Example"); + + testLog.clearLog(); + + // create a Java file and an Aspect file + proj.getFile("src/MyJavaFile.java").create(new ReaderInputStream(new StringReader("public class MyJavaFile { }")), + true, null); + proj.getFile("src/MyAspectFile.aj").create(new ReaderInputStream(new StringReader("public aspect MyAspectFile { }")), + true, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // now delete the files + proj.getFile("src/MyJavaFile.java").delete(true, null); + proj.getFile("src/MyAspectFile.aj").delete(true, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // check log + + // should not have found any changes, only additions and deletions + assertEquals(1, testLog.numberOfEntriesForMessage("build: Examined delta - 0 changed, 2 added, and 0 deleted source files in required project Bean Example")); + assertEquals(1, testLog.numberOfEntriesForMessage("build: Examined delta - 0 changed, 0 added, and 2 deleted source files in required project Bean Example")); + + // all of these items should appear twice: once on creation and once on deletion + assertEquals(2, testLog.numberOfEntriesForMessage("Compiler configuration for project Bean Example has been read by compiler. Resetting.")); + assertEquals(2, testLog.numberOfEntriesForMessage("Configuration was [PROJECTSOURCEFILES_CHANGED]")); + assertEquals(2, testLog.numberOfEntriesForMessage("Resetting list of modified source files. Was []")); + + // occurs 4 times: twice on creation and twice on deletion + assertEquals(4, testLog.numberOfEntriesForMessage("CoreCompilerConfiguration for project Bean Example registered a configuration change: [PROJECTSOURCEFILES_CHANGED]")); + + // this last entry occurs only once after the aspect is deleted + assertEquals(1, testLog.numberOfEntriesForMessage("Preparing for build: not going to be incremental because an aspect was deleted")); + } + + public void testClasspathChange() throws Exception { + // load project and full build + IProject proj = createPredefinedProject("Bean Example"); + + // touch classpath + proj.getFile(".classpath").touch(null); + + testLog.clearLog(); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // look at AJDT Event trace + // the configuration should have registered a change: + assertEquals(1, testLog.numberOfEntriesForMessage("CoreCompilerConfiguration for project Bean Example registered a configuration change: [ASPECTPATH_CHANGED, CLASSPATH_CHANGED, INPATH_CHANGED]")); + + // classpath has been changed, so should not see this message + assertEquals(0, testLog.numberOfEntriesForMessage("build: Examined delta - no source file or classpath changes for project Bean Example")); + } + + /** + * before the first build after a clean, any changes to the + * configuration should not be recorded because the compiler has + * nothing to compare the changes to. + * @throws Exception + */ + public void testChangeBeforeBuild() throws Exception { + // load project and full build + IProject proj = createPredefinedProject("Bean Example"); + + testLog.clearLog(); + + // now do a clean so that the previous build is forgotten + getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, null); + + proj.getFile("src/bean/Point.java").touch(null); + proj.getFile("src/bean/BoundPoint.aj").touch(null); + proj.getFile(".classpath").touch(null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + + // since there was no state before and hence no ResourceDelta, + // we know that there must be certain entries missing from the log + assertEquals(0, testLog.numberOfEntriesForMessage("File: /Users/andrew/Eclipse/Workspaces/junit-workspace/Bean Example/src/bean/Point.java has changed.")); + assertEquals(0, testLog.numberOfEntriesForMessage("File: /Users/andrew/Eclipse/Workspaces/junit-workspace/Bean Example/src/bean/BoundPoint.aj has changed.")); + assertEquals(0, testLog.numberOfEntriesForMessage("CoreCompilerConfiguration for project Bean Example registered a configuration change: [PROJECTSOURCEFILES_CHANGED]")); + + assertEquals(1, testLog.numberOfEntriesForMessage("Compiler configuration for project Bean Example doesn't know previous state, so assuming EVERYTHING has changed.")); + + // and what should we be seeing about the classpath? + + // the previous set of config changes was *everything*, so + // this was sent to the compiler + assertEquals(1, testLog.numberOfEntriesForMessage("Configuration was [PROJECTSOURCEFILES_CHANGED, JAVAOPTIONS_CHANGED, ASPECTPATH_CHANGED, CLASSPATH_CHANGED, INPATH_CHANGED, NONSTANDARDOPTIONS_CHANGED, OUTJAR_CHANGED, PROJECTSOURCERESOURCES_CHANGED, OUTPUTDESTINATIONS_CHANGED, INJARS_CHANGED]")); + } + + // also test creating and deleting source files and resources + public void testAddDeleteChangeReources() throws Exception { + // load project and full build + IProject proj = createPredefinedProject("Bean Example"); + + testLog.clearLog(); + + // create a resource + proj.getFile("src/nothing.txt").create(new ReaderInputStream(new StringReader("nothing interesting")), + true, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // touch the resource + proj.getFile("src/nothing.txt").touch(null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // delete the resource + proj.getFile("src/nothing.txt").delete(true, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // check log + // 3 builds, but only 2 should have resource files changed in it + // only occurs when resources are added or deleted. + assertEquals(2, testLog.numberOfEntriesForMessage("CoreCompilerConfiguration for project Bean Example registered a configuration change: [PROJECTSOURCERESOURCES_CHANGED]")); + + // no source files have changed, though + assertEquals(3, testLog.numberOfEntriesForMessage("build: Examined delta - no source file or classpath changes for project Bean Example")); + + // also make sure the file was copied and deleted properly + assertEquals(1, testLog.numberOfEntriesForMessage("Copying added file nothing.txt")); + assertEquals(1, testLog.numberOfEntriesForMessage("Deleting existing file nothing.txt")); + assertEquals(1, testLog.numberOfEntriesForMessage("Copying changed file nothing.txt")); + assertEquals(1, testLog.numberOfEntriesForMessage("Deleting removed file nothing.txt")); + } + + // now test what happens when the build is broken + // not really sure what the behavior should be. + public void testBadBuild() throws Exception { + // load project and full build + IProject proj = createPredefinedProject("Bean Example"); + + testLog.clearLog(); + + // create a source file + proj.getFile("src/MyAspectFile.aj").create(new ReaderInputStream(new StringReader("public aspect MyAspectFile { }")), + true, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // add an error to the source file + proj.getFile("src/MyAspectFile.aj").appendContents(new ReaderInputStream(new StringReader("XXX")), + true, false, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + + // remove the error + proj.getFile("src/MyAspectFile.aj").setContents(new ReaderInputStream(new StringReader("public aspect MyAspectFile { }")), 0, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // check log + testLog.printLog(); + } + + + +} Index: workspace/JavaProj1/src/c/B.java =================================================================== RCS file: workspace/JavaProj1/src/c/B.java diff -N workspace/JavaProj1/src/c/B.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/JavaProj1/src/c/B.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,5 @@ +package c; + +public class B { + +} Index: workspace/JavaProj1/bin/c/B.class =================================================================== RCS file: workspace/JavaProj1/bin/c/B.class diff -N workspace/JavaProj1/bin/c/B.class --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/JavaProj1/bin/c/B.class 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,5 @@ +1c/Bjava/lang/Object()VCode + LineNumberTableLocalVariableTablethisLc/B; +SourceFileB.java!/* +  + Index: workspace/AspectProj3-Has Outjar/output.jar =================================================================== RCS file: workspace/AspectProj3-Has Outjar/output.jar diff -N workspace/AspectProj3-Has Outjar/output.jar --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/AspectProj3-Has Outjar/output.jar 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,3 @@ +PK]$9META-INF/MANIFEST.MFMLK-. +K-*ϳR03r.JM,IMuRp,.HM.Rp-I-PKW97PK]$9f/OnOutJar.classENPjn8hA=zxRmRr8%E&;}#8&*kg Q\xQXeSo,J 60mOrEIBKBmD +A w*PU!i t(8ًdn]b4ʡpmR~PK}>PK]$9W97META-INF/MANIFEST.MFPK]$9}>f/OnOutJar.classPK} Index: src/org/eclipse/ajdt/core/tests/ajde/CoreCompilerConfigurationTests2.java =================================================================== RCS file: src/org/eclipse/ajdt/core/tests/ajde/CoreCompilerConfigurationTests2.java diff -N src/org/eclipse/ajdt/core/tests/ajde/CoreCompilerConfigurationTests2.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ajdt/core/tests/ajde/CoreCompilerConfigurationTests2.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,210 @@ +package org.eclipse.ajdt.core.tests.ajde; + +import java.io.StringReader; + +import org.eclipse.ajdt.core.AspectJCorePreferences; +import org.eclipse.ajdt.core.AspectJPlugin; +import org.eclipse.ajdt.core.tests.AJDTCoreTestCase; +import org.eclipse.ajdt.core.tests.testutils.ReaderInputStream; +import org.eclipse.ajdt.core.tests.testutils.TestLogger; +import org.eclipse.ajdt.core.tests.testutils.Utils; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IncrementalProjectBuilder; + +/** + * this set of tests ensures that the CoreCompilerConfiguration.getClasspathElementsWithModifiedContents() method + * works properly + * + * Actually, this test class tests the method AJBuilder.getChangedRequiredProjects + */ +public class CoreCompilerConfigurationTests2 extends AJDTCoreTestCase { + + private TestLogger testLog; + + private IProject jp1; +// private IProject jp2; // not used + private IProject jp3; + private IProject ap1; + private IProject ap2; + private IProject ap3; + private IProject myProj; + + protected void setUp() throws Exception { + super.setUp(); + Utils.setAutobuilding(false); + testLog = new TestLogger(); + AspectJPlugin.getDefault().setAJLogger(testLog); + + jp1 = createPredefinedProject("JavaProj1"); + /* jp2 = */ createPredefinedProject("JavaProj2-On Inpath"); + jp3 = createPredefinedProject("JavaProj3-ClassFolder"); + ap1 = createPredefinedProject("AspectProj1"); + ap2 = createPredefinedProject("AspectProj2-On AspectPath"); + ap3 = createPredefinedProject("AspectProj3-Has Outjar"); + myProj = createPredefinedProject("AspectProjWeCareAbout"); + + AspectJCorePreferences.setIncrementalCompilationOptimizationsEnabled(true); + } + + protected void tearDown() throws Exception { + super.tearDown(); + Utils.setAutobuilding(true); + AspectJCorePreferences.setIncrementalCompilationOptimizationsEnabled(false); + } + + /* + * When there are no changes, only the + * projects on the inpath should be listed as modified + */ + public void testNoChange() throws Exception { + testLog.clearLog(); + + // change myProj + myProj.getFile("src/a/B.java").touch(null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // check log + // should see that the project on the inpath was considered changed. + assertEquals(1, testLog.numberOfEntriesForMessage("[/Users/andrew/Eclipse/Workspaces/junit-workspace/JavaProj2-On Inpath/bin]")); + + // ensure that this is the only time the list has been set + assertEquals(1, testLog.numberOfEntriesForMessage("Setting list of classpath elements with modified contents:")); + } + + /* + * the project as well as the in path project should appear + */ + public void testChangeAspectProject() throws Exception { + testLog.clearLog(); + + // change the project + ap1.getFile("src/AFile.java").create(new ReaderInputStream(new StringReader("class AFile {}")), false, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // check log + // This first entry is from when project ap1 is built + assertEquals(1, testLog.numberOfEntriesForMessage(" []")); + // this message comes from the project we care about + assertEquals(1, testLog.numberOfEntriesForMessage("[/Users/andrew/Eclipse/Workspaces/junit-workspace/AspectProj1/bin, /Users/andrew/Eclipse/Workspaces/junit-workspace/JavaProj2-On Inpath/bin]")); + + // ensure that these are the only 2 times the list has been set + assertEquals(2, testLog.numberOfEntriesForMessage("Setting list of classpath elements with modified contents:")); + } + + public void testChangeAspectProjectOnAspectPath() throws Exception { + testLog.clearLog(); + + // change the project + ap2.getFile("src/AFile.java").create(new ReaderInputStream(new StringReader("class AFile {}")), false, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // check log + // This first entry is from when project ap2 is built + assertEquals(1, testLog.numberOfEntriesForMessage(" []")); + // this message comes from the project we care about + assertEquals(1, testLog.numberOfEntriesForMessage("[/Users/andrew/Eclipse/Workspaces/junit-workspace/AspectProj2-On AspectPath/bin, /Users/andrew/Eclipse/Workspaces/junit-workspace/JavaProj2-On Inpath/bin]")); + + // ensure that these are the only 2 times the list has been set + assertEquals(2, testLog.numberOfEntriesForMessage("Setting list of classpath elements with modified contents:")); + } + + public void testChangeJavaProject() throws Exception { + testLog.clearLog(); + + // change the project + jp1.getFile("src/AFile.java").create(new ReaderInputStream(new StringReader("class AFile {}")), false, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // check log + // this message comes from the project we care about + assertEquals(1, testLog.numberOfEntriesForMessage("[/Users/andrew/Eclipse/Workspaces/junit-workspace/JavaProj1/bin, /Users/andrew/Eclipse/Workspaces/junit-workspace/JavaProj2-On Inpath/bin]")); + + // ensure that this is the only time the list has been set + assertEquals(1, testLog.numberOfEntriesForMessage("Setting list of classpath elements with modified contents:")); + } + + public void testChangeJavaProjectNonStructuralChange() throws Exception { + testLog.clearLog(); + + // change the project---non-structural change + jp1.getFile("src/c/B.java").touch(null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // check log + // this message comes from the project we care about + // nothing other than the inpath should be on the list + assertEquals(1, testLog.numberOfEntriesForMessage("[/Users/andrew/Eclipse/Workspaces/junit-workspace/JavaProj2-On Inpath/bin]")); + + // ensure that this is the only time the list has been set + assertEquals(1, testLog.numberOfEntriesForMessage("Setting list of classpath elements with modified contents:")); + } + + public void testChangeClassFolder() throws Exception { + testLog.clearLog(); + + // change the project + jp3.getFile("src/AFile.java").create(new ReaderInputStream(new StringReader("class AFile {}")), false, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // incremental build...again + // we have a situation where there is a double build because there + // is a binary folder dependency. + // In general, we don't recommend binary folder dependencies for + // this reason (should use project dependencies instead) + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + + // check log + // this message comes from the project we care about on the first build + assertEquals(1, testLog.numberOfEntriesForMessage("[/Users/andrew/Eclipse/Workspaces/junit-workspace/JavaProj2-On Inpath/bin]")); + + // this message comes from the project we care about on the second build + assertEquals(1, testLog.numberOfEntriesForMessage("[/Users/andrew/Eclipse/Workspaces/junit-workspace/JavaProj3-ClassFolder/bin, /Users/andrew/Eclipse/Workspaces/junit-workspace/JavaProj2-On Inpath/bin]")); + + // ensure that this is the only time the list has been set + assertEquals(2, testLog.numberOfEntriesForMessage("Setting list of classpath elements with modified contents:")); + } + + public void testChangeJar() throws Exception { + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + testLog.clearLog(); + + // change the project + ap3.getFile("src/AFile.java").create(new ReaderInputStream(new StringReader("class AFile {}")), false, null); + + // incremental build + getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + waitForAutoBuild(); + + // check log + // This first entry is from when project ap3 is built + assertEquals(1, testLog.numberOfEntriesForMessage(" []")); + // this message comes from the project we care about + assertEquals(1, testLog.numberOfEntriesForMessage("[/Users/andrew/Eclipse/Workspaces/junit-workspace/AspectProj3-Has Outjar/output.jar, /Users/andrew/Eclipse/Workspaces/junit-workspace/JavaProj2-On Inpath/bin]")); + + // ensure that this is the only time the list has been set + assertEquals(2, testLog.numberOfEntriesForMessage("Setting list of classpath elements with modified contents:")); + } +} Index: workspace/JavaProj2-On Inpath/.classpath =================================================================== RCS file: workspace/JavaProj2-On Inpath/.classpath diff -N workspace/JavaProj2-On Inpath/.classpath --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/JavaProj2-On Inpath/.classpath 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,6 @@ + + + + + + Index: workspace/JavaProj1/src/c/D.java =================================================================== RCS file: workspace/JavaProj1/src/c/D.java diff -N workspace/JavaProj1/src/c/D.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/JavaProj1/src/c/D.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,7 @@ +package c; + +public class D { + int x() { + return 9; + } +} Index: workspace/JavaProj1/.project =================================================================== RCS file: workspace/JavaProj1/.project diff -N workspace/JavaProj1/.project --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/JavaProj1/.project 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,17 @@ + + + JavaProj1 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + Index: workspace/JavaProj3-ClassFolder/.project =================================================================== RCS file: workspace/JavaProj3-ClassFolder/.project diff -N workspace/JavaProj3-ClassFolder/.project --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ workspace/JavaProj3-ClassFolder/.project 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,17 @@ + + + JavaProj3-ClassFolder + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + #P org.eclipse.ajdt.core Index: src/org/eclipse/ajdt/internal/core/ResourceChangeListener.java =================================================================== RCS file: src/org/eclipse/ajdt/internal/core/ResourceChangeListener.java diff -N src/org/eclipse/ajdt/internal/core/ResourceChangeListener.java --- src/org/eclipse/ajdt/internal/core/ResourceChangeListener.java 13 Nov 2006 14:14:22 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2006 IBM Corporation 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: - * Luzius Meisser - initial implementation - *******************************************************************************/ -package org.eclipse.ajdt.internal.core; - -import org.eclipse.ajdt.core.AspectJPlugin; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IResourceChangeListener; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.runtime.CoreException; - -public class ResourceChangeListener implements IResourceChangeListener { - - private ResourceDeltaVisitor myDeltaVisitor; - - /* - * (non-Javadoc) - * - * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) - */ - public ResourceChangeListener() { - myDeltaVisitor = new ResourceDeltaVisitor(); - } - - public void resourceChanged(IResourceChangeEvent event) { - if (event.getType() == IResourceChangeEvent.POST_CHANGE) { - IResourceDelta delta = event.getDelta(); - // avoid processing deltas for non-AspectJ projects, - if (delta != null) { - IResourceDelta[] cd = delta.getAffectedChildren(); - if (cd == null) { - try { - delta.accept(myDeltaVisitor); - } catch (CoreException e) { - } - } else { - for (int i = 0; i < cd.length; i++) { - try { - IResource res = cd[i].getResource(); - if (res == null) { - cd[i].accept(myDeltaVisitor); - } else { - IProject proj = res.getProject(); - // if we don't know the project, or it is - // no longer accessible, we'd better process - // the delta. Otherwise we only process it - // if it is an AspectJ project. - if ((proj == null) || !proj.isAccessible() - || AspectJPlugin.isAJProject(proj)) { - cd[i].accept(myDeltaVisitor); - } - } - } catch (CoreException e) { - } - } - } - } - } - } -} \ No newline at end of file Index: src/org/eclipse/ajdt/internal/core/ResourceDeltaVisitor.java =================================================================== RCS file: src/org/eclipse/ajdt/internal/core/ResourceDeltaVisitor.java diff -N src/org/eclipse/ajdt/internal/core/ResourceDeltaVisitor.java --- src/org/eclipse/ajdt/internal/core/ResourceDeltaVisitor.java 15 Jan 2007 17:00:48 -0000 1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2006 IBM Corporation 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: - * Luzius Meisser - initial implementation - * Matthew Ford - Bug 154339 - * Helen Hawkins - updated for new ajde interface (bug 148190) - *******************************************************************************/ -package org.eclipse.ajdt.internal.core; - -import org.eclipse.ajdt.core.AspectJPlugin; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.IResourceDeltaVisitor; - -public class ResourceDeltaVisitor implements IResourceDeltaVisitor { - - /* - * (non-Javadoc) - * - * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) - */ - public ResourceDeltaVisitor() { - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta) - */ - public boolean visit(IResourceDelta delta) { - IResource myRes = delta.getResource(); - if (myRes.getType() == IResource.PROJECT) { - switch (delta.getKind()) { - case IResourceDelta.REMOVED: - // remove the compiler associated with this project from the factory - AspectJPlugin.getDefault().getCompilerFactory() - .removeCompilerForProject(myRes.getProject()); - break; - case IResourceDelta.CHANGED: - if (!myRes.getProject().isOpen()) { - // remove the compiler associated with this project from the - // factory - project could remain closed indefinitely, therefore, - // don't want to hang on to the compiler instance - AspectJPlugin.getDefault().getCompilerFactory() - .removeCompilerForProject(myRes.getProject()); - } - break; - } - } - return true; - } -} \ No newline at end of file Index: src/org/eclipse/ajdt/internal/core/ajde/CoreCompilerConfiguration.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.core/src/org/eclipse/ajdt/internal/core/ajde/CoreCompilerConfiguration.java,v retrieving revision 1.5 diff -u -r1.5 CoreCompilerConfiguration.java --- src/org/eclipse/ajdt/internal/core/ajde/CoreCompilerConfiguration.java 3 Sep 2008 20:54:49 -0000 1.5 +++ src/org/eclipse/ajdt/internal/core/ajde/CoreCompilerConfiguration.java 6 Sep 2008 04:40:32 -0000 @@ -22,6 +22,7 @@ import org.aspectj.ajde.core.ICompilerConfiguration; import org.aspectj.ajde.core.IOutputLocationManager; +import org.aspectj.ajdt.internal.core.builder.CompilerConfigurationChangeFlags; import org.eclipse.ajdt.core.AJLog; import org.eclipse.ajdt.core.AspectJCorePreferences; import org.eclipse.ajdt.core.AspectJPlugin; @@ -47,8 +48,9 @@ import org.eclipse.osgi.util.NLS; /** - * ICompilerConfiguration implementation which returns information for all methods except getNonStandardOptions(). - * + * ICompilerConfiguration implementation which returns information for all + * methods except getNonStandardOptions(). This implementation is used + * if ajdt.core plugin is not present in the platform */ public class CoreCompilerConfiguration implements ICompilerConfiguration { @@ -56,8 +58,25 @@ protected IProject project; private CoreOutputLocationManager locationManager; - public CoreCompilerConfiguration(IProject project) { + // fully qualified list of file names that have been touched since + // last build + // set to null originally since we don't know anything + // about build state when first created. Assume everything + // has changed. + private List/* File */ modifiedFiles = null; + // set of flags describing what has changed since last + // build + // initially set to EVERYTHING since we don't know + // build state when first created. + private int configurationChanges; + + // list of classpath entries that have been rebuilt since last build + private List /*String*/ classpathElementsWithModifiedContents = null; + + public CoreCompilerConfiguration(IProject project) { this.project = project; + AJLog.log(AJLog.BUILDER, "Compiler configuration for project " + project.getName() + " doesn't know previous state, so assuming EVERYTHING has changed."); + configurationChanges = EVERYTHING; } public Map getJavaOptionsMap() { @@ -434,10 +453,102 @@ return result; } - // List modifiedFiles = new ArrayList(); - - public void addModifiedFile(String string) { - // modifiedFiles.add(string); + public void addModifiedFile(File changedFile) { + AJLog.log(AJLog.BUILDER, "File: " + changedFile + " has changed."); + if (modifiedFiles != null) { + modifiedFiles.add(changedFile); + } else { + AJLog.log(AJLog.BUILDER, " but, we don't have any state yet, so not recording the change."); + } + } + + /** + * Flag this compiler configuration as having had a change. + * This is reset after a call to {@link #configurationRead()} + * @param changeFlag change flag from + * {@link CompilerConfigurationChangeFlags} + */ + public void configurationChanged(int changeFlag) { + configurationChanges |= changeFlag; + logConfigurationChange(changeFlag); + } + + private void logConfigurationChange(int changeFlag) { + List changeKind = new ArrayList(); + if ((changeFlag & PROJECTSOURCEFILES_CHANGED) != NO_CHANGES) { + changeKind.add("PROJECTSOURCEFILES_CHANGED"); + } + if ((changeFlag & JAVAOPTIONS_CHANGED) != NO_CHANGES) { + changeKind.add("JAVAOPTIONS_CHANGED"); + } + if ((changeFlag & ASPECTPATH_CHANGED) != NO_CHANGES) { + changeKind.add("ASPECTPATH_CHANGED"); + } + if ((changeFlag & CLASSPATH_CHANGED) != NO_CHANGES) { + changeKind.add("CLASSPATH_CHANGED"); + } + if ((changeFlag & INPATH_CHANGED) != NO_CHANGES) { + changeKind.add("INPATH_CHANGED"); + } + if ((changeFlag & NONSTANDARDOPTIONS_CHANGED) != NO_CHANGES) { + changeKind.add("NONSTANDARDOPTIONS_CHANGED"); + } + if ((changeFlag & OUTJAR_CHANGED) != NO_CHANGES) { + changeKind.add("OUTJAR_CHANGED"); + } + if ((changeFlag & PROJECTSOURCERESOURCES_CHANGED) != NO_CHANGES) { + changeKind.add("PROJECTSOURCERESOURCES_CHANGED"); + } + if ((changeFlag & OUTPUTDESTINATIONS_CHANGED) != NO_CHANGES) { + changeKind.add("OUTPUTDESTINATIONS_CHANGED"); + } + // deprecated + if ((changeFlag & INJARS_CHANGED) != NO_CHANGES) { + changeKind.add("INJARS_CHANGED"); + } + AJLog.log(AJLog.BUILDER, "CoreCompilerConfiguration for project " + project.getName() + " registered a configuration change: " + changeKind); + } + + /** + * converts the current configuration change list to a + * human readable string + * @return human readable string denoting all configuration + * changes since last read. + */ + private String toConfigurationString() { + List changeKind = new ArrayList(); + if ((configurationChanges & PROJECTSOURCEFILES_CHANGED) != NO_CHANGES) { + changeKind.add("PROJECTSOURCEFILES_CHANGED"); + } + if ((configurationChanges & JAVAOPTIONS_CHANGED) != NO_CHANGES) { + changeKind.add("JAVAOPTIONS_CHANGED"); + } + if ((configurationChanges & ASPECTPATH_CHANGED) != NO_CHANGES) { + changeKind.add("ASPECTPATH_CHANGED"); + } + if ((configurationChanges & CLASSPATH_CHANGED) != NO_CHANGES) { + changeKind.add("CLASSPATH_CHANGED"); + } + if ((configurationChanges & INPATH_CHANGED) != NO_CHANGES) { + changeKind.add("INPATH_CHANGED"); + } + if ((configurationChanges & NONSTANDARDOPTIONS_CHANGED) != NO_CHANGES) { + changeKind.add("NONSTANDARDOPTIONS_CHANGED"); + } + if ((configurationChanges & OUTJAR_CHANGED) != NO_CHANGES) { + changeKind.add("OUTJAR_CHANGED"); + } + if ((configurationChanges & PROJECTSOURCERESOURCES_CHANGED) != NO_CHANGES) { + changeKind.add("PROJECTSOURCERESOURCES_CHANGED"); + } + if ((configurationChanges & OUTPUTDESTINATIONS_CHANGED) != NO_CHANGES) { + changeKind.add("OUTPUTDESTINATIONS_CHANGED"); + } + // deprecated + if ((configurationChanges & INJARS_CHANGED) != NO_CHANGES) { + changeKind.add("INJARS_CHANGED"); + } + return changeKind.toString(); } /** @@ -445,14 +556,33 @@ * build. */ public void configurationRead() { + // we now know nothing has changed + AJLog.log(AJLog.BUILDER, "Compiler configuration for project " + project.getName() + " has been read by compiler. Resetting."); + AJLog.log(AJLog.BUILDER, " Configuration was " + toConfigurationString()); + + // we are still not keeping track of some changes: + // JAVAOPTIONS_CHANGED | NONSTANDARDOPTIONS_CHANGED | OUTJAR_CHANGED | + // OUTPUTDESTINATIONS_CHANGED | INJARS_CHANGED + configurationChanges = NO_CHANGES; + resetModifiedList(); } /** * Need to tell AspectJ what has changed in the configuration since the last build was done - the lazy answer (which causes it * to behave as it always used to) is EVERYTHING. + * + * @see CompilerConfigurationChangeFlags + * @see AspectJCorePreferences#isIncrementalCompilationOptimizationsEnabled */ public int getConfigurationChanges() { - return EVERYTHING; + // if the optimization flag is turned off, then return EVERYTHING + if (!AspectJCorePreferences.isIncrementalCompilationOptimizationsEnabled()) { + AJLog.log(AJLog.BUILDER, "Optimizations turned off, so assuming all parts of configuration have changed"); + return EVERYTHING; + } else { + AJLog.log(AJLog.BUILDER, "Sending the following configuration changes to the compiler: " + toConfigurationString()); + return AspectJCorePreferences.isIncrementalCompilationOptimizationsEnabled() ? configurationChanges : EVERYTHING; + } } /** @@ -460,22 +590,48 @@ * analysing delta changes. Returning null means we have no idea and will cause AspectJ to do the analysis to work it out. */ public List getProjectSourceFilesChanged() { - return null;// null means we dont know - // if (modifiedFiles == null) { - // AJLog.log("Nothing changed??"); - // } else { - // AJLog.log(modifiedFiles.size() + " changes"); - // } - // if (modifiedFiles.isEmpty()) - // return null; - // return modifiedFiles; + if (!AspectJCorePreferences.isIncrementalCompilationOptimizationsEnabled()) { + AJLog.log(AJLog.BUILDER, "Optimizations turned off, so assuming all source files have changed"); + return null; + } else if (modifiedFiles == null) { + // null means we dont know + AJLog.log(AJLog.BUILDER, "We don't know what has changed since last build, so assuming all source files have changed"); + return null; + } else { + AJLog.log(AJLog.BUILDER, modifiedFiles.size() + " source file changes since last build"); + return modifiedFiles; + } } public void resetModifiedList() { - // modifiedFiles.clear(); + AJLog.log(AJLog.BUILDER, "Resetting list of modified source files. Was " + + (modifiedFiles == null ? "null" : modifiedFiles.toString())); + modifiedFiles = new ArrayList(); + } + + public void resetClasspathElementsWithModifiedContents() { + classpathElementsWithModifiedContents = null; + } + public void setClasspathElementsWithModifiedContents(List /*String*/ modifiedContents) { + AJLog.log(AJLog.BUILDER, "Setting list of classpath elements with modified contents:"); + AJLog.log(AJLog.BUILDER, " " + modifiedContents.toString()); + classpathElementsWithModifiedContents = modifiedContents; + } + + // must go through the classpath and look at projects we depend on that have been built before our + // most recent last build + public List getClasspathElementsWithModifiedContents() { + return classpathElementsWithModifiedContents; } - public List getClasspathElementsWithModifiedContents() { - return null; + + /** + * helper method that grabs the compiler configuration for a particular project + * creates one if it does not exist + * @param project + * @return the project's compiler configuration + */ + public static CoreCompilerConfiguration getCompilerConfigurationForProject(IProject project) { + return (CoreCompilerConfiguration) AspectJPlugin.getDefault().getCompilerFactory().getCompilerForProject(project).getCompilerConfiguration(); } } Index: src/org/eclipse/ajdt/internal/core/ajde/CoreCompilerFactory.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.core/src/org/eclipse/ajdt/internal/core/ajde/CoreCompilerFactory.java,v retrieving revision 1.2 diff -u -r1.2 CoreCompilerFactory.java --- src/org/eclipse/ajdt/internal/core/ajde/CoreCompilerFactory.java 19 Jul 2008 00:20:48 -0000 1.2 +++ src/org/eclipse/ajdt/internal/core/ajde/CoreCompilerFactory.java 6 Sep 2008 04:40:32 -0000 @@ -19,6 +19,9 @@ /** * ICompilerFactory implementation which returns AjCompilers with * core implementations of the required interfaces. + * + * This class is only used if ajdt.ui plugin is not available + * */ public class CoreCompilerFactory implements ICompilerFactory { @@ -45,10 +48,13 @@ * No longer record the AjCompiler for the given project. */ public void removeCompilerForProject(IProject project) { - // firstly clean up any state associated with the compiler - getCompilerForProject(project).clearLastState(); - // remove compiler from the map - compilerMap.remove(project); + // firstly clean up any state associated with the compiler + AjCompiler compiler = (AjCompiler) compilerMap.get(project); + if (compiler != null) { + compiler.clearLastState(); + // remove compiler from the map + compilerMap.remove(project); + } } /** Index: src/org/eclipse/ajdt/core/BuildConfig.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/BuildConfig.java,v retrieving revision 1.6 diff -u -r1.6 BuildConfig.java --- src/org/eclipse/ajdt/core/BuildConfig.java 11 May 2007 11:43:23 -0000 1.6 +++ src/org/eclipse/ajdt/core/BuildConfig.java 6 Sep 2008 04:40:26 -0000 @@ -12,9 +12,11 @@ package org.eclipse.ajdt.core; import java.util.ArrayList; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.WeakHashMap; import org.eclipse.core.resources.IContainer; @@ -33,7 +35,7 @@ public class BuildConfig { - private static Map projectsToIncludedSourceFiles = new WeakHashMap(); + private static Map /*IProject, List*/ projectsToIncludedSourceFiles = new WeakHashMap(); /** * Returns all of the currently included source files in a project @@ -74,6 +76,48 @@ projectsToIncludedSourceFiles.put(project, sourceFiles); return sourceFiles; } + + + + /** + * Experimental version of above that uses a set, not a list + * @param project + * @return + */ + public static Set /* IFile */getIncludedSourceFilesSet(IProject project) { + if (projectsToIncludedSourceFiles.get(project) instanceof List) { + return (Set) projectsToIncludedSourceFiles.get(project); + } + Set sourceFiles = new HashSet(); + try { + IJavaProject jp = JavaCore.create(project); + IClasspathEntry[] cpes = jp.getRawClasspath(); + for (int i = 0; i < cpes.length; i++) { + if ((cpes[i] instanceof ClasspathEntry) + && (cpes[i].getEntryKind() == IClasspathEntry.CPE_SOURCE)) { + ClasspathEntry cp = (ClasspathEntry) cpes[i]; + char[][] incl = cp.fullInclusionPatternChars(); + char[][] excl = cp.fullExclusionPatternChars(); + IPath path = cpes[i].getPath(); + IResource res = project.findMember(path + .removeFirstSegments(1)); + if ((res != null) && (res instanceof IContainer)) { + List l = allFiles((IContainer) res); + for (Iterator iter = l.iterator(); iter.hasNext();) { + IFile file = (IFile) iter.next(); + if (!Util.isExcluded(file, incl, excl)) { + sourceFiles.add(file); + } + } + } + } + } + } catch (JavaModelException e) { + } + projectsToIncludedSourceFiles.put(project, sourceFiles); + return sourceFiles; + } + /** * Invalidate the list of included source files for a project Index: src/org/eclipse/ajdt/core/AspectJCorePreferences.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/AspectJCorePreferences.java,v retrieving revision 1.10 diff -u -r1.10 AspectJCorePreferences.java --- src/org/eclipse/ajdt/core/AspectJCorePreferences.java 21 Aug 2008 16:56:21 -0000 1.10 +++ src/org/eclipse/ajdt/core/AspectJCorePreferences.java 6 Sep 2008 04:40:25 -0000 @@ -45,6 +45,7 @@ public class AspectJCorePreferences { public static final String OPTION_AutobuildSuppressed = "org.eclipse.ajdt.ui.builder.autobuildSuppressed"; //$NON-NLS-1$ + public static final String OPTION_IncrementalCompilationOptimizations = "org.eclipse.ajdt.ui.builder.incrementalCompilationOptimizations"; //$NON-NLS-1$ private static final String ASPECTPATH_ATTRIBUTE_NAME = "org.eclipse.ajdt.aspectpath"; //$NON-NLS-1$ @@ -990,5 +991,22 @@ .getPluginPreferences(); store.setValue(OPTION_AutobuildSuppressed, done); } + + /** + * Checks to see if the compiler option for incremental build optimizations + * is on or off + * @return + */ + public static boolean isIncrementalCompilationOptimizationsEnabled() { + Preferences store = AspectJPlugin.getDefault() + .getPluginPreferences(); + return store.getBoolean(OPTION_IncrementalCompilationOptimizations); + } + + public static void setIncrementalCompilationOptimizationsEnabled(boolean value) { + Preferences store = AspectJPlugin.getDefault() + .getPluginPreferences(); + store.setValue(OPTION_IncrementalCompilationOptimizations, value); + } } Index: src/org/eclipse/ajdt/core/AspectJPlugin.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/AspectJPlugin.java,v retrieving revision 1.36 diff -u -r1.36 AspectJPlugin.java --- src/org/eclipse/ajdt/core/AspectJPlugin.java 19 Jul 2008 00:20:49 -0000 1.36 +++ src/org/eclipse/ajdt/core/AspectJPlugin.java 6 Sep 2008 04:40:25 -0000 @@ -13,7 +13,7 @@ package org.eclipse.ajdt.core; import org.eclipse.ajdt.core.model.AJModel; -import org.eclipse.ajdt.internal.core.ResourceChangeListener; +import org.eclipse.ajdt.internal.core.CompilerConfigResourceChangeListener; import org.eclipse.ajdt.internal.core.ajde.CoreCompilerFactory; import org.eclipse.ajdt.internal.core.ajde.ICompilerFactory; import org.eclipse.core.resources.IProject; @@ -119,7 +119,7 @@ super.start(context); checkForCUprovider(); getWorkspace().addResourceChangeListener( - new ResourceChangeListener(), + new CompilerConfigResourceChangeListener(), IResourceChangeEvent.POST_CHANGE); setCompilerFactory(new CoreCompilerFactory()); } Index: src/org/eclipse/ajdt/core/builder/AJBuilder.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.core/src/org/eclipse/ajdt/core/builder/AJBuilder.java,v retrieving revision 1.50 diff -u -r1.50 AJBuilder.java --- src/org/eclipse/ajdt/core/builder/AJBuilder.java 21 Aug 2008 05:18:05 -0000 1.50 +++ src/org/eclipse/ajdt/core/builder/AJBuilder.java 6 Sep 2008 04:40:30 -0000 @@ -14,8 +14,10 @@ package org.eclipse.ajdt.core.builder; import java.io.File; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Hashtable; import java.util.Iterator; import java.util.List; @@ -23,7 +25,9 @@ import java.util.Set; import org.aspectj.ajde.core.AjCompiler; +import org.aspectj.ajde.core.ICompilerConfiguration; import org.aspectj.ajdt.internal.core.builder.AjState; +import org.aspectj.ajdt.internal.core.builder.CompilerConfigurationChangeFlags; import org.aspectj.ajdt.internal.core.builder.IStateListener; import org.aspectj.ajdt.internal.core.builder.IncrementalStateManager; import org.eclipse.ajdt.core.AJLog; @@ -37,13 +41,15 @@ import org.eclipse.ajdt.core.text.CoreMessages; import org.eclipse.ajdt.internal.core.AspectJRTInitializer; import org.eclipse.ajdt.internal.core.ajde.CoreCompilerConfiguration; -import org.eclipse.ajdt.internal.core.ajde.CoreOutputLocationManager; +import org.eclipse.core.internal.resources.ResourceException; import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IResourceStatus; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IWorkspaceRoot; @@ -52,8 +58,10 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.jdt.core.IClasspathEntry; @@ -62,7 +70,9 @@ import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.core.ClasspathEntry; +import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.JavaProject; +import org.eclipse.jdt.internal.core.builder.State; import org.eclipse.jdt.internal.core.util.Util; import org.eclipse.osgi.util.NLS; import org.osgi.service.prefs.BackingStoreException; @@ -156,9 +166,8 @@ } if (kind != FULL_BUILD) { - // XXX need to add check here for whether the classpath has changed - if (!sourceFilesChanged(dta, project)){ - AJLog.log(AJLog.BUILDER,"build: Examined delta - no source file changes for project " //$NON-NLS-1$ + if (!sourceFilesChanged(dta, project) && !classpathChanged(dta, project)){ + AJLog.log(AJLog.BUILDER,"build: Examined delta - no source file or classpath changes for project " //$NON-NLS-1$ + project.getName() ); // if the source files of any projects which the current @@ -186,6 +195,7 @@ IAJCompilerMonitor compilerMonitor = (IAJCompilerMonitor) compiler.getBuildProgressMonitor(); + // Bug 43711 must do a clean and rebuild if we can't // find a buildConfig file from a previous compilation if (kind == FULL_BUILD || @@ -197,10 +207,19 @@ } else { AJLog.log(AJLog.BUILDER,"Unable to empty output folder on build all - why cant we find the IJavaProject?"); //$NON-NLS-1$ } + } else { + // doing an incremental build + if (AspectJCorePreferences.isIncrementalCompilationOptimizationsEnabled()) { + // Bug 245566: + // facilitate incremental compilation by checking + // classpath for projects that have changed since the last build + long timestamp = getLastBuildTimeStamp(compiler); + compilerConfig.setClasspathElementsWithModifiedContents(getChangedRequiredProjects(timestamp)); + } } compilerMonitor.prepare(new SubProgressMonitor(progressMonitor,100)); - AJLog.log(AJLog.BUILDER_CLASSPATH,"Classpath="+compilerConfig.getClasspath()); //$NON-NLS-1$ + AJLog.log(AJLog.BUILDER_CLASSPATH,"Classpath = " + compilerConfig.getClasspath()); //$NON-NLS-1$ // ---------------------------------------- // Do the compilation @@ -217,10 +236,13 @@ doRefreshAfterBuild(project, dependingProjects, javaProject); - // update the relationship map - CoreOutputLocationManager outputLocManager = (CoreOutputLocationManager) - compilerConfig.getOutputLocationManager(); - Set/*File*/ touchedFiles = outputLocManager.getTouchedClassFiles(); + // not needed now. This will be used to help create the relationship + // map more efficiently +// CoreOutputLocationManager outputLocManager = (CoreOutputLocationManager) +// compilerConfig.getOutputLocationManager(); +// Set/*File*/ touchedFiles = outputLocManager.getTouchedClassFiles(); + + // update the relationship map boolean inc = (kind == IncrementalProjectBuilder.INCREMENTAL_BUILD) || (kind == IncrementalProjectBuilder.AUTO_BUILD); AJModel.getInstance().createMap(project,true,inc); @@ -235,6 +257,28 @@ return requiredProjects; } + // check to see if the .classpath has changed. + // we know exactly where it is located, so no need for a visitor + private boolean classpathChanged(IResourceDelta dta, IProject project) { + IResourceDelta[] children = dta.getAffectedChildren(); + for (int i = 0; i < children.length; i++) { + IResourceDelta child = children[i]; + if (child.getResource().getName().equals(".classpath")) { + return true; + } + } + return false; + } + + private long getLastBuildTimeStamp(AjCompiler compiler) { + AjState state = IncrementalStateManager.retrieveStateFor(compiler.getId()); + if (state != null) { + return state.getLastBuildTime(); + } else { + return 0; + } + } + private String buildKindString(int kind) { switch(kind) { case IncrementalProjectBuilder.AUTO_BUILD: @@ -250,7 +294,126 @@ } } - /** + /** + * returns a list of fully qualified names of entries on the classpath + * that have been rebuilt since last build + * @return + */ + private List /*String*/ getChangedRequiredProjects(long lastBuildTimestamp) { + try { + // first find all the projects that have changed since last build + IProject[] projectsOnClasspath = getRequiredProjects(getProject(), true); + List /*IProject*/ changedProjects = new ArrayList(); + for (int i = 0; i < projectsOnClasspath.length; i++) { + IProject project = projectsOnClasspath[i]; + + // get timestamp of last build for this project + long otherTimestamp = -1; + if (AspectJPlugin.isAJProject(project)) { + AjCompiler compiler = AspectJPlugin.getDefault().getCompilerFactory().getCompilerForProject(project); + otherTimestamp = getLastBuildTimeStamp(compiler); + } else if (project.hasNature(JavaCore.NATURE_ID)) { + Object s = JavaModelManager.getJavaModelManager().getLastBuiltState(project, null); + if (s != null && s instanceof State) { + State state = (State) s; + // need to use reflection to get at the last build time + otherTimestamp = getLastBuildTime(state); + } + } else { + otherTimestamp = -1; + } + if (lastBuildTimestamp <= otherTimestamp) { + changedProjects.add(project); + } + } + List /*String*/ changedEntries = new ArrayList(); + + // now that we have all the projects, need to find out what they contribute to + // this project's path. could be itself, a jar, or a class folder + if (changedProjects.size() > 0) { + IClasspathEntry[] thisClasspath = JavaCore.create(getProject()).getResolvedClasspath(true); + for (Iterator projIter = changedProjects.iterator(); projIter + .hasNext();) { + IProject changedProject = (IProject) projIter.next(); + for (int i = 0; i < thisClasspath.length; i++) { + IClasspathEntry classpathEntry = thisClasspath[i]; + switch (classpathEntry.getEntryKind()) { + case IClasspathEntry.CPE_PROJECT: + if (changedProject.getFullPath().equals(classpathEntry.getPath())) { + // resolve project and add all entries + changedEntries.addAll(listOfClassPathEntriesToListOfString(AspectJCorePreferences.resolveDependentProjectClasspath( + changedProject, classpathEntry))); + } + break; + case IClasspathEntry.CPE_LIBRARY: + if (changedProject.getFullPath().isPrefixOf(classpathEntry.getPath())) { + // only add if this path exists + IWorkspaceRoot root = getProject().getWorkspace().getRoot(); + IFile onPath = root.getFile(classpathEntry.getPath()); + if (onPath.exists() || + root.getFolder(onPath.getFullPath()).exists()) { // may be a folder + changedEntries.add(onPath.getLocation().toPortableString()); + } + } + } + } + } + } + // if all else went well, also add the inpath the the list of changed projects. + // Adding the inpath always is just a conservative estimate of what has changed. + // + // For Java projects, we only know the last structural build time. Usually this is + // fine, but if the Java project is on the inpath, then we care about the last + // build of any kind, which we can't be sure of. + // (Actually, we need to know this for Aspect path projects, but aspectj can give us + // precise time of the last build. + // + // So, as a conservative estimate, put all inpath entries onto the list. + Set inPathFiles = CoreCompilerConfiguration.getCompilerConfigurationForProject(getProject()).getInpath(); + if (inPathFiles != null) { + for (Iterator fileIter = inPathFiles.iterator(); fileIter.hasNext();) { + File inpathFile = (File) fileIter.next(); + changedEntries.add(inpathFile.getAbsolutePath()); + } + } + return changedEntries; + } catch (Exception e) { + // something went wrong. + // return null to imply everything's changed + AspectJPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, AspectJPlugin.PLUGIN_ID, + "Error determining list of entries on classpath that have changed.", e)); + return null; + } + } + + private List/*String*/ listOfClassPathEntriesToListOfString( + List/*IClassPathEntry*/ entries) { + IWorkspaceRoot root = getProject().getWorkspace().getRoot(); + List strings = new ArrayList(entries.size()); + for (Iterator iterator = entries.iterator(); iterator + .hasNext();) { + IClasspathEntry entry = (IClasspathEntry) iterator.next(); + IFile onPath = root.getFile(entry.getPath()); + // only add if exists + if (onPath.exists() || + root.getFolder(onPath.getFullPath()).exists()) { // may be a class folder + + strings.add(onPath.getLocation().toPortableString()); + } + } + return strings; + } + + private static Field state_lastStructuralBuildTime = null; + private static long getLastBuildTime(State state) throws Exception { + if (state_lastStructuralBuildTime == null) { + state_lastStructuralBuildTime = State.class.getDeclaredField("lastStructuralBuildTime"); + state_lastStructuralBuildTime.setAccessible(true); + } + return state_lastStructuralBuildTime.getLong(state); + } + + /** * Refreshes the project's out folders after a build * try to be as precise as possible because this can be a time consuming task * @@ -442,7 +605,7 @@ /** * Copies non-src resources to the output directory (bug 78579). The main * part of this method was taken from - * org.eclipse.jdt.internal.core.builder.IncrementalImageBuilder.findSourceFiles(IResourceDelta) + * {@link org.eclipse.jdt.internal.core.builder.IncrementalImageBuilder.findSourceFiles(IResourceDelta)} * * @param IJavaProject - the project which is being built * @param IResourceDelta - the projects delta @@ -456,12 +619,15 @@ IPath srcPath = srcEntry.getPath().removeFirstSegments(1); IContainer srcContainer = getContainerForGivenPath(srcPath,project.getProject()); - if(srcContainer.equals(project.getProject())) { + // handle case where project root is a source folder + if (srcContainer.equals(project.getProject())) { int segmentCount = delta.getFullPath().segmentCount(); IResourceDelta[] children = delta.getAffectedChildren(); - for (int j = 0, m = children.length; j < m; j++) - if (!isExcludedFromProject(project,children[j].getFullPath(),srcEntries)) + for (int j = 0, m = children.length; j < m; j++) { + if (!isExcludedFromProject(project,children[j].getFullPath(),srcEntries)) { copyResources(project, children[j], srcEntry, segmentCount); + } + } } else { IPath projectRelativePath = srcEntry.getPath().removeFirstSegments(1); projectRelativePath.makeRelative(); @@ -474,9 +640,10 @@ int segmentCount = sourceDelta.getFullPath().segmentCount(); IResourceDelta[] children = sourceDelta.getAffectedChildren(); try { - for (int j = 0, m = children.length; j < m; j++) + for (int j = 0, m = children.length; j < m; j++) { copyResources(project, children[j], srcEntry, segmentCount); - } catch (org.eclipse.core.internal.resources.ResourceException e) { + } + } catch (ResourceException e) { // catch the case that a package has been renamed and collides on disk with an as-yet-to-be-deleted package if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) { return false; @@ -530,8 +697,9 @@ // fall thru & collect all the resource files case IResourceDelta.CHANGED : IResourceDelta[] children = sourceDelta.getAffectedChildren(); - for (int i = 0, l = children.length; i < l; i++) + for (int i = 0, l = children.length; i < l; i++) { copyResources(javaProject, children[i],srcEntry, segmentCount); + } return; case IResourceDelta.REMOVED : IPath removedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount); @@ -544,15 +712,17 @@ // only a package fragment was removed, same as removing multiple source files createFolder(removedPackagePath, outputFolder); // ensure package exists in the output folder IResourceDelta[] removedChildren = sourceDelta.getAffectedChildren(); - for (int j = 0, m = removedChildren.length; j < m; j++) + for (int j = 0, m = removedChildren.length; j < m; j++) { copyResources(javaProject,removedChildren[j], srcEntry, segmentCount); + } return; } } } IFolder removedPackageFolder = outputFolder.getFolder(removedPackagePath); - if (removedPackageFolder.exists()) + if (removedPackageFolder.exists()) { removedPackageFolder.delete(IResource.FORCE, null); + } } return; case IResource.FILE : @@ -567,6 +737,7 @@ || resourcePath.getFileExtension().equals("java"))) { //$NON-NLS-1$ return; } + IResource outputFile = outputFolder.getFile(resourcePath); switch (sourceDelta.getKind()) { case IResourceDelta.ADDED : @@ -580,17 +751,26 @@ outputFile.setDerived(true); Util.setReadOnly(outputFile, false); // just in case the original was read only outputFile.refreshLocal(IResource.DEPTH_ZERO,null); + // mark this change so compiler knows about it. + CoreCompilerConfiguration.getCompilerConfigurationForProject(getProject()) + .configurationChanged( + CompilerConfigurationChangeFlags.PROJECTSOURCERESOURCES_CHANGED); return; case IResourceDelta.REMOVED : if (outputFile.exists()) { AJLog.log(AJLog.BUILDER,"Deleting removed file " + resourcePath);//$NON-NLS-1$ outputFile.delete(IResource.FORCE, null); } + // mark this change so compiler knows about it. + CoreCompilerConfiguration.getCompilerConfigurationForProject(getProject()) + .configurationChanged( + CompilerConfigurationChangeFlags.PROJECTSOURCERESOURCES_CHANGED); return; case IResourceDelta.CHANGED : if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0 - && (sourceDelta.getFlags() & IResourceDelta.ENCODING) == 0) + && (sourceDelta.getFlags() & IResourceDelta.ENCODING) == 0) { return; // skip it since it really isn't changed + } if (outputFile.exists()) { AJLog.log(AJLog.BUILDER,"Deleting existing file " + resourcePath);//$NON-NLS-1$ outputFile.delete(IResource.FORCE, null); @@ -922,11 +1102,8 @@ // clean the output folders and do a refresh if not // automatically building (so that output dir reflects the // changes) - if (AspectJPlugin.getWorkspace().getDescription().isAutoBuilding()) { - cleanOutputFolders(JavaCore.create(project),false); - } else { - cleanOutputFolders(JavaCore.create(project),true); - } + cleanOutputFolders(JavaCore.create(project), + !AspectJPlugin.getWorkspace().getDescription().isAutoBuilding()); } private void removeProblemsAndTasksFor(IResource resource) { @@ -937,60 +1114,141 @@ } } catch (CoreException e) { } - AJLog.log(AJLog.BUILDER,"Removed problems and tasks for project "+resource.getName()); //$NON-NLS-1$ + if (resource != null) { + AJLog.log(AJLog.BUILDER,"Removed problems and tasks for project "+resource.getName()); //$NON-NLS-1$ + } } - - public boolean sourceFilesChanged(IResourceDelta delta, IProject project) { - if (delta!=null && delta.getAffectedChildren().length!=0) { - List includedFileNames = BuildConfig.getIncludedSourceFiles(project); + + + /** + * Determine if any source files have changed and if so record it in the compiler configuration for the + * project + * @param delta + * @param project + * @return true if a source file has changed. False otherwise + */ + public boolean sourceFilesChanged(IResourceDelta delta, IProject project) { + AJLog.logStart("SourceFilesChanged"); + if (delta != null && delta.getAffectedChildren().length != 0) { + + // XXX might be better if this were a Set. + // look into this + List /*IFile*/ includedFileNames = BuildConfig.getIncludedSourceFiles(project); +// Set /*IFile*/ includedFileNames = BuildConfig.getIncludedSourceFilesSet(project); + IJavaProject ijp = JavaCore.create(project); if (ijp == null) { return true; } try { - IPath outputPath = ijp.getOutputLocation(); - if (project.getFullPath().equals(outputPath)) { - outputPath = null; - } - if (sourceFilesChanged(delta, includedFileNames,outputPath)) { - AJLog.log(AJLog.BUILDER,"build: Examined delta - source file changes in " //$NON-NLS-1$ + SourceFilesChangedVisitor visitor = new SourceFilesChangedVisitor(project, includedFileNames); + delta.accept(visitor); + if (visitor.hasChanges()) { + AJLog.log(AJLog.BUILDER,"build: Examined delta - " + visitor.getNumberChanged() + //$NON-NLS-1$ + " changed, " + visitor.getNumberAdded() + " added, and " + //$NON-NLS-1$ //$NON-NLS-2$ + visitor.getNumberRemoved() + " deleted source files in " //$NON-NLS-1$ + "required project " + project.getName() ); //$NON-NLS-1$ return true; } else { return false; } - } catch (JavaModelException e) {} + } catch (CoreException e) { + AspectJPlugin.getDefault().getLog().log( + new Status(IStatus.ERROR, + AspectJPlugin.PLUGIN_ID, "Error finding source file changes", e)); + } } + AJLog.logEnd(AJLog.BUILDER,"SourceFilesChanged"); return true; } - private boolean sourceFilesChanged(IResourceDelta dta, List includedFileNames,IPath outputLocation) { //IProject project) { - if (dta == null) return false; + private class SourceFilesChangedVisitor implements IResourceDeltaVisitor { + private final List includedFileNames; + private final CoreCompilerConfiguration compilerConfiguration; + private final IProject affectedProject; + private int numberChanged; + private int numberAdded; + private int numberRemoved; + + private SourceFilesChangedVisitor(IProject affectedProject, + List includedFileNames) { + this.includedFileNames = includedFileNames; + this.affectedProject = affectedProject; + compilerConfiguration = CoreCompilerConfiguration.getCompilerConfigurationForProject(affectedProject); + numberChanged = 0; + numberAdded = 0; + numberRemoved = 0; + } - if (outputLocation!=null && outputLocation.equals(dta.getFullPath()) ) { - return false; - } - String resname = dta.getFullPath().toString(); - - if (CoreUtils.ASPECTJ_SOURCE_FILTER.accept(resname)) { - if ((includedFileNames==null) || includedFileNames.contains(dta.getResource()) - || dta.getKind() == IResourceDelta.REMOVED) { - return true; - } else { + /** + * Look for changed resources that we care about. + */ + public boolean visit(IResourceDelta delta) throws CoreException { + String resname = delta.getFullPath().toString(); + + if (delta.getResource().getType() == IResource.FILE) { + if (CoreUtils.ASPECTJ_SOURCE_FILTER.accept(resname)) { + + switch (delta.getKind()) { + case IResourceDelta.REMOVED: + case IResourceDelta.REMOVED_PHANTOM: + // don't check to see if these files are on the list of included + // files because they have already been removed and we won't find + // them on the list. + // be conservative and set the flag regardless. + compilerConfiguration.configurationChanged( + CompilerConfigurationChangeFlags.PROJECTSOURCEFILES_CHANGED); + numberRemoved++; + break; + + case IResourceDelta.ADDED: + case IResourceDelta.ADDED_PHANTOM: + if (includedFileNames.contains(delta.getResource())) { + compilerConfiguration.configurationChanged( + CompilerConfigurationChangeFlags.PROJECTSOURCEFILES_CHANGED); + numberAdded++; + break; + } + case IResourceDelta.CHANGED: + if (includedFileNames.contains(delta.getResource())) { + compilerConfiguration.addModifiedFile(new File(delta.getResource() + .getLocation().toPortableString())); + numberChanged++; + } + } + } else if (resname.endsWith(".classpath")) { //$NON-NLS-1$ + // also need to ensure that this is a project classpath + IContainer parent = delta.getResource().getParent(); + if (parent.getFullPath().equals(affectedProject.getFullPath())) { + // we don't know what has changed exactly. + // be conservative + compilerConfiguration.configurationChanged( + CompilerConfigurationChangeFlags.CLASSPATH_CHANGED | + CompilerConfigurationChangeFlags.ASPECTPATH_CHANGED | + CompilerConfigurationChangeFlags.INPATH_CHANGED); + } + } return false; + } else { + + // want to fully traverse this delta if not + // a leaf node + return true; } - } else if (resname.endsWith(".classpath")){ //$NON-NLS-1$ - return true; - } else { - boolean kids_results = false; - int i = 0; - IResourceDelta[] kids = dta.getAffectedChildren(); - while (!kids_results && i < kids.length) { - kids_results = kids_results | sourceFilesChanged(kids[i], includedFileNames, outputLocation); - i++; - } - return kids_results; - } + } + public int getNumberChanged() { + return numberChanged; + } + public int getNumberAdded() { + return numberAdded; + } + public int getNumberRemoved() { + return numberRemoved; + } + + public boolean hasChanges() { + return numberAdded + numberChanged + numberRemoved > 0; + } } public static void addStateListener() { @@ -1006,8 +1264,9 @@ public void pathChangeDetected() { } - public void buildSuccessful(boolean arg0) { - AJLog.log(AJLog.COMPILER,"AspectJ reports build successful, build was: "+(arg0?"FULL":"INCREMENTAL")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + public void buildSuccessful(boolean wasFull) { + AJLog.log(AJLog.COMPILER,"AspectJ reports build successful, build was: " + //$NON-NLS-1$ + (wasFull ? "FULL" : "INCREMENTAL")); //$NON-NLS-1$ //$NON-NLS-2$ } public void detectedAspectDeleted(File f) { Index: src/org/eclipse/ajdt/internal/core/CompilerConfigResourceDeltaVisitor.java =================================================================== RCS file: src/org/eclipse/ajdt/internal/core/CompilerConfigResourceDeltaVisitor.java diff -N src/org/eclipse/ajdt/internal/core/CompilerConfigResourceDeltaVisitor.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ajdt/internal/core/CompilerConfigResourceDeltaVisitor.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation 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: + * Luzius Meisser - initial implementation + * Matthew Ford - Bug 154339 + * Helen Hawkins - updated for new ajde interface (bug 148190) + *******************************************************************************/ +package org.eclipse.ajdt.internal.core; + +import org.eclipse.ajdt.core.AspectJPlugin; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; + +/** + * Removes stored compiler info for projects when they are deleted or closed. + * + */ +public class CompilerConfigResourceDeltaVisitor implements IResourceDeltaVisitor { + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) + */ + public CompilerConfigResourceDeltaVisitor() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta) + */ + public boolean visit(IResourceDelta delta) { + IResource myRes = delta.getResource(); + if (myRes.getType() == IResource.PROJECT) { + switch (delta.getKind()) { + case IResourceDelta.REMOVED: + // remove the compiler associated with this project from the factory + AspectJPlugin.getDefault().getCompilerFactory() + .removeCompilerForProject(myRes.getProject()); + break; + case IResourceDelta.CHANGED: + if (!myRes.getProject().isOpen()) { + // remove the compiler associated with this project from the + // factory - project could remain closed indefinitely, therefore, + // don't want to hang on to the compiler instance + AspectJPlugin.getDefault().getCompilerFactory() + .removeCompilerForProject(myRes.getProject()); + } + break; + } + } + return true; + } +} Index: src/org/eclipse/ajdt/internal/core/CompilerConfigResourceChangeListener.java =================================================================== RCS file: src/org/eclipse/ajdt/internal/core/CompilerConfigResourceChangeListener.java diff -N src/org/eclipse/ajdt/internal/core/CompilerConfigResourceChangeListener.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ajdt/internal/core/CompilerConfigResourceChangeListener.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation 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: + * Luzius Meisser - initial implementation + *******************************************************************************/ +package org.eclipse.ajdt.internal.core; + +import org.eclipse.ajdt.core.AspectJPlugin; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.runtime.CoreException; + +/** + * This listener will add or remove compilers for projects when they are removed or closed + * + */ +public class CompilerConfigResourceChangeListener implements IResourceChangeListener { + + private CompilerConfigResourceDeltaVisitor myDeltaVisitor; + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) + */ + public CompilerConfigResourceChangeListener() { + myDeltaVisitor = new CompilerConfigResourceDeltaVisitor(); + } + + public void resourceChanged(IResourceChangeEvent event) { + if (event.getType() == IResourceChangeEvent.POST_CHANGE) { + IResourceDelta delta = event.getDelta(); + // avoid processing deltas for non-AspectJ projects, + if (delta != null) { + IResourceDelta[] cd = delta.getAffectedChildren(); + if (cd == null) { + try { + delta.accept(myDeltaVisitor); + } catch (CoreException e) { + } + } else { + for (int i = 0; i < cd.length; i++) { + try { + IResource res = cd[i].getResource(); + if (res == null) { + cd[i].accept(myDeltaVisitor); + } else { + IProject proj = res.getProject(); + // if we don't know the project, or it is + // no longer accessible, we'd better process + // the delta. Otherwise we only process it + // if it is an AspectJ project. + if ((proj == null) || !proj.isAccessible() + || AspectJPlugin.isAJProject(proj)) { + cd[i].accept(myDeltaVisitor); + } + } + } catch (CoreException e) { + } + } + } + } + } + } +} #P org.eclipse.ajdt.ui Index: src/org/eclipse/ajdt/ui/AspectJUIPlugin.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.ui/src/org/eclipse/ajdt/ui/AspectJUIPlugin.java,v retrieving revision 1.65 diff -u -r1.65 AspectJUIPlugin.java --- src/org/eclipse/ajdt/ui/AspectJUIPlugin.java 19 Jul 2008 00:20:32 -0000 1.65 +++ src/org/eclipse/ajdt/ui/AspectJUIPlugin.java 6 Sep 2008 04:40:43 -0000 @@ -24,7 +24,7 @@ import org.eclipse.ajdt.core.javaelements.AJCompilationUnitManager; import org.eclipse.ajdt.internal.builder.UIBuildListener; import org.eclipse.ajdt.internal.core.ajde.ICompilerFactory; -import org.eclipse.ajdt.internal.javamodel.ResourceChangeListener; +import org.eclipse.ajdt.internal.javamodel.AJCompilationUnitResourceChangeListener; import org.eclipse.ajdt.internal.ui.ajde.UICompilerFactory; import org.eclipse.ajdt.internal.ui.editor.AspectJTextTools; import org.eclipse.ajdt.internal.ui.lazystart.Utils; @@ -277,7 +277,7 @@ // listener for aspectj model if (!AspectJPlugin.usingCUprovider) { AspectJPlugin.getWorkspace().addResourceChangeListener( - new ResourceChangeListener(), + new AJCompilationUnitResourceChangeListener(), IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.POST_CHANGE Index: src/org/eclipse/ajdt/internal/ui/preferences/AJCompilerPreferencePage.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.ui/src/org/eclipse/ajdt/internal/ui/preferences/AJCompilerPreferencePage.java,v retrieving revision 1.39 diff -u -r1.39 AJCompilerPreferencePage.java --- src/org/eclipse/ajdt/internal/ui/preferences/AJCompilerPreferencePage.java 19 Jul 2008 00:20:32 -0000 1.39 +++ src/org/eclipse/ajdt/internal/ui/preferences/AJCompilerPreferencePage.java 6 Sep 2008 04:40:37 -0000 @@ -121,6 +121,9 @@ AspectJCorePreferences.OPTION_AutobuildSuppressed, AspectJPreferences.VALUE_FALSE); defaultValueMap.put( + AspectJCorePreferences.OPTION_IncrementalCompilationOptimizations, + AspectJPreferences.VALUE_FALSE); + defaultValueMap.put( AspectJPreferences.OPTION_ReportInvalidAbsoluteTypeName, AspectJPreferences.VALUE_WARNING); defaultValueMap.put( @@ -426,6 +429,7 @@ excomposite.setClient(othersComposite); othersComposite.setLayout(new GridLayout(nColumns, false)); + // suppress autobuild label = UIMessages.CompilerConfigurationBlock_aj_suppressAutoBuild; Button b = addCheckBox(othersComposite, label, AspectJCorePreferences.OPTION_AutobuildSuppressed, enableDisableValues, 0, false); useAspectJCorePreferences(b); @@ -433,6 +437,14 @@ // ignoring the original value. b.setSelection(getAspectJCorePLuginPreferences().getBoolean(AspectJCorePreferences.OPTION_AutobuildSuppressed)); + // incremental compiler optimizations + label = UIMessages.CompilerConfigurationBlock_aj_incrementalCompilerOptimizations; + b = addCheckBox(othersComposite, label, AspectJCorePreferences.OPTION_IncrementalCompilationOptimizations, enableDisableValues, 0, false); + useAspectJCorePreferences(b); + // a little kludgy, but here we re-set the selection to be what is stored in AJ core preferences. + // ignoring the original value. + b.setSelection(getAspectJCorePLuginPreferences().getBoolean(AspectJCorePreferences.OPTION_IncrementalCompilationOptimizations)); + } label = UIMessages.CompilerConfigurationBlock_aj_messages_matching; Index: src/org/eclipse/ajdt/internal/ui/text/UIMessages.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.ui/src/org/eclipse/ajdt/internal/ui/text/UIMessages.java,v retrieving revision 1.55 diff -u -r1.55 UIMessages.java --- src/org/eclipse/ajdt/internal/ui/text/UIMessages.java 26 Aug 2008 15:14:30 -0000 1.55 +++ src/org/eclipse/ajdt/internal/ui/text/UIMessages.java 6 Sep 2008 04:40:39 -0000 @@ -416,6 +416,7 @@ public static String CompilerConfigurationBlock_aj_builder_settings; public static String CompilerConfigurationBlock_aj_suppressAutoBuild; + public static String CompilerConfigurationBlock_aj_incrementalCompilerOptimizations; static { NLS.initializeMessages(BUNDLE_NAME, UIMessages.class); Index: src/org/eclipse/ajdt/internal/ui/text/UIMessages.properties =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.ui/src/org/eclipse/ajdt/internal/ui/text/UIMessages.properties,v retrieving revision 1.64 diff -u -r1.64 UIMessages.properties --- src/org/eclipse/ajdt/internal/ui/text/UIMessages.properties 26 Aug 2008 15:14:30 -0000 1.64 +++ src/org/eclipse/ajdt/internal/ui/text/UIMessages.properties 6 Sep 2008 04:40:42 -0000 @@ -564,6 +564,7 @@ CompilerConfigurationBlock_aj_suppressAutoBuild=Suppress autobuild - Suppress automatic building of AspectJ projects \n\ (select this option if incremental building of\n\ AspectJ projects is taking too long) +CompilerConfigurationBlock_aj_incrementalCompilerOptimizations=Incremental Compiler Optimizations - Enable/disable experimental incremental compiler optimizations BuildPathsBlock_ChooseOutputFolderDialog_title= BuildPathsBlock_ChooseOutputFolderDialog_description= Index: src/org/eclipse/ajdt/internal/ui/ajde/UIComplierConfiguration.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.ui/src/org/eclipse/ajdt/internal/ui/ajde/UIComplierConfiguration.java,v retrieving revision 1.1 diff -u -r1.1 UIComplierConfiguration.java --- src/org/eclipse/ajdt/internal/ui/ajde/UIComplierConfiguration.java 15 Jan 2007 17:00:52 -0000 1.1 +++ src/org/eclipse/ajdt/internal/ui/ajde/UIComplierConfiguration.java 6 Sep 2008 04:40:34 -0000 @@ -14,6 +14,11 @@ import org.eclipse.ajdt.internal.ui.preferences.AspectJPreferences; import org.eclipse.core.resources.IProject; +/** + * A complete implementation of ICompilerConfiguration. If the ajdt.ui + * plugin is not present in the platform, then CoreCompilerConfiguration + * is used instead. + */ public class UIComplierConfiguration extends CoreCompilerConfiguration { public UIComplierConfiguration(IProject project) { Index: src/org/eclipse/ajdt/internal/ui/ajde/UICompilerFactory.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.ajdt/AJDT_src/org.eclipse.ajdt.ui/src/org/eclipse/ajdt/internal/ui/ajde/UICompilerFactory.java,v retrieving revision 1.1 diff -u -r1.1 UICompilerFactory.java --- src/org/eclipse/ajdt/internal/ui/ajde/UICompilerFactory.java 15 Jan 2007 17:00:52 -0000 1.1 +++ src/org/eclipse/ajdt/internal/ui/ajde/UICompilerFactory.java 6 Sep 2008 04:40:34 -0000 @@ -14,9 +14,18 @@ import java.util.Map; import org.aspectj.ajde.core.AjCompiler; +import org.eclipse.ajdt.internal.core.ajde.CoreCompilerFactory; import org.eclipse.ajdt.internal.core.ajde.ICompilerFactory; import org.eclipse.core.resources.IProject; +/** + * ICompilerFactory implementation which returns AjCompilers with + * core implementations of the required interfaces. + * + * If ajdt.ui plugin is not present, then CoreCompilerFactory is used instead + * + * @see CoreCompilerFactory + */ public class UICompilerFactory implements ICompilerFactory { private Map compilerMap = new HashMap(); @@ -37,9 +46,12 @@ public void removeCompilerForProject(IProject project) { // firstly clean up any state associated with the compiler - getCompilerForProject(project).clearLastState(); - // remove compiler from the map - compilerMap.remove(project); + AjCompiler compiler = (AjCompiler) compilerMap.get(project); + if (compiler != null) { + compiler.clearLastState(); + // remove compiler from the map + compilerMap.remove(project); + } } public boolean hasCompilerForProject(IProject project) { Index: src/org/eclipse/ajdt/internal/javamodel/ResourceChangeListener.java =================================================================== RCS file: src/org/eclipse/ajdt/internal/javamodel/ResourceChangeListener.java diff -N src/org/eclipse/ajdt/internal/javamodel/ResourceChangeListener.java --- src/org/eclipse/ajdt/internal/javamodel/ResourceChangeListener.java 13 Nov 2006 14:14:25 -0000 1.6 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation 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: - * Luzius Meisser - initial implementation - *******************************************************************************/ -package org.eclipse.ajdt.internal.javamodel; -import org.eclipse.ajdt.core.AspectJPlugin; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IResourceChangeListener; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.runtime.CoreException; -/** - * @author Luzius Meisser - * - */ -public class ResourceChangeListener implements IResourceChangeListener { - private ResourceDeltaVisitor myDeltaVisitor; - /* - * (non-Javadoc) - * - * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) - */ - public ResourceChangeListener() { - myDeltaVisitor = new ResourceDeltaVisitor(); - } - - public void resourceChanged(IResourceChangeEvent event) { - if (event.getType() == IResourceChangeEvent.POST_CHANGE){ - IResourceDelta delta = event.getDelta(); - // avoid processing deltas for non-AspectJ projects, - if (delta != null) { - IResourceDelta[] cd = delta.getAffectedChildren(); - if (cd == null) { - try { - delta.accept(myDeltaVisitor); - } catch (CoreException e) { - } - } else { - for (int i = 0; i < cd.length; i++) { - try { - IResource res = cd[i].getResource(); - if (res == null) { - cd[i].accept(myDeltaVisitor); - } else { - IProject proj = res.getProject(); - // if we don't know the project, or it is - // no longer accessible, we'd better process - // the delta. Otherwise we only process it - // if it is an AspectJ project. - if ((proj == null) || !proj.isAccessible() - || AspectJPlugin.isAJProject(proj)) { - cd[i].accept(myDeltaVisitor); - } - } - } catch (CoreException e) { - } - } - } - } - } - } -} \ No newline at end of file Index: src/org/eclipse/ajdt/internal/javamodel/ResourceDeltaVisitor.java =================================================================== RCS file: src/org/eclipse/ajdt/internal/javamodel/ResourceDeltaVisitor.java diff -N src/org/eclipse/ajdt/internal/javamodel/ResourceDeltaVisitor.java --- src/org/eclipse/ajdt/internal/javamodel/ResourceDeltaVisitor.java 13 Nov 2006 14:14:25 -0000 1.7 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2006 IBM Corporation 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: - * Luzius Meisser - initial implementation - *******************************************************************************/ -package org.eclipse.ajdt.internal.javamodel; - -import org.eclipse.ajdt.core.javaelements.AJCompilationUnitManager; -import org.eclipse.ajdt.internal.utils.AJDTUtils; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.IResourceDeltaVisitor; - -/** - * Notifies the AJCompilationUnitManager if files got added or removed. - * - */ -public class ResourceDeltaVisitor implements IResourceDeltaVisitor { - - /* - * (non-Javadoc) - * - * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) - */ - public ResourceDeltaVisitor() { - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta) - */ - public boolean visit(IResourceDelta delta) { - IResource myRes = delta.getResource(); - if (myRes.getType() == IResource.FILE) { - switch (delta.getKind()) { - case IResourceDelta.REMOVED: - AJCompilationUnitUtils - .removeFileFromModelAndCloseEditors((IFile) myRes); - AJDTUtils.refreshPackageExplorer(); - break; - case IResourceDelta.ADDED: - AJCompilationUnitManager.INSTANCE - .getAJCompilationUnit((IFile) myRes); - AJDTUtils.refreshPackageExplorer(); - break; - } - } - return true; - } -} \ No newline at end of file Index: src/org/eclipse/ajdt/internal/javamodel/AJCompilationUnitResourceDeltaVisitor.java =================================================================== RCS file: src/org/eclipse/ajdt/internal/javamodel/AJCompilationUnitResourceDeltaVisitor.java diff -N src/org/eclipse/ajdt/internal/javamodel/AJCompilationUnitResourceDeltaVisitor.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ajdt/internal/javamodel/AJCompilationUnitResourceDeltaVisitor.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation 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: + * Luzius Meisser - initial implementation + *******************************************************************************/ +package org.eclipse.ajdt.internal.javamodel; + +import org.eclipse.ajdt.core.javaelements.AJCompilationUnitManager; +import org.eclipse.ajdt.internal.utils.AJDTUtils; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; + +/** + * Notifies the AJCompilationUnitManager if files got added or removed. + * + */ +public class AJCompilationUnitResourceDeltaVisitor implements IResourceDeltaVisitor { + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) + */ + public AJCompilationUnitResourceDeltaVisitor() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta) + */ + public boolean visit(IResourceDelta delta) { + IResource myRes = delta.getResource(); + if (myRes.getType() == IResource.FILE) { + switch (delta.getKind()) { + case IResourceDelta.REMOVED: + AJCompilationUnitUtils + .removeFileFromModelAndCloseEditors((IFile) myRes); + AJDTUtils.refreshPackageExplorer(); + break; + case IResourceDelta.ADDED: + AJCompilationUnitManager.INSTANCE + .getAJCompilationUnit((IFile) myRes); + AJDTUtils.refreshPackageExplorer(); + break; + } + } + return true; + } +} Index: src/org/eclipse/ajdt/internal/javamodel/AJCompilationUnitResourceChangeListener.java =================================================================== RCS file: src/org/eclipse/ajdt/internal/javamodel/AJCompilationUnitResourceChangeListener.java diff -N src/org/eclipse/ajdt/internal/javamodel/AJCompilationUnitResourceChangeListener.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/ajdt/internal/javamodel/AJCompilationUnitResourceChangeListener.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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: + * Luzius Meisser - initial implementation + *******************************************************************************/ +package org.eclipse.ajdt.internal.javamodel; +import org.eclipse.ajdt.core.AspectJPlugin; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.runtime.CoreException; +/** + * @author Luzius Meisser + * + */ +public class AJCompilationUnitResourceChangeListener implements IResourceChangeListener { + private AJCompilationUnitResourceDeltaVisitor myDeltaVisitor; + /* + * (non-Javadoc) + * + * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) + */ + public AJCompilationUnitResourceChangeListener() { + myDeltaVisitor = new AJCompilationUnitResourceDeltaVisitor(); + } + + public void resourceChanged(IResourceChangeEvent event) { + if (event.getType() == IResourceChangeEvent.POST_CHANGE){ + IResourceDelta delta = event.getDelta(); + // avoid processing deltas for non-AspectJ projects, + if (delta != null) { + IResourceDelta[] cd = delta.getAffectedChildren(); + if (cd == null) { + try { + delta.accept(myDeltaVisitor); + } catch (CoreException e) { + } + } else { + for (int i = 0; i < cd.length; i++) { + try { + IResource res = cd[i].getResource(); + if (res == null) { + cd[i].accept(myDeltaVisitor); + } else { + IProject proj = res.getProject(); + // if we don't know the project, or it is + // no longer accessible, we'd better process + // the delta. Otherwise we only process it + // if it is an AspectJ project. + if ((proj == null) || !proj.isAccessible() + || AspectJPlugin.isAJProject(proj)) { + cd[i].accept(myDeltaVisitor); + } + } + } catch (CoreException e) { + } + } + } + } + } + } +}