Search in sources :

Example 6 with ProjectConfigSnapshot

use of org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot in project n4js by eclipse.

the class XWorkspaceManager method collectAllResourceDescriptions.

private List<IResourceDescription> collectAllResourceDescriptions(Iterable<? extends ProjectConfigSnapshot> projects) {
    List<IResourceDescription> result = new ArrayList<>();
    for (ProjectConfigSnapshot pc : projects) {
        String projectID = pc.getName();
        ResourceDescriptionsData data = workspaceIndex.getProjectIndex(projectID);
        if (data != null) {
            Iterables.addAll(result, data.getAllResourceDescriptions());
        }
    }
    return result;
}
Also used : ResourceDescriptionsData(org.eclipse.xtext.resource.impl.ResourceDescriptionsData) ProjectConfigSnapshot(org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot) IResourceDescription(org.eclipse.xtext.resource.IResourceDescription) ArrayList(java.util.ArrayList)

Example 7 with ProjectConfigSnapshot

use of org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot in project n4js by eclipse.

the class XWorkspaceBuilder method doIncrementalWorkspaceUpdateAndBuild.

/**
 * Based on the raw, "reported changes" accumulated in {@link #newDirtyFiles} / {@link #newDeletedFiles}, do the
 * following:
 * <ol>
 * <li>perform an update of the workspace configuration, if necessary, which may lead to additional "discovered
 * changes" (e.g. resources in newly added source folders),
 * <li><em>move</em> the "reported changes" together with the "discovered changes" to {@link #dirtyFiles} /
 * {@link #deletedFiles} / {@link #affectedByDeletedProjects},
 * <li>then trigger an incremental build.
 * </ol>
 */
protected IResourceDescription.Event doIncrementalWorkspaceUpdateAndBuild(CancelIndicator cancelIndicator) {
    // in case many incremental build tasks pile up in the queue (e.g. while a non-cancelable initial build is
    // running), we don't want to repeatedly invoke IWorkspaceManager#update() in each of those tasks but only in
    // the last one; therefore, we here check for a cancellation:
    operationCanceledManager.checkCanceled(cancelIndicator);
    Set<URI> newDirtyFiles = new LinkedHashSet<>(this.newDirtyFiles);
    Set<URI> newDeletedFiles = new LinkedHashSet<>(this.newDeletedFiles);
    boolean newRefreshRequest = this.newRefreshRequest;
    this.newDirtyFiles.clear();
    this.newDeletedFiles.clear();
    this.newRefreshRequest = false;
    Stopwatch stopwatch = Stopwatch.createStarted();
    if (newRefreshRequest) {
        lspLogger.log("Refreshing ...");
    }
    UpdateResult updateResult = workspaceManager.update(newDirtyFiles, newDeletedFiles, newRefreshRequest);
    WorkspaceChanges changes = updateResult.changes;
    List<URI> actualDirtyFiles = UtilN4.concat(changes.getAddedURIs(), changes.getChangedURIs());
    List<URI> actualDeletedFiles = new ArrayList<>(changes.getRemovedURIs());
    if (newRefreshRequest) {
        // scan all source folders of all projects for source file additions, changes, and deletions
        // - including source files of added projects,
        // - including source files of added source folders of existing projects,
        // - including source files of removed source folders of existing projects,
        // - *not* including source files of removed projects.
        actualDirtyFiles = new ArrayList<>();
        actualDeletedFiles = new ArrayList<>();
        for (ProjectBuilder projectBuilder : workspaceManager.getProjectBuilders()) {
            ResourceChangeSet sourceFileChanges = projectBuilder.scanForSourceFileChanges();
            actualDirtyFiles.addAll(sourceFileChanges.getDirty());
            actualDeletedFiles.addAll(sourceFileChanges.getDeleted());
        }
    } else {
        // scan only the added source folders (including those of added projects) for source files
        actualDirtyFiles.addAll(scanAddedSourceFoldersForNewSourceFiles(changes, scanner));
        // collect URIs from removed source folders (*not* including those of removed projects)
        actualDeletedFiles.addAll(getURIsFromRemovedSourceFolders(changes));
    }
    queue(this.dirtyFiles, actualDeletedFiles, actualDirtyFiles);
    queue(this.deletedFiles, actualDirtyFiles, actualDeletedFiles);
    // take care of removed projects
    Set<ProjectConfigSnapshot> deletedProjects = new HashSet<>();
    for (ProjectConfigSnapshot prjConfig : changes.getRemovedProjects()) {
        deletedProjects.add(prjConfig);
    }
    for (ProjectConfigSnapshot prjConfig : Iterables.concat(changes.getAddedProjects(), changes.getChangedProjects())) {
        deletedProjects.remove(prjConfig);
    }
    for (ProjectConfigSnapshot delPrj : deletedProjects) {
        ImmutableSet<? extends ProjectConfigSnapshot> affected = updateResult.oldWorkspaceConfigSnapshot.getProjectsDependingOn(delPrj.getName());
        this.affectedByDeletedProjects.addAll(affected);
    }
    handleContentsOfRemovedProjects(updateResult.removedProjectsContents);
    if (newRefreshRequest) {
        lspLogger.log("... refresh done (" + stopwatch.toString() + "; " + "projects added/removed: " + changes.getAddedProjects().size() + "/" + changes.getRemovedProjects().size() + "; " + "files dirty/deleted: " + dirtyFiles.size() + "/" + deletedFiles.size() + ").");
    }
    for (String cyclicProject : updateResult.cyclicProjectChanges) {
        ProjectConfigSnapshot projectConfig = workspaceManager.getWorkspaceConfig().findProjectByID(cyclicProject);
        Collection<URI> projectDescriptionUris = projectConfig.getProjectDescriptionUris();
        dirtyFiles.addAll(projectDescriptionUris);
    }
    if (dirtyFiles.isEmpty() && deletedFiles.isEmpty() && affectedByDeletedProjects.isEmpty()) {
        return new ResourceDescriptionChangeEvent(Collections.emptyList());
    }
    return doIncrementalBuild(cancelIndicator);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Stopwatch(com.google.common.base.Stopwatch) ArrayList(java.util.ArrayList) ResourceChangeSet(org.eclipse.n4js.xtext.ide.server.ResourceChangeSet) URI(org.eclipse.emf.common.util.URI) ResourceDescriptionChangeEvent(org.eclipse.xtext.resource.impl.ResourceDescriptionChangeEvent) WorkspaceChanges(org.eclipse.n4js.xtext.workspace.WorkspaceChanges) ProjectConfigSnapshot(org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot) UpdateResult(org.eclipse.n4js.xtext.ide.server.build.XWorkspaceManager.UpdateResult) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 8 with ProjectConfigSnapshot

use of org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot in project n4js by eclipse.

the class XWorkspaceBuilder method doIncrementalBuild.

/**
 * Run the build on the workspace
 */
private IResourceDescription.Event doIncrementalBuild(CancelIndicator cancelIndicator) {
    lspLogger.log("Building ...");
    WorkspaceConfigSnapshot workspaceConfig = workspaceManager.getWorkspaceConfig();
    boolean hasDependencyCycle = workspaceConfig.hasDependencyCycle();
    try {
        Set<URI> dirtyFilesToBuild = new LinkedHashSet<>(this.dirtyFiles);
        Set<URI> deletedFilesToBuild = new LinkedHashSet<>(this.deletedFiles);
        Map<String, Set<URI>> project2dirty = computeProjectToUriMap(dirtyFilesToBuild);
        Map<String, Set<URI>> project2deleted = computeProjectToUriMap(deletedFilesToBuild);
        Set<String> changedProjects = Sets.union(project2dirty.keySet(), project2deleted.keySet());
        List<ProjectConfigSnapshot> changedPCs = changedProjects.stream().map(workspaceConfig::findProjectByID).collect(Collectors.toList());
        BuildOrderIterator pboIterator = buildOrderFactory.createBuildOrderIterator(workspaceConfig, changedPCs);
        pboIterator.visit(affectedByDeletedProjects);
        while (pboIterator.hasNext()) {
            ProjectConfigSnapshot projectConfig = pboIterator.next();
            String projectName = projectConfig.getName();
            ProjectBuilder projectBuilder = workspaceManager.getProjectBuilder(projectName);
            Set<URI> projectDirty = project2dirty.getOrDefault(projectName, Collections.emptySet());
            Set<URI> projectDeleted = project2deleted.getOrDefault(projectName, Collections.emptySet());
            XBuildResult projectResult;
            AffectedResourcesRecordingFactory recordingFactory = new AffectedResourcesRecordingFactory(buildRequestFactory);
            try {
                projectResult = projectBuilder.doIncrementalBuild(recordingFactory, projectDirty, projectDeleted, toBeConsideredDeltas, cancelIndicator);
            } catch (Throwable t) {
                // re-schedule the affected files since a subsequent build may not detect those as affected
                // anymore but we may have produced artifacts for these already
                this.dirtyFiles.addAll(recordingFactory.getAffectedResources());
                throw t;
            }
            List<Delta> newlyBuiltDeltas = projectResult.getAffectedResources();
            recordBuildProgress(newlyBuiltDeltas);
            pboIterator.visitAffected(newlyBuiltDeltas);
        }
        List<IResourceDescription.Delta> result = toBeConsideredDeltas;
        onBuildDone(false, false, hasDependencyCycle, Optional.absent());
        lspLogger.log("... build done.");
        return new ResourceDescriptionChangeEvent(result);
    } catch (Throwable th) {
        boolean wasCanceled = operationCanceledManager.isOperationCanceledException(th);
        onBuildDone(false, wasCanceled, hasDependencyCycle, Optional.of(th));
        if (wasCanceled) {
            lspLogger.log("... build canceled.");
            operationCanceledManager.propagateIfCancelException(th);
        }
        // unknown exception or error (and not a cancellation case):
        // QueueExecutorService will log this as an error with stack trace, so here we just use #log():
        lspLogger.log("... build ABORTED due to exception: " + th.getMessage());
        throw th;
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) WorkspaceConfigSnapshot(org.eclipse.n4js.xtext.workspace.WorkspaceConfigSnapshot) HashSet(java.util.HashSet) ResourceChangeSet(org.eclipse.n4js.xtext.ide.server.ResourceChangeSet) LinkedHashSet(java.util.LinkedHashSet) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) URI(org.eclipse.emf.common.util.URI) ResourceDescriptionChangeEvent(org.eclipse.xtext.resource.impl.ResourceDescriptionChangeEvent) ProjectConfigSnapshot(org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot) Delta(org.eclipse.xtext.resource.IResourceDescription.Delta) DefaultResourceDescriptionDelta(org.eclipse.xtext.resource.impl.DefaultResourceDescriptionDelta) BuildOrderIterator(org.eclipse.n4js.xtext.workspace.BuildOrderIterator)

Example 9 with ProjectConfigSnapshot

use of org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot in project n4js by eclipse.

the class WorkspaceConfigAllContainerState method getContainerHandle.

@Override
public String getContainerHandle(URI uri) {
    WorkspaceConfigSnapshot ws = getWorkspaceConfig();
    ProjectConfigSnapshot project = ws != null ? ws.findProjectContaining(uri) : null;
    return project != null ? project.getName() : null;
}
Also used : WorkspaceConfigSnapshot(org.eclipse.n4js.xtext.workspace.WorkspaceConfigSnapshot) ProjectConfigSnapshot(org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot)

Example 10 with ProjectConfigSnapshot

use of org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot in project n4js by eclipse.

the class N4JSProjectConfig method update.

/**
 * Updates this project configuration's internal state.
 * <p>
 * This methods handles changes from
 * <ul>
 * <li>existing -> existing (w/o project modifications) and from
 * <li>existing -> non-existing (project deletion)
 * </ul>
 */
public WorkspaceChanges update(WorkspaceConfigSnapshot oldWorkspaceConfig, URI changedResource, ConfigSnapshotFactory configSnapshotFactory) {
    String projectID = getName();
    ProjectConfigSnapshot oldProjectConfig = oldWorkspaceConfig.findProjectByID(projectID);
    if (!exists()) {
        // project was deleted
        return oldProjectConfig != null ? WorkspaceChanges.createProjectRemoved(oldProjectConfig) : WorkspaceChanges.NO_CHANGES;
    }
    URI pckjson = getProjectDescriptionURI().toURI();
    if (!pckjson.equals(changedResource)) {
        // different file was saved/modified (not package.json)
        return WorkspaceChanges.NO_CHANGES;
    }
    // package.json was modified
    updateProjectStateFromDisk();
    ProjectConfigSnapshot newProjectConfig = configSnapshotFactory.createProjectConfigSnapshot(this);
    if (oldProjectConfig == null) {
        return WorkspaceChanges.createProjectAdded(newProjectConfig);
    }
    return computeChanges(oldProjectConfig, newProjectConfig);
}
Also used : ProjectConfigSnapshot(org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot) URI(org.eclipse.emf.common.util.URI) FileURI(org.eclipse.n4js.workspace.locations.FileURI)

Aggregations

ProjectConfigSnapshot (org.eclipse.n4js.xtext.workspace.ProjectConfigSnapshot)25 URI (org.eclipse.emf.common.util.URI)9 WorkspaceConfigSnapshot (org.eclipse.n4js.xtext.workspace.WorkspaceConfigSnapshot)9 Stopwatch (com.google.common.base.Stopwatch)4 Path (java.nio.file.Path)4 ArrayList (java.util.ArrayList)4 LinkedHashSet (java.util.LinkedHashSet)4 FileURI (org.eclipse.n4js.workspace.locations.FileURI)4 WorkspaceChanges (org.eclipse.n4js.xtext.workspace.WorkspaceChanges)4 IResourceDescription (org.eclipse.xtext.resource.IResourceDescription)4 HashSet (java.util.HashSet)3 Set (java.util.Set)3 ImmutableSet (com.google.common.collect.ImmutableSet)2 Injector (com.google.inject.Injector)2 File (java.io.File)2 Collections (java.util.Collections)2 TreeMap (java.util.TreeMap)2 N4JSProjectConfigSnapshot (org.eclipse.n4js.workspace.N4JSProjectConfigSnapshot)2 ResourceChangeSet (org.eclipse.n4js.xtext.ide.server.ResourceChangeSet)2 XIProjectConfig (org.eclipse.n4js.xtext.workspace.XIProjectConfig)2