@Override public void build(final IBuildContext context, IProgressMonitor monitor) throws CoreException { if (!isEnabled(context)) { return; } final List<IResourceDescription.Delta> deltas = getRelevantDeltas(context); if (deltas.isEmpty()) { return; } StoppedTask task = Stopwatches.forTask( "org.eclipse.xtext.builder.BuilderParticipant.build(IBuildContext, IProgressMonitor)"); try { task.start(); // monitor handling if (monitor.isCanceled()) throw new OperationCanceledException(); SubMonitor subMonitor = SubMonitor.convert(monitor, context.getBuildType() == BuildType.RECOVERY ? 5 : 3); EclipseResourceFileSystemAccess2 access = fileSystemAccessProvider.get(); IProject builtProject = context.getBuiltProject(); access.setProject(builtProject); Map<String, OutputConfiguration> outputConfigurations = getOutputConfigurations(context); refreshOutputFolders(context, outputConfigurations, subMonitor.newChild(1)); if (subMonitor.isCanceled()) { throw new OperationCanceledException(); } access.setOutputConfigurations(outputConfigurations); if (context.getBuildType() == BuildType.CLEAN || context.getBuildType() == BuildType.RECOVERY) { SubMonitor cleanMonitor = SubMonitor.convert(subMonitor.newChild(2), outputConfigurations.size()); for (OutputConfiguration config : outputConfigurations.values()) { cleanOutput(context, config, access, cleanMonitor.newChild(1)); } if (context.getBuildType() == BuildType.CLEAN) return; } Map<OutputConfiguration, Iterable<IMarker>> generatorMarkers = getGeneratorMarkers(builtProject, outputConfigurations.values()); if (subMonitor.isCanceled()) { throw new OperationCanceledException(); } doBuild( deltas, outputConfigurations, generatorMarkers, context, access, subMonitor.newChild(2)); } finally { task.stop(); } }
/** @since 2.7 */ protected void doBuild( List<IResourceDescription.Delta> deltas, Map<String, OutputConfiguration> outputConfigurations, Map<OutputConfiguration, Iterable<IMarker>> generatorMarkers, IBuildContext context, EclipseResourceFileSystemAccess2 access, IProgressMonitor progressMonitor) throws CoreException { final int numberOfDeltas = deltas.size(); SubMonitor subMonitor = SubMonitor.convert(progressMonitor, numberOfDeltas / MONITOR_CHUNK_SIZE + 1); SubMonitor currentMonitor = null; int clusterIndex = 0; for (int i = 0; i < numberOfDeltas; i++) { IResourceDescription.Delta delta = deltas.get(i); if (subMonitor.isCanceled()) { throw new OperationCanceledException(); } if (i % 10 == 0) { subMonitor.subTask( "Compiling chunk " + (i / MONITOR_CHUNK_SIZE + 1) + " of " + (numberOfDeltas / MONITOR_CHUNK_SIZE + 1)); currentMonitor = subMonitor.newChild(1); access.setMonitor(currentMonitor); } if (logger.isDebugEnabled()) { logger.debug("Compiling " + delta.getUri() + " (" + i + " of " + numberOfDeltas + ")"); } if (delta.getNew() != null && !clusteringPolicy.continueProcessing( context.getResourceSet(), delta.getUri(), clusterIndex)) { clearResourceSet(context.getResourceSet()); clusterIndex = 0; } Set<IFile> derivedResources = getDerivedResources(delta, outputConfigurations, generatorMarkers); access.setPostProcessor(getPostProcessor(delta, context, derivedResources)); if (doGenerate(delta, context, access)) { clusterIndex++; access.flushSourceTraces(); } cleanDerivedResources(delta, derivedResources, context, access, currentMonitor); } }
protected Map<String, OutputConfiguration> getOutputConfigurations(IBuildContext context) { Set<OutputConfiguration> configurations = outputConfigurationProvider.getOutputConfigurations(context.getBuiltProject()); return uniqueIndex( configurations, new Function<OutputConfiguration, String>() { @Override public String apply(OutputConfiguration from) { return from.getName(); } }); }
/** @since 2.3 */ protected List<IResourceDescription.Delta> getRelevantDeltas(IBuildContext context) { List<IResourceDescription.Delta> result = newArrayList(); for (IResourceDescription.Delta delta : context.getDeltas()) { if (resourceServiceProvider.canHandle(delta.getUri()) && (resourceServiceProvider instanceof IResourceServiceProviderExtension) && !((IResourceServiceProviderExtension) resourceServiceProvider) .isReadOnly(delta.getUri())) { result.add(delta); } } return result; }
protected boolean shouldGenerate(Resource resource, IBuildContext context) { try { Iterable<Pair<IStorage, IProject>> storages = storage2UriMapper.getStorages(resource.getURI()); for (Pair<IStorage, IProject> pair : storages) { if (pair.getFirst() instanceof IFile && pair.getSecond().equals(context.getBuiltProject())) { IFile file = (IFile) pair.getFirst(); return file.findMaxProblemSeverity(null, true, IResource.DEPTH_INFINITE) != IMarker.SEVERITY_ERROR; } } return false; } catch (CoreException exc) { throw new WrappedException(exc); } }
protected void refreshOutputFolders( IBuildContext ctx, Map<String, OutputConfiguration> outputConfigurations, IProgressMonitor monitor) throws CoreException { SubMonitor subMonitor = SubMonitor.convert(monitor, outputConfigurations.size()); for (OutputConfiguration config : outputConfigurations.values()) { SubMonitor child = subMonitor.newChild(1); final IProject project = ctx.getBuiltProject(); for (IContainer container : getOutputs(project, config)) { if (monitor.isCanceled()) { throw new OperationCanceledException(); } container.refreshLocal(IResource.DEPTH_INFINITE, child); } } }
protected void handleChangedContents( Delta delta, IBuildContext context, EclipseResourceFileSystemAccess2 fileSystemAccess) throws CoreException { // TODO: we will run out of memory here if the number of deltas is large enough Resource resource = context.getResourceSet().getResource(delta.getUri(), true); saveResourceStorage(resource, fileSystemAccess); if (shouldGenerate(resource, context)) { try { registerCurrentSourceFolder(context, delta, fileSystemAccess); generator.doGenerate(resource, fileSystemAccess); } catch (RuntimeException e) { if (e.getCause() instanceof CoreException) { throw (CoreException) e.getCause(); } throw e; } } }
/** @since 2.7 */ protected void cleanDerivedResources( Delta delta, Set<IFile> derivedResources, IBuildContext context, EclipseResourceFileSystemAccess2 access, IProgressMonitor deleteMonitor) throws CoreException { String uri = delta.getUri().toString(); for (IFile iFile : newLinkedHashSet(derivedResources)) { if (deleteMonitor.isCanceled()) { throw new OperationCanceledException(); } IMarker marker = derivedResourceMarkers.findDerivedResourceMarker(iFile, uri); if (marker != null) marker.delete(); if (derivedResourceMarkers.findDerivedResourceMarkers(iFile).length == 0) { access.deleteFile(iFile, deleteMonitor); context.needRebuild(); } } }
/** @since 2.5 */ protected void cleanOutput( IBuildContext ctx, OutputConfiguration config, EclipseResourceFileSystemAccess2 access, IProgressMonitor monitor) throws CoreException { final IProject project = ctx.getBuiltProject(); for (IContainer container : getOutputs(project, config)) { if (!container.exists()) { return; } if (config.isCanClearOutputDirectory()) { for (IResource resource : container.members()) { if (!config.isKeepLocalHistory()) { resource.delete(IResource.NONE, monitor); } else if (access == null) { resource.delete(IResource.KEEP_HISTORY, monitor); } else { delete(resource, config, access, monitor); } } } else if (config.isCleanUpDerivedResources()) { List<IFile> resources = derivedResourceMarkers.findDerivedResources(container, null); for (IFile iFile : resources) { if (monitor.isCanceled()) { throw new OperationCanceledException(); } if (access != null) { access.deleteFile(iFile, config.getName(), monitor); } else { iFile.delete( config.isKeepLocalHistory() ? IResource.KEEP_HISTORY : IResource.NONE, monitor); } } } } }
protected boolean isEnabled(final IBuildContext context) { return builderPreferenceAccess.isAutoBuildEnabled(context.getBuiltProject()); }