use of org.eclipse.n4js.projectModel.IN4JSProject in project n4js by eclipse.
the class N4HeadlessCompiler method computeDependencyGraph.
/**
* Recursive part of {@link #computeDependencyGraph(Set, Multimap, Multimap, Collection)}. The given project is
* processed only if it has not been processed already. If that is the case, it will either be added to the given
* list of independent projects, or a dependency from the given project to each of the projects it depends on is
* added. Finally, the algorithm calls itself for each dependency.
*
* @param project
* the project being processed
* @param visitedProjects
* set of projects already processed
* @param pendencies
* maps projects to the projects that depend on them
* @param dependencies
* maps projects to the projects they depend on
* @param independent
* projects without dependencies
*/
private static void computeDependencyGraph(IN4JSProject project, Set<IN4JSProject> visitedProjects, Multimap<IN4JSProject, IN4JSProject> pendencies, Multimap<IN4JSProject, IN4JSProject> dependencies, Collection<IN4JSProject> independent) {
if (!visitedProjects.add(project))
return;
ImmutableList<? extends IN4JSProject> pendingProjects = project.getDependenciesAndImplementedApis();
if (pendingProjects.isEmpty()) {
independent.add(project);
} else {
for (IN4JSProject pendingProject : pendingProjects) {
pendencies.put(pendingProject, project);
dependencies.put(project, pendingProject);
computeDependencyGraph(pendingProject, visitedProjects, pendencies, dependencies, independent);
}
}
}
use of org.eclipse.n4js.projectModel.IN4JSProject in project n4js by eclipse.
the class N4HeadlessCompiler method computeBuildOrder.
/*
* ===============================================================================================================
*
* COMPUTING THE PROJECT BUILD ORDER AND INITIALIZING THE MARKINGS
*
* ===============================================================================================================
*/
/**
* Sort in build-order. Wraps each element of {@code toSort} with {@link MarkedProject} and applies all
* {@code buildMarker} for which the element is a (transitively) declared dependency
*
* @param allProjectsToCompile
* unsorted projects, these include the dependencies as well as the projects to compile
* @param requestedProjects
* only the projects which were requested to be compiled
* @return sorted projects: earlier projects don't depend on later
*/
private static List<MarkedProject> computeBuildOrder(List<? extends IN4JSProject> allProjectsToCompile, List<? extends IN4JSProject> requestedProjects) {
// This algorithm only operates on the following map of marked projects.
Map<IN4JSProject, MarkedProject> markedProjects = new HashMap<>();
allProjectsToCompile.stream().forEach(project -> markedProjects.put(project, new MarkedProject(project)));
// Maps a project to the projects that depend on it.
Multimap<IN4JSProject, IN4JSProject> pendencies = TreeMultimap.create(N4JSProjectComparator.INSTANCE, N4JSProjectComparator.INSTANCE);
// Maps a project to the projects it depends on.
Multimap<IN4JSProject, IN4JSProject> dependencies = TreeMultimap.create(N4JSProjectComparator.INSTANCE, N4JSProjectComparator.INSTANCE);
// Sorted set of projects without dependencies (starting points) to determine their order.
SortedSet<IN4JSProject> independentProjects = new TreeSet<>(N4JSProjectComparator.INSTANCE);
// Initialize preconditions, dependencies, and independent projects.
computeDependencyGraph(markedProjects.keySet(), pendencies, dependencies, independentProjects);
// Mark the projects to build, using a set to remove duplicates.
for (IN4JSProject project : new HashSet<>(requestedProjects)) markDependencies(project, project, markedProjects, dependencies);
return computeBuildOrderDepthFirst(markedProjects, pendencies, dependencies, independentProjects);
}
use of org.eclipse.n4js.projectModel.IN4JSProject in project n4js by eclipse.
the class N4HeadlessCompiler method markDependencies.
/**
* Recursively marks the dependency subgraph by applying the given marker to each transitive dependency of the given
* markee. Assumes that there are no cyclic dependencies in the given dependency map.
*
* @param marker
* the marker to apply
* @param markee
* the project to be marked
* @param markables
* lookup map for the markable projects
* @param dependencies
* maps a project to the projects it depends on
*/
private static void markDependencies(IN4JSProject marker, IN4JSProject markee, Map<IN4JSProject, MarkedProject> markables, Multimap<IN4JSProject, IN4JSProject> dependencies) {
// Set the mark
MarkedProject projectToMark = markables.get(markee);
projectToMark.markWith(marker);
// Recursively apply to all dependencies of the given markee
for (IN4JSProject dependency : dependencies.get(markee)) markDependencies(marker, dependency, markables, dependencies);
}
use of org.eclipse.n4js.projectModel.IN4JSProject in project n4js by eclipse.
the class N4HeadlessCompiler method computeBuildOrderDepthFirst.
/**
* Recursive part of {@link #computeBuildOrderDepthFirst(Map, Multimap, Multimap, Collection)}. If all dependencies
* of the given project have already been processed, it is added to the build order. Then, all projects that depend
* on the given project are processed recursively.
*
* @param project
* the project to process
* @param markedProjects
* the marked projects
* @param pendencies
* maps projects to the projects that depend on them
* @param dependencies
* maps projects to the projects they depend on
* @param result
* the build order being computed
*/
private static void computeBuildOrderDepthFirst(IN4JSProject project, Map<IN4JSProject, MarkedProject> markedProjects, Multimap<IN4JSProject, IN4JSProject> pendencies, Multimap<IN4JSProject, IN4JSProject> dependencies, List<MarkedProject> result) {
// process its children.
if (dependencies.get(project).isEmpty()) {
// The current project is ready to be processed.
result.add(markedProjects.get(project));
// Remove this project from the dependencies of all pending projects.
for (IN4JSProject dependentProject : pendencies.get(project)) {
dependencies.get(dependentProject).remove(project);
// Now process the pending project itself.
computeBuildOrderDepthFirst(dependentProject, markedProjects, pendencies, dependencies, result);
}
}
}
use of org.eclipse.n4js.projectModel.IN4JSProject in project n4js by eclipse.
the class ProjectImportEnablingScope method getElementsWithDesiredProjectID.
/**
* This method asks {@link #delegate} for elements matching provided <code>moduleSpecifier</code>. Returned results
* are filtered by expected {@link IN4JSProject#getProjectId()}.
*/
private Collection<IEObjectDescription> getElementsWithDesiredProjectID(QualifiedName moduleSpecifier, String projectId) {
final Iterable<IEObjectDescription> moduleSpecifierMatchesWithPossibleDuplicates = delegate.getElements(moduleSpecifier);
// delegate may return multiple entries since it allows duplication (normal 'shadowing' of scopes is not
// applied). We filter duplicates by uniqueness of target EObject URI.
final Map<String, IEObjectDescription> result = new HashMap<>();
for (IEObjectDescription desc : moduleSpecifierMatchesWithPossibleDuplicates) {
final IN4JSProject containingProject = n4jsCore.findProject(desc.getEObjectURI()).orNull();
if (containingProject != null && projectId.equals(containingProject.getProjectId())) {
result.put(desc.getEObjectURI().toString(), desc);
}
}
return result.values();
}
Aggregations