use of com.intellij.util.graph.DFSTBuilder in project intellij-community by JetBrains.
the class JavaModuleGraphUtil method findCycles.
// Looks for cycles between Java modules in the project sources.
// Library/JDK modules are excluded - in assumption there can't be any lib -> src dependencies.
// Module references are resolved "globally" (i.e., without taking project dependencies into account).
private static List<Set<PsiJavaModule>> findCycles(Project project) {
Set<PsiJavaModule> projectModules = ContainerUtil.newHashSet();
for (Module module : ModuleManager.getInstance(project).getModules()) {
Collection<VirtualFile> files = FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, module.getModuleScope(false));
// aborts the process when there are incorrect modules in the project
if (files.size() > 1)
return Collections.emptyList();
Optional.ofNullable(ContainerUtil.getFirstItem(files)).map(PsiManager.getInstance(project)::findFile).map(f -> f instanceof PsiJavaFile ? ((PsiJavaFile) f).getModuleDeclaration() : null).ifPresent(projectModules::add);
}
if (!projectModules.isEmpty()) {
MultiMap<PsiJavaModule, PsiJavaModule> relations = MultiMap.create();
for (PsiJavaModule module : projectModules) {
for (PsiRequiresStatement statement : module.getRequires()) {
PsiJavaModule dependency = PsiJavaModuleReference.resolve(statement, statement.getModuleName(), true);
if (dependency != null && projectModules.contains(dependency)) {
relations.putValue(module, dependency);
}
}
}
if (!relations.isEmpty()) {
Graph<PsiJavaModule> graph = new ChameleonGraph<>(relations, false);
DFSTBuilder<PsiJavaModule> builder = new DFSTBuilder<>(graph);
Collection<Collection<PsiJavaModule>> components = builder.getComponents();
if (!components.isEmpty()) {
return components.stream().map(ContainerUtil::newLinkedHashSet).collect(Collectors.toList());
}
}
}
return Collections.emptyList();
}
use of com.intellij.util.graph.DFSTBuilder in project intellij-community by JetBrains.
the class TypeMigrationLabeler method sortMigratedUsages.
private TypeMigrationUsageInfo[] sortMigratedUsages(TypeMigrationUsageInfo[] infos) {
final DFSTBuilder<TypeMigrationUsageInfo> builder = new DFSTBuilder<>(GraphGenerator.generate(new InboundSemiGraph<TypeMigrationUsageInfo>() {
@Override
public Collection<TypeMigrationUsageInfo> getNodes() {
final Set<TypeMigrationUsageInfo> infos = new HashSet<>();
for (Map.Entry<TypeMigrationUsageInfo, HashSet<Pair<TypeMigrationUsageInfo, PsiType>>> entry : myRootsTree.entrySet()) {
infos.add(entry.getKey());
infos.addAll(ContainerUtil.map(entry.getValue(), pair -> pair.getFirst()));
}
return infos;
}
@Override
public Iterator<TypeMigrationUsageInfo> getIn(TypeMigrationUsageInfo n) {
final HashSet<Pair<TypeMigrationUsageInfo, PsiType>> rawNodes = myRootsTree.get(n);
if (rawNodes == null) {
return Collections.<TypeMigrationUsageInfo>emptyList().iterator();
}
final List<TypeMigrationUsageInfo> in = ContainerUtil.map(rawNodes, pair -> pair.getFirst());
return in.iterator();
}
}));
final Comparator<TypeMigrationUsageInfo> cmp = builder.comparator();
Arrays.sort(infos, (info1, info2) -> {
final TypeMigrationUsageInfo i1 = info1.getOwnerRoot();
final TypeMigrationUsageInfo i2 = info2.getOwnerRoot();
if (i1 == null && i2 == null) {
return 0;
}
if (i1 == null) {
return 1;
}
if (i2 == null) {
return -1;
}
final PsiElement element1 = info1.getElement();
final PsiElement element2 = info2.getElement();
LOG.assertTrue(element1 != null && element2 != null);
if (element1.equals(element2)) {
return 0;
}
final TextRange range1 = element1.getTextRange();
final TextRange range2 = element2.getTextRange();
if (range1.contains(range2)) {
return 1;
}
if (range2.contains(range1)) {
return -1;
}
final int res = cmp.compare(i1, i2);
if (res != 0) {
return res;
}
return range2.getStartOffset() - range1.getStartOffset();
});
return infos;
}
use of com.intellij.util.graph.DFSTBuilder in project intellij-community by JetBrains.
the class ResolverTree method reduceCyclicVariables.
private void reduceCyclicVariables() {
final Set<PsiTypeVariable> nodes = new HashSet<>();
final Set<Constraint> candidates = new HashSet<>();
final Map<PsiTypeVariable, Set<PsiTypeVariable>> ins = new HashMap<>();
final Map<PsiTypeVariable, Set<PsiTypeVariable>> outs = new HashMap<>();
for (final Constraint constraint : myConstraints) {
final PsiType left = constraint.getLeft();
final PsiType right = constraint.getRight();
if (left instanceof PsiTypeVariable && right instanceof PsiTypeVariable) {
final PsiTypeVariable leftVar = (PsiTypeVariable) left;
final PsiTypeVariable rightVar = (PsiTypeVariable) right;
candidates.add(constraint);
nodes.add(leftVar);
nodes.add(rightVar);
Set<PsiTypeVariable> in = ins.get(leftVar);
Set<PsiTypeVariable> out = outs.get(rightVar);
if (in == null) {
final Set<PsiTypeVariable> newIn = new HashSet<>();
newIn.add(rightVar);
ins.put(leftVar, newIn);
} else {
in.add(rightVar);
}
if (out == null) {
final Set<PsiTypeVariable> newOut = new HashSet<>();
newOut.add(leftVar);
outs.put(rightVar, newOut);
} else {
out.add(leftVar);
}
}
}
final DFSTBuilder<PsiTypeVariable> dfstBuilder = new DFSTBuilder<>(new Graph<PsiTypeVariable>() {
@Override
public Collection<PsiTypeVariable> getNodes() {
return nodes;
}
@Override
public Iterator<PsiTypeVariable> getIn(final PsiTypeVariable n) {
final Set<PsiTypeVariable> in = ins.get(n);
if (in == null) {
return EmptyIterator.getInstance();
}
return in.iterator();
}
@Override
public Iterator<PsiTypeVariable> getOut(final PsiTypeVariable n) {
final Set<PsiTypeVariable> out = outs.get(n);
if (out == null) {
return EmptyIterator.getInstance();
}
return out.iterator();
}
});
final TIntArrayList sccs = dfstBuilder.getSCCs();
final Map<PsiTypeVariable, Integer> index = new HashMap<>();
sccs.forEach(new TIntProcedure() {
int myTNumber;
@Override
public boolean execute(int size) {
for (int j = 0; j < size; j++) {
index.put(dfstBuilder.getNodeByTNumber(myTNumber + j), myTNumber);
}
myTNumber += size;
return true;
}
});
for (final Constraint constraint : candidates) {
if (index.get(constraint.getLeft()).equals(index.get(constraint.getRight()))) {
myConstraints.remove(constraint);
}
}
Binding binding = myBindingFactory.create();
for (final PsiTypeVariable fromVar : index.keySet()) {
final PsiTypeVariable toVar = dfstBuilder.getNodeByNNumber(index.get(fromVar).intValue());
if (!fromVar.equals(toVar)) {
binding = binding.compose(myBindingFactory.create(fromVar, toVar));
if (binding == null) {
break;
}
}
}
if (binding != null && binding.nonEmpty()) {
myCurrentBinding = myCurrentBinding.compose(binding);
myConstraints = apply(binding);
}
}
use of com.intellij.util.graph.DFSTBuilder in project intellij-community by JetBrains.
the class InspectionProfileImpl method initialize.
@Override
protected void initialize(@Nullable Project project) {
SchemeDataHolder<? super InspectionProfileImpl> dataHolder = myDataHolder;
if (dataHolder != null) {
myDataHolder = null;
Element element = dataHolder.read();
if (element.getName().equals("component")) {
element = element.getChild("profile");
}
assert element != null;
readExternal(element);
}
if (myBaseProfile != null) {
myBaseProfile.initInspectionTools(project);
}
final List<InspectionToolWrapper> tools;
try {
tools = createTools(project);
} catch (ProcessCanceledException ignored) {
return;
}
final Map<String, List<String>> dependencies = new THashMap<>();
for (InspectionToolWrapper toolWrapper : tools) {
addTool(project, toolWrapper, dependencies);
}
DFSTBuilder<String> builder = new DFSTBuilder<>(GraphGenerator.generate(new InboundSemiGraph<String>() {
@Override
public Collection<String> getNodes() {
return dependencies.keySet();
}
@Override
public Iterator<String> getIn(String n) {
return dependencies.get(n).iterator();
}
}));
if (builder.isAcyclic()) {
myScopesOrder = ArrayUtil.toStringArray(builder.getSortedNodes());
}
copyToolsConfigurations(project);
initialized = true;
if (dataHolder != null) {
// should be only after set myInitialized
dataHolder.updateDigest(this);
}
}
use of com.intellij.util.graph.DFSTBuilder in project intellij-community by JetBrains.
the class ModifiableModelCommitter method createDFSTBuilder.
private static DFSTBuilder<RootModelImpl> createDFSTBuilder(List<RootModelImpl> rootModels, final ModifiableModuleModel moduleModel) {
final Map<String, RootModelImpl> nameToModel = ContainerUtil.newHashMap();
for (RootModelImpl rootModel : rootModels) {
String name = rootModel.getModule().getName();
LOG.assertTrue(!nameToModel.containsKey(name), name);
nameToModel.put(name, rootModel);
}
Module[] modules = moduleModel.getModules();
for (Module module : modules) {
String name = module.getName();
if (!nameToModel.containsKey(name)) {
RootModelImpl rootModel = ((ModuleRootManagerImpl) ModuleRootManager.getInstance(module)).getRootModel();
nameToModel.put(name, rootModel);
}
}
final Collection<RootModelImpl> allRootModels = nameToModel.values();
InboundSemiGraph<RootModelImpl> graph = new InboundSemiGraph<RootModelImpl>() {
@Override
public Collection<RootModelImpl> getNodes() {
return allRootModels;
}
@Override
public Iterator<RootModelImpl> getIn(RootModelImpl rootModel) {
OrderEnumerator entries = rootModel.orderEntries().withoutSdk().withoutLibraries().withoutModuleSourceEntries();
List<String> namesList = entries.process(new RootPolicy<List<String>>() {
@Override
public List<String> visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry, List<String> strings) {
Module module = moduleOrderEntry.getModule();
if (module != null && !module.isDisposed()) {
strings.add(module.getName());
} else {
final Module moduleToBeRenamed = moduleModel.getModuleToBeRenamed(moduleOrderEntry.getModuleName());
if (moduleToBeRenamed != null && !moduleToBeRenamed.isDisposed()) {
strings.add(moduleToBeRenamed.getName());
}
}
return strings;
}
}, new ArrayList<>());
String[] names = ArrayUtil.toStringArray(namesList);
List<RootModelImpl> result = new ArrayList<>();
for (String name : names) {
RootModelImpl depRootModel = nameToModel.get(name);
if (depRootModel != null) {
// it is ok not to find one
result.add(depRootModel);
}
}
return result.iterator();
}
};
return new DFSTBuilder<>(GraphGenerator.generate(CachingSemiGraph.cache(graph)));
}
Aggregations