private void handleChangedContents(Delta delta, IProject aProject, ResourceSet resourceSet) throws CoreException { // TODO: we will run out of memory here if the number of deltas is large enough Resource resource = resourceSet.getResource(delta.getUri(), true); if (shouldGenerate(resource, aProject)) { try { compositeGenerator.doGenerate(resource, access); } catch (RuntimeException e) { if (e instanceof GeneratorException) { N4JSActivator .getInstance() .getLog() .log(new Status(IStatus.ERROR, N4JSActivator.getInstance().getBundle().getSymbolicName(), e .getMessage(), e.getCause())); } if (e.getCause() instanceof CoreException) { throw (CoreException) e.getCause(); } throw e; } } }
@Override protected void updateMarkers(Delta delta, ResourceSet resourceSet, IProgressMonitor monitor) { Measurement mes = dcValidations.getMeasurement("validation"); super.updateMarkers(delta, resourceSet, monitor); mes.end(); if (resourceSet != null) { // resourceSet is null during clean build mes = dcTranspilation.getMeasurement("transpilation"); IBuildParticipantInstruction instruction = (IBuildParticipantInstruction) EcoreUtil.getAdapter( resourceSet.eAdapters(), IBuildParticipantInstruction.class); if (instruction == null) { throw new IllegalStateException(); } try { instruction.process(delta, resourceSet, monitor); } catch (CoreException e) { handleCoreException(e); } mes.end(); } }
/** * {@inheritDoc} * * This marks {@code n4js} as affected if the manifest of the project changes. In turn, they will be revalidated and * taken into consideration for the code generation step. */ @Override public boolean isAffected(Collection<IResourceDescription.Delta> deltas, IResourceDescription candidate, IResourceDescriptions context) { boolean result = basicIsAffected(deltas, candidate); if (!result) { for (IResourceDescription.Delta delta : deltas) { URI uri = delta.getUri(); if (IN4JSProject.N4MF_MANIFEST.equalsIgnoreCase(uri.lastSegment())) { URI prefixURI = uri.trimSegments(1).appendSegment(""); if (candidate.getURI().replacePrefix(prefixURI, prefixURI) != null) { return true; } } } } return result; }
@Override public void build(IBuildContext context, IProgressMonitor monitor) throws CoreException { SubMonitor progress = SubMonitor.convert(monitor); if (!prefs.isCompilerEnabled()) { return; } final List<IResourceDescription.Delta> deltas = getRelevantDeltas(context); if (deltas.isEmpty()) { return; } if (progress.isCanceled()) { throw new OperationCanceledException(); } progress.beginTask("Compiling solidity...", deltas.size()); List<URI> uris = deltas.stream().map(delta -> delta.getUri()).collect(Collectors.toList()); compiler.compile(uris, progress); context.getBuiltProject().refreshLocal(IProject.DEPTH_INFINITE, progress); progress.done(); }
/** {@inheritDoc} */ @Override public void process(final Delta delta, final ResourceSet resourceSet, final IProgressMonitor monitor) { URI uri = delta.getUri(); ILanguageSpecificResourcePostProcessor postProcessor = getPostProcessor(uri); if (postProcessor != null) { try { traceSet.started(ResourcePostProcessingEvent.class, uri); SubMonitor subMonitor = SubMonitor.convert(monitor, 1); if (delta.getNew() != null) { if (resourceSet == null) { throw new IllegalArgumentException("resourceSet may not be null for changed resources."); //$NON-NLS-1$ } postProcessor.processChanged(uri, resourceSet.getResource(uri, true), resourceSet, subMonitor.newChild(1)); } else { postProcessor.processDeleted(uri, resourceSet, subMonitor.newChild(1)); } } finally { traceSet.ended(ResourcePostProcessingEvent.class); } } }
/** * Updates the markers on a single resource. * * @param delta * for the changed resource * @param resourceSet * containing the resource * @param monitor * to report progress */ @Override protected void updateMarkers(final Delta delta, final ResourceSet resourceSet, final IProgressMonitor monitor) { ResourceValidationRuleSummaryEvent.Collector traceCollector = null; try { traceSet.started(ResourceValidationEvent.class, delta.getUri()); if (traceSet.isEnabled(ResourceValidationRuleSummaryEvent.class)) { traceCollector = ResourceValidationRuleSummaryEvent.Collector.addToLoadOptions(resourceSet); } super.updateMarkers(delta, resourceSet, monitor); } finally { if (traceCollector != null) { traceCollector.postEvents(delta.getUri(), traceSet); } traceSet.ended(ResourceValidationEvent.class); } }
/** * {@inheritDoc} Schedules a full clean build if the target platform changes. */ @Override public void platformChanged(final IResourceDescriptionsData newPlatform, final Collection<Delta> deltas, final boolean mustRebuild) { if (newPlatform == null) { // Hmmm... context deactivated. Events for removing the project from the index will be generated anyway, so no build necessary. // TODO: check! setResourceDescriptionsData(new NullResourceDescriptionsData()); return; } // Deltas? if (isLoaded()) { // If we're not loaded yet, then this event is due to the initial loading of the platform in super.load. In this case, // we are in a build anyway, aren't we? // TODO: this is pretty convoluted. We should try to disentangle this OO spaghetti code. Is it good enough to simply not notify listeners in // AbstractXtextTargetPlatformManager if it was the initial load? if (newPlatform instanceof AbstractResourceDescriptionsData) { ((AbstractResourceDescriptionsData) newPlatform).beginChanges(); } setResourceDescriptionsData((ResourceDescriptionsData) newPlatform); ResourceDescriptionChangeEvent event = new ResourceDescriptionChangeEvent(deltas); notifyListeners(event); } if (mustRebuild) { buildTrigger.scheduleFullBuild(); } }
/** * Bulk method to return all resources (managed by this manager) which are affected by the given set of deltas. * * @param deltas * deltas * @param candidates * candidates * @param context * context index * @return collection of affected resources */ public Collection<URI> getAffectedResources(final Collection<Delta> deltas, final Collection<URI> candidates, final IResourceDescriptions context) { // Don't filter by isInterestedIn() in this bulk method. First, isInterestedIn() is based on file extensions, which may or may not // work precisely. Second, it filters by haveEObjectdescriptionsChanged(), but the MonitoredClusteringBuilderState already ensures that // the delta does not contain unchanged resource descriptions. // // By not pre-filtering the deltas, we can also ensure that resource description managers for different languages will end up making // identical queries to findAllReferencingResources() and findExactReferencingResources(), which is crucial to make the cache in // MonitoredClusteringBuilderState be effective. // // See also the comment on MonitoredClusteringBuilderState.FindReferenceCachingState. if (deltas.isEmpty() || candidates.isEmpty()) { return ImmutableSet.of(); } return getAffectedResources(deltas, new Predicate<URI>() { @Override public boolean apply(final URI input) { return candidates.contains(input) && isManagerFor(input); } }, (IResourceDescriptions2) context); }
/** * Prepare mocks for all tests. */ public static void prepareMocksBase() { oldDesc = mock(IResourceDescription.class); newDesc = mock(IResourceDescription.class); delta = mock(Delta.class); resource = mock(Resource.class); uriCorrect = mock(URI.class); when(uriCorrect.isPlatformResource()).thenReturn(true); when(uriCorrect.isFile()).thenReturn(true); when(uriCorrect.toFileString()).thenReturn(DUMMY_PATH); when(uriCorrect.toPlatformString(true)).thenReturn(DUMMY_PATH); when(delta.getNew()).thenReturn(newDesc); when(delta.getOld()).thenReturn(oldDesc); when(delta.getUri()).thenReturn(uriCorrect); when(resource.getURI()).thenReturn(uriCorrect); file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uriCorrect.toPlatformString(true))); Iterable<Pair<IStorage, IProject>> storages = singleton(Tuples.<IStorage, IProject> create(file, file.getProject())); mapperCorrect = mock(Storage2UriMapperImpl.class); when(mapperCorrect.getStorages(uriCorrect)).thenReturn(storages); }
/** * Removes the contexts for all checks of a deleted catalog. * * @param delta * the delta * @throws CoreException * the core exception */ @SuppressWarnings("unchecked") public void removeContexts(final Delta delta) throws CoreException { final IProject project = RuntimeProjectUtil.getProject(delta.getUri(), mapper); if (project != null) { IFile file = projectHelper.getHelpFile(project, CheckContextsExtensionHelper.CONTEXTS_FILE_NAME); CtxHelpModel model = new CtxHelpModel(CoreUtility.getTextDocument(file.getContents()), false); model.setUnderlyingResource(file); model.load(); CtxHelpRoot root = model.getCtxHelpRoot(); Iterable<CtxHelpContext> contexts = Iterables.filter(Lists.newArrayList(root.getChildren()), CtxHelpContext.class); for (CtxHelpContext context : contexts) { Iterable<IEObjectDescription> catalogs = delta.getOld().getExportedObjectsByType(CheckPackage.Literals.CHECK_CATALOG); for (IEObjectDescription catalog : catalogs) { if (context.getId().startsWith(catalog.getName().getLastSegment().toLowerCase() + "_")) { root.removeChild(context); } } } model.save(); model.dispose(); } }
/** * Add an extension to the <code>plugin.xml</code> file. * * @param context * build context * @param delta * resource delta * @param monitor * progress monitor * @throws CoreException * the core exception */ public void changePluginXmlFile(final IBuildContext context, final Delta delta, final IProgressMonitor monitor) throws CoreException { URI uri = delta.getUri(); CheckCatalog catalog = projectHelper.getCatalog(context, uri); if (catalog == null) { throw new CoreException(new Status(IStatus.ERROR, Activator.getPluginId(), IStatus.ERROR, "No Catalog found", null)); //$NON-NLS-1$ } IFile file = getPluginFile(uri); if (!validPluginFile(file)) { createNewFile(catalog, file, monitor); } else { if (!catalogValidates(catalog)) { removeExtensions(file, catalog, monitor); } else { updateExtensions(file, catalog, monitor); // TODO improve by only updating the manifest if the validator extension has changed.. } } mergeManifest(catalog, monitor); }
@Override public boolean isAffected(final Collection<Delta> deltas, final IResourceDescription candidate, final IResourceDescriptions context) { // final boolean result = false; final URI newUri = candidate.getURI(); final Set<URI> deltaUris = new HashSet<>(); for (final Delta d : deltas) { deltaUris.add(GamlResourceServices.properlyEncodedURI(d.getUri())); } final Iterator<URI> it = GamlResourceIndexer.allImportsOf(newUri); while (it.hasNext()) { final URI next = it.next(); if (deltaUris.contains(next)) { return true; } } return super.isAffected(deltas, candidate, context); }
/***/ public static String print(ImmutableList<Delta> deltas) { int i = 1; String buff = "Deltas : \n"; for (Delta delta : deltas) { buff += "Delta " + i + "[" + delta.getUri() + "]: {\n"; buff += " old : " + toString(delta.getOld()) + "\n"; buff += " new : " + toString(delta.getNew()) + "\n"; buff += "}\n\n"; i++; } return buff; }
@Override public void finish(List<Delta> deltas, IProgressMonitor progressMonitor) throws CoreException { for (Delta delta : deltas) { if (delta.getNew() == null) { String uri = delta.getUri().toString(); recordDerivedResources(uri); deleteObsoleteResources(uri, progressMonitor); } } deleteEmptyDirectories(progressMonitor); }
@Override public void finish(List<Delta> deltas, IProgressMonitor progressMonitor) throws CoreException { SubMonitor cleanMonitor = SubMonitor.convert(progressMonitor, outputConfigurations.size()); for (OutputConfiguration config : outputConfigurations.values()) { cleanOutput(project, config, cleanMonitor.newChild(1)); } }
/** * {@inheritDoc} * * Initializes an adapter which is attached to the builder's resource set. This adapter will be used later on to * process each delta after the corresponding resource was validated. * * @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) { Measurement mes = dcBuild.getMeasurement("build " + Instant.now()); builderStateLogger.log("N4JSGenerateImmediatelyBuilderState.doUpdate() >>>"); logBuildData(buildData, " of before #doUpdate"); IProject project = getProject(buildData); try { BuildType buildType = N4JSBuildTypeTracker.getBuildType(project); IBuildParticipantInstruction instruction; if (buildType == null) { instruction = IBuildParticipantInstruction.NOOP; } else { instruction = findJSBuilderParticipant().prepareBuild(project, buildType); } // removed after the build automatically; // the resource set is discarded afterwards, anyway buildData.getResourceSet().eAdapters().add(instruction); } catch (CoreException e) { handleCoreException(e); } Collection<Delta> modifiedDeltas = super.doUpdate(buildData, newData, monitor); logBuildData(buildData, " of after #doUpdate"); builderStateLogger.log("Modified deltas: " + modifiedDeltas); builderStateLogger.log("N4JSGenerateImmediatelyBuilderState.doUpdate() <<<"); mes.end(); return modifiedDeltas; }
/** * Intentionally package visible producer for the {@link IBuildParticipantInstruction}. * * @param project * the currently build project * @param buildType * the current build type * @return a StatefulBuilderParticipant. Never <code>null</code>. */ IBuildParticipantInstruction prepareBuild(IProject project, IXtextBuilderParticipant.BuildType buildType) throws CoreException { if (!isEnabled(project)) { return IBuildParticipantInstruction.NOOP; } EclipseResourceFileSystemAccess2 access = fileSystemAccessProvider.get(); access.setProject(project); final Map<String, OutputConfiguration> outputConfigurations = getOutputConfigurations(project); refreshOutputFolders(project, outputConfigurations, null); access.setOutputConfigurations(outputConfigurations); if (buildType == BuildType.CLEAN || buildType == BuildType.RECOVERY) { IBuildParticipantInstruction clean = new CleanInstruction(project, outputConfigurations, getDerivedResourceMarkers()); if (buildType == BuildType.RECOVERY) { clean.finish(Collections.<Delta> emptyList(), null); } else { return clean; } } Map<OutputConfiguration, Iterable<IMarker>> generatorMarkers = getGeneratorMarkers(project, outputConfigurations.values()); BuildInstruction buildInstruction = new BuildInstruction(project, outputConfigurations, getDerivedResourceMarkers(), access, generatorMarkers, storage2UriMapper, compositeGenerator, injector); return buildInstruction; }
/** * Computes if a candidate is affected by any change, aka delta. It is affected, if */ private boolean basicIsAffected(Collection<Delta> deltas, final IResourceDescription candidate) { // The super implementation DefaultResourceDescriptionManager#isAffected is based on a tradeoff / some // assumptions which do not hold for n4js wrt to manifest changes // computed the first time we need it, do not compute eagerly Collection<QualifiedName> namesImportedByCandidate = null; for (IResourceDescription.Delta delta : deltas) { if (delta.haveEObjectDescriptionsChanged() && fileExtensionTypeHelper.isTypable(delta.getUri().fileExtension())) { if (null == namesImportedByCandidate) { // note: this does not only contain the explicitly imported names, but indirectly // imported names as well! namesImportedByCandidate = getImportedNames(candidate); } if (isAffected(namesImportedByCandidate, delta.getNew()) // we may added a new exported name! || isAffected(namesImportedByCandidate, delta.getOld())) { // we may removed an exported name if (hasDependencyTo(candidate, delta)) { // isAffected does not compare project names return true; } } } } return false; }
private List<Delta> getRelevantDeltas(IBuildContext context) { List<Delta> filtered = Lists.newArrayList(); for (Delta delta : context.getDeltas()) { if (delta.getUri().fileExtension().equals("sol")) { filtered.add(delta); } } return filtered; }
@Override public boolean isAffected(final Collection<IResourceDescription.Delta> deltas, final IResourceDescription candidate, final IResourceDescriptions context) throws IllegalArgumentException { Collection<QualifiedName> importedNames = IterableExtensions.<QualifiedName>toSet(candidate.getImportedNames()); for (final IResourceDescription.Delta delta : deltas) { boolean _hasChanges = this.hasChanges(delta, candidate); if (_hasChanges) { if ((this.isAffected(importedNames, delta.getNew()) || this.isAffected(importedNames, delta.getOld()))) { return true; } } } return false; }
@Override public boolean isAffected(Collection<Delta> deltas, IResourceDescription candidate, IResourceDescriptions context) throws IllegalArgumentException { Set<URI> outgoingReferences = descriptionUtils.collectOutgoingReferences(candidate); if (!outgoingReferences.isEmpty()) { for (IResourceDescription.Delta delta : deltas) if (delta.haveEObjectDescriptionsChanged() && outgoingReferences.contains(delta.getUri())) return true; } return false; }
/** * Put a new resource description into the index, or remove one if the delta has no new description. A delta for a * particular URI may be registered more than once; overwriting any earlier registration. * * @param delta * The resource change. * @since 2.9 */ public void register(Delta delta) { final IResourceDescription newDesc = delta.getNew(); if (newDesc == null) { removeDescription(delta.getUri()); } else { addDescription(delta.getUri(), newDesc); } }
@Override public boolean isAffected(Delta delta, IResourceDescription candidate) throws IllegalArgumentException { if (!hasChanges(delta, candidate)) return false; Set<QualifiedName> names = Sets.newHashSet(); addExportedNames(names,delta.getOld()); addExportedNames(names,delta.getNew()); return !Collections.disjoint(names, getImportedNames(candidate)); }
/** * Prepare mocks for all tests. */ @Override protected void beforeAllTests() { super.beforeAllTests(); participant = new FormatBuilderParticipant(); delta = mock(Delta.class); uriCorrect = mock(URI.class); when(delta.getUri()).thenReturn(uriCorrect); }
@Override protected void handleChangedContents(final Delta delta, final IBuildContext context, final EclipseResourceFileSystemAccess2 fsa) throws CoreException { if (isAffected(delta, resourceServiceProvider)) { Resource resource = context.getResourceSet().getResource(delta.getUri(), true); if (shouldGenerate(resource, context) && resource.getContents().get(0) instanceof FormatConfiguration) { generator.doGenerate(resource, fsa); } } }
@Override protected void updateMarkers(final Delta delta, final ResourceSet resourceSet, final IProgressMonitor monitor) throws OperationCanceledException { if (StreamSupport.stream(mapper.getStorages(delta.getUri()).spliterator(), true).anyMatch(pair -> { IStorage storage = pair.getFirst(); IProject project = pair.getSecond(); return project.getFullPath().isPrefixOf(storage.getFullPath()); })) { LOGGER.debug("Processed " + delta.getUri()); //$NON-NLS-1$ super.updateMarkers(delta, resourceSet, monitor); } else { LOGGER.debug("Skipped " + delta.getUri()); //$NON-NLS-1$ } }
@Override public void descriptionsChanged(final IResourceDescription.Event event) { for (Delta delta : event.getDeltas()) { IResourceDescription newDesc = delta.getNew(); if (newDesc == null) { dirtyResources.remove(delta.getUri()); } else { dirtyResources.add(delta.getUri()); } } dirtyDescriptionsChanged(event); }
/** {@inheritDoc} */ @Override public void descriptionsChanged(final Event event) { for (Delta d : event.getDeltas()) { if (containerState.contains(d.getUri())) { discardCachedContainer(resourceDescriptions, handle); if (resourceDescriptions instanceof IResourceDescription.Event.Source) { ((IResourceDescription.Event.Source) resourceDescriptions).removeListener(this); } break; } } }
@Override @SuppressWarnings("PMD.AvoidInstanceofChecksInCatchClause") public synchronized ImmutableList<Delta> update(final BuildData buildData, final IProgressMonitor monitor) { ensureLoaded(); final SubMonitor subMonitor = SubMonitor.convert(monitor, org.eclipse.xtext.builder.builderState.Messages.AbstractBuilderState_0, 1); subMonitor.subTask(org.eclipse.xtext.builder.builderState.Messages.AbstractBuilderState_0); checkForCancellation(monitor); final ResourceDescriptionsData newData = getCopiedResourceDescriptionsData(); Collection<IResourceDescription.Delta> result = null; try { result = doUpdate(buildData, newData, subMonitor.newChild(1)); // update the reference setResourceDescriptionsData(newData, monitor); // CHECKSTYLE:OFF } catch (Throwable t) { // CHECKSTYLE:ON if (!operationCanceledManager.isOperationCanceledException(t)) { LOGGER.error("Failed to update index. Executing rollback.", t); //$NON-NLS-1$ } if (newData instanceof AbstractResourceDescriptionsData) { ((AbstractResourceDescriptionsData) newData).rollbackChanges(); } throw t; } final ResourceDescriptionChangeEvent event = new ResourceDescriptionChangeEvent(result); notifyListeners(event); return event.getDeltas(); }
/** * Add deltas for the removed resources. * * @param deletedUris * URIs of the removed resources * @param deltas * Deltas * @param savedDescriptions * previously saved old resource descriptions */ protected void addDeletedURIsToDeltas(final Set<URI> deletedUris, final Set<Delta> deltas, final Map<URI, IResourceDescription> savedDescriptions) { for (final URI uri : deletedUris) { final IResourceDescription oldDescription = getSavedResourceDescription(savedDescriptions, uri); if (oldDescription != null) { final IResourceDescription.Manager manager = getResourceDescriptionManager(uri); if (manager != null) { deltas.add(manager.createDelta(oldDescription, null)); } } } }
/** {@inheritDoc} */ @Override public boolean isAffected(final Collection<Delta> deltas, final IResourceDescription candidate, final IResourceDescriptions context) { // NOPMD(NPathComplexity) final Collection<Delta> filteredDeltas = getInterestingDeltas(deltas); if (filteredDeltas.isEmpty()) { return false; } final List<IContainer> containers = getContainerManager().getVisibleContainers(candidate, context); for (final Delta delta : filteredDeltas) { final URI deltaURI = delta.getUri();// NOPMD - potentially could be lost due to call on getNew() after // deleted resources are no longer visible resources so we test them, too. if (delta.getNew() == null && isReferencedBy(delta, candidate, context)) { if (LOGGER.isDebugEnabled()) { LOGGER.debug(candidate.getURI() + " is affected by " + delta.getUri()); //$NON-NLS-1$ } return true; } for (IContainer container : containers) { if (container.getResourceDescription(deltaURI) != null) { if (isReferencedBy(delta, candidate, context)) { if (LOGGER.isDebugEnabled()) { // NOPMD AvoidDeeplyNestedIfStmts LOGGER.debug(candidate.getURI() + " is affected by " + delta.getUri()); //$NON-NLS-1$ } return true; } break; } } } return false; }
/** * Filters the set of deltas to those which are of {@link #isInterestedIn(Delta) interest} to resources managed by this manager. * * @param deltas * deltas to filter * @return filtered deltas */ private Collection<Delta> getInterestingDeltas(final Collection<Delta> deltas) { final Collection<Delta> filteredDeltas = Lists.newArrayList(); for (final Delta delta : deltas) { if (isInterestedIn(delta) && delta.haveEObjectDescriptionsChanged()) { filteredDeltas.add(delta); } } return filteredDeltas; }
@Override public void build(final IBuildContext context, final IProgressMonitor monitor) throws CoreException { if (!isEnabled(context)) { return; } this.progressMonitor = monitor; super.build(context, monitor); for (Delta delta : context.getDeltas()) { if (delta.getNew() == null) { // means that a catalog has been deleted handleDeletion(delta, context); } } }
@Override public void finish(List<Delta> deltas, IProgressMonitor progressMonitor) throws CoreException { // nothing to do here }
@Override public void process(Delta delta, ResourceSet resourceSet, IProgressMonitor progressMonitor) throws CoreException { // nothing to do here }
@Override public void process(Delta delta, ResourceSet resourceSet, IProgressMonitor progressMonitor) throws CoreException { // do nothing }
/** * Overriding this method to make sure that resources of all affected URIs are fully re-loaded if needed, instead of * only loading the TModule from the corresponding resource description. * <p> * This is required in case the URIs in an affected resource contain indices of a changed resource; just loading the * TModule from the user data won't update these indices. For details see the example provided in IDEBUG-347. * <p> * NOTE: this should be removed once the URI scheme has been changed to use names instead of indices. */ @Override protected void queueAffectedResources( Set<URI> allRemainingURIs, IResourceDescriptions oldState, CurrentDescriptions newState, Collection<Delta> changedDeltas, Collection<Delta> allDeltas, BuildData buildData, final IProgressMonitor monitor) { // don't wanna copy super-class method, so using this helper to get the set of affected URIs: final Set<URI> affectedURIs = new HashSet<>(allRemainingURIs); super.queueAffectedResources(allRemainingURIs, oldState, newState, changedDeltas, allDeltas, buildData, monitor); // affected URIs have been removed from allRemainingURIs by super class affectedURIs.removeAll(allRemainingURIs); for (URI currAffURI : affectedURIs) { final IResourceDescription resDesc = this.getResourceDescription(currAffURI); if (!N4MF_MANIFEST.equals(currAffURI.lastSegment())) { /*- * This logic here is required to get rid of the invalid serialized TModules information from the index * which are working with an index based approach. Consider the below example: * * -------Module A------ *1 //class XYZ { } *2 function foo() { } *3 export public class A { } * * -------Module B------ *1 import { A } from "A" *2 import { C } from "C" *3 *4 var arrCC : Array<A>; *5 var t2 : C = new C(); *6 t2.m(arrCC); * * -------Module C------ *1 import { A } from "A" *2 *3 export public class C { *4 m(param : Array<A>) { } *5 } * * * Commenting out line 1 in module A will trigger rebuild of A, and related module B and C in this order. * When loading module B, module C has to be resolved as it imports it, quickly jump to module C and load * class A from module A, class A used to have index 1 (in the serialized TModule in the Xtext index) as * it was the second top level element, but that is not true any more, because 'foo' was just commented out, * so index 1 in module A is not class A any more but 'foo'. With this, line 6 in module B will fail, * because it will think that the method 'm' accepts an array of 'foo' and not A any more. * * The following code will be executed after A was processed and B and C are the "affectedURIs". With this * code, we make sure that the cached TModule of C (in the user data of C's resource description) won't be * used while processing B during proxy resolution. */ newState.register(new DefaultResourceDescriptionDelta(resDesc, new ResourceDescriptionWithoutModuleUserData(resDesc))); } } }
@Override public IResourceDescription.Delta createDelta(final IResourceDescription oldDescription, final IResourceDescription newDescription) { return new DefaultResourceDescriptionDelta(oldDescription, newDescription); }
@Override public boolean isAffected(final IResourceDescription.Delta delta, final IResourceDescription candidate) throws IllegalArgumentException { throw new UnsupportedOperationException("TODO: auto-generated method stub"); }
@Override public Delta createDelta(IResourceDescription oldDescription, IResourceDescription newDescription) { return new DefaultResourceDescriptionDelta(oldDescription, newDescription); }