/** @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())) result.add(delta); } return result; }
/** @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; }
/** @since 2.7 */ protected boolean doGenerate( IResourceDescription.Delta delta, IBuildContext context, IFileSystemAccess access) { if (delta.getNew() != null) { try { handleChangedContents(delta, context, access); } catch (OperationCanceledException e) { throw e; } catch (Exception e) { addMarkerAndLogError(delta.getUri(), e); } return true; } return false; }
/** @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); } }
@Override public boolean isAffected( Collection<Delta> deltas, IResourceDescription candidate, IResourceDescriptions context) { Set<URI> outgoingReferences = descriptionUtils.collectOutgoingReferences(candidate); if (!outgoingReferences.isEmpty()) { for (IResourceDescription.Delta delta : deltas) if (hasChanges(delta, candidate) && outgoingReferences.contains(delta.getUri())) return true; } // this is a tradeoff - we could either check whether a given delta uri is contained // in a reachable container and check for intersecting names afterwards, or we can do // the other way round // unfortunately there is no way to decide reliably which algorithm scales better // note that this method is called for each description so we have something like a // number of deltas x number of resources which is not really nice List<IContainer> containers = null; Collection<QualifiedName> importedNames = getImportedNames(candidate); for (IResourceDescription.Delta delta : deltas) { if (hasChanges(delta, candidate)) { // not a java resource - delta's resource should be contained in a visible container // as long as we did not delete the resource URI uri = delta.getUri(); if ((uri.isPlatform() || uri.isArchive()) && delta.getNew() != null) { if (containers == null) containers = containerManager.getVisibleContainers(candidate, context); boolean descriptionIsContained = false; for (int i = 0; i < containers.size() && !descriptionIsContained; i++) { descriptionIsContained = containers.get(i).hasResourceDescription(uri); } if (!descriptionIsContained) return false; } if (isAffected(importedNames, delta.getNew()) || isAffected(importedNames, delta.getOld())) { return true; } } } return false; }
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; } final int numberOfDeltas = deltas.size(); // monitor handling if (monitor.isCanceled()) throw new OperationCanceledException(); SubMonitor subMonitor = SubMonitor.convert(monitor, numberOfDeltas + 3); EclipseResourceFileSystemAccess2 access = fileSystemAccessProvider.get(); final IProject builtProject = context.getBuiltProject(); access.setProject(builtProject); final Map<String, OutputConfiguration> outputConfigurations = getOutputConfigurations(context); refreshOutputFolders(context, outputConfigurations, subMonitor.newChild(1)); access.setOutputConfigurations(outputConfigurations); if (context.getBuildType() == BuildType.CLEAN || context.getBuildType() == BuildType.RECOVERY) { SubMonitor cleanMonitor = SubMonitor.convert(subMonitor.newChild(1), outputConfigurations.size()); for (OutputConfiguration config : outputConfigurations.values()) { cleanOutput(context, config, cleanMonitor.newChild(1)); } if (context.getBuildType() == BuildType.CLEAN) return; } Map<OutputConfiguration, Iterable<IMarker>> generatorMarkers = newHashMap(); for (OutputConfiguration config : outputConfigurations.values()) { if (config.isCleanUpDerivedResources()) { final IFolder outputFolder = builtProject.getFolder(config.getOutputDirectory()); final Iterable<IMarker> markers = derivedResourceMarkers.findDerivedResourceMarkers( outputFolder, generatorIdProvider.getGeneratorIdentifier()); generatorMarkers.put(config, markers); } } for (int i = 0; i < numberOfDeltas; i++) { final IResourceDescription.Delta delta = deltas.get(i); // monitor handling if (subMonitor.isCanceled()) throw new OperationCanceledException(); subMonitor.subTask( "Compiling " + delta.getUri().lastSegment() + " (" + i + " of " + numberOfDeltas + ")"); access.setMonitor(subMonitor.newChild(1)); final String uri = delta.getUri().toString(); final Set<IFile> derivedResources = newLinkedHashSet(); for (OutputConfiguration config : outputConfigurations.values()) { if (config.isCleanUpDerivedResources()) { Iterable<IMarker> markers = generatorMarkers.get(config); for (IMarker marker : markers) { String source = derivedResourceMarkers.getSource(marker); if (source != null && source.equals(uri)) derivedResources.add((IFile) marker.getResource()); } } } access.setPostProcessor( new EclipseResourceFileSystemAccess2.IFileCallback() { public boolean beforeFileDeletion(IFile file) { derivedResources.remove(file); context.needRebuild(); return true; } public void afterFileUpdate(IFile file) { handleFileAccess(file); } public void afterFileCreation(IFile file) { handleFileAccess(file); } protected void handleFileAccess(IFile file) { try { derivedResources.remove(file); derivedResourceMarkers.installMarker(file, uri); context.needRebuild(); } catch (CoreException e) { throw new RuntimeException(e); } } }); if (delta.getNew() != null) { handleChangedContents(delta, context, access); } access.flushSourceTraces(); SubMonitor deleteMonitor = SubMonitor.convert(subMonitor.newChild(1), derivedResources.size()); for (IFile iFile : newLinkedHashSet(derivedResources)) { IMarker marker = derivedResourceMarkers.findDerivedResourceMarker(iFile, uri); if (marker != null) marker.delete(); if (derivedResourceMarkers.findDerivedResourceMarkers(iFile).length == 0) { access.deleteFile(iFile, deleteMonitor); context.needRebuild(); } } } }
/** * Whether the given delta is considered to have changed from the candidate's perspective. By * default this will just call {@link * org.eclipse.xtext.resource.IResourceDescription.Delta#haveEObjectDescriptionsChanged() * Delta#haveEObjectDescriptionsChanged()}. But in some cases even "internal" changes (that are * not visible in the EObjectDescriptions) could be interesting. * * @since 2.7 */ protected boolean hasChanges(IResourceDescription.Delta delta, IResourceDescription candidate) { return delta.haveEObjectDescriptionsChanged(); }