Lines 13-18
Link Here
|
13 |
*******************************************************************************/ |
13 |
*******************************************************************************/ |
14 |
package org.eclipse.core.internal.events; |
14 |
package org.eclipse.core.internal.events; |
15 |
|
15 |
|
|
|
16 |
import org.eclipse.core.resources.IncrementalProjectBuilder; |
17 |
|
16 |
import java.util.*; |
18 |
import java.util.*; |
17 |
import org.eclipse.core.internal.dtree.DeltaDataTree; |
19 |
import org.eclipse.core.internal.dtree.DeltaDataTree; |
18 |
import org.eclipse.core.internal.resources.*; |
20 |
import org.eclipse.core.internal.resources.*; |
Lines 132-150
Link Here
|
132 |
|
134 |
|
133 |
private void basicBuild(int trigger, IncrementalProjectBuilder builder, Map args, MultiStatus status, IProgressMonitor monitor) { |
135 |
private void basicBuild(int trigger, IncrementalProjectBuilder builder, Map args, MultiStatus status, IProgressMonitor monitor) { |
134 |
try { |
136 |
try { |
135 |
currentBuilder = builder; |
137 |
InternalBuilder currentBuilder2 = builder; |
136 |
//clear any old requests to forget built state |
138 |
//clear any old requests to forget built state |
137 |
currentBuilder.clearForgetLastBuiltState(); |
139 |
currentBuilder2.clearForgetLastBuiltState(); |
138 |
// Figure out want kind of build is needed |
140 |
// Figure out want kind of build is needed |
139 |
boolean clean = trigger == IncrementalProjectBuilder.CLEAN_BUILD; |
141 |
boolean clean = trigger == IncrementalProjectBuilder.CLEAN_BUILD; |
140 |
currentLastBuiltTree = currentBuilder.getLastBuiltTree(); |
142 |
currentLastBuiltTree = currentBuilder2.getLastBuiltTree(); |
141 |
// If no tree is available we have to do a full build |
143 |
// If no tree is available we have to do a full build |
142 |
if (!clean && currentLastBuiltTree == null) |
144 |
if (!clean && currentLastBuiltTree == null) |
143 |
trigger = IncrementalProjectBuilder.FULL_BUILD; |
145 |
trigger = IncrementalProjectBuilder.FULL_BUILD; |
144 |
//don't build if this builder doesn't respond to the given trigger |
146 |
//don't build if this builder doesn't respond to the given trigger |
145 |
if (!builder.getCommand().isBuilding(trigger)) { |
147 |
if (!builder.getCommand().isBuilding(trigger)) { |
146 |
if (clean) |
148 |
if (clean) |
147 |
currentBuilder.setLastBuiltTree(null); |
149 |
currentBuilder2.setLastBuiltTree(null); |
148 |
return; |
150 |
return; |
149 |
} |
151 |
} |
150 |
// For incremental builds, grab a pointer to the current state before computing the delta |
152 |
// For incremental builds, grab a pointer to the current state before computing the delta |
Lines 152-164
Link Here
|
152 |
int depth = -1; |
154 |
int depth = -1; |
153 |
try { |
155 |
try { |
154 |
//short-circuit if none of the projects this builder cares about have changed. |
156 |
//short-circuit if none of the projects this builder cares about have changed. |
155 |
if (!needsBuild(currentBuilder, trigger)) { |
157 |
if (!needsBuild(currentBuilder2, trigger)) { |
156 |
//use up the progress allocated for this builder |
158 |
//use up the progress allocated for this builder |
157 |
monitor.beginTask("", 1); //$NON-NLS-1$ |
159 |
monitor.beginTask("", 1); //$NON-NLS-1$ |
158 |
monitor.done(); |
160 |
monitor.done(); |
159 |
return; |
161 |
return; |
160 |
} |
162 |
} |
161 |
String name = currentBuilder.getLabel(); |
163 |
String name = currentBuilder2.getLabel(); |
162 |
String message; |
164 |
String message; |
163 |
if (name != null) |
165 |
if (name != null) |
164 |
message = NLS.bind(Messages.events_invoking_2, name, builder.getProject().getFullPath()); |
166 |
message = NLS.bind(Messages.events_invoking_2, name, builder.getProject().getFullPath()); |
Lines 169-191
Link Here
|
169 |
//release workspace lock while calling builders |
171 |
//release workspace lock while calling builders |
170 |
depth = getWorkManager().beginUnprotected(); |
172 |
depth = getWorkManager().beginUnprotected(); |
171 |
//do the build |
173 |
//do the build |
172 |
SafeRunner.run(getSafeRunnable(trigger, args, status, monitor)); |
174 |
SafeRunner.run(getSafeRunnable(trigger, args, status, monitor, currentBuilder2)); |
173 |
} finally { |
175 |
} finally { |
174 |
if (depth >= 0) |
176 |
if (depth >= 0) |
175 |
getWorkManager().endUnprotected(depth); |
177 |
getWorkManager().endUnprotected(depth); |
176 |
// Be sure to clean up after ourselves. |
178 |
// Be sure to clean up after ourselves. |
177 |
if (clean || currentBuilder.wasForgetStateRequested()) { |
179 |
if (clean || currentBuilder2.wasForgetStateRequested()) { |
178 |
currentBuilder.setLastBuiltTree(null); |
180 |
currentBuilder2.setLastBuiltTree(null); |
179 |
} else { |
181 |
} else { |
180 |
// remember the current state as the last built state. |
182 |
// remember the current state as the last built state. |
181 |
ElementTree lastTree = workspace.getElementTree(); |
183 |
ElementTree lastTree = workspace.getElementTree(); |
182 |
lastTree.immutable(); |
184 |
lastTree.immutable(); |
183 |
currentBuilder.setLastBuiltTree(lastTree); |
185 |
currentBuilder2.setLastBuiltTree(lastTree); |
184 |
} |
186 |
} |
185 |
hookEndBuild(builder); |
187 |
hookEndBuild(builder); |
186 |
} |
188 |
} |
187 |
} finally { |
189 |
} finally { |
188 |
currentBuilder = null; |
190 |
// currentBuilder = null; |
189 |
currentTree = null; |
191 |
currentTree = null; |
190 |
currentLastBuiltTree = null; |
192 |
currentLastBuiltTree = null; |
191 |
currentDelta = null; |
193 |
currentDelta = null; |
Lines 198-204
Link Here
|
198 |
checkCanceled(trigger, monitor); |
200 |
checkCanceled(trigger, monitor); |
199 |
BuildCommand command = (BuildCommand) commands[i]; |
201 |
BuildCommand command = (BuildCommand) commands[i]; |
200 |
IProgressMonitor sub = Policy.subMonitorFor(monitor, 1); |
202 |
IProgressMonitor sub = Policy.subMonitorFor(monitor, 1); |
201 |
IncrementalProjectBuilder builder = getBuilder(project, command, i, status); |
203 |
IncrementalProjectBuilder builder; |
|
|
204 |
if(IncrementalProjectBuilder.PARALLEL_FULL_BUILD == trigger) { |
205 |
builder = getParallelBuilder(project, command, i, status); |
206 |
} else { |
207 |
builder = getBuilder(project, command, i, status); |
208 |
} |
202 |
if (builder != null) |
209 |
if (builder != null) |
203 |
basicBuild(trigger, builder, command.getArguments(false), status, sub); |
210 |
basicBuild(trigger, builder, command.getArguments(false), status, sub); |
204 |
} |
211 |
} |
Lines 207-212
Link Here
|
207 |
} |
214 |
} |
208 |
} |
215 |
} |
209 |
|
216 |
|
|
|
217 |
private IncrementalProjectBuilder getParallelBuilder(IProject project, BuildCommand command, int buildSpecIndex, MultiStatus status) throws CoreException { |
218 |
// always construct a new builder for parallel builds (think about pooling here) |
219 |
InternalBuilder result = initializeBuilder(command.getBuilderName(), project, buildSpecIndex, status); |
220 |
((BuildCommand) command).setBuilder((IncrementalProjectBuilder) result); |
221 |
result.setCommand(command); |
222 |
result.setProject(project); |
223 |
result.startupOnInitialize(); |
224 |
// } |
225 |
if (!validateNature(result, command.getBuilderName())) { |
226 |
//skip this builder and null its last built tree because it is invalid |
227 |
//if the nature gets added or re-enabled a full build will be triggered |
228 |
result.setLastBuiltTree(null); |
229 |
return null; |
230 |
} |
231 |
return (IncrementalProjectBuilder) result; |
232 |
} |
233 |
|
210 |
/** |
234 |
/** |
211 |
* Runs all builders on the given project. |
235 |
* Runs all builders on the given project. |
212 |
* @return A status indicating if the build succeeded or failed |
236 |
* @return A status indicating if the build succeeded or failed |
Lines 327-333
Link Here
|
327 |
* Runs all builders on all projects. |
351 |
* Runs all builders on all projects. |
328 |
* @return A status indicating if the build succeeded or failed |
352 |
* @return A status indicating if the build succeeded or failed |
329 |
*/ |
353 |
*/ |
330 |
public IStatus build(int trigger, IProgressMonitor monitor) { |
354 |
public IStatus build(final int trigger, IProgressMonitor monitor) { |
331 |
monitor = Policy.monitorFor(monitor); |
355 |
monitor = Policy.monitorFor(monitor); |
332 |
try { |
356 |
try { |
333 |
monitor.beginTask(Messages.events_building_0, TOTAL_BUILD_WORK); |
357 |
monitor.beginTask(Messages.events_building_0, TOTAL_BUILD_WORK); |
Lines 335-346
Link Here
|
335 |
return Status.OK_STATUS; |
359 |
return Status.OK_STATUS; |
336 |
try { |
360 |
try { |
337 |
hookStartBuild(trigger); |
361 |
hookStartBuild(trigger); |
338 |
IProject[] ordered = workspace.getBuildOrder(); |
362 |
final MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.BUILD_FAILED, Messages.events_errors, null); |
339 |
HashSet leftover = new HashSet(Arrays.asList(workspace.getRoot().getProjects(IContainer.INCLUDE_HIDDEN))); |
363 |
IProject[] ordered = workspace.getBuildOrder(); |
340 |
leftover.removeAll(Arrays.asList(ordered)); |
364 |
HashSet leftover = new HashSet(Arrays.asList(workspace.getRoot().getProjects(IContainer.INCLUDE_HIDDEN))); |
341 |
IProject[] unordered = (IProject[]) leftover.toArray(new IProject[leftover.size()]); |
365 |
leftover.removeAll(Arrays.asList(ordered)); |
342 |
MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.BUILD_FAILED, Messages.events_errors, null); |
366 |
IProject[] unordered = (IProject[]) leftover.toArray(new IProject[leftover.size()]); |
343 |
basicBuildLoop(ordered, unordered, trigger, status, monitor); |
367 |
basicBuildLoop(ordered, unordered, trigger, status, monitor); |
344 |
return status; |
368 |
return status; |
345 |
} finally { |
369 |
} finally { |
346 |
hookEndBuild(trigger); |
370 |
hookEndBuild(trigger); |
Lines 455-461
Link Here
|
455 |
* The outermost workspace operation has finished. Do an autobuild if necessary. |
479 |
* The outermost workspace operation has finished. Do an autobuild if necessary. |
456 |
*/ |
480 |
*/ |
457 |
public void endTopLevel(boolean needsBuild) { |
481 |
public void endTopLevel(boolean needsBuild) { |
458 |
autoBuildJob.build(needsBuild); |
482 |
// autoBuildJob.build(needsBuild); |
459 |
} |
483 |
} |
460 |
|
484 |
|
461 |
/** |
485 |
/** |
Lines 594-601
Link Here
|
594 |
|
618 |
|
595 |
/** |
619 |
/** |
596 |
* Returns the safe runnable instance for invoking a builder |
620 |
* Returns the safe runnable instance for invoking a builder |
|
|
621 |
* @param currentBuilder2 |
597 |
*/ |
622 |
*/ |
598 |
private ISafeRunnable getSafeRunnable(final int trigger, final Map args, final MultiStatus status, final IProgressMonitor monitor) { |
623 |
private ISafeRunnable getSafeRunnable(final int trigger, final Map args, final MultiStatus status, final IProgressMonitor monitor, final InternalBuilder currentBuilder2) { |
599 |
return new ISafeRunnable() { |
624 |
return new ISafeRunnable() { |
600 |
public void handleException(Throwable e) { |
625 |
public void handleException(Throwable e) { |
601 |
if (e instanceof OperationCanceledException) { |
626 |
if (e instanceof OperationCanceledException) { |
Lines 603-620
Link Here
|
603 |
Policy.debug("Build canceled"); //$NON-NLS-1$ |
628 |
Policy.debug("Build canceled"); //$NON-NLS-1$ |
604 |
//just discard built state when a builder cancels, to ensure |
629 |
//just discard built state when a builder cancels, to ensure |
605 |
//that it is called again on the very next build. |
630 |
//that it is called again on the very next build. |
606 |
currentBuilder.forgetLastBuiltState(); |
631 |
currentBuilder2.forgetLastBuiltState(); |
607 |
throw (OperationCanceledException) e; |
632 |
throw (OperationCanceledException) e; |
608 |
} |
633 |
} |
609 |
//ResourceStats.buildException(e); |
634 |
//ResourceStats.buildException(e); |
610 |
// don't log the exception....it is already being logged in SafeRunner#run |
635 |
// don't log the exception....it is already being logged in SafeRunner#run |
611 |
|
636 |
|
612 |
//add a generic message to the MultiStatus |
637 |
//add a generic message to the MultiStatus |
613 |
String builderName = currentBuilder.getLabel(); |
638 |
String builderName = currentBuilder2.getLabel(); |
614 |
if (builderName == null || builderName.length() == 0) |
639 |
if (builderName == null || builderName.length() == 0) |
615 |
builderName = currentBuilder.getClass().getName(); |
640 |
builderName = currentBuilder2.getClass().getName(); |
616 |
String pluginId = currentBuilder.getPluginId(); |
641 |
String pluginId = currentBuilder2.getPluginId(); |
617 |
String message = NLS.bind(Messages.events_builderError, builderName, currentBuilder.getProject().getName()); |
642 |
String message = NLS.bind(Messages.events_builderError, builderName, currentBuilder2.getProject().getName()); |
618 |
status.add(new Status(IStatus.ERROR, pluginId, IResourceStatus.BUILD_FAILED, message, e)); |
643 |
status.add(new Status(IStatus.ERROR, pluginId, IResourceStatus.BUILD_FAILED, message, e)); |
619 |
|
644 |
|
620 |
//add the exception status to the MultiStatus |
645 |
//add the exception status to the MultiStatus |
Lines 626-637
Link Here
|
626 |
IProject[] prereqs = null; |
651 |
IProject[] prereqs = null; |
627 |
//invoke the appropriate build method depending on the trigger |
652 |
//invoke the appropriate build method depending on the trigger |
628 |
if (trigger != IncrementalProjectBuilder.CLEAN_BUILD) |
653 |
if (trigger != IncrementalProjectBuilder.CLEAN_BUILD) |
629 |
prereqs = currentBuilder.build(trigger, args, monitor); |
654 |
prereqs = currentBuilder2.build(trigger, args, monitor); |
630 |
else |
655 |
else |
631 |
currentBuilder.clean(monitor); |
656 |
currentBuilder2.clean(monitor); |
632 |
if (prereqs == null) |
657 |
if (prereqs == null) |
633 |
prereqs = new IProject[0]; |
658 |
prereqs = new IProject[0]; |
634 |
currentBuilder.setInterestingProjects((IProject[]) prereqs.clone()); |
659 |
currentBuilder2.setInterestingProjects((IProject[]) prereqs.clone()); |
635 |
} |
660 |
} |
636 |
}; |
661 |
}; |
637 |
} |
662 |
} |
Lines 1032-1035
Link Here
|
1032 |
Policy.log(status); |
1057 |
Policy.log(status); |
1033 |
return workspace.getRoot(); |
1058 |
return workspace.getRoot(); |
1034 |
} |
1059 |
} |
|
|
1060 |
|
1061 |
public void buildParallel(IProgressMonitor subMonitorFor) { |
1062 |
IProject[] projects = workspace.getRoot().getProjects(IContainer.INCLUDE_HIDDEN); |
1063 |
DirectedGraphs<IProject> directedGraphs = new DirectedGraphs<IProject>(); |
1064 |
for (IProject project : projects) { |
1065 |
directedGraphs.addNode(new Node<IProject>(project)); |
1066 |
} |
1067 |
for (IProject project : projects) { |
1068 |
if (!project.isAccessible()) |
1069 |
continue; |
1070 |
ProjectDescription desc = ((Project)project).internalGetDescription(); |
1071 |
if (desc == null) |
1072 |
continue; |
1073 |
IProject[] refs = desc.getAllReferences(false); |
1074 |
Node<IProject> node = directedGraphs.getNodeWithContent(project); |
1075 |
for (IProject referencedProject : refs) { |
1076 |
Node<IProject> node2 = directedGraphs.getNodeWithContent(referencedProject); |
1077 |
node2.addOutgoingEdge(node); |
1078 |
} |
1079 |
} |
1080 |
ThreadPoolBuilder threadPoolBuilder = new ThreadPoolBuilder(); |
1081 |
try { |
1082 |
final MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.BUILD_FAILED, Messages.events_errors, null); |
1083 |
IBuildExecutor<IProject> buildExecutor = new IBuildExecutor<IProject>() { |
1084 |
public void executeBuild(IProject project) { |
1085 |
NullProgressMonitor progressMonitor = new NullProgressMonitor(); |
1086 |
basicBuild(project, IncrementalProjectBuilder.PARALLEL_FULL_BUILD, status, progressMonitor); |
1087 |
}}; |
1088 |
threadPoolBuilder.run(directedGraphs, buildExecutor); |
1089 |
} catch (InterruptedException e) { |
1090 |
e.printStackTrace(); |
1091 |
} |
1092 |
} |
1035 |
} |
1093 |
} |