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;
}
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);
}
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;
}
}
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;
}
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);
}
Aggregations