Search in sources :

Example 21 with Delta

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

the class MonitoredClusteringBuilderState method updateDeltas.

/**
 * Updates the markers on a collection of resource.
 *
 * @param deltas
 *          for the changed resources
 * @param resourceSet
 *          containing the resource
 * @param monitor
 *          to report progress
 */
protected void updateDeltas(final Collection<Delta> deltas, final ResourceSet resourceSet, final IProgressMonitor monitor) {
    SubMonitor progress = SubMonitor.convert(monitor, deltas.size() * 2);
    for (Delta delta : deltas) {
        checkForCancellation(monitor);
        updateMarkers(delta, resourceSet, progress.newChild(1));
        postProcess(delta, resourceSet, progress.newChild(1));
    }
}
Also used : Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) DefaultResourceDescriptionDelta(org.eclipse.xtext.resource.impl.DefaultResourceDescriptionDelta) SubMonitor(org.eclipse.core.runtime.SubMonitor)

Example 22 with Delta

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

the class MonitoredClusteringBuilderState method doUpdate.

/**
 * {@inheritDoc}
 */
@Override
protected // CHECKSTYLE:CHECK-OFF NestedTryDepth
Collection<Delta> doUpdate(final BuildData buildData, final ResourceDescriptionsData newData, final IProgressMonitor monitor) {
    // NOPMD
    final SubMonitor progress = SubMonitor.convert(monitor, 100);
    // Step 1: Clean the set of deleted URIs. If any of them are also added, they're not deleted.
    final Set<URI> toBeDeleted = Sets.newHashSet(buildData.getToBeDeleted());
    toBeDeleted.removeAll(buildData.getToBeUpdated());
    ResourceSet resourceSet = buildData.getResourceSet();
    // Step 2: Create a new state (old state minus the deleted resources). This, by virtue of the flag above
    // 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.
    final CurrentDescriptions2 newState = createCurrentDescriptions(resourceSet, newData);
    final Map<URI, IResourceDescription> oldDescriptions = saveOldDescriptions(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.
    // CHECKSTYLE:CONSTANTS-OFF
    writeNewResourceDescriptions(buildData, this, newState, newData, progress.newChild(20));
    // CHECKSTYLE:CONSTANTS-ON
    // clear resource set to wipe out derived state of phase 1 model inference and all corresponding references
    clearResourceSet(resourceSet);
    LOGGER.info(Messages.MonitoredClusteringBuilderState_PHASE_ONE_DONE);
    checkForCancellation(progress);
    // in this set as potential candidates. Make sure that notInDelta is a modifiable Set, not some immutable view.
    for (final URI uri : toBeDeleted) {
        checkForCancellation(monitor);
        newData.removeDescription(uri);
    }
    final Set<URI> allRemainingURIs = createCandidateSet(newData.getAllURIs());
    allRemainingURIs.removeAll(buildData.getToBeUpdated());
    for (URI remainingURI : buildData.getAllRemainingURIs()) {
        allRemainingURIs.remove(remainingURI);
    }
    flushChanges(newData);
    // 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()) {
        addDeletedURIsToDeltas(toBeDeleted, allDeltas, oldDescriptions);
        // Here, we have only the deltas for deleted resources in allDeltas. Make sure that all markers are removed.
        // Normally, resources in toBeDeleted will have their storage(s) deleted, so Eclipse will automatically
        // remove the markers. However, if the ToBeBuiltComputer adds resources to the tobeDeleted set that are not or
        // have not been physically removed, markers would otherwise remain even though the resource is no longer part
        // of the Xtext world (index). Since the introduction of IResourcePostProcessor, we also need to do this to give
        // the post-processor a chance to do whatever needs doing when a resource is removed.
        updateDeltas(allDeltas, resourceSet, progress.newChild(1));
    }
    // 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.newChild(1));
    IProject currentProject = getBuiltProject(buildData);
    IResourceLoader.LoadOperation loadOperation = null;
    final BuilderWatchdog watchdog = new BuilderWatchdog();
    try {
        traceSet.started(BuildLinkingEvent.class);
        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. Do this in chunks.
        final SubMonitor subProgress = progress.newChild(80);
        final CancelIndicator cancelMonitor = new CancelIndicator() {

            @Override
            public boolean isCanceled() {
                return subProgress.isCanceled();
            }
        };
        watchdog.start();
        int index = 1;
        while (!queue.isEmpty()) {
            // CHECKSTYLE:CONSTANTS-OFF
            subProgress.setWorkRemaining(queue.size() * 3);
            // CHECKSTYLE:CONSTANTS-ON
            final List<Delta> newDeltas = Lists.newArrayListWithExpectedSize(clusterSize);
            final List<Delta> changedDeltas = Lists.newArrayListWithExpectedSize(clusterSize);
            while (!queue.isEmpty() && loadingStrategy.mayProcessAnotherResource(resourceSet, newDeltas.size())) {
                if (subProgress.isCanceled() || !loadOperation.hasNext()) {
                    if (!loadOperation.hasNext()) {
                        LOGGER.warn(Messages.MonitoredClusteringBuilderState_NO_MORE_RESOURCES);
                    }
                    loadOperation.cancel();
                    throw new OperationCanceledException();
                }
                // Load the resource and create a new resource description
                URI changedURI = null;
                Resource resource = null;
                Delta newDelta = null;
                final long initialMemory = Runtime.getRuntime().freeMemory();
                final int initialResourceSetSize = resourceSet.getResources().size();
                final long initialTime = System.nanoTime();
                try {
                    // Load the resource and create a new resource description
                    resource = addResource(loadOperation.next().getResource(), resourceSet);
                    changedURI = resource.getURI();
                    traceSet.started(ResourceProcessingEvent.class, changedURI);
                    queue.remove(changedURI);
                    if (toBeDeleted.contains(changedURI)) {
                        break;
                    }
                    watchdog.reportWorkStarted(changedURI);
                    traceSet.started(ResourceLinkingEvent.class, changedURI);
                    final IResourceDescription.Manager manager = getResourceDescriptionManager(changedURI);
                    if (manager != null) {
                        final Object[] bindings = { Integer.valueOf(index), Integer.valueOf(index + queue.size()), URI.decode(resource.getURI().lastSegment()) };
                        subProgress.subTask(NLS.bind(Messages.MonitoredClusteringBuilderState_UPDATE_DESCRIPTIONS, bindings));
                        // Resolve links here!
                        try {
                            EcoreUtil2.resolveLazyCrossReferences(resource, cancelMonitor);
                            final IResourceDescription description = manager.getResourceDescription(resource);
                            final IResourceDescription copiedDescription = descriptionCopier.copy(description);
                            newDelta = manager.createDelta(getSavedResourceDescription(oldDescriptions, changedURI), copiedDescription);
                        } catch (StackOverflowError ex) {
                            queue.remove(changedURI);
                            logStackOverflowErrorStackTrace(ex, changedURI);
                        }
                    }
                // CHECKSTYLE:CHECK-OFF IllegalCatch - guard against ill behaved implementations
                } catch (final Exception ex) {
                    // CHECKSTYLE:CHECK-ON IllegalCatch
                    pollForCancellation(monitor);
                    if (ex instanceof LoadOperationException) {
                        // NOPMD
                        LoadOperationException loadException = (LoadOperationException) ex;
                        if (loadException.getCause() instanceof TimeoutException) {
                            // Load request timed out, URI of the resource is not available
                            String message = loadException.getCause().getMessage();
                            LOGGER.warn(message);
                        } else {
                            // Exception when loading resource, URI should be available
                            changedURI = ((LoadOperationException) ex).getUri();
                            LOGGER.error(NLS.bind(Messages.MonitoredClusteringBuilderState_CANNOT_LOAD_RESOURCE, changedURI), ex);
                        }
                    } else {
                        LOGGER.error(NLS.bind(Messages.MonitoredClusteringBuilderState_CANNOT_LOAD_RESOURCE, changedURI), ex);
                    }
                    if (changedURI != null) {
                        queue.remove(changedURI);
                    }
                    if (resource != null) {
                        resourceSet.getResources().remove(resource);
                    }
                    final IResourceDescription oldDescription = getSavedResourceDescription(oldDescriptions, changedURI);
                    if (oldDescription != null) {
                        newDelta = new DefaultResourceDescriptionDelta(oldDescription, null);
                    }
                } finally {
                    traceSet.ended(ResourceLinkingEvent.class);
                }
                if (newDelta != null) {
                    allDeltas.add(newDelta);
                    if (newDelta.haveEObjectDescriptionsChanged()) {
                        changedDeltas.add(newDelta);
                    }
                    if (recordDeltaAsNew(newDelta)) {
                        newDeltas.add(newDelta);
                        // Make the new resource description known in the new index.
                        newState.register(newDelta);
                    }
                    try {
                        // Validate directly, instead of bulk validating after the cluster.
                        updateMarkers(newDelta, resourceSet, subProgress.newChild(1, SubMonitor.SUPPRESS_ALL_LABELS));
                        postProcess(newDelta, resourceSet, subProgress.newChild(1));
                    } catch (StackOverflowError ex) {
                        queue.remove(changedURI);
                        logStackOverflowErrorStackTrace(ex, changedURI);
                    }
                } else {
                    subProgress.worked(2);
                }
                if (changedURI != null) {
                    final long memoryDelta = Runtime.getRuntime().freeMemory() - initialMemory;
                    final int resourceSetSizeDelta = resourceSet.getResources().size() - initialResourceSetSize;
                    final long timeDelta = System.nanoTime() - initialTime;
                    traceSet.trace(ResourceLinkingMemoryEvent.class, changedURI, memoryDelta, resourceSetSizeDelta, timeDelta);
                    watchdog.reportWorkEnded(index, index + queue.size());
                }
                // Clear caches of resource
                if (resource instanceof XtextResource) {
                    ((XtextResource) resource).getCache().clear(resource);
                }
                traceSet.ended(ResourceProcessingEvent.class);
                buildData.getSourceLevelURICache().getSources().remove(changedURI);
                subProgress.worked(1);
                index++;
            }
            loadOperation.cancel();
            queueAffectedResources(allRemainingURIs, this, newState, changedDeltas, allDeltas, buildData, subProgress.newChild(1));
            newDeltas.clear();
            changedDeltas.clear();
            if (queue.size() > 0) {
                loadOperation = crossLinkingResourceLoader.create(resourceSet, currentProject);
                loadOperation.load(queue);
            }
            if (!queue.isEmpty()) {
                traceSet.trace(ClusterClosedEvent.class, Long.valueOf(resourceSet.getResources().size()));
                clearResourceSet(resourceSet);
            }
        // TODO flush required here or elsewhere ?
        // flushChanges(newData);
        }
    } finally {
        // Report the current size of the resource set
        traceSet.trace(ClusterClosedEvent.class, Long.valueOf(resourceSet.getResources().size()));
        if (loadOperation != null) {
            loadOperation.cancel();
        }
        traceSet.ended(BuildLinkingEvent.class);
        watchdog.interrupt();
    }
    return allDeltas;
// CHECKSTYLE:CHECK-ON NestedTryDepth
}
Also used : IResourceDescription(org.eclipse.xtext.resource.IResourceDescription) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) XtextResource(org.eclipse.xtext.resource.XtextResource) URI(org.eclipse.emf.common.util.URI) Manager(org.eclipse.xtext.resource.IResourceDescription.Manager) IResourceLoader(org.eclipse.xtext.builder.resourceloader.IResourceLoader) TimeoutException(java.util.concurrent.TimeoutException) DefaultResourceDescriptionDelta(org.eclipse.xtext.resource.impl.DefaultResourceDescriptionDelta) SubMonitor(org.eclipse.core.runtime.SubMonitor) Resource(org.eclipse.emf.ecore.resource.Resource) StorageAwareResource(org.eclipse.xtext.resource.persistence.StorageAwareResource) XtextResource(org.eclipse.xtext.resource.XtextResource) ResourceSet(org.eclipse.emf.ecore.resource.ResourceSet) IProject(org.eclipse.core.resources.IProject) TimeoutException(java.util.concurrent.TimeoutException) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) WrappedException(org.eclipse.emf.common.util.WrappedException) LoadOperationException(org.eclipse.xtext.builder.resourceloader.IResourceLoader.LoadOperationException) LoadOperationException(org.eclipse.xtext.builder.resourceloader.IResourceLoader.LoadOperationException) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) DefaultResourceDescriptionDelta(org.eclipse.xtext.resource.impl.DefaultResourceDescriptionDelta) CancelIndicator(org.eclipse.xtext.util.CancelIndicator)

Example 23 with Delta

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

the class MonitoredClusteringBuilderState method writeResources.

/**
 * Writes a list of resources into the index given their {@link URI}s.
 *
 * @param toWrite
 *          The {@link URI} of the resources to write
 * @param buildData
 *          The underlying data for the write operation.
 * @param oldState
 *          The old index
 * @param newState
 *          The new index
 * @param monitor
 *          The progress monitor used for user feedback
 * @return a List with the list of loaded resources {@link URI} in the first position and a list of {@link URI}s of resources that could not be loaded in the
 *         second position.
 */
@SuppressWarnings("unchecked")
private List<List<URI>> writeResources(final Collection<URI> toWrite, final BuildData buildData, final IResourceDescriptions oldState, final CurrentDescriptions newState, final IProgressMonitor monitor) {
    ResourceSet resourceSet = buildData.getResourceSet();
    IProject currentProject = getBuiltProject(buildData);
    List<URI> toBuild = Lists.newLinkedList();
    List<URI> toRetry = Lists.newLinkedList();
    IResourceLoader.LoadOperation loadOperation = null;
    try {
        int resourcesToWriteSize = toWrite.size();
        int index = 1;
        loadOperation = globalIndexResourceLoader.create(resourceSet, currentProject);
        loadOperation.load(toWrite);
        // large resources and "scarce" memory (say, about 500MB).
        while (loadOperation.hasNext()) {
            if (monitor.isCanceled()) {
                loadOperation.cancel();
                throw new OperationCanceledException();
            }
            URI uri = null;
            Resource resource = null;
            try {
                resource = addResource(loadOperation.next().getResource(), resourceSet);
                uri = resource.getURI();
                final Object[] bindings = { Integer.valueOf(index), Integer.valueOf(resourcesToWriteSize), uri.fileExtension(), URI.decode(uri.lastSegment()) };
                monitor.subTask(NLS.bind(Messages.MonitoredClusteringBuilderState_WRITE_ONE_DESCRIPTION, bindings));
                traceSet.started(ResourceIndexingEvent.class, uri);
                final IResourceDescription.Manager manager = getResourceDescriptionManager(uri);
                if (manager != null) {
                    final IResourceDescription description = manager.getResourceDescription(resource);
                    // We don't care here about links, we really just want the exported objects so that we can link in the next phase.
                    // Set flag to make unresolvable cross-references raise an error
                    resourceSet.getLoadOptions().put(ILazyLinkingResource2.MARK_UNRESOLVABLE_XREFS, Boolean.FALSE);
                    final IResourceDescription copiedDescription = new FixedCopiedResourceDescription(description);
                    final boolean hasUnresolvedLinks = resourceSet.getLoadOptions().get(ILazyLinkingResource2.MARK_UNRESOLVABLE_XREFS) == Boolean.TRUE;
                    if (hasUnresolvedLinks) {
                        toRetry.add(uri);
                        resourceSet.getResources().remove(resource);
                    } else {
                        final Delta intermediateDelta = manager.createDelta(oldState.getResourceDescription(uri), copiedDescription);
                        newState.register(intermediateDelta);
                        toBuild.add(uri);
                    }
                }
            } catch (final WrappedException ex) {
                pollForCancellation(monitor);
                if (uri == null && ex instanceof LoadOperationException) {
                    // NOPMD
                    uri = ((LoadOperationException) ex).getUri();
                }
                LOGGER.error(NLS.bind(Messages.MonitoredClusteringBuilderState_CANNOT_LOAD_RESOURCE, uri), ex);
                if (resource != null) {
                    resourceSet.getResources().remove(resource);
                }
                if (uri != null) {
                    final IResourceDescription oldDescription = oldState.getResourceDescription(uri);
                    if (oldDescription != null) {
                        newState.register(new DefaultResourceDescriptionDelta(oldDescription, null));
                    }
                }
            // CHECKSTYLE:CHECK-OFF IllegalCatch
            // If we couldn't load it, there's no use trying again: do not add it to the queue
            } catch (final Throwable e) {
                // unfortunately the parser sometimes crashes (yet unreported Xtext bug)
                // CHECKSTYLE:CHECK-ON IllegalCatch
                pollForCancellation(monitor);
                LOGGER.error(NLS.bind(Messages.MonitoredClusteringBuilderState_CANNOT_LOAD_RESOURCE, uri), e);
                if (resource != null) {
                    resourceSet.getResources().remove(resource);
                }
            } finally {
                // Clear caches of resource
                if (resource instanceof XtextResource) {
                    ((XtextResource) resource).getCache().clear(resource);
                }
                traceSet.ended(ResourceIndexingEvent.class);
                monitor.worked(1);
            }
            if (!loadingStrategy.mayProcessAnotherResource(resourceSet, resourceSet.getResources().size())) {
                clearResourceSet(resourceSet);
            }
            index++;
        }
    } finally {
        if (loadOperation != null) {
            loadOperation.cancel();
        }
    }
    return Lists.newArrayList(toBuild, toRetry);
}
Also used : WrappedException(org.eclipse.emf.common.util.WrappedException) IResourceDescription(org.eclipse.xtext.resource.IResourceDescription) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) Resource(org.eclipse.emf.ecore.resource.Resource) StorageAwareResource(org.eclipse.xtext.resource.persistence.StorageAwareResource) XtextResource(org.eclipse.xtext.resource.XtextResource) XtextResource(org.eclipse.xtext.resource.XtextResource) ResourceSet(org.eclipse.emf.ecore.resource.ResourceSet) URI(org.eclipse.emf.common.util.URI) IProject(org.eclipse.core.resources.IProject) LoadOperationException(org.eclipse.xtext.builder.resourceloader.IResourceLoader.LoadOperationException) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) DefaultResourceDescriptionDelta(org.eclipse.xtext.resource.impl.DefaultResourceDescriptionDelta) Manager(org.eclipse.xtext.resource.IResourceDescription.Manager) IResourceLoader(org.eclipse.xtext.builder.resourceloader.IResourceLoader) DefaultResourceDescriptionDelta(org.eclipse.xtext.resource.impl.DefaultResourceDescriptionDelta)

Example 24 with Delta

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

the class RebuildingXtextBuilder method doBuild.

/**
 * Like the super implementation, except the build is not triggered if
 * both toBeDeleted and toBeUpdated are empty. {@inheritDoc}
 */
@SuppressWarnings("nls")
@Override
protected void doBuild(final ToBeBuilt toBeBuilt, final IProgressMonitor monitor, final BuildType type) throws CoreException {
    if (toBeBuilt.getToBeDeleted().size() != 0 || toBeBuilt.getToBeUpdated().size() != 0) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Starting " + type.name() + " build:" + "\ndeleted(" + toBeBuilt.getToBeDeleted().size() + ")=" + toBeBuilt.getToBeDeleted().toString() + "\nupdated(" + toBeBuilt.getToBeUpdated().size() + ")=" + toBeBuilt.getToBeUpdated().toString());
        }
        // build + participant + rebuild
        SubMonitor progress = SubMonitor.convert(monitor, 1 + 1 + 1);
        ResourceSet resourceSet = getResourceSetProvider().get(getProject());
        resourceSet.getLoadOptions().put(ResourceDescriptionsProvider.NAMED_BUILDER_SCOPE, Boolean.TRUE);
        if (resourceSet instanceof ResourceSetImpl) {
            ((ResourceSetImpl) resourceSet).setURIResourceMap(Maps.<URI, Resource>newHashMap());
        }
        BuildData buildData = new BuildData(getProject().getName(), resourceSet, toBeBuilt, queuedBuildData);
        ImmutableList<Delta> deltas = builderState.update(buildData, progress.newChild(1));
        if (participant != null) {
            final BuildContext buildContext = new BuildContext(this, resourceSet, deltas, type);
            // remember the current workspace tree
            final ElementTree oldTree = ((Workspace) ResourcesPlugin.getWorkspace()).getElementTree();
            oldTree.immutable();
            participant.build(buildContext, progress.newChild(1));
            if (buildContext.isRebuildRequired() && rebuilds++ <= 2) {
                final ElementTree newTree = ((Workspace) ResourcesPlugin.getWorkspace()).getElementTree();
                newTree.immutable();
                final ResourceDelta generatedDelta = ResourceDeltaFactory.computeDelta((Workspace) ResourcesPlugin.getWorkspace(), oldTree, newTree, getProject().getFullPath(), -1);
                // rebuild the generated delta
                ResourcesPlugin.getWorkspace().checkpoint(false);
                incrementalBuild(generatedDelta, progress.newChild(1));
            }
        } else {
            progress.worked(2);
        }
        resourceSet.getResources().clear();
        resourceSet.eAdapters().clear();
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Build done.");
        }
    } else if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Ignoring empty " + type.name() + " build.");
    }
}
Also used : BuildData(org.eclipse.xtext.builder.impl.BuildData) QueuedBuildData(org.eclipse.xtext.builder.impl.QueuedBuildData) ResourceSetImpl(org.eclipse.emf.ecore.resource.impl.ResourceSetImpl) ResourceDelta(org.eclipse.core.internal.events.ResourceDelta) IResourceDelta(org.eclipse.core.resources.IResourceDelta) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) ResourceDelta(org.eclipse.core.internal.events.ResourceDelta) IResourceDelta(org.eclipse.core.resources.IResourceDelta) SubMonitor(org.eclipse.core.runtime.SubMonitor) ResourceSet(org.eclipse.emf.ecore.resource.ResourceSet) ElementTree(org.eclipse.core.internal.watson.ElementTree) Workspace(org.eclipse.core.internal.resources.Workspace)

Example 25 with Delta

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

the class FixedDirtyStateEditorSupport method isReparseRequired.

/**
 * {@inheritDoc}
 */
@Override
protected boolean isReparseRequired(final XtextResource resource, final Event event) {
    // NOPMD (NPath complexity)
    IResourceDescription.Manager resourceDescriptionManager = resource.getResourceServiceProvider().getResourceDescriptionManager();
    final IResourceDescription description = resourceDescriptionManager.getResourceDescription(resource);
    // The DefaultResourceDescriptionManager honors container visibility only for platform and archive URIs... oh well; let's do it explicitly here.
    final IContainer.Manager containerManager = resource.getResourceServiceProvider().getContainerManager();
    // Unfortunately, we need a Collection in the call to isAffected() below...
    List<Delta> visibleChanges = Lists.newArrayList(Iterables.filter(event.getDeltas(), new Predicate<Delta>() {

        private List<IContainer> containers;

        private Iterable<IContainer> getContainers() {
            // Getting the containers is a relatively expensive operation. We delay doing this until we really need it.
            if (containers == null) {
                containers = containerManager.getVisibleContainers(description, resourceDescriptions);
            }
            return containers;
        }

        @Override
        public boolean apply(final Delta delta) {
            if (delta.haveEObjectDescriptionsChanged()) {
                if (delta.getNew() == null) {
                    // If it was deleted, we don't know whether it was visible. Hmphhh.
                    return true;
                }
                if (delta.getUri().isFile()) {
                    // Apparently these are java-resources, which are always visible?! (c.f. Xtext bug 383919.)
                    return true;
                }
                for (IContainer container : getContainers()) {
                    if (container.hasResourceDescription(delta.getUri())) {
                        return true;
                    }
                }
            }
            return false;
        }
    }));
    // Fix Xtext bug 383919: delegate the whole checking to the description manager, which may have optimized processing in place anyway.
    if (resourceDescriptionManager.isAffected(visibleChanges, description, resourceDescriptions)) {
        return true;
    }
    if (!isDirty() && !getDirtyStateManager().hasContent(resource.getURI())) {
        IResourceDescription originalDescription = resourceDescriptions.getResourceDescription(resource.getURI());
        if (originalDescription != null && descriptionUtils != null) {
            Set<URI> outgoingReferences = descriptionUtils.collectOutgoingReferences(originalDescription);
            for (Delta delta : visibleChanges) {
                if (outgoingReferences.contains(delta.getUri())) {
                    return true;
                }
            }
        }
    }
    return false;
}
Also used : IResourceDescription(org.eclipse.xtext.resource.IResourceDescription) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) List(java.util.List) IContainer(org.eclipse.xtext.resource.IContainer) URI(org.eclipse.emf.common.util.URI) Predicate(com.google.common.base.Predicate)

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