private void handleCanceled(Throwable t) { // If the cancelation happens due to an external interruption, don't pass an // OperationCanceledException on to the BuildManager as it would force a full // build in the next round. Instead, save the resource deltas to be reprocessed // next time. // @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=454716 if (!isInterrupted()) operationCanceledManager.propagateIfCancelException(t); buildLogger.log("Build interrupted."); queuedBuildData.rollback(); doRememberLastBuiltState(); }
/** * @param monitor the progress monitor to use for reporting progress to the user. It is the * caller's responsibility to call done() on the given monitor. Accepts null, indicating that * no progress should be reported and that the operation cannot be cancelled. */ protected void doBuild(ToBeBuilt toBeBuilt, IProgressMonitor monitor, BuildType type) throws CoreException { buildLogger.log("Building " + getProject().getName()); // return early if there's nothing to do. // we reuse the isEmpty() impl from BuildData assuming that it doesnT access the ResourceSet // which is still null // and would be expensive to create. boolean indexingOnly = type == BuildType.RECOVERY; if (new BuildData(getProject().getName(), null, toBeBuilt, queuedBuildData, indexingOnly) .isEmpty()) return; SubMonitor progress = SubMonitor.convert(monitor, 2); ResourceSet resourceSet = getResourceSetProvider().get(getProject()); resourceSet .getLoadOptions() .put(ResourceDescriptionsProvider.NAMED_BUILDER_SCOPE, Boolean.TRUE); BuildData buildData = new BuildData( getProject().getName(), resourceSet, toBeBuilt, queuedBuildData, indexingOnly); ImmutableList<Delta> deltas = builderState.update(buildData, progress.newChild(1)); if (participant != null && !indexingOnly) { SourceLevelURICache sourceLevelURIs = buildData.getSourceLevelURICache(); Set<URI> sources = sourceLevelURIs.getSources(); participant.build( new BuildContext(this, resourceSet, deltas, sources, type), progress.newChild(1)); try { getProject().getWorkspace().checkpoint(false); } catch ( NoClassDefFoundError e) { // guard against broken Eclipse installations / bogus project configuration log.error(e.getMessage(), e); } } else { progress.worked(1); } resourceSet.eSetDeliver(false); resourceSet.getResources().clear(); resourceSet.eAdapters().clear(); }
@SuppressWarnings("rawtypes") @Override protected IProject[] build(final int kind, Map args, IProgressMonitor monitor) throws CoreException { if (IBuildFlag.FORGET_BUILD_STATE_ONLY.isSet(args)) { forgetLastBuiltState(); return getProject().getReferencedProjects(); } Job.getJobManager().addJobChangeListener(MAKE_EGIT_JOB_SYSTEM); long startTime = System.currentTimeMillis(); StoppedTask task = Stopwatches.forTask(String.format("XtextBuilder.build[%s]", getKindAsString(kind))); try { queuedBuildData.createCheckpoint(); if (shouldCancelBuild(kind)) { throw new OperationCanceledException("Build has been interrupted"); } task.start(); if (monitor != null) { final String taskName = Messages.XtextBuilder_Building + getProject().getName() + ": "; // $NON-NLS-1$ monitor = new ProgressMonitorWrapper(monitor) { @Override public void subTask(String name) { super.subTask(taskName + name); } @Override public boolean isCanceled() { boolean shouldCancelBuild = shouldCancelBuild(kind); if (shouldCancelBuild) buildLogger.log("interrupted"); return shouldCancelBuild || super.isCanceled(); } }; } SubMonitor progress = SubMonitor.convert(monitor, 1); if (kind == FULL_BUILD) { fullBuild(progress.newChild(1), IBuildFlag.RECOVERY_BUILD.isSet(args)); } else { IResourceDelta delta = getDelta(getProject()); if (delta == null || isOpened(delta)) { fullBuild(progress.newChild(1), IBuildFlag.RECOVERY_BUILD.isSet(args)); } else { incrementalBuild(delta, progress.newChild(1)); } } } catch (CoreException e) { log.error(e.getMessage(), e); throw e; } catch (OperationCanceledException e) { handleCanceled(e); } catch (OperationCanceledError err) { handleCanceled(err); } catch (Exception e) { log.error(e.getMessage(), e); buildLogger.log( e.getClass().getSimpleName() + " while building " + getProject().getName() + ": " + e.getMessage() + " (see logs for details)"); forgetLastBuiltState(); } finally { queuedBuildData.discardCheckpoint(); if (monitor != null) monitor.done(); String message = "Build " + getProject().getName() + " in " + (System.currentTimeMillis() - startTime) + " ms"; log.info(message); buildLogger.log(message); task.stop(); Job.getJobManager().removeJobChangeListener(MAKE_EGIT_JOB_SYSTEM); } return getProject().getReferencedProjects(); }