]> source.dussan.org Git - aspectj.git/commitdiff
Fix for problem introduced when checking contents of dirs on the classpath for change...
authoraclement <aclement>
Tue, 5 Apr 2005 14:50:06 +0000 (14:50 +0000)
committeraclement <aclement>
Tue, 5 Apr 2005 14:50:06 +0000 (14:50 +0000)
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjState.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/IStateListener.java [new file with mode: 0644]
tests/src/org/aspectj/systemtest/incremental/IncrementalTests.java

index e5668bc32f82d690ba8bcfc4b027f937d1be7113..a747db5cd64591ca56e196d4e32d25356de9a9df 100644 (file)
@@ -29,13 +29,13 @@ import org.aspectj.ajdt.internal.compiler.InterimCompilationResult;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.Message;
 import org.aspectj.bridge.SourceLocation;
-import org.aspectj.util.FileUtil;
-import org.aspectj.weaver.bcel.UnwovenClassFile;
 import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
 import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
 import org.aspectj.org.eclipse.jdt.internal.core.builder.ReferenceCollection;
 import org.aspectj.org.eclipse.jdt.internal.core.builder.StringSet;
+import org.aspectj.util.FileUtil;
+import org.aspectj.weaver.bcel.UnwovenClassFile;
 
 
 /**
@@ -44,6 +44,9 @@ import org.aspectj.org.eclipse.jdt.internal.core.builder.StringSet;
 public class AjState {
        AjBuildManager buildManager;
        
+       // static so beware of multi-threading bugs...
+       public static IStateListener stateListener = null;
+       
        long lastSuccessfulBuildTime = -1;
        long currentBuildTime = -1;
        AjBuildConfig buildConfig;
@@ -100,6 +103,7 @@ public class AjState {
                    // coming - otherwise a file that has been deleted from an inpath jar 
                    // since the last build will not be deleted from the output directory.
                    removeAllResultsOfLastBuild();
+                       if (stateListener!=null) stateListener.pathChangeDetected();
                    return false;
                }
                
@@ -180,7 +184,9 @@ public class AjState {
                });
                for (int i = 0; i < classFiles.length; i++) {
                        long modTime = classFiles[i].lastModified();
-                       if (modTime + 1000 >= lastSuccessfulBuildTime) return true;
+                       if (modTime + 1000 >= lastSuccessfulBuildTime) {
+                               return true;
+                       }
                }
                return false;
        }
@@ -189,20 +195,21 @@ public class AjState {
                boolean changed = false;
                List oldClasspath = oldConfig.getClasspath();
                List newClasspath = newConfig.getClasspath();
-               if (changed(oldClasspath,newClasspath,true)) return true;
+               if (stateListener!=null) stateListener.aboutToCompareClasspaths(oldClasspath,newClasspath);
+               if (changed(oldClasspath,newClasspath,true,oldConfig.getOutputDir())) return true;
                List oldAspectpath = oldConfig.getAspectpath();
                List newAspectpath = newConfig.getAspectpath();
-               if (changed(oldAspectpath,newAspectpath,true)) return true;
+               if (changed(oldAspectpath,newAspectpath,true,oldConfig.getOutputDir())) return true;
                List oldInJars = oldConfig.getInJars();
                List newInJars = newConfig.getInJars();
-               if (changed(oldInJars,newInJars,false)) return true;
+               if (changed(oldInJars,newInJars,false,oldConfig.getOutputDir())) return true;
                List oldInPath = oldConfig.getInpath();
                List newInPath = newConfig.getInpath();
-               if (changed(oldInPath, newInPath,false)) return true;
+               if (changed(oldInPath, newInPath,false,oldConfig.getOutputDir())) return true;
                return changed;
        }
        
-       private boolean changed(List oldPath, List newPath, boolean checkClassFiles) {
+       private boolean changed(List oldPath, List newPath, boolean checkClassFiles, File oldOutputLocation) {
                if (oldPath == null) oldPath = new ArrayList();
                if (newPath == null) newPath = new ArrayList();
                if (oldPath.size() != newPath.size()) {
@@ -222,8 +229,10 @@ public class AjState {
                        if (f.exists() && !f.isDirectory() && (f.lastModified() >= lastSuccessfulBuildTime)) {
                                return true;
                        }
-                       if (f.exists() && f.isDirectory() && checkClassFiles) {
-                               return classFileChangedInDirSinceLastBuild(f);
+                       if (f.exists() && f.isDirectory() && checkClassFiles && !(f.equals(oldOutputLocation))) {
+                               boolean b= classFileChangedInDirSinceLastBuild(f);
+                               if (b && stateListener!=null) stateListener.detectedClassChangeInThisDir(f);
+                               if (b) return true;
                        }
                }
                return false;
@@ -639,4 +648,5 @@ public class AjState {
                        addDependentsOf(intRes.unwovenClassFiles()[i].getClassName());
                }
        }
+
 }
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/IStateListener.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/IStateListener.java
new file mode 100644 (file)
index 0000000..b1f64dd
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2005 IBM and other contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.ajdt.internal.core.builder;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Implementations of this interface get told interesting information about
+ * decisions made in AjState objects.  Should help us improve incremental
+ * compilation, and ease the testing of incremental compilation!
+ *
+ * Not yet complete, will expand as we determine what extra useful information
+ * should be recorded.
+ * 
+ * @author AndyClement
+ */
+public interface IStateListener {
+
+       public void detectedClassChangeInThisDir(File f);
+
+       public void aboutToCompareClasspaths(List oldClasspath, List newClasspath);
+
+       public void pathChangeDetected();
+
+}
index aa34783b92f8a7ce24874a85610792950dd59ab0..41528d40cd0d1b9f6f205b5c60178f79f3a9604a 100644 (file)
 package org.aspectj.systemtest.incremental;
 
 import java.io.File;
+import java.util.List;
 
 import junit.framework.Test;
 
+import org.aspectj.ajdt.internal.core.builder.AjState;
+import org.aspectj.ajdt.internal.core.builder.IStateListener;
 import org.aspectj.testing.XMLBasedAjcTestCase;
 
 public class IncrementalTests extends org.aspectj.testing.XMLBasedAjcTestCase {
@@ -101,6 +104,28 @@ public class IncrementalTests extends org.aspectj.testing.XMLBasedAjcTestCase {
     copyFileAndDoIncrementalBuild("changes/Main.20.java","src/app/Main.java");
     run("app.Main");
   }
+  
+  /**
+   * See bug report 85297.  We plugged a hole so that we check whether the contents of
+   * directories on the classpath have changed when deciding whether we can do an
+   * incremental build or not - the implementation didn't allow for the output location
+   * being on the classpath.  This test verifies the fix is OK
+   */
+  public void testIncrementalOKWithOutputPathOnClasspath() throws Exception {
+         class MyStateListener implements IStateListener {
+           public boolean pathChange = false;
+               public void pathChangeDetected() {pathChange = true;}
+               public void aboutToCompareClasspaths(List oldClasspath, List newClasspath) {}
+               public void detectedClassChangeInThisDir(File f) {}
+         };
+         MyStateListener sl = new MyStateListener();
+         AjState.stateListener = sl;
+         runTest("change source");
+         nextIncrement(false);
+         copyFileAndDoIncrementalBuild("changes/Main.20.java","src/app/Main.java");
+         assertTrue("Did not expect a path change to be detected ",!sl.pathChange);
+         run("app.Main");
+  }
 
   public void test009() throws Exception {
     runTest("incrementally change only string literal, still expect advice");