diff --git a/source/com/intellij/cyclicDependencies/CyclicDependenciesBuilder.java b/source/com/intellij/cyclicDependencies/CyclicDependenciesBuilder.java index 2128833fd733..e120ad49acf9 100644 --- a/source/com/intellij/cyclicDependencies/CyclicDependenciesBuilder.java +++ b/source/com/intellij/cyclicDependencies/CyclicDependenciesBuilder.java @@ -1,18 +1,15 @@ package com.intellij.cyclicDependencies; import com.intellij.analysis.AnalysisScope; -import com.intellij.compiler.Chunk; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.util.Pair; import com.intellij.packageDependencies.ForwardDependenciesBuilder; import com.intellij.psi.*; import com.intellij.util.graph.CachingSemiGraph; -import com.intellij.util.graph.DFSTBuilder; import com.intellij.util.graph.Graph; import com.intellij.util.graph.GraphGenerator; @@ -189,132 +186,29 @@ public class CyclicDependenciesBuilder{ return result; } - /*public Set getDependentFilesInPackage(PsiPackage pack, PsiPackage depPack) { - final Set result = new HashSet(); - final Map> dependencies = myForwardBuilder.getDependencies(); - final Set allPsiPackageFiles = getAllPsiPackageFiles(pack); - for (Iterator it = allPsiPackageFiles.iterator(); it.hasNext();) { - PsiFile file = it.next(); - final Set psiFiles = dependencies.get(file); - if (psiFiles == null){ - continue; - } - for (Iterator iterator = psiFiles.iterator(); iterator.hasNext();) { - PsiFile psiFile = iterator.next(); - if (psiFile.getContainingDirectory().getPackage().getQualifiedName().startsWith(depPack.getQualifiedName())){ - result.add(psiFile); - } - } - } - return result; - } - public Set getDependentFilesInPackage(PsiPackage firstPack, PsiPackage middlePack, PsiPackage lastPack) { - Set result = new HashSet(); - - final Map> dependencies = myForwardBuilder.getDependencies(); - final Set allPsiPackageFiles = getAllPsiPackageFiles(middlePack); - - for (Iterator it = allPsiPackageFiles.iterator(); it.hasNext();) { - PsiFile file = it.next(); - final Set psiFiles = dependencies.get(file); - if (psiFiles == null){ - continue; - } - for (Iterator iterator = psiFiles.iterator(); iterator.hasNext();) { - PsiFile psiFile = iterator.next(); - if (psiFile.getContainingDirectory().getPackage().getQualifiedName().startsWith(lastPack.getQualifiedName())){ - result.add(file); - } - } - } - result.addAll(getDependentFilesInPackage(firstPack, middlePack)); - return result; - } - - private Set getAllPsiPackageFiles(PsiPackage aPackage){ - Set result = new HashSet(); - final PsiDirectory[] directories = aPackage.getDirectories(); - if (directories == null){ - return result; - } - for (int i = 0; i < directories.length; i++) { - PsiDirectory directory = directories[i]; - final PsiFile[] files = directory.getFiles(); - if (files == null){ - continue; - } - for (int j = 0; j < files.length; j++) { - PsiFile file = files[j]; - if (getScope().contains(file)){ - result.add(file); - } - } - final PsiDirectory[] subdirectories = directory.getSubdirectories(); - if (subdirectories == null){ - continue; - } - for (int j = 0; j < subdirectories.length; j++) { - PsiDirectory subdirectory = subdirectories[j]; - result.addAll(getAllPsiPackageFiles(subdirectory.getPackage())); - } - } - return result; - } -*/ public HashMap>> getCyclicDependencies() { return myCyclicDependencies; } public HashMap>> getCycles(Collection packages) { + if (myGraph == null){ + myGraph = buildGraph(); + } final HashMap>> result = new HashMap>>(); - final List> chunks = buildChunks(); for (Iterator iterator = packages.iterator(); iterator.hasNext();) { PsiPackage psiPackage = iterator.next(); - final List> chunksByPackage = findChunksByPackage(psiPackage, chunks); - for (Iterator> it = chunksByPackage.iterator(); it.hasNext();) { - Chunk chunk = it.next(); - if (chunk.getNodes().size() == 1){ - continue; - } Set> paths2Pack = result.get(psiPackage); if (paths2Pack == null) { paths2Pack = new HashSet>(); result.put(psiPackage, paths2Pack); } paths2Pack.addAll(CyclicGraphUtil.getNodeCycles(myGraph, psiPackage)); - /*final CyclicDependenciesUtil.GraphTraverser graphTraverser = new CyclicDependenciesUtil.GraphTraverser(psiPackage, chunk, 10, myGraph); - paths2Pack.addAll(graphTraverser.convert(graphTraverser.traverse()));*/ - } - } - /*for (Iterator> iterator = chunks.iterator(); iterator.hasNext();) { - Chunk chunk = iterator.next(); - for (Iterator it = chunk.getNodes().iterator(); it.hasNext();) { - PsiPackage pack = it.next(); - Set> chunks2Pack = result.get(pack); - if (chunks2Pack == null) { - chunks2Pack = new HashSet>(); - result.put(pack, chunks2Pack); - } - chunks2Pack.add(chunk); - } - - }*/ - return result; - } - - private List> findChunksByPackage(PsiPackage pack, List> chunks) { - List> result = new ArrayList>(); - for (Iterator> iterator = chunks.iterator(); iterator.hasNext();) { - Chunk chunk = iterator.next(); - if (chunk.containsNode(pack)) { - result.add(chunk); - } } return result; } - public Map getAllProjectPackages() { + public Map getAllScopePackages() { if (myPackages.isEmpty()) { final PsiManager psiManager = PsiManager.getInstance(getProject()); getScope().accept(new PsiRecursiveElementVisitor() { @@ -336,7 +230,7 @@ public class CyclicDependenciesBuilder{ private Graph buildGraph() { final Graph graph = GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph() { public Collection getNodes() { - return getAllProjectPackages().values(); + return getAllScopePackages().values(); } public Iterator getIn(PsiPackage psiPack) { @@ -371,30 +265,8 @@ public class CyclicDependenciesBuilder{ } private PsiPackage findPackage(String packName) { - final PsiPackage psiPackage = getAllProjectPackages().get(packName); + final PsiPackage psiPackage = getAllScopePackages().get(packName); return psiPackage; } - private List> buildChunks() { - if (myGraph == null) { - myGraph = buildGraph(); - } - final DFSTBuilder dfstBuilder = new DFSTBuilder(myGraph); - dfstBuilder.buildDFST(); - final LinkedList> sccs = dfstBuilder.getSCCs(); - List> chunks = new ArrayList>(); - for (Iterator> i = sccs.iterator(); i.hasNext();) { - Set packs = new HashSet(); - final Pair p = i.next(); - final Integer biT = p.getFirst(); - final int binum = biT.intValue(); - - for (int j = 0; j < p.getSecond().intValue(); j++) { - packs.add(dfstBuilder.getNodeByTNumber(binum + j)); - } - chunks.add(new Chunk(packs)); - } - return chunks; - } - } diff --git a/source/com/intellij/cyclicDependencies/ui/CycleNode.java b/source/com/intellij/cyclicDependencies/ui/CycleNode.java index 7715c776f94a..a616d8330ab6 100644 --- a/source/com/intellij/cyclicDependencies/ui/CycleNode.java +++ b/source/com/intellij/cyclicDependencies/ui/CycleNode.java @@ -2,13 +2,9 @@ package com.intellij.cyclicDependencies.ui; import com.intellij.packageDependencies.ui.PackageDependenciesNode; import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiElement; import javax.swing.*; -import javax.swing.tree.MutableTreeNode; -import javax.swing.tree.DefaultMutableTreeNode; import java.util.Set; -import java.util.Iterator; /** * User: anna @@ -20,7 +16,7 @@ public class CycleNode extends PackageDependenciesNode{ } public void addFile(PsiFile file, boolean isMarked) { - super.addFile(file, isMarked); //To change body of overridden methods use File | Settings | File Templates. + super.addFile(file, isMarked); } public Icon getOpenIcon() { diff --git a/source/com/intellij/cyclicDependencies/ui/CyclicDependenciesPanel.java b/source/com/intellij/cyclicDependencies/ui/CyclicDependenciesPanel.java index 9c8d992e9895..85323a82a0ec 100644 --- a/source/com/intellij/cyclicDependencies/ui/CyclicDependenciesPanel.java +++ b/source/com/intellij/cyclicDependencies/ui/CyclicDependenciesPanel.java @@ -362,10 +362,6 @@ public class CyclicDependenciesPanel extends JPanel { else { setIcon(node.getClosedIcon()); } - - if (node.hasMarked() && !selected) { - setForeground(Color.red); - } append(node.toString(), SimpleTextAttributes.REGULAR_ATTRIBUTES); } } diff --git a/testData/dependencies/cycle/noCycle/com/a/A.java b/testData/dependencies/cycle/noCycle/com/a/A.java new file mode 100644 index 000000000000..93db78960126 --- /dev/null +++ b/testData/dependencies/cycle/noCycle/com/a/A.java @@ -0,0 +1,4 @@ +package com.a; +public class A{ + +} \ No newline at end of file diff --git a/testData/dependencies/cycle/noCycle/com/b/B.java b/testData/dependencies/cycle/noCycle/com/b/B.java new file mode 100644 index 000000000000..d6ec84e7dfa8 --- /dev/null +++ b/testData/dependencies/cycle/noCycle/com/b/B.java @@ -0,0 +1,5 @@ +package com.b; +import com.a.A; +public class B{ +A aa = new A(); +} \ No newline at end of file diff --git a/testData/dependencies/cycle/t6/com/a/A.java b/testData/dependencies/cycle/t6/com/a/A.java new file mode 100644 index 000000000000..fab818d15420 --- /dev/null +++ b/testData/dependencies/cycle/t6/com/a/A.java @@ -0,0 +1,5 @@ +package com.a; +import com.b.B1; +public class A{ + B1 b = new B1(); +} \ No newline at end of file diff --git a/testData/dependencies/cycle/t6/com/b/B1.java b/testData/dependencies/cycle/t6/com/b/B1.java new file mode 100644 index 000000000000..cbd550c188e4 --- /dev/null +++ b/testData/dependencies/cycle/t6/com/b/B1.java @@ -0,0 +1,4 @@ +package com.b; +public class B1{ + +} \ No newline at end of file diff --git a/testData/dependencies/cycle/t6/com/b/B2.java b/testData/dependencies/cycle/t6/com/b/B2.java new file mode 100644 index 000000000000..38b8c9d34194 --- /dev/null +++ b/testData/dependencies/cycle/t6/com/b/B2.java @@ -0,0 +1,5 @@ +package com.b; +import com.c.C; +public class B2{ +C cc= new C(); +} \ No newline at end of file diff --git a/testData/dependencies/cycle/t6/com/c/C.java b/testData/dependencies/cycle/t6/com/c/C.java new file mode 100644 index 000000000000..37c3465565fc --- /dev/null +++ b/testData/dependencies/cycle/t6/com/c/C.java @@ -0,0 +1,5 @@ +package com.c; +import com.a.A; +public class C{ +A aa = new A(); +} \ No newline at end of file diff --git a/testSource/com/intellij/dependencies/CyclicDependenciesTest.java b/testSource/com/intellij/dependencies/CyclicDependenciesTest.java index f5f82c211b66..16d2104572ba 100644 --- a/testSource/com/intellij/dependencies/CyclicDependenciesTest.java +++ b/testSource/com/intellij/dependencies/CyclicDependenciesTest.java @@ -130,6 +130,33 @@ public class CyclicDependenciesTest extends PsiTestCase { checkResult(expected, cyclicDependencies, true); } + public void testT6() { + //A->B1 + //B2->C + //C->A + final CyclicDependenciesBuilder builder = new CyclicDependenciesBuilder(myProject, + new AnalysisScope(myProject, AnalysisScope.SOURCE_JAVA_FILES)); + builder.analyze(); + final HashMap>> cyclicDependencies = builder.getCyclicDependencies(); + HashMap expected = new HashMap(); + expected.put("com.b", new String[][]{{"com.a", "com.c", "com.b"}}); + expected.put("com.c", new String[][]{{"com.b", "com.a", "com.c"}}); + expected.put("com.a", new String[][]{{"com.c", "com.b", "com.a"}}); + checkResult(expected, cyclicDependencies, true); + } + + public void testNoCycle(){ + //B->A + final CyclicDependenciesBuilder builder = new CyclicDependenciesBuilder(myProject, + new AnalysisScope(myProject, AnalysisScope.SOURCE_JAVA_FILES)); + builder.analyze(); + final HashMap>> cyclicDependencies = builder.getCyclicDependencies(); + HashMap expected = new HashMap(); + expected.put("com.b", new String[0][0]); + expected.put("com.a", new String[0][0]); + checkResult(expected, cyclicDependencies, true); + } + private void checkResult(HashMap expected, HashMap>> cycles) { assertEquals(expected.size(), cycles.size()); Iterator it = cycles.keySet().iterator();