Search in sources :

Example 6 with Delta

use of org.eclipse.xtext.resource.IResourceDescription.Delta in project xtext-core by eclipse.

the class DefaultResourceDescriptionManager method isAffected.

@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);
    if (!importedNames.isEmpty()) {
        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 isAffectedByExtensions(deltas, candidate, context);
                    }
                }
                if (isAffected(importedNames, delta.getNew()) || isAffected(importedNames, delta.getOld())) {
                    return true;
                }
            }
        }
    }
    return isAffectedByExtensions(deltas, candidate, context);
}
Also used : IResourceDescription(org.eclipse.xtext.resource.IResourceDescription) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) QualifiedName(org.eclipse.xtext.naming.QualifiedName) IContainer(org.eclipse.xtext.resource.IContainer) URI(org.eclipse.emf.common.util.URI)

Example 7 with Delta

use of org.eclipse.xtext.resource.IResourceDescription.Delta in project xtext-eclipse by eclipse.

the class DirtyStateAwareResourceDescriptions method globalDescriptionsChanged.

public void globalDescriptionsChanged(IResourceDescription.Event event) {
    ResourceDescriptionChangeEvent changeEvent = new ResourceDescriptionChangeEvent(Iterables.filter(event.getDeltas(), new Predicate<IResourceDescription.Delta>() {

        @Override
        public boolean apply(Delta input) {
            URI uri = input.getUri();
            return !dirtyStateManager.hasContent(uri);
        }
    }));
    notifyListeners(changeEvent);
}
Also used : IResourceDescription(org.eclipse.xtext.resource.IResourceDescription) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) ChangedResourceDescriptionDelta(org.eclipse.xtext.resource.impl.ChangedResourceDescriptionDelta) URI(org.eclipse.emf.common.util.URI) ResourceDescriptionChangeEvent(org.eclipse.xtext.resource.impl.ResourceDescriptionChangeEvent) Predicate(com.google.common.base.Predicate)

Example 8 with Delta

use of org.eclipse.xtext.resource.IResourceDescription.Delta in project xtext-eclipse by eclipse.

the class ClusteringBuilderState method doUpdate.

/**
 * Actually do the build.
 *
 * @param buildData
 *            the data that should be considered for the update
 * @param newData
 *            the new resource descriptions as they are to be persisted (the new index after the build).
 *            Initially contains the old resource descriptions.
 * @param monitor
 *            The progress monitor
 * @return A list of deltas describing all changes made by the build.
 */
@Override
protected Collection<Delta> doUpdate(BuildData buildData, ResourceDescriptionsData newData, IProgressMonitor monitor) {
    // We assume that we have 101 ticks to work with:
    // 20 for writeNewResourceDescription
    // 1 for queueAffectedResources
    // 80 for updating and queueAffectedResources
    // Within the mentioned 80 ticks we assume that 2/3 is spent for updating and 1/3 for queueAffectedResources
    final SubMonitor progress = SubMonitor.convert(monitor, 101);
    // Step 1: Clean the set of deleted URIs. If any of them are also added, they're not deleted.
    final Set<URI> toBeDeleted = buildData.getAndRemoveToBeDeleted();
    // Step 2: Create a new state (old state minus the deleted resources). This, by virtue of the flag
    // NAMED_BUILDER_SCOPE in the resource set's load options
    // and a Guice binding, is the index that is used during the build; i.e., linking during the build will
    // use this. Once the build is completed, the persistable index is reset to the contents of newState by
    // virtue of the newMap, which is maintained in synch with this.
    ResourceSet resourceSet = buildData.getResourceSet();
    final CurrentDescriptions newState = new CurrentDescriptions(resourceSet, newData, buildData);
    buildData.getSourceLevelURICache().cacheAsSourceURIs(toBeDeleted);
    installSourceLevelURIs(buildData);
    // Step 3: Create a queue; write new temporary resource descriptions for the added or updated resources so that we can link
    // subsequently; put all the added or updated resources into the queue.
    writeNewResourceDescriptions(buildData, this, newState, progress.split(20));
    if (progress.isCanceled()) {
        throw new OperationCanceledException();
    }
    // in this set as potential candidates.
    for (final URI uri : toBeDeleted) {
        newData.removeDescription(uri);
    }
    final Set<URI> allRemainingURIs = Sets.newLinkedHashSet(newData.getAllURIs());
    allRemainingURIs.removeAll(buildData.getToBeUpdated());
    for (URI remainingURI : buildData.getAllRemainingURIs()) {
        allRemainingURIs.remove(remainingURI);
    }
    // TODO: consider to remove any entry from upstream projects and independent projects
    // from the set of remaining uris (template method or service?)
    // this should reduce the number of to-be-checked descriptions significantly
    // for common setups (large number of reasonable sized projects)
    // Our return value. It contains all the deltas resulting from this build.
    final Set<Delta> allDeltas = Sets.newHashSet();
    // Step 5: Put all resources depending on a deleted resource into the queue. Also register the deltas in allDeltas.
    if (!toBeDeleted.isEmpty()) {
        for (final URI uri : toBeDeleted) {
            final IResourceDescription oldDescription = this.getResourceDescription(uri);
            if (oldDescription != null) {
                allDeltas.add(new DefaultResourceDescriptionDelta(oldDescription, null));
            }
        }
    }
    // Add all pending deltas to all deltas (may be scheduled java deltas)
    Collection<Delta> pendingDeltas = buildData.getAndRemovePendingDeltas();
    allDeltas.addAll(pendingDeltas);
    queueAffectedResources(allRemainingURIs, this, newState, allDeltas, allDeltas, buildData, progress.split(1));
    installSourceLevelURIs(buildData);
    IProject currentProject = getBuiltProject(buildData);
    LoadOperation loadOperation = null;
    try {
        Queue<URI> queue = buildData.getURIQueue();
        loadOperation = crossLinkingResourceLoader.create(resourceSet, currentProject);
        loadOperation.load(queue);
        // Step 6: Iteratively got through the queue. For each resource, create a new resource description and queue all depending
        // resources that are not yet in the delta. Validate resources.
        final SubMonitor subProgress = progress.split(80);
        CancelIndicator cancelMonitor = new MonitorBasedCancelIndicator(progress);
        while (!queue.isEmpty()) {
            // heuristic: we multiply the size of the queue by 3 and spent 2 ticks for updating
            // and 1 tick for queueAffectedResources since we assume that loading etc. is
            // slower than queueAffectedResources.
            subProgress.setWorkRemaining((queue.size() + 1) * 3);
            int clusterIndex = 0;
            final List<Delta> changedDeltas = Lists.newArrayList();
            while (!queue.isEmpty()) {
                if (subProgress.isCanceled()) {
                    loadOperation.cancel();
                    throw new OperationCanceledException();
                }
                if (!clusteringPolicy.continueProcessing(resourceSet, null, clusterIndex)) {
                    break;
                }
                URI changedURI = null;
                URI actualResourceURI = null;
                Resource resource = null;
                Delta newDelta = null;
                try {
                    // Load the resource and create a new resource description
                    LoadResult loadResult = loadOperation.next();
                    changedURI = loadResult.getUri();
                    actualResourceURI = loadResult.getResource().getURI();
                    resource = addResource(loadResult.getResource(), resourceSet);
                    subProgress.subTask("Updating resource " + resource.getURI().lastSegment());
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("Update resource description " + actualResourceURI);
                    }
                    queue.remove(changedURI);
                    if (toBeDeleted.contains(changedURI)) {
                        break;
                    }
                    buildLogger.log("indexing " + changedURI);
                    final IResourceDescription.Manager manager = getResourceDescriptionManager(actualResourceURI);
                    if (manager != null) {
                        // Resolve links here!
                        try {
                            EcoreUtil2.resolveLazyCrossReferences(resource, cancelMonitor);
                            final IResourceDescription description = manager.getResourceDescription(resource);
                            final IResourceDescription copiedDescription = BuilderStateUtil.create(description);
                            newDelta = manager.createDelta(this.getResourceDescription(actualResourceURI), copiedDescription);
                        } catch (OperationCanceledException e) {
                            loadOperation.cancel();
                            throw e;
                        } catch (WrappedException e) {
                            throw e;
                        } catch (RuntimeException e) {
                            LOGGER.error("Error resolving cross references on resource '" + actualResourceURI + "'", e);
                            throw new LoadOperationException(actualResourceURI, e);
                        }
                    }
                } catch (final WrappedException ex) {
                    if (ex instanceof LoadOperationException) {
                        changedURI = ((LoadOperationException) ex).getUri();
                    }
                    Throwable cause = ex.getCause();
                    boolean wasResourceNotFound = false;
                    if (cause instanceof CoreException) {
                        if (IResourceStatus.RESOURCE_NOT_FOUND == ((CoreException) cause).getStatus().getCode()) {
                            wasResourceNotFound = true;
                        }
                    }
                    if (changedURI == null) {
                        // $NON-NLS-1$
                        LOGGER.error("Error loading resource", ex);
                    } else {
                        queue.remove(changedURI);
                        if (toBeDeleted.contains(changedURI))
                            break;
                        if (!wasResourceNotFound)
                            // $NON-NLS-1$
                            LOGGER.error("Error loading resource from: " + changedURI.toString(), ex);
                        if (resource != null) {
                            resourceSet.getResources().remove(resource);
                        }
                        final IResourceDescription oldDescription = this.getResourceDescription(changedURI);
                        final IResourceDescription newDesc = newState.getResourceDescription(changedURI);
                        ResourceDescriptionImpl indexReadyDescription = newDesc != null ? BuilderStateUtil.create(newDesc) : null;
                        if ((oldDescription != null || indexReadyDescription != null) && oldDescription != indexReadyDescription) {
                            newDelta = new DefaultResourceDescriptionDelta(oldDescription, indexReadyDescription);
                        }
                    }
                }
                if (newDelta != null) {
                    allDeltas.add(newDelta);
                    clusterIndex++;
                    if (newDelta.haveEObjectDescriptionsChanged())
                        changedDeltas.add(newDelta);
                    // Make the new resource description known and update the map.
                    newState.register(newDelta);
                    // Validate now.
                    if (!buildData.isIndexingOnly()) {
                        try {
                            updateMarkers(newDelta, resourceSet, subProgress);
                        } catch (OperationCanceledException e) {
                            loadOperation.cancel();
                            throw e;
                        } catch (Exception e) {
                            LOGGER.error("Error validating " + newDelta.getUri(), e);
                        }
                    }
                }
                // 2 ticks for updating since updating makes 2/3 of the work
                subProgress.split(2);
            }
            loadOperation.cancel();
            queueAffectedResources(allRemainingURIs, this, newState, changedDeltas, allDeltas, buildData, subProgress.split(1));
            installSourceLevelURIs(buildData);
            if (queue.size() > 0) {
                loadOperation = crossLinkingResourceLoader.create(resourceSet, currentProject);
                loadOperation.load(queue);
            }
            // Release memory
            if (!queue.isEmpty() && !clusteringPolicy.continueProcessing(resourceSet, null, clusterIndex))
                clearResourceSet(resourceSet);
        }
    } finally {
        if (loadOperation != null)
            loadOperation.cancel();
        if (!progress.isCanceled())
            progress.done();
    }
    return allDeltas;
}
Also used : IResourceDescription(org.eclipse.xtext.resource.IResourceDescription) ResourceDescriptionImpl(org.eclipse.xtext.builder.builderState.impl.ResourceDescriptionImpl) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) URI(org.eclipse.emf.common.util.URI) MonitorBasedCancelIndicator(org.eclipse.xtext.builder.MonitorBasedCancelIndicator) LoadOperation(org.eclipse.xtext.builder.resourceloader.IResourceLoader.LoadOperation) DefaultResourceDescriptionDelta(org.eclipse.xtext.resource.impl.DefaultResourceDescriptionDelta) WrappedException(org.eclipse.emf.common.util.WrappedException) SubMonitor(org.eclipse.core.runtime.SubMonitor) Resource(org.eclipse.emf.ecore.resource.Resource) StorageAwareResource(org.eclipse.xtext.resource.persistence.StorageAwareResource) ResourceSet(org.eclipse.emf.ecore.resource.ResourceSet) IProject(org.eclipse.core.resources.IProject) LoadResult(org.eclipse.xtext.builder.resourceloader.IResourceLoader.LoadResult) CoreException(org.eclipse.core.runtime.CoreException) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) LoadOperationException(org.eclipse.xtext.builder.resourceloader.IResourceLoader.LoadOperationException) WrappedException(org.eclipse.emf.common.util.WrappedException) LoadOperationException(org.eclipse.xtext.builder.resourceloader.IResourceLoader.LoadOperationException) CoreException(org.eclipse.core.runtime.CoreException) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) DefaultResourceDescriptionDelta(org.eclipse.xtext.resource.impl.DefaultResourceDescriptionDelta) MonitorBasedCancelIndicator(org.eclipse.xtext.builder.MonitorBasedCancelIndicator) CancelIndicator(org.eclipse.xtext.util.CancelIndicator)

Example 9 with Delta

use of org.eclipse.xtext.resource.IResourceDescription.Delta in project xtext-eclipse by eclipse.

the class ParallelBuilderParticipant method doBuild.

@Override
protected void doBuild(List<Delta> deltas, Map<String, OutputConfiguration> outputConfigurations, Map<OutputConfiguration, Iterable<IMarker>> generatorMarkers, IBuildContext context, EclipseResourceFileSystemAccess2 access, IProgressMonitor progressMonitor) throws CoreException {
    BlockingQueue<FileSystemAccessRequest> requestQueue = newBlockingQueue(QUEUE_CAPACITY);
    // This queue is only used from the current thread
    // thus there is no need for a blocking queue. The add operation should also not block the
    // builder thread
    Queue<ParallelBuildContext> afterGenerateQueue = new ArrayDeque<ParallelBuildContext>(QUEUE_CAPACITY);
    FileSystemAccessQueue fileSystemAccessQueue = new FileSystemAccessQueue(requestQueue, progressMonitor);
    Tripwire tripwire = new Tripwire();
    EList<Adapter> adapters = context.getResourceSet().eAdapters();
    EObservableAdapterList observableAdapters = (EObservableAdapterList) adapters;
    adapters.add(fileSystemAccessQueue);
    observableAdapters.addListener(tripwire);
    try {
        SubMonitor subMonitor = SubMonitor.convert(progressMonitor, 1);
        subMonitor.subTask("Compiling...");
        access.setMonitor(subMonitor.split(1));
        List<ListenableFuture<?>> tasks = Lists.newArrayList();
        ListeningExecutorService executor = executors.getExecutor();
        for (IResourceDescription.Delta delta : deltas) {
            if (getResourceServiceProvider().canHandle(delta.getUri())) {
                try {
                    ParallelBuildContext parallelBuildContext = new ParallelBuildContext(delta, context, outputConfigurations, generatorMarkers, fileSystemAccessQueue, afterGenerateQueue, access, progressMonitor);
                    Runnable runnable = createRunnable(parallelBuildContext);
                    tasks.add(executor.submit(runnable));
                } catch (Exception e) {
                    addMarkerAndLogError(delta.getUri(), e);
                }
            }
        }
        ListenableFuture<List<Object>> generatorResult = Futures.successfulAsList(tasks);
        List<SimpleEntry<URI, Throwable>> exceptions = Lists.newArrayList();
        boolean interrupted = false;
        try {
            /*
				 * it is important to check generatorResult and requestQueue second
				 * as it can happen that if you use !requestQueue.isEmpty() || !generatorResult.isDone()
				 * that the generatorResult.isDone() becomes true after requestQueue.isEmpty() was checked
				 * and thus requestQueue.isEmpty() changes back to false
				 * but we stop the while loop anyway and thus miss generated files.
				 */
            while (!generatorResult.isDone() || !requestQueue.isEmpty()) {
                if (subMonitor.isCanceled()) {
                    cancelProcessing(requestQueue, afterGenerateQueue, generatorResult);
                    throw new OperationCanceledException();
                }
                FileSystemAccessRequest request = null;
                try {
                    request = requestQueue.poll(QUEUE_POLL_TIMEOUT, TimeUnit.MILLISECONDS);
                } catch (InterruptedException e) {
                    interrupted = true;
                }
                if (request != null) {
                    try {
                        request.run();
                    } catch (OperationCanceledException e) {
                        cancelProcessing(requestQueue, afterGenerateQueue, generatorResult);
                        throw e;
                    } catch (Exception e) {
                        Throwable cause = e;
                        if (cause instanceof CoreException) {
                            cause = cause.getCause();
                        }
                        exceptions.add(new SimpleEntry<URI, Throwable>(request.getUri(), cause));
                    }
                }
            }
        } finally {
            if (interrupted) {
                Thread.currentThread().interrupt();
            }
            for (SimpleEntry<URI, Throwable> exception : exceptions) {
                addMarkerAndLogError(exception.getKey(), exception.getValue());
            }
        }
    } finally {
        observableAdapters.removeListener(tripwire);
        adapters.remove(fileSystemAccessQueue);
    }
}
Also used : IResourceDescription(org.eclipse.xtext.resource.IResourceDescription) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) Adapter(org.eclipse.emf.common.notify.Adapter) FileSystemAccessQueue(org.eclipse.xtext.generator.FileSystemAccessQueue) URI(org.eclipse.emf.common.util.URI) FileSystemAccessRequest(org.eclipse.xtext.generator.FileSystemAccessRequest) EObservableAdapterList(org.eclipse.emf.common.notify.impl.BasicNotifierImpl.EObservableAdapterList) EList(org.eclipse.emf.common.util.EList) List(java.util.List) EObservableAdapterList(org.eclipse.emf.common.notify.impl.BasicNotifierImpl.EObservableAdapterList) SimpleEntry(java.util.AbstractMap.SimpleEntry) SubMonitor(org.eclipse.core.runtime.SubMonitor) ArrayDeque(java.util.ArrayDeque) CoreException(org.eclipse.core.runtime.CoreException) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) CoreException(org.eclipse.core.runtime.CoreException) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService)

Example 10 with Delta

use of org.eclipse.xtext.resource.IResourceDescription.Delta in project xtext-eclipse by eclipse.

the class XtextBuilder method doClean.

/**
 * @param toBeBuilt the collected URIs that should be handled by this clean operation.
 * @param removedProjects additional projects that were available but do no longer have the Xtext nature or have been deleted
 *
 * @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 doClean(ToBeBuilt toBeBuilt, Set<String> removedProjects, IProgressMonitor monitor) throws CoreException {
    SubMonitor progress = SubMonitor.convert(monitor, 2);
    SetWithProjectNames toBeDeletedAndProjects = new SetWithProjectNames(toBeBuilt.getToBeDeleted(), getProject().getName(), removedProjects);
    ImmutableList<Delta> deltas = builderState.clean(toBeDeletedAndProjects, progress.split(1));
    if (participant != null) {
        Set<URI> sourceURIs = new SourceLevelURICache().getSourcesFrom(toBeBuilt.getToBeDeleted(), resourceServiceProvideRegistry);
        participant.build(new BuildContext(this, getResourceSetProvider().get(getProject()), deltas, sourceURIs, BuildType.CLEAN), progress.split(1));
    } else {
        progress.worked(1);
    }
}
Also used : IResourceDelta(org.eclipse.core.resources.IResourceDelta) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) SubMonitor(org.eclipse.core.runtime.SubMonitor) URI(org.eclipse.emf.common.util.URI)

Aggregations

Delta (org.eclipse.xtext.resource.IResourceDescription.Delta)38 URI (org.eclipse.emf.common.util.URI)22 IResourceDescription (org.eclipse.xtext.resource.IResourceDescription)17 SubMonitor (org.eclipse.core.runtime.SubMonitor)13 DefaultResourceDescriptionDelta (org.eclipse.xtext.resource.impl.DefaultResourceDescriptionDelta)10 OperationCanceledException (org.eclipse.core.runtime.OperationCanceledException)8 Resource (org.eclipse.emf.ecore.resource.Resource)8 ResourceSet (org.eclipse.emf.ecore.resource.ResourceSet)7 IFile (org.eclipse.core.resources.IFile)5 IProject (org.eclipse.core.resources.IProject)5 IResourceDelta (org.eclipse.core.resources.IResourceDelta)5 WrappedException (org.eclipse.emf.common.util.WrappedException)4 IJavaProject (org.eclipse.jdt.core.IJavaProject)4 QualifiedName (org.eclipse.xtext.naming.QualifiedName)4 ArrayList (java.util.ArrayList)3 List (java.util.List)3 CoreException (org.eclipse.core.runtime.CoreException)3 IClasspathEntry (org.eclipse.jdt.core.IClasspathEntry)3 LoadOperationException (org.eclipse.xtext.builder.resourceloader.IResourceLoader.LoadOperationException)3 IContainer (org.eclipse.xtext.resource.IContainer)3