Extend dependency handling
diff --git a/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/core/builder/IBuildState.java b/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/core/builder/IBuildState.java
index 926a0bc..cc00948 100644
--- a/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/core/builder/IBuildState.java
+++ b/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/core/builder/IBuildState.java
@@ -21,6 +21,10 @@
* Eventually it will be used to collect dependencies between project sources.
*/
public interface IBuildState {
+
+ static int STRUCTURAL = 1;
+ static int CONTENT = 2;
+
/**
* @param path
*/
@@ -35,6 +39,15 @@
void recordDependency(IPath path, IPath dependency);
/**
+ *
+ * @param path
+ * @param dependency
+ * @param flags
+ * @since 4.0
+ */
+ void recordDependency(IPath path, IPath dependency, int flags);
+
+ /**
* Records the structural change at the specified path
*
* @param path
diff --git a/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/AbstractBuildState.java b/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/AbstractBuildState.java
index ff6d3ea..a957496 100644
--- a/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/AbstractBuildState.java
+++ b/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/AbstractBuildState.java
@@ -41,4 +41,8 @@
public void resetStructuralChanges() {
structuralChanges.clear();
}
+
+ public final void recordDependency(IPath path, IPath dependency) {
+ recordDependency(path, dependency, STRUCTURAL);
+ }
}
diff --git a/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/BuildStateStub.java b/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/BuildStateStub.java
index 28b09c7..728906e 100644
--- a/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/BuildStateStub.java
+++ b/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/BuildStateStub.java
@@ -21,6 +21,6 @@
public void recordImportProblem(IPath path) {
}
- public void recordDependency(IPath path, IPath dependency) {
+ public void recordDependency(IPath path, IPath dependency, int flags) {
}
}
diff --git a/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/ScriptBuilder.java b/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/ScriptBuilder.java
index fed3fca..7022ff0 100644
--- a/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/ScriptBuilder.java
+++ b/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/ScriptBuilder.java
@@ -28,6 +28,7 @@
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -109,44 +110,46 @@
log("\nStarting build of " + this.currentProject.getName() //$NON-NLS-1$
+ " @ " + new Date(startTime)); //$NON-NLS-1$
}
- this.scriptProject = (ScriptProject) DLTKCore.create(currentProject);
- if (!ScriptProjectUtil.isBuilderEnabled(scriptProject)) {
- if (monitor != null) {
- monitor.done();
- }
- return null;
- }
- IEnvironment environment = EnvironmentManager
- .getEnvironment(scriptProject);
- if (environment == null || !environment.isConnected()) {
- // Do not build if environment is not available.
- // TODO: Store build requests and call builds when connection will
- // be established.
- if (monitor != null) {
- monitor.done();
- }
- return null;
- }
- final String version = currentProject
- .getPersistentProperty(PROPERTY_BUILDER_VERSION);
- if (version == null) {
- removeWrongTaskMarkers();
- currentProject.setPersistentProperty(PROPERTY_BUILDER_VERSION,
- CURRENT_VERSION);
- kind = FULL_BUILD;
- } else if (!CURRENT_VERSION.equals(version)) {
- if ("200810012003".equals(version)) { //$NON-NLS-1$
- removeWrongTaskMarkers();
- }
- currentProject.setPersistentProperty(PROPERTY_BUILDER_VERSION,
- CURRENT_VERSION);
- kind = FULL_BUILD;
- }
- if (monitor == null) {
- monitor = new NullProgressMonitor();
- }
- IProject[] requiredProjects = getRequiredProjects(true);
+ IProject[] requiredProjects = null;
try {
+ this.scriptProject = (ScriptProject) DLTKCore
+ .create(currentProject);
+ if (!ScriptProjectUtil.isBuilderEnabled(scriptProject)) {
+ if (monitor != null) {
+ monitor.done();
+ }
+ return null;
+ }
+ IEnvironment environment = EnvironmentManager
+ .getEnvironment(scriptProject);
+ if (environment == null || !environment.isConnected()) {
+ // Do not build if environment is not available.
+ // TODO: Store build requests and call builds when connection
+ // will
+ // be established.
+ if (monitor != null) {
+ monitor.done();
+ }
+ return null;
+ }
+ final String version = currentProject
+ .getPersistentProperty(PROPERTY_BUILDER_VERSION);
+ if (version == null) {
+ removeWrongTaskMarkers();
+ currentProject.setPersistentProperty(PROPERTY_BUILDER_VERSION,
+ CURRENT_VERSION);
+ kind = FULL_BUILD;
+ } else if (!CURRENT_VERSION.equals(version)) {
+ if ("200810012003".equals(version)) { //$NON-NLS-1$
+ removeWrongTaskMarkers();
+ }
+ currentProject.setPersistentProperty(PROPERTY_BUILDER_VERSION,
+ CURRENT_VERSION);
+ kind = FULL_BUILD;
+ }
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
if (kind == FULL_BUILD) {
if (DEBUG)
log("Performing full build as requested by user"); //$NON-NLS-1$
@@ -169,38 +172,47 @@
} else {
if (DEBUG)
log("Performing incremental build"); //$NON-NLS-1$
+ requiredProjects = getRequiredProjects(true);
incrementalBuild(delta, requiredProjects, monitor);
}
}
}
} catch (OperationCanceledException e) {
// TODO what?
+ } finally {
+ cleanup();
}
- long endTime = 0;
if (DEBUG || TRACE) {
- endTime = System.currentTimeMillis();
- }
- if (DEBUG) {
- log("Finished build of " + currentProject.getName() //$NON-NLS-1$
- + " @ " + new Date(endTime) + ", elapsed " + (endTime - startTime) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
- if (TRACE) {
- System.out
- .println("-----SCRIPT-BUILDER-INFORMATION-TRACE----------------------------"); //$NON-NLS-1$
- System.out.println("Finished build of project:" //$NON-NLS-1$
- + currentProject.getName() + "\n" //$NON-NLS-1$
- + "Building time:" //$NON-NLS-1$
- + Long.toString(endTime - startTime) + "\n" //$NON-NLS-1$
- + "Build type:" //$NON-NLS-1$
- + (kind == FULL_BUILD ? "Full build" //$NON-NLS-1$
- : "Incremental build")); //$NON-NLS-1$
- System.out
- .println("-----------------------------------------------------------------"); //$NON-NLS-1$
+ final long endTime = System.currentTimeMillis();
+ if (DEBUG) {
+ log("Finished build of " + currentProject.getName() //$NON-NLS-1$
+ + " @ " + new Date(endTime) + ", elapsed " + (endTime - startTime) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ if (TRACE) {
+ System.out
+ .println("-----SCRIPT-BUILDER-INFORMATION-TRACE----------------------------"); //$NON-NLS-1$
+ System.out.println("Finished build of project:" //$NON-NLS-1$
+ + currentProject.getName() + "\n" //$NON-NLS-1$
+ + "Building time:" //$NON-NLS-1$
+ + Long.toString(endTime - startTime) + "\n" //$NON-NLS-1$
+ + "Build type:" //$NON-NLS-1$
+ + (kind == FULL_BUILD ? "Full build" //$NON-NLS-1$
+ : "Incremental build")); //$NON-NLS-1$
+ System.out
+ .println("-----------------------------------------------------------------"); //$NON-NLS-1$
+ }
}
monitor.done();
+ if (requiredProjects == null) {
+ requiredProjects = getRequiredProjects(true);
+ }
return requiredProjects;
}
+ private void cleanup() {
+ lastState = null;
+ }
+
private static boolean isProjectConfigChange(IResourceDelta projectDelta) {
final String[] filenames = {
IScriptProjectFilenames.BUILDPATH_FILENAME,
@@ -260,17 +272,21 @@
}
}
- private class BuildState extends AbstractBuildState {
- public BuildState(String projectName) {
- super(projectName);
+ private static class BuildState extends AbstractBuildState {
+ final State state;
+
+ public BuildState(State state) {
+ super(state.scriptProjectName);
+ this.state = state;
}
public void recordImportProblem(IPath path) {
- ScriptBuilder.this.lastState.recordImportProblem(path);
+ this.state.recordImportProblem(path);
}
- public void recordDependency(IPath path, IPath dependency) {
- ScriptBuilder.this.lastState.recordDependency(path, dependency);
+ public void recordDependency(IPath path, IPath dependency, int flags) {
+ Assert.isTrue(flags != 0);
+ this.state.recordDependency(path, dependency, flags);
}
}
@@ -404,8 +420,8 @@
protected static final String NONAME = ""; //$NON-NLS-1$
protected void fullBuild(final IProgressMonitor monitor) {
- this.lastState = clearLastState();
- final IBuildState buildState = new BuildState(currentProject.getName());
+ final State newState = clearLastState();
+ final IBuildState buildState = new BuildState(newState);
IScriptBuilder[] builders = null;
try {
monitor.setTaskName(NLS.bind(
@@ -440,14 +456,15 @@
}
}
saveBuilderVersions(builders);
- updateExternalFolderLocations(buildChange);
+ updateExternalFolderLocations(newState, buildChange);
} catch (CoreException e) {
DLTKCore.error(e);
} finally {
resetBuilders(builders, buildState, monitor);
ModelManager.getModelManager().setLastBuiltState(currentProject,
- this.lastState);
+ newState);
monitor.done();
+ this.lastState = null;
}
}
@@ -477,19 +494,12 @@
protected void incrementalBuild(IResourceDelta delta,
IProject[] requiredProjects, IProgressMonitor monitor)
throws CoreException {
- State newState = new State(this);
+ final State newState = new State(this);
+ newState.copyFrom(this.lastState);
+ final Set<IPath> externalFoldersBefore = new HashSet<IPath>(
+ newState.getExternalFolders());
- final Set<IPath> externalFoldersBefore;
- if (this.lastState != null) {
- newState.copyFrom(this.lastState);
- externalFoldersBefore = new HashSet<IPath>(
- newState.getExternalFolders());
- } else {
- externalFoldersBefore = new HashSet<IPath>();
- }
-
- this.lastState = newState;
- final BuildState buildState = new BuildState(currentProject.getName());
+ final BuildState buildState = new BuildState(newState);
IScriptBuilder[] builders = null;
try {
monitor.setTaskName(NLS.bind(
@@ -504,7 +514,7 @@
IBuildChange buildChange = null;
if (isBuilderVersionChange(builders)) {
buildChange = new FullBuildChange(currentProject, monitor);
- this.lastState.resetDependencies();
+ newState.resetDependencies();
}
if (buildChange == null) {
buildChange = createBuildChange(delta, requiredProjects,
@@ -517,35 +527,21 @@
builder.prepare(buildChange, buildState, monitor);
if (buildChange.getBuildType() == IScriptBuilder.FULL_BUILD
&& buildChange instanceof IncrementalBuildChange) {
+ if (TRACE) {
+ System.out.println("Full build requested by "
+ + builder.getClass().getName());
+ }
buildChange = new FullBuildChange(currentProject, monitor);
- this.lastState.resetDependencies();
+ newState.resetDependencies();
}
}
- final Set<IPath> processed = new HashSet<IPath>();
- final Set<IPath> queue = new HashSet<IPath>();
if (buildChange instanceof IncrementalBuildChange) {
final Set<IPath> changes = ((IncrementalBuildChange) buildChange)
.getChangedPaths();
if (TRACE) {
System.out.println(" Changes: " + changes);
}
- queue.addAll(this.lastState.dependenciesOf(changes, true));
- for (IProjectChange projectChange : buildChange
- .getRequiredProjectChanges()) {
- Collection<IPath> projectChanges = ((IncrementalProjectChange) projectChange)
- .getChangedPaths();
- final State projectState = getLastState(
- projectChange.getProject(), monitor);
- if (projectState != null) {
- projectChanges = projectState
- .allDependenciesOf(projectChanges);
- }
- queue.addAll(this.lastState.dependenciesOf(projectChanges,
- false));
- }
- this.lastState.removeDependenciesFor(changes);
- processed.addAll(changes);
- queue.removeAll(processed);
+ newState.removeDependenciesFor(changes);
}
for (IScriptBuilder builder : builders) {
if (monitor.isCanceled()) {
@@ -561,52 +557,79 @@
}
}
}
- while (!buildState.getStructuralChanges().isEmpty()
- && !queue.isEmpty()) {
- if (TRACE) {
- System.out.println(" Queue: " + queue);
+ newState.recordStructuralChanges(buildState.getStructuralChanges());
+ if (buildChange instanceof IncrementalBuildChange) {
+ final Set<IPath> processed = new HashSet<IPath>();
+ final Set<IPath> changes = ((IncrementalBuildChange) buildChange)
+ .getChangedPaths();
+ processed.addAll(changes);
+ final Set<IPath> queue = new HashSet<IPath>();
+ // TODO review cross-project dependency handling
+ for (IProjectChange projectChange : buildChange
+ .getRequiredProjectChanges()) {
+ final Collection<IPath> projectChanges = ((IncrementalProjectChange) projectChange)
+ .getChangedPaths();
+ final State projectState = getLastState(
+ projectChange.getProject(), monitor);
+ if (projectState != null) {
+ projectChanges.addAll(projectState
+ .getAllStructuralDependencies(projectChanges));
+ }
+ queue.addAll(this.lastState.dependenciesOf(projectChanges,
+ buildState.getStructuralChanges(), false));
}
- final Set<IPath> nextQueue = new HashSet<IPath>();
- nextQueue.addAll(this.lastState.dependenciesOf(queue, false));
- this.lastState.removeDependenciesFor(queue);
final IWorkspaceRoot root = ResourcesPlugin.getWorkspace()
.getRoot();
- final List<IFile> files = new ArrayList<IFile>();
- for (IPath path : queue) {
- files.add(root.getFile(path));
- }
- buildState.resetStructuralChanges();
- final DependencyBuildChange qChange = new DependencyBuildChange(
- currentProject, delta, files, monitor);
- for (IScriptBuilder builder : builders) {
- if (monitor.isCanceled()) {
- throw new OperationCanceledException();
+ for (;;) {
+ queue.addAll(this.lastState.dependenciesOf(changes,
+ buildState.getStructuralChanges(), true));
+ queue.removeAll(processed);
+ if (queue.isEmpty()) {
+ break;
}
- final long start = TRACE ? System.currentTimeMillis() : 0;
- builder.build(qChange, buildState, monitor);
if (TRACE) {
- final long elapsed = System.currentTimeMillis() - start;
- if (elapsed > TRACE_BUILDER_MIN_ELAPSED_TIME) {
- System.out.println(builder.getClass().getName()
- + " " + elapsed + "ms");
+ System.out.println(" Queue: " + queue);
+ }
+ newState.removeDependenciesFor(queue);
+ final List<IFile> files = new ArrayList<IFile>();
+ for (IPath path : queue) {
+ files.add(root.getFile(path));
+ }
+ buildState.resetStructuralChanges();
+ final DependencyBuildChange qChange = new DependencyBuildChange(
+ currentProject, delta, files, monitor);
+ for (IScriptBuilder builder : builders) {
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ final long start = TRACE ? System.currentTimeMillis()
+ : 0;
+ builder.build(qChange, buildState, monitor);
+ if (TRACE) {
+ final long elapsed = System.currentTimeMillis()
+ - start;
+ if (elapsed > TRACE_BUILDER_MIN_ELAPSED_TIME) {
+ System.out.println(builder.getClass().getName()
+ + " " + elapsed + "ms");
+ }
}
}
+ changes.clear();
+ changes.addAll(queue);
+ processed.addAll(queue);
+ queue.clear();
}
- processed.addAll(queue);
- nextQueue.removeAll(processed);
- queue.clear();
- // TODO prevent cycles
- queue.addAll(nextQueue);
}
saveBuilderVersions(builders);
- updateExternalFolderLocations(buildChange);
+ updateExternalFolderLocations(newState, buildChange);
} catch (CoreException e) {
DLTKCore.error(e);
} finally {
resetBuilders(builders, buildState, monitor);
ModelManager.getModelManager().setLastBuiltState(currentProject,
- this.lastState);
+ newState);
monitor.done();
+ this.lastState = null;
}
}
@@ -661,10 +684,10 @@
externalFoldersBefore));
}
- private void updateExternalFolderLocations(IBuildChange buildChange)
- throws CoreException {
- this.lastState.externalFolderLocations.clear();
- this.lastState.externalFolderLocations.addAll(buildChange
+ private static void updateExternalFolderLocations(State state,
+ IBuildChange buildChange) throws CoreException {
+ state.externalFolderLocations.clear();
+ state.externalFolderLocations.addAll(buildChange
.getExternalPaths(IProjectChange.DEFAULT));
}
diff --git a/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/State.java b/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/State.java
index 7c0936f..05ff66d 100644
--- a/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/State.java
+++ b/core/plugins/org.eclipse.dltk.core/model/org/eclipse/dltk/internal/core/builder/State.java
@@ -14,6 +14,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -27,6 +28,7 @@
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.dltk.compiler.util.SimpleLookupTable;
+import org.eclipse.dltk.core.builder.IBuildState;
public class State {
// NOTE: this state cannot contain types that are not defined in this
@@ -37,21 +39,42 @@
int buildNumber;
long lastStructuralBuildTime;
SimpleLookupTable structuralBuildTimes;
+ Set<IPath> structuralChanges;
/**
- * 0x16 boolean noCleanExternalFolders is always present
+ * <ul>
+ * <li>0x16 boolean noCleanExternalFolders is always present
+ * <li>0x17 dependencies
+ * <li>0x18 dependencies + flags
+ * </ul>
**/
- public static final byte VERSION = 0x0017;
+ public static final byte VERSION = 0x0018;
Set<IPath> externalFolderLocations = new HashSet<IPath>();
boolean noCleanExternalFolders = false;
+ static class DependencyInfo {
+ int flags;
+
+ public DependencyInfo() {
+ }
+
+ public DependencyInfo(DependencyInfo source) {
+ this.flags = source.flags;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(flags);
+ }
+ }
+
/**
* Full (absolute,including project) path to the set of paths, depending on
* it.
*/
- private final Map<IPath, Set<IPath>> dependencies = new HashMap<IPath, Set<IPath>>();
+ private final Map<IPath, Map<IPath, DependencyInfo>> dependencies = new HashMap<IPath, Map<IPath, DependencyInfo>>();
private final Set<IPath> importProblems = new HashSet<IPath>();
@@ -86,6 +109,7 @@
this.buildNumber = lastState.buildNumber + 1;
this.lastStructuralBuildTime = lastState.lastStructuralBuildTime;
this.structuralBuildTimes = lastState.structuralBuildTimes;
+ this.structuralChanges = null;
this.externalFolderLocations.clear();
this.externalFolderLocations.addAll(lastState.externalFolderLocations);
@@ -100,6 +124,14 @@
return this.externalFolderLocations;
}
+ void recordStructuralChanges(Set<IPath> changes) {
+ if (changes != null && !changes.isEmpty()) {
+ this.structuralChanges = new HashSet<IPath>(changes);
+ } else {
+ this.structuralChanges = null;
+ }
+ }
+
static State read(IProject project, DataInputStream in) throws IOException {
if (ScriptBuilder.DEBUG)
System.out.println("About to read state " + project.getName()); //$NON-NLS-1$
@@ -132,9 +164,10 @@
final int dependencyCount = in.readInt();
newState.dependencies.clear();
for (int i = 0; i < dependencyCount; ++i) {
- final Set<IPath> paths = new HashSet<IPath>();
- newState.dependencies.put(Path.fromOSString(in.readUTF()), paths);
- readPaths(in, paths);
+ final Map<IPath, DependencyInfo> paths = new HashMap<IPath, DependencyInfo>();
+ newState.dependencies.put(Path.fromPortableString(in.readUTF()),
+ paths);
+ readDependencyPaths(in, paths);
}
newState.importProblems.clear();
readPaths(in, newState.importProblems);
@@ -186,9 +219,10 @@
}
out.writeBoolean(this.noCleanExternalFolders);
out.writeInt(dependencies.size());
- for (Map.Entry<IPath, Set<IPath>> entry : dependencies.entrySet()) {
+ for (Map.Entry<IPath, Map<IPath, DependencyInfo>> entry : dependencies
+ .entrySet()) {
out.writeUTF(entry.getKey().toPortableString());
- writePaths(out, entry.getValue());
+ writeDependencyPaths(out, entry.getValue());
}
writePaths(out, importProblems);
}
@@ -209,6 +243,26 @@
}
}
+ private static void readDependencyPaths(DataInputStream in,
+ Map<IPath, DependencyInfo> paths) throws IOException {
+ final int pathCount = in.readInt();
+ for (int j = 0; j < pathCount; ++j) {
+ final IPath path = Path.fromPortableString(in.readUTF());
+ final DependencyInfo depInfo = new DependencyInfo();
+ depInfo.flags = in.readInt();
+ paths.put(path, depInfo);
+ }
+ }
+
+ private void writeDependencyPaths(DataOutputStream out,
+ Map<IPath, DependencyInfo> paths) throws IOException {
+ out.writeInt(paths.size());
+ for (Map.Entry<IPath, DependencyInfo> entry : paths.entrySet()) {
+ out.writeUTF(entry.getKey().toPortableString());
+ out.writeInt(entry.getValue().flags);
+ }
+ }
+
/**
* Returns a string representation of the receiver.
*/
@@ -232,15 +286,20 @@
importProblems.add(path);
}
- protected void recordDependency(IPath path, IPath dependency) {
+ protected void recordDependency(IPath path, IPath dependency, int flags) {
Assert.isLegal(scriptProjectName.equals(path.segment(0)));
Assert.isLegal(!path.equals(dependency));
- Set<IPath> paths = dependencies.get(dependency);
+ Map<IPath, DependencyInfo> paths = dependencies.get(dependency);
if (paths == null) {
- paths = new HashSet<IPath>();
+ paths = new HashMap<IPath, DependencyInfo>();
dependencies.put(dependency, paths);
}
- paths.add(path);
+ DependencyInfo depInfo = paths.get(path);
+ if (depInfo == null) {
+ depInfo = new DependencyInfo();
+ paths.put(path, depInfo);
+ }
+ depInfo.flags |= flags;
}
protected void resetDependencies() {
@@ -249,46 +308,69 @@
}
protected void removeDependenciesFor(Set<IPath> paths) {
- for (Iterator<Map.Entry<IPath, Set<IPath>>> i = dependencies.entrySet()
- .iterator(); i.hasNext();) {
- final Map.Entry<IPath, Set<IPath>> entry = i.next();
- if (entry.getValue().removeAll(paths) && entry.getValue().isEmpty()) {
+ for (Iterator<Map.Entry<IPath, Map<IPath, DependencyInfo>>> i = dependencies
+ .entrySet().iterator(); i.hasNext();) {
+ final Map.Entry<IPath, Map<IPath, DependencyInfo>> entry = i.next();
+ if (entry.getValue().keySet().removeAll(paths)
+ && entry.getValue().isEmpty()) {
i.remove();
}
}
importProblems.removeAll(paths);
}
- protected Collection<IPath> dependenciesOf(Collection<IPath> paths,
- boolean includeImportProblems) {
- final Collection<IPath> result = new ArrayList<IPath>();
+ protected Set<IPath> dependenciesOf(Collection<IPath> paths,
+ Set<IPath> structuralChanges, boolean includeImportProblems) {
+ final Set<IPath> result = new HashSet<IPath>();
if (includeImportProblems) {
- result.addAll(importProblems);
+ for (IPath path : importProblems) {
+ result.add(path);
+ }
}
for (IPath path : paths) {
- final Set<IPath> deps = dependencies.get(path);
+ final boolean structuralChange = structuralChanges.contains(path);
+ final Map<IPath, DependencyInfo> deps = dependencies.get(path);
if (deps != null) {
- result.addAll(deps);
+ for (Map.Entry<IPath, DependencyInfo> entry : deps.entrySet()) {
+ if (structuralChange
+ || ((entry.getValue().flags & IBuildState.CONTENT) != 0)) {
+ result.add(entry.getKey());
+ }
+ }
}
}
return result;
}
- protected Collection<IPath> allDependenciesOf(Collection<IPath> paths) {
- final Collection<IPath> result = new HashSet<IPath>();
- final List<IPath> queue = new ArrayList<IPath>();
- while (!paths.isEmpty()) {
- result.addAll(paths);
- for (IPath path : paths) {
- final Set<IPath> deps = dependencies.get(path);
+ protected Collection<IPath> getAllStructuralDependencies(
+ Collection<IPath> paths) {
+ if (structuralChanges == null) {
+ return Collections.emptyList();
+ }
+ final Set<IPath> result = new HashSet<IPath>();
+ result.addAll(paths);
+ result.retainAll(structuralChanges);
+ if (result.isEmpty()) {
+ return Collections.emptyList();
+ }
+ final List<IPath> queue = new ArrayList<IPath>(result);
+ while (!queue.isEmpty()) {
+ final List<IPath> nextQueue = new ArrayList<IPath>();
+ for (IPath path : queue) {
+ final Map<IPath, DependencyInfo> deps = dependencies.get(path);
if (deps != null) {
- queue.addAll(deps);
+ for (Map.Entry<IPath, DependencyInfo> entry : deps
+ .entrySet()) {
+ if (!result.contains(entry.getKey())
+ && ((entry.getValue().flags & IBuildState.STRUCTURAL) != 0)) {
+ nextQueue.add(entry.getKey());
+ }
+ }
}
}
- queue.removeAll(result);
- paths.clear();
- paths.addAll(queue);
+ result.addAll(nextQueue);
queue.clear();
+ queue.addAll(nextQueue);
}
return result;
}