public static <Node> List<Chunk<Node>> buildChunks(Graph<Node> graph) { final DFSTBuilder<Node> dfstBuilder = new DFSTBuilder<Node>(graph); final TIntArrayList sccs = dfstBuilder.getSCCs(); final List<Chunk<Node>> chunks = new ArrayList<Chunk<Node>>(); sccs.forEach(new TIntProcedure() { int myTNumber = 0; public boolean execute(int size) { Set<Node> packs = new LinkedHashSet<Node>(); for (int j = 0; j < size; j++) { packs.add(dfstBuilder.getNodeByTNumber(myTNumber + j)); } chunks.add(new Chunk<Node>(packs)); myTNumber += size; return true; } }); return chunks; }
private Graph<PsiPackage> buildGraph() { final Graph<PsiPackage> graph = GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<PsiPackage>() { public Collection<PsiPackage> getNodes() { return getAllScopePackages().values(); } public Iterator<PsiPackage> getIn(PsiPackage psiPack) { final Set<PsiPackage> psiPackages = myPackageDependencies.get(psiPack); if (psiPackages == null) { //for packs without java classes return new HashSet<PsiPackage>().iterator(); } return psiPackages.iterator(); } })); return graph; }
private static void buildDependenciesForModule(final Module module, final Graph<Module> graph, Map<Module, Collection<Module>> map) { final Set<Module> deps = new com.intellij.util.containers.HashSet<Module>(); map.put(module, deps); new Object() { void traverse(Module m) { for (Iterator<Module> iterator = graph.getIn(m); iterator.hasNext();) { final Module dep = iterator.next(); if (!deps.contains(dep)) { deps.add(dep); traverse(dep); } } } }.traverse(module); }
private Graph<Compiler> createCompilerGraph(final List<Compiler> compilers) { return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<Compiler>() { public Collection<Compiler> getNodes() { return compilers; } public Iterator<Compiler> getIn(Compiler compiler) { final Set<FileType> compilerInput = myCompilerToInputTypes.get(compiler); if (compilerInput == null || compilerInput.isEmpty()) { return Collections.<Compiler>emptySet().iterator(); } final Set<Compiler> inCompilers = new HashSet<Compiler>(); for (Map.Entry<Compiler, Set<FileType>> entry : myCompilerToOutputTypes.entrySet()) { final Set<FileType> outputs = entry.getValue(); Compiler comp = entry.getKey(); if (outputs != null && ContainerUtil.intersects(compilerInput, outputs)) { inCompilers.add(comp); } } return inCompilers.iterator(); } })); }
static Comparator<IdeaPluginDescriptor> getPluginDescriptorComparator(Map<PluginId, IdeaPluginDescriptorImpl> idToDescriptorMap) { final Graph<PluginId> graph = createPluginIdGraph(idToDescriptorMap); final DFSTBuilder<PluginId> builder = new DFSTBuilder<PluginId>(graph); /* if (!builder.isAcyclic()) { final Pair<String,String> circularDependency = builder.getCircularDependency(); throw new Exception("Cyclic dependencies between plugins are not allowed: \"" + circularDependency.getFirst() + "\" and \"" + circularDependency.getSecond() + ""); } */ final Comparator<PluginId> idComparator = builder.comparator(); return new Comparator<IdeaPluginDescriptor>() { @Override public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) { return idComparator.compare(o1.getPluginId(), o2.getPluginId()); } }; }
private Graph<PsiJavaPackage> buildGraph() { final Graph<PsiJavaPackage> graph = GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<PsiJavaPackage>() { public Collection<PsiJavaPackage> getNodes() { return getAllScopePackages().values(); } public Iterator<PsiJavaPackage> getIn(PsiJavaPackage psiPack) { final Set<PsiJavaPackage> psiPackages = myPackageDependencies.get(psiPack); if (psiPackages == null) { //for packs without java classes return new HashSet<PsiJavaPackage>().iterator(); } return psiPackages.iterator(); } })); return graph; }
@NotNull public static List<Module> getAllDependentModules(@NotNull Module module) { final ArrayList<Module> list = new ArrayList<Module>(); final Graph<Module> graph = ModuleManager.getInstance(module.getProject()).moduleGraph(); for (Iterator<Module> i = graph.getOut(module); i.hasNext();) { list.add(i.next()); } return list; }
private Graph<Module> moduleGraph(final boolean includeTests) { return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<Module>() { @Override public Collection<Module> getNodes() { return myModules.values(); } @Override public Iterator<Module> getIn(Module m) { Module[] dependentModules = ModuleRootManager.getInstance(m).getDependencies(includeTests); return Arrays.asList(dependentModules).iterator(); } })); }
@NotNull @Override public List<Module> getAllDependentModules(@NotNull Module module) { final ArrayList<Module> list = new ArrayList<Module>(); final Graph<Module> graph = getModuleGraph(true); for (Iterator<Module> i = graph.getOut(module); i.hasNext();) { list.add(i.next()); } return list; }
private Graph<Module> getModuleGraph(final boolean includeTests) { return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<Module>() { @Override public Collection<Module> getNodes() { return ContainerUtil.list(getModules()); } @Override public Iterator<Module> getIn(Module m) { Module[] dependentModules = getModifiableRootModel(m).getModuleDependencies(includeTests); return Arrays.asList(dependentModules).iterator(); } })); }
@NotNull private static Graph<PluginId> createPluginIdGraph(@NotNull final Map<PluginId, ? extends IdeaPluginDescriptor> idToDescriptorMap) { final List<PluginId> ids = new ArrayList<PluginId>(idToDescriptorMap.keySet()); // this magic ensures that the dependent plugins always follow their dependencies in lexicographic order // needed to make sure that extensions are always in the same order Collections.sort(ids, new Comparator<PluginId>() { @Override public int compare(@NotNull PluginId o1, @NotNull PluginId o2) { return o2.getIdString().compareTo(o1.getIdString()); } }); return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<PluginId>() { @Override public Collection<PluginId> getNodes() { return ids; } @Override public Iterator<PluginId> getIn(PluginId pluginId) { final IdeaPluginDescriptor descriptor = idToDescriptorMap.get(pluginId); List<PluginId> plugins = new ArrayList<PluginId>(); for (PluginId dependentPluginId : descriptor.getDependentPluginIds()) { // check for missing optional dependency IdeaPluginDescriptor dep = idToDescriptorMap.get(dependentPluginId); if (dep != null) { plugins.add(dep.getPluginId()); } } return plugins.iterator(); } })); }
public static Map<Module, Collection<Module>> buildAllDependencies(final Project project) { Graph<Module> graph = ModuleManager.getInstance(project).moduleGraph(); Map<Module, Collection<Module>> result = new HashMap<Module, Collection<Module>>(); for (final Module module : graph.getNodes()) { buildDependenciesForModule(module, graph, result); } return result; }
private Graph<Module> buildGraph() { final Graph<Module> graph = ModuleManager.getInstance(myProject).moduleGraph(); if (isForwardDirection()) { return graph; } else { return GraphAlgorithms.getInstance().invertEdgeDirections(graph); } }
/** Find an Android module that depends on this module; prefer app modules over library modules */ @Nullable private static Module findAndroidModule(@NonNull final Module module) { // Search for dependencies of this module Graph<Module> graph = ApplicationManager.getApplication().runReadAction(new Computable<Graph<Module>>() { @Override public Graph<Module> compute() { return ModuleManager.getInstance(module.getProject()).moduleGraph(); } }); Set<AndroidFacet> facets = Sets.newHashSet(); HashSet<Module> seen = Sets.newHashSet(); seen.add(module); addAndroidModules(facets, seen, graph, module); // Prefer Android app modules for (AndroidFacet facet : facets) { if (!facet.isLibraryProject()) { return facet.getModule(); } } // Resort to library modules if no app module depends directly on it if (!facets.isEmpty()) { return facets.iterator().next().getModule(); } return null; }
private static void addAndroidModules(Set<AndroidFacet> androidFacets, Set<Module> seen, Graph<Module> graph, Module module) { Iterator<Module> iterator = graph.getOut(module); while (iterator.hasNext()) { Module dep = iterator.next(); AndroidFacet facet = AndroidFacet.getInstance(dep); if (facet != null) { androidFacets.add(facet); } if (!seen.contains(dep)) { seen.add(dep); addAndroidModules(androidFacets, seen, graph, dep); } } }
@Override public void check(ProjectStructureProblemsHolder problemsHolder) { final Graph<Chunk<ModuleRootModel>> graph = ModuleCompilerUtil.toChunkGraph(myContext.getModulesConfigurator().createGraphGenerator()); final Collection<Chunk<ModuleRootModel>> chunks = graph.getNodes(); List<String> cycles = new ArrayList<String>(); for (Chunk<ModuleRootModel> chunk : chunks) { final Set<ModuleRootModel> modules = chunk.getNodes(); List<String> names = new ArrayList<String>(); for (ModuleRootModel model : modules) { names.add(model.getModule().getName()); } if (modules.size() > 1) { cycles.add(StringUtil.join(names, ", ")); } } if (!cycles.isEmpty()) { final Project project = myContext.getProject(); final PlaceInProjectStructureBase place = new PlaceInProjectStructureBase(project, ProjectStructureConfigurable.getInstance(project).createModulesPlace(), this); final String message; final String description; if (cycles.size() > 1) { message = "Circular dependencies"; @NonNls final String br = "<br> "; StringBuilder cyclesString = new StringBuilder(); for (int i = 0; i < cycles.size(); i++) { cyclesString.append(br).append(i + 1).append(". ").append(cycles.get(i)); } description = ProjectBundle.message("module.circular.dependency.warning.description", cyclesString); } else { message = ProjectBundle.message("module.circular.dependency.warning.short", cycles.get(0)); description = null; } problemsHolder.registerProblem(new ProjectStructureProblemDescription(message, description, place, ProjectStructureProblemType.warning("module-circular-dependency"), Collections.<ConfigurationErrorQuickFix>emptyList())); } }
private Graph<Module> moduleGraph(final boolean includeTests) { return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<Module>() { @Override public Collection<Module> getNodes() { return myPathToModule.values(); } @Override public Iterator<Module> getIn(Module m) { Module[] dependentModules = ModuleRootManager.getInstance(m).getDependencies(includeTests); return Arrays.asList(dependentModules).iterator(); } })); }
private static Graph<PluginId> createPluginIdGraph(final Map<PluginId, IdeaPluginDescriptorImpl> idToDescriptorMap) { final List<PluginId> ids = new ArrayList<PluginId>(idToDescriptorMap.keySet()); // this magic ensures that the dependent plugins always follow their dependencies in lexicographic order // needed to make sure that extensions are always in the same order Collections.sort(ids, new Comparator<PluginId>() { @Override public int compare(PluginId o1, PluginId o2) { return o2.getIdString().compareTo(o1.getIdString()); } }); return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<PluginId>() { @Override public Collection<PluginId> getNodes() { return ids; } @Override public Iterator<PluginId> getIn(PluginId pluginId) { final IdeaPluginDescriptor descriptor = idToDescriptorMap.get(pluginId); ArrayList<PluginId> plugins = new ArrayList<PluginId>(); for (PluginId dependentPluginId : descriptor.getDependentPluginIds()) { // check for missing optional dependency if (idToDescriptorMap.containsKey(dependentPluginId)) { plugins.add(dependentPluginId); } } return plugins.iterator(); } })); }
private Graph<TranslatingCompiler> createCompilerGraph(final List<TranslatingCompiler> compilers) { return GraphGenerator.generate(new InboundSemiGraph<TranslatingCompiler>() { @Override public Collection<TranslatingCompiler> getNodes() { return compilers; } @Override public Iterator<TranslatingCompiler> getIn(TranslatingCompiler compiler) { final Collection<FileType> compilerInput = myTranslatingCompilerInputFileTypes.get(compiler); if (compilerInput == null || compilerInput.isEmpty()) { return Collections.<TranslatingCompiler>emptySet().iterator(); } final Set<TranslatingCompiler> inCompilers = new HashSet<>(); for (Map.Entry<TranslatingCompiler, Collection<FileType>> entry : myTranslatingCompilerOutputFileTypes.entrySet()) { final Collection<FileType> outputs = entry.getValue(); TranslatingCompiler comp = entry.getKey(); if (outputs != null && ContainerUtil.intersects(compilerInput, outputs)) { inCompilers.add(comp); } } return inCompilers.iterator(); } }); }
@Nonnull @RequiredReadAction public static List<Module> getAllDependentModules(@Nonnull Module module) { final ArrayList<Module> list = new ArrayList<Module>(); final Graph<Module> graph = ModuleManager.getInstance(module.getProject()).moduleGraph(); for (Iterator<Module> i = graph.getOut(module); i.hasNext(); ) { list.add(i.next()); } return list; }
private static RequiresGraph buildRequiresGraph(Project project) { MultiMap<PsiJavaModule, PsiJavaModule> relations = MultiMap.create(); Set<String> transitiveEdges = ContainerUtil.newTroveSet(); for(Module module : ModuleManager.getInstance(project).getModules()) { Collection<VirtualFile> files = FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, module.getModuleScope()); Optional.ofNullable(ContainerUtil.getFirstItem(files)).map(PsiManager.getInstance(project)::findFile).map(f -> f instanceof PsiJavaFile ? ((PsiJavaFile) f).getModuleDeclaration() : null) .ifPresent(m -> visit(m, relations, transitiveEdges)); } Graph<PsiJavaModule> graph = GraphGenerator.generate(new ChameleonGraph<>(relations, true)); return new RequiresGraph(graph, transitiveEdges); }
@Override public CommonProblemDescriptor[] checkElement(@NotNull RefEntity refEntity, @NotNull AnalysisScope scope, @NotNull InspectionManager manager, @NotNull final GlobalInspectionContext globalContext) { if (refEntity instanceof RefModule){ final RefModule refModule = (RefModule)refEntity; final Module module = refModule.getModule(); if (module.isDisposed() || !scope.containsModule(module)) return CommonProblemDescriptor.EMPTY_ARRAY; final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); final OrderEntry[] declaredDependencies = moduleRootManager.getOrderEntries(); final Module[] declaredModuleDependencies = moduleRootManager.getDependencies(); List<CommonProblemDescriptor> descriptors = new ArrayList<CommonProblemDescriptor>(); final Set<Module> modules = refModule.getUserData(UnnecessaryModuleDependencyAnnotator.DEPENDENCIES); Graph<Module> graph = myGraph.get(); if (graph == null) { graph = ModuleManager.getInstance(globalContext.getProject()).moduleGraph(); myGraph = new SoftReference<Graph<Module>>(graph); } final RefManager refManager = globalContext.getRefManager(); for (final OrderEntry entry : declaredDependencies) { if (entry instanceof ModuleOrderEntry) { final Module dependency = ((ModuleOrderEntry)entry).getModule(); if (dependency != null) { if (modules == null || !modules.contains(dependency)) { List<String> dependenciesThroughExported = null; if (((ModuleOrderEntry)entry).isExported()) { final Iterator<Module> iterator = graph.getOut(module); while (iterator.hasNext()) { final Module dep = iterator.next(); final RefModule depRefModule = refManager.getRefModule(dep); if (depRefModule != null) { final Set<Module> neededModules = depRefModule.getUserData(UnnecessaryModuleDependencyAnnotator.DEPENDENCIES); if (neededModules != null && neededModules.contains(dependency)) { if (dependenciesThroughExported == null) { dependenciesThroughExported = new ArrayList<String>(); } dependenciesThroughExported.add(dep.getName()); } } } } if (modules != null) { List<String> transitiveDependencies = new ArrayList<String>(); final OrderEntry[] dependenciesOfDependencies = ModuleRootManager.getInstance(dependency).getOrderEntries(); for (OrderEntry secondDependency : dependenciesOfDependencies) { if (secondDependency instanceof ModuleOrderEntry && ((ModuleOrderEntry)secondDependency).isExported()) { final Module mod = ((ModuleOrderEntry)secondDependency).getModule(); if (mod != null && modules.contains(mod) && ArrayUtil.find(declaredModuleDependencies, mod) < 0) { transitiveDependencies.add(mod.getName()); } } } if (!transitiveDependencies.isEmpty()) { final String exported = StringUtil.join(transitiveDependencies, ", "); descriptors.add(manager.createProblemDescriptor(InspectionsBundle.message("unnecessary.module.dependency.exported.problem.descriptor1", module.getName(), dependency.getName(), exported))); continue; } } descriptors.add(createDescriptor(scope, manager, module, dependency, dependenciesThroughExported)); } } } } return descriptors.isEmpty() ? null : descriptors.toArray(new CommonProblemDescriptor[descriptors.size()]); } return null; }
public GraphTraverser(final Node begin, final Chunk<Node> chunk, final int maxPathsCount, final Graph<Node> graph) { myBegin = begin; myChunk = chunk; myMaxPathsCount = maxPathsCount; myGraph = graph; }
@Override @NotNull public Graph<Module> moduleGraph() { return moduleGraph(true); }
@NotNull @Override public Graph<Module> moduleGraph(boolean includeTests) { ApplicationManager.getApplication().assertReadAccessAllowed(); return myModuleModel.moduleGraph(includeTests); }
public ShortestPathFinder(Graph<Node> graph) { myGraph = graph; }
public CycleFinder(Graph<Node> graph) { myGraph = graph; }
public KShortestPathsFinder(@NotNull Graph<Node> graph, @NotNull Node start, @NotNull Node finish, @NotNull ProgressIndicator progressIndicator) { myGraph = graph; myStart = start; myFinish = finish; myProgressIndicator = progressIndicator; }