public static boolean FORCE_INCREMENTAL_DURING_TESTING = false;
- // if set to true we will not do a full build if we see a type changed on our classpath
- // but no type in this state instance references it
- public static boolean IGNORE_NON_REFERENCED_TYPES = true;
-
private AjBuildManager buildManager;
private boolean couldBeSubsequentIncrementalBuild = false;
private INameEnvironment nameEnvironment;
return false;
}
- if (simpleStrings.elementSize > 20)
+ if (simpleStrings.elementSize > 20) {
simpleStrings = new StringSet(3);
- else
+ } else {
simpleStrings.clear();
- if (qualifiedStrings.elementSize > 20)
+ }
+ if (qualifiedStrings.elementSize > 20) {
qualifiedStrings = new StringSet(3);
- else
+ } else {
qualifiedStrings.clear();
+ }
if ((newBuildConfig.getChanged() & PROJECTSOURCEFILES_CHANGED) == 0) {
addedFiles = Collections.EMPTY_SET;
private static int MAX_AFFECTED_FILES_BEFORE_FULL_BUILD = 30;
+ public static final FileFilter classFileFilter = new FileFilter() {
+ public boolean accept(File pathname) {
+ return pathname.getName().endsWith(".class");
+ }
+ };
+
/**
* Analyse .class files in the directory specified, if they have changed since the last successful build then see if we can
* determine which source files in our project depend on the change. If we can then we can still do an incremental build, if we
*
*/
private int classFileChangedInDirSinceLastBuildRequiringFullBuild(File dir) {
- int defaultReply = (IGNORE_NON_REFERENCED_TYPES ? CLASS_FILE_CHANGED_THAT_NEEDS_FULL_BUILD
- : CLASS_FILE_CHANGED_THAT_NEEDS_INCREMENTAL_BUILD);
- // Is another AspectJ project building into that directory?
+ // Are we managing that output directory?
AjState state = IncrementalStateManager.findStateManagingOutputLocation(dir);
if (listenerDefined()) {
if (state != null) {
}
}
- File[] classFiles = FileUtil.listFiles(dir, new FileFilter() {
- public boolean accept(File pathname) {
- return pathname.getName().endsWith(".class");
- }
- });
+ List classFiles = FileUtil.listClassFiles(dir);
- for (int i = 0; i < classFiles.length; i++) {
- long modTime = classFiles[i].lastModified();
+ for (Iterator iterator = classFiles.iterator(); iterator.hasNext();) {
+ File classFile = (File) iterator.next();
+ long modTime = classFile.lastModified();
if ((modTime + 1000) >= lastSuccessfulBuildTime) {
- // so the class on disk has changed since our last successful build
+ // so the class on disk has changed since the last successful build for this state object
+
+ // BUG? we stop on the first change that leads us to an incremental build, surely we need to continue and look
+ // at all files incase another change means we need to incremental a bit more stuff?
// To work out if it is a real change we should ask any state
- // object managing this output location whether the file has
+ // object managing the output location whether the file has
// structurally changed or not
if (state != null) {
- if (state.isAspect(classFiles[i])) {
+ if (state.isAspect(classFile)) {
return CLASS_FILE_CHANGED_THAT_NEEDS_FULL_BUILD;
}
- if (state.hasStructuralChangedSince(classFiles[i], lastSuccessfulBuildTime)) {
- if (listenerDefined())
- getListener().recordDecision("Structural change detected in : " + classFiles[i]);
+ if (state.hasStructuralChangedSince(classFile, lastSuccessfulBuildTime)) {
+ if (listenerDefined()) {
+ getListener().recordDecision("Structural change detected in : " + classFile);
+ }
- if (!IGNORE_NON_REFERENCED_TYPES || isTypeWeReferTo(classFiles[i])) {
+ if (isTypeWeReferTo(classFile)) {
if (affectedFiles.size() > MAX_AFFECTED_FILES_BEFORE_FULL_BUILD)
return CLASS_FILE_CHANGED_THAT_NEEDS_FULL_BUILD;
}
} else {
if (listenerDefined())
- getListener().recordDecision("Change detected in " + classFiles[i] + " but it is not structural");
+ getListener().recordDecision("Change detected in " + classFile + " but it is not structural");
}
- // Is the change in a type that any of our source files care about? and if it is, is it
- // a structural change?
- // if (!IGNORE_NON_REFERENCED_TYPES || isTypeWeReferTo(classFiles[i])) {
- // if (affectedFiles.size() > MAX_AFFECTED_FILES_BEFORE_FULL_BUILD)
- // return CLASS_FILE_CHANGED_THAT_NEEDS_FULL_BUILD;
- // if (state.hasStructuralChangedSince(classFiles[i], lastSuccessfulBuildTime))
- // return defaultReply;
- // }
} else {
// No state object to ask, so it only matters if we know which type depends on this file
- if (!IGNORE_NON_REFERENCED_TYPES) {
- return CLASS_FILE_CHANGED_THAT_NEEDS_FULL_BUILD;
+ if (isTypeWeReferTo(classFile)) {
+ if (affectedFiles.size() > MAX_AFFECTED_FILES_BEFORE_FULL_BUILD)
+ return CLASS_FILE_CHANGED_THAT_NEEDS_FULL_BUILD;
+ return CLASS_FILE_CHANGED_THAT_NEEDS_INCREMENTAL_BUILD;
} else {
- if (isTypeWeReferTo(classFiles[i])) {
- if (affectedFiles.size() > MAX_AFFECTED_FILES_BEFORE_FULL_BUILD)
- return CLASS_FILE_CHANGED_THAT_NEEDS_FULL_BUILD;
- return CLASS_FILE_CHANGED_THAT_NEEDS_INCREMENTAL_BUILD;
- } else {
- return CLASS_FILE_NO_CHANGES;
- }
+ return CLASS_FILE_NO_CHANGES;
}
}
}
private boolean pathChange(AjBuildConfig previousConfig, AjBuildConfig newConfig) {
int changes = newConfig.getChanged();
- // currently very coarse grained
if ((changes & (CLASSPATH_CHANGED | ASPECTPATH_CHANGED | INPATH_CHANGED | OUTPUTDESTINATIONS_CHANGED | INJARS_CHANGED)) != 0) {
List oldOutputLocs = getOutputLocations(previousConfig);
* @return true if a change is detected that requires a full build
*/
private boolean changedAndNeedsFullBuild(List oldPath, List newPath, boolean checkClassFiles, List outputLocs) {
- if (oldPath == null)
+ if (oldPath == null) {
oldPath = new ArrayList();
- if (newPath == null)
+ }
+ if (newPath == null) {
newPath = new ArrayList();
+ }
if (oldPath.size() != newPath.size()) {
return true;
}
return true;
}
if (checkClassFiles && f.exists() && f.isDirectory()) {
+
+ // We should use here a list/set of directories we know have or have not changed - some kind of
+ // List<File> buildConfig.getClasspathEntriesWithChangedContents()
+ // and then only proceed to look inside directories if it is one of these, ignoring others -
+ // that should save a massive amount of processing for incremental builds in a multi project scenario
+
boolean foundMatch = false;
for (Iterator iterator = outputLocs.iterator(); iterator.hasNext();) {
File dir = (File) iterator.next();