diff --git a/resources/src/idea/ActionManager.xml b/resources/src/idea/ActionManager.xml
index 7b3aba621c0e..40d66591a403 100644
--- a/resources/src/idea/ActionManager.xml
+++ b/resources/src/idea/ActionManager.xml
@@ -431,6 +431,7 @@
+
diff --git a/source/com/intellij/analysis/AnalysisScope.java b/source/com/intellij/analysis/AnalysisScope.java
index 7d811e454b9f..3b77a2acf563 100644
--- a/source/com/intellij/analysis/AnalysisScope.java
+++ b/source/com/intellij/analysis/AnalysisScope.java
@@ -10,17 +10,19 @@ package com.intellij.analysis;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.impl.ModuleUtil;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ContentIterator;
-import com.intellij.openapi.roots.FileIndex;
-import com.intellij.openapi.roots.ModuleRootManager;
-import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.roots.*;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.ArrayUtil;
import java.io.File;
-import java.util.HashSet;
+import java.util.*;
public class AnalysisScope {
private static final Logger LOG = Logger.getInstance("#com.intellij.analysis.AnalysisScope");
@@ -39,6 +41,7 @@ public class AnalysisScope {
private final int myType;
private HashSet myFilesSet;
+
public interface PsiFileFilter {
boolean accept(PsiFile file);
}
@@ -143,21 +146,92 @@ public class AnalysisScope {
}
}
+ public AnalysisScope[] getNarrowedComplementaryScope(Project defaultProject) {
+ if (myType == PROJECT) {
+ return new AnalysisScope[]{new AnalysisScope(defaultProject, SOURCE_JAVA_FILES)};
+ }
+ final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(defaultProject).getFileIndex();
+ final HashSet modules = new HashSet();
+ if (myType == FILE) {
+ if (myElement instanceof PsiJavaFile) {
+ PsiJavaFile psiJavaFile = (PsiJavaFile)myElement;
+ final PsiClass[] classes = psiJavaFile.getClasses();
+ boolean onlyPackLocalClasses = true;
+ for (int i = 0; i < classes.length; i++) {
+ final PsiClass aClass = classes[i];
+ if (aClass.hasModifierProperty(PsiModifier.PUBLIC)) {
+ onlyPackLocalClasses = false;
+ }
+ }
+ if (onlyPackLocalClasses) {
+ return new AnalysisScope[]{new AnalysisScope(psiJavaFile.getContainingDirectory().getPackage(), SOURCE_JAVA_FILES)};
+ }
+ }
+ final VirtualFile vFile = ((PsiFile)myElement).getVirtualFile();
+ modules.addAll(getAllInterstingModules(fileIndex, vFile));
+ }
+ else if (myType == DIRECTORY) {
+ final VirtualFile vFile = ((PsiDirectory)myElement).getVirtualFile();
+ modules.addAll(getAllInterstingModules(fileIndex, vFile));
+ }
+ else if (myType == PACKAGE) {
+ final PsiDirectory[] directories = ((PsiPackage)myElement).getDirectories();
+ for (int idx = 0; idx < directories.length; idx++) {
+ modules.addAll(getAllInterstingModules(fileIndex, directories[idx].getVirtualFile()));
+ }
+ }
+ else if (myType == MODULE) {
+ modules.add(myModule);
+ }
+
+ if (modules.isEmpty()) {
+ return new AnalysisScope[]{new AnalysisScope(defaultProject, SOURCE_JAVA_FILES)};
+ }
+ HashSet result = new HashSet();
+ final Module[] allModules = ModuleManager.getInstance(defaultProject).getModules();
+ for (int i = 0; i < allModules.length; i++) {
+ for (Iterator iterator = modules.iterator(); iterator.hasNext();) {
+ final Module module = iterator.next();
+ if (allModules[i].equals(module)) {
+ result.add(new AnalysisScope(allModules[i], SOURCE_JAVA_FILES));
+ continue;
+ }
+ if (ModuleManager.getInstance(defaultProject).isModuleDependent(allModules[i], module)) {
+ result.add(new AnalysisScope(allModules[i], SOURCE_JAVA_FILES));
+ }
+ }
+ }
+ return result.toArray(new AnalysisScope[result.size()]);
+ }
+
+ private HashSet getAllInterstingModules(final ProjectFileIndex fileIndex, final VirtualFile vFile) {
+ final HashSet modules = new HashSet();
+ if (fileIndex.isInLibrarySource(vFile) || fileIndex.isInLibraryClasses(vFile)) {
+ final OrderEntry[] orderEntries = fileIndex.getOrderEntriesForFile(vFile);
+ for (int j = 0; j < orderEntries.length; j++) {
+ modules.add(orderEntries[j].getOwnerModule());
+ }
+ }
+ else {
+ modules.add(fileIndex.getModuleForFile(vFile));
+ }
+ return modules;
+ }
+
+
public void accept(final PsiElementVisitor visitor) {
if (myProject != null) {
final FileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
- projectFileIndex.iterateContent(
- new ContentIterator() {
- public boolean processFile(VirtualFile fileOrDir) {
- if (projectFileIndex.isContentJavaSourceFile(fileOrDir)) {
- PsiFile psiFile = PsiManager.getInstance(myProject).findFile(fileOrDir);
- LOG.assertTrue(psiFile != null);
- psiFile.accept(visitor);
- }
- return true;
+ projectFileIndex.iterateContent(new ContentIterator() {
+ public boolean processFile(VirtualFile fileOrDir) {
+ if (projectFileIndex.isContentJavaSourceFile(fileOrDir)) {
+ PsiFile psiFile = PsiManager.getInstance(myProject).findFile(fileOrDir);
+ LOG.assertTrue(psiFile != null);
+ psiFile.accept(visitor);
}
+ return true;
}
- );
+ });
}
else if (myModule != null) {
final FileIndex moduleFileIndex = ModuleRootManager.getInstance(myModule).getFileIndex();
diff --git a/source/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java b/source/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
index fefe134bf991..02cc31b44b22 100644
--- a/source/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
+++ b/source/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java
@@ -23,9 +23,10 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.TextRange;
-import com.intellij.packageDependencies.DependenciesBuilder;
+import com.intellij.packageDependencies.ForwardDependenciesBuilder;
import com.intellij.packageDependencies.DependencyRule;
import com.intellij.packageDependencies.DependencyValidationManager;
+import com.intellij.packageDependencies.DependenciesBuilder;
import com.intellij.psi.*;
import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.psi.search.TodoItem;
@@ -269,7 +270,7 @@ public class GeneralHighlightingPass extends TextEditorHighlightingPass {
private void collectDependencyProblems(final List list) {
if (myUpdateAll && myFile instanceof PsiJavaFile && myFile.isPhysical() && myFile.getVirtualFile() != null &&
mySettings.getInspectionProfile().isToolEnabled(HighlightDisplayKey.ILLEGAL_DEPENDENCY)) {
- DependenciesBuilder builder = new DependenciesBuilder(myProject, new AnalysisScope(myFile, AnalysisScope.SOURCE_JAVA_FILES));
+ DependenciesBuilder builder = new ForwardDependenciesBuilder(myProject, new AnalysisScope(myFile, AnalysisScope.SOURCE_JAVA_FILES));
final DependencyValidationManager validationManager = DependencyValidationManager.getInstance(myProject);
builder.analyzeFileDependencies(myFile, new DependenciesBuilder.DependencyProcessor() {
public void process(PsiElement place, PsiElement dependency) {
diff --git a/source/com/intellij/compiler/impl/CompileDriver.java b/source/com/intellij/compiler/impl/CompileDriver.java
index 2c5a2e9d5fe7..742c6674896d 100644
--- a/source/com/intellij/compiler/impl/CompileDriver.java
+++ b/source/com/intellij/compiler/impl/CompileDriver.java
@@ -42,6 +42,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
+import com.intellij.packageDependencies.ForwardDependenciesBuilder;
import com.intellij.packageDependencies.DependenciesBuilder;
import com.intellij.psi.PsiCompiledElement;
import com.intellij.psi.PsiFile;
@@ -1027,7 +1028,7 @@ public class CompileDriver {
final TranslatingCompilerStateCache cache,
VfsSnapshot snapshot,
Set sourcesWithOutputRemoved) {
- final DependenciesBuilder builder = new DependenciesBuilder(myProject, new AnalysisScope(psiFile, AnalysisScope.SOURCE_JAVA_FILES));
+ final DependenciesBuilder builder = new ForwardDependenciesBuilder(myProject, new AnalysisScope(psiFile, AnalysisScope.SOURCE_JAVA_FILES));
builder.analyze();
final Map> dependencies = builder.getDependencies();
final Set dependentFiles = dependencies.get(psiFile);
diff --git a/source/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java b/source/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java
index a6f983d8a063..f02f62a58723 100644
--- a/source/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java
+++ b/source/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java
@@ -64,7 +64,7 @@ public class ScopeEditorPanel {
myTreeToolbar.setLayout(new BorderLayout());
myTreeToolbar.add(createTreeToolbar(), BorderLayout.WEST);
- myTreeExpantionMonitor = TreeExpantionMonitor.install(myPackageTree);
+ myTreeExpantionMonitor = TreeExpantionMonitor.install(myPackageTree, myProject);
myTreeMarker = new TreeModelBuilder.Marker() {
public boolean isMarked(PsiFile file) {
diff --git a/source/com/intellij/packageDependencies/BackwardDependenciesBuilder.java b/source/com/intellij/packageDependencies/BackwardDependenciesBuilder.java
new file mode 100644
index 000000000000..f3a9a1c487a0
--- /dev/null
+++ b/source/com/intellij/packageDependencies/BackwardDependenciesBuilder.java
@@ -0,0 +1,92 @@
+package com.intellij.packageDependencies;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.analysis.AnalysisScope;
+import com.intellij.psi.*;
+
+import java.util.*;
+
+/**
+ * User: anna
+ * Date: Jan 16, 2005
+ */
+public class BackwardDependenciesBuilder extends DependenciesBuilder {
+
+ public BackwardDependenciesBuilder(final Project project, final AnalysisScope scope) {
+ super(project, scope);
+ }
+
+ public String getRootNodeNameInUsageView() {
+ return "Usages of the left tree scope selection in the right tree scope selection";
+ }
+
+ public String getInitialUsagesPosition() {
+ return "Select where to search in right tree and what to search in left tree.";
+ }
+
+ public boolean isBackward(){
+ return true;
+ }
+
+ public void analyze() {
+ final AnalysisScope[] scopes = getScope().getNarrowedComplementaryScope(getProject());
+ final DependenciesBuilder[] builders = new DependenciesBuilder[scopes.length];
+ int totalCount = 0;
+ for (int i = 0; i < scopes.length; i++) {
+ AnalysisScope scope = scopes[i];
+ totalCount += scope.getFileCount();
+ }
+ final int finalTotalFilesCount = totalCount;
+ totalCount = 0;
+ for (int i = 0; i < scopes.length; i++) {
+ AnalysisScope scope = scopes[i];
+ builders[i] = new ForwardDependenciesBuilder(getProject(), scope);
+ builders[i].setInitialFileCount(totalCount);
+ builders[i].setTotalFileCount(finalTotalFilesCount);
+ builders[i].analyze();
+ totalCount += scope.getFileCount();
+ }
+
+ final PsiManager psiManager = PsiManager.getInstance(getProject());
+ psiManager.startBatchFilesProcessingMode();
+ try {
+ getScope().accept(new PsiRecursiveElementVisitor() {
+ public void visitReferenceExpression(PsiReferenceExpression expression) {
+ }
+
+ public void visitFile(final PsiFile file) {
+ ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+ if (indicator != null) {
+ if (indicator.isCanceled()) {
+ throw new ProcessCanceledException();
+ }
+ indicator.setText("Analyzing package dependencies");
+ indicator.setText2(file.getVirtualFile().getPresentableUrl());
+ indicator.setFraction(((double) ++myFileCount) / getScope().getFileCount());
+ }
+ for (int i = 0; i < builders.length; i++) {
+ final Map> dependencies = builders[i].getDependencies();
+ for (Iterator iterator = dependencies.keySet().iterator(); iterator.hasNext();) {
+ final PsiFile psiFile = iterator.next();
+ if (dependencies.get(psiFile).contains(file)) {
+ Set fileDeps = getDependencies().get(file);
+ if (fileDeps == null) {
+ fileDeps = new HashSet();
+ getDependencies().put(file, fileDeps);
+ }
+ fileDeps.add(psiFile);
+ }
+ }
+ }
+ psiManager.dropResolveCaches();
+ }
+ });
+ }
+ finally {
+ psiManager.finishBatchFilesProcessingMode();
+ }
+ }
+}
diff --git a/source/com/intellij/packageDependencies/DependenciesBuilder.java b/source/com/intellij/packageDependencies/DependenciesBuilder.java
index 6155b7869a5a..7134669e7aec 100644
--- a/source/com/intellij/packageDependencies/DependenciesBuilder.java
+++ b/source/com/intellij/packageDependencies/DependenciesBuilder.java
@@ -1,76 +1,59 @@
package com.intellij.packageDependencies;
-import com.intellij.analysis.AnalysisScope;
-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.psi.*;
-import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.analysis.AnalysisScope;
+import com.intellij.openapi.project.Project;
import java.util.*;
-public class DependenciesBuilder {
+/**
+ * User: anna
+ * Date: Jan 19, 2005
+ */
+public abstract class DependenciesBuilder {
private Project myProject;
private final AnalysisScope myScope;
private final Map> myDependencies = new HashMap>();
- private final int myTotalFileCount;
- private int myFileCount = 0;
+ protected int myTotalFileCount;
+ protected int myFileCount = 0;
- public DependenciesBuilder(Project project, AnalysisScope scope) {
+ protected DependenciesBuilder(final Project project, final AnalysisScope scope) {
myProject = project;
myScope = scope;
myTotalFileCount = scope.getFileCount();
}
- public AnalysisScope getScope() {
- return myScope;
+ protected void setInitialFileCount(final int fileCount) {
+ myFileCount = fileCount;
}
- public void analyze() {
- final PsiManager psiManager = PsiManager.getInstance(myProject);
- psiManager.startBatchFilesProcessingMode();
- try {
- myScope.accept(new PsiRecursiveElementVisitor() {
- public void visitReferenceExpression(PsiReferenceExpression expression) {
- }
-
- public void visitFile(final PsiFile file) {
- ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
- if (indicator != null) {
- if (indicator.isCanceled()) {
- throw new ProcessCanceledException();
- }
- indicator.setText("Analyzing package dependencies");
- indicator.setText2(file.getVirtualFile().getPresentableUrl());
- indicator.setFraction(((double)++myFileCount) / myTotalFileCount);
- }
-
- final Set fileDeps = new HashSet();
- myDependencies.put(file, fileDeps);
- analyzeFileDependencies(file, new DependencyProcessor() {
- public void process(PsiElement place, PsiElement dependency) {
- PsiFile dependencyFile = dependency.getContainingFile();
- if (dependencyFile != null && dependencyFile.isPhysical()) {
- fileDeps.add(dependencyFile);
- }
- }
- });
- psiManager.dropResolveCaches();
- }
- });
- }
- finally {
- psiManager.finishBatchFilesProcessingMode();
- }
+ protected void setTotalFileCount(final int totalFileCount) {
+ myTotalFileCount = totalFileCount;
}
public Map> getDependencies() {
return myDependencies;
}
- public Map>> getIllegalDependencies() {
+ public AnalysisScope getScope() {
+ return myScope;
+ }
+
+ public Project getProject() {
+ return myProject;
+ }
+
+ public abstract String getRootNodeNameInUsageView();
+
+ public abstract String getInitialUsagesPosition();
+
+ public abstract boolean isBackward();
+
+ public abstract void analyze();
+
+ public Map>> getIllegalDependencies(){
Map>> result = new HashMap>>();
DependencyValidationManager validator = DependencyValidationManager.getInstance(myProject);
for (Iterator iterator = myDependencies.keySet().iterator(); iterator.hasNext();) {
@@ -79,7 +62,8 @@ public class DependenciesBuilder {
Map> illegal = null;
for (Iterator depsIterator = deps.iterator(); depsIterator.hasNext();) {
PsiFile dependency = depsIterator.next();
- final DependencyRule rule = validator.getViolatorDependencyRule(file, dependency);
+ final DependencyRule rule = isBackward() ? validator.getViolatorDependencyRule(dependency, file) :
+ validator.getViolatorDependencyRule(file, dependency);
if (rule != null) {
if (illegal == null) {
illegal = new HashMap>();
@@ -146,4 +130,4 @@ public class DependenciesBuilder {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/source/com/intellij/packageDependencies/DependencyValidationManager.java b/source/com/intellij/packageDependencies/DependencyValidationManager.java
index 2e41342e5e57..864ed24b8cb5 100644
--- a/source/com/intellij/packageDependencies/DependencyValidationManager.java
+++ b/source/com/intellij/packageDependencies/DependencyValidationManager.java
@@ -70,12 +70,7 @@ public class DependencyValidationManager extends NamedScopesHolder implements Pr
});
}
- public void addContent(DependenciesBuilder builder) {
- DependenciesPanel panel = new DependenciesPanel(myProject, builder);
- Content content = PeerFactory.getInstance().getContentFactory().createContent(panel,
- "Dependencies of " + builder.getScope().getDisplayName(),
- false);
- panel.setContent(content);
+ public void addContent(Content content) {
myContentManager.addContent(content);
myContentManager.setSelectedContent(content);
ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.DEPENDENCIES).activate(null);
diff --git a/source/com/intellij/packageDependencies/FindDependencyUtil.java b/source/com/intellij/packageDependencies/FindDependencyUtil.java
index b49d2108fe8d..b6670ce92107 100644
--- a/source/com/intellij/packageDependencies/FindDependencyUtil.java
+++ b/source/com/intellij/packageDependencies/FindDependencyUtil.java
@@ -42,4 +42,40 @@ public class FindDependencyUtil {
return usages.toArray(new UsageInfo[usages.size()]);
}
+
+ public static UsageInfo[] findBackwardDependencies(final DependenciesBuilder builder, final Set searchIn, final Set searchFor) {
+ final List usages = new ArrayList();
+ ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+
+
+ final Set deps = new HashSet();
+ for (Iterator iterator = searchFor.iterator(); iterator.hasNext();) {
+ PsiFile psiFile = iterator.next();
+ deps.addAll(builder.getDependencies().get(psiFile));
+ }
+ deps.retainAll(searchIn);
+ if (deps.isEmpty()) return new UsageInfo[0];
+
+ int totalCount = deps.size();
+ int count = 0;
+ for (Iterator inIterator = deps.iterator(); inIterator.hasNext();) {
+ final PsiFile psiFile = inIterator.next();
+ if (indicator != null) {
+ if (indicator.isCanceled()) throw new ProcessCanceledException();
+ indicator.setFraction(((double)++count)/totalCount);
+ indicator.setText("Searching for usages in: " + psiFile.getVirtualFile().getPresentableUrl());
+ }
+
+ builder.analyzeFileDependencies(psiFile, new DependenciesBuilder.DependencyProcessor() {
+ public void process(PsiElement place, PsiElement dependency) {
+ PsiFile dependencyFile = dependency.getContainingFile();
+ if (searchFor.contains(dependencyFile)) {
+ usages.add(new UsageInfo(place));
+ }
+ }
+ });
+ }
+
+ return usages.toArray(new UsageInfo[usages.size()]);
+ }
}
\ No newline at end of file
diff --git a/source/com/intellij/packageDependencies/ForwardDependenciesBuilder.java b/source/com/intellij/packageDependencies/ForwardDependenciesBuilder.java
new file mode 100644
index 000000000000..9c7a405e3bb0
--- /dev/null
+++ b/source/com/intellij/packageDependencies/ForwardDependenciesBuilder.java
@@ -0,0 +1,68 @@
+package com.intellij.packageDependencies;
+
+import com.intellij.analysis.AnalysisScope;
+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.psi.*;
+
+import java.util.*;
+
+public class ForwardDependenciesBuilder extends DependenciesBuilder {
+
+ public ForwardDependenciesBuilder(Project project, AnalysisScope scope) {
+ super(project, scope);
+ }
+
+ public String getRootNodeNameInUsageView(){
+ return "Usages of the right tree scope selection in the left tree scope selection";
+ }
+
+ public String getInitialUsagesPosition(){
+ return "Select where to search in left tree and what to search in right tree.";
+ }
+
+ public boolean isBackward(){
+ return false;
+ }
+
+ public void analyze() {
+ final PsiManager psiManager = PsiManager.getInstance(getProject());
+ psiManager.startBatchFilesProcessingMode();
+ try {
+ getScope().accept(new PsiRecursiveElementVisitor() {
+ public void visitReferenceExpression(PsiReferenceExpression expression) {
+ }
+
+ public void visitFile(final PsiFile file) {
+ ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+ if (indicator != null) {
+ if (indicator.isCanceled()) {
+ throw new ProcessCanceledException();
+ }
+ indicator.setText("Analyzing package dependencies");
+ indicator.setText2(file.getVirtualFile().getPresentableUrl());
+ indicator.setFraction(((double)++ myFileCount) / myTotalFileCount);
+ }
+
+ final Set fileDeps = new HashSet();
+ getDependencies().put(file, fileDeps);
+ analyzeFileDependencies(file, new DependencyProcessor() {
+ public void process(PsiElement place, PsiElement dependency) {
+ PsiFile dependencyFile = dependency.getContainingFile();
+ if (dependencyFile != null && dependencyFile.isPhysical()) {
+ fileDeps.add(dependencyFile);
+ }
+ }
+ });
+ psiManager.dropResolveCaches();
+ }
+ });
+ }
+ finally {
+ psiManager.finishBatchFilesProcessingMode();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesHandler.java b/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesHandler.java
index 0da5d0c8be67..5ef3a7278e14 100644
--- a/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesHandler.java
+++ b/source/com/intellij/packageDependencies/actions/AnalyzeDependenciesHandler.java
@@ -3,8 +3,12 @@ package com.intellij.packageDependencies.actions;
import com.intellij.analysis.AnalysisScope;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
-import com.intellij.packageDependencies.DependenciesBuilder;
import com.intellij.packageDependencies.DependencyValidationManager;
+import com.intellij.packageDependencies.ForwardDependenciesBuilder;
+import com.intellij.packageDependencies.DependenciesBuilder;
+import com.intellij.packageDependencies.ui.DependenciesPanel;
+import com.intellij.ui.content.Content;
+import com.intellij.peer.PeerFactory;
public class AnalyzeDependenciesHandler {
private Project myProject;
@@ -16,13 +20,18 @@ public class AnalyzeDependenciesHandler {
}
public void analyze() {
- final DependenciesBuilder builder = new DependenciesBuilder(myProject, myScope);
+ final DependenciesBuilder forwardBuilder = new ForwardDependenciesBuilder(myProject, myScope);
if (ApplicationManager.getApplication().runProcessWithProgressSynchronously(new Runnable() {
public void run() {
- builder.analyze();
+ forwardBuilder.analyze();
}
}, "Analyzing Dependencies", true, myProject)) {
- DependencyValidationManager.getInstance(myProject).addContent(builder);
+ DependenciesPanel panel = new DependenciesPanel(myProject, forwardBuilder);
+ Content content = PeerFactory.getInstance().getContentFactory().createContent(panel,
+ "Dependencies of " + forwardBuilder.getScope().getDisplayName(),
+ false);
+ panel.setContent(content);
+ DependencyValidationManager.getInstance(myProject).addContent(content);
}
}
}
\ No newline at end of file
diff --git a/source/com/intellij/packageDependencies/actions/BackwardDependenciesAction.java b/source/com/intellij/packageDependencies/actions/BackwardDependenciesAction.java
new file mode 100644
index 000000000000..bd5d0591d9a7
--- /dev/null
+++ b/source/com/intellij/packageDependencies/actions/BackwardDependenciesAction.java
@@ -0,0 +1,19 @@
+package com.intellij.packageDependencies.actions;
+
+import com.intellij.analysis.BaseAnalysisAction;
+import com.intellij.analysis.AnalysisScope;
+import com.intellij.openapi.project.Project;
+
+/**
+ * User: anna
+ * Date: Jan 16, 2005
+ */
+public class BackwardDependenciesAction extends BaseAnalysisAction{
+ public BackwardDependenciesAction() {
+ super(AnalysisScope.SOURCE_JAVA_FILES, "Backward Dependency Analysis", "Analyze", "Analysis");
+ }
+
+ protected void analyze(Project project, AnalysisScope scope) {
+ new BackwardDependenciesHandler(project, scope).analyze();
+ }
+}
diff --git a/source/com/intellij/packageDependencies/actions/BackwardDependenciesHandler.java b/source/com/intellij/packageDependencies/actions/BackwardDependenciesHandler.java
new file mode 100644
index 000000000000..f8bc50dda0bb
--- /dev/null
+++ b/source/com/intellij/packageDependencies/actions/BackwardDependenciesHandler.java
@@ -0,0 +1,43 @@
+package com.intellij.packageDependencies.actions;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.analysis.AnalysisScope;
+import com.intellij.packageDependencies.DependencyValidationManager;
+import com.intellij.packageDependencies.BackwardDependenciesBuilder;
+import com.intellij.packageDependencies.DependenciesBuilder;
+import com.intellij.packageDependencies.ui.DependenciesPanel;
+import com.intellij.ui.content.Content;
+import com.intellij.peer.PeerFactory;
+
+/**
+ * User: anna
+ * Date: Jan 16, 2005
+ */
+public class BackwardDependenciesHandler {
+ private Project myProject;
+ private AnalysisScope myScope;
+
+ public BackwardDependenciesHandler(Project project, AnalysisScope scope) {
+ myProject = project;
+ myScope = scope;
+ }
+
+ public void analyze() {
+ final DependenciesBuilder builder = new BackwardDependenciesBuilder(myProject, myScope);
+
+ if (ApplicationManager.getApplication().runProcessWithProgressSynchronously(new Runnable() {
+ public void run() {
+ builder.analyze();
+ }
+ }, "Analyzing Backward Dependencies", true, myProject)) {
+ DependenciesPanel panel = new DependenciesPanel(myProject, builder);
+ Content content = PeerFactory.getInstance().getContentFactory().createContent(panel,
+ "Backward Dependencies of " + builder.getScope().getDisplayName(),
+ false);
+ panel.setContent(content);
+ DependencyValidationManager.getInstance(myProject).addContent(content);
+
+ }
+ }
+}
diff --git a/source/com/intellij/packageDependencies/ui/DependenciesPanel.java b/source/com/intellij/packageDependencies/ui/DependenciesPanel.java
index d5758f0730f7..04b95422e2e6 100644
--- a/source/com/intellij/packageDependencies/ui/DependenciesPanel.java
+++ b/source/com/intellij/packageDependencies/ui/DependenciesPanel.java
@@ -12,30 +12,29 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
-import com.intellij.packageDependencies.DependenciesBuilder;
-import com.intellij.packageDependencies.DependencyRule;
-import com.intellij.packageDependencies.DependencyUISettings;
-import com.intellij.packageDependencies.DependencyValidationManager;
+import com.intellij.packageDependencies.*;
import com.intellij.packageDependencies.actions.AnalyzeDependenciesHandler;
+import com.intellij.packageDependencies.actions.BackwardDependenciesHandler;
import com.intellij.pom.Navigatable;
import com.intellij.psi.*;
import com.intellij.ui.*;
import com.intellij.ui.content.Content;
import com.intellij.util.Icons;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.Tree;
import com.intellij.util.ui.tree.TreeUtil;
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
-import javax.swing.tree.DefaultTreeCellRenderer;
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.TreePath;
-import javax.swing.tree.TreeSelectionModel;
+import javax.swing.event.TreeExpansionListener;
+import javax.swing.event.TreeExpansionEvent;
+import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
+import java.util.List;
public class DependenciesPanel extends JPanel {
private Map> myDependencies;
@@ -64,7 +63,7 @@ public class DependenciesPanel extends JPanel {
myBuilder = builder;
myIllegalDependencies = myBuilder.getIllegalDependencies();
myProject = project;
- myUsagesPanel = new UsagesPanel(myProject);
+ myUsagesPanel = new UsagesPanel(myProject, myBuilder);
Splitter treeSplitter = new Splitter();
treeSplitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myLeftTree));
@@ -76,8 +75,8 @@ public class DependenciesPanel extends JPanel {
add(splitter, BorderLayout.CENTER);
add(createToolbar(), BorderLayout.NORTH);
- myRightTreeExpantionMonitor = TreeExpantionMonitor.install(myRightTree);
- myLeftTreeExpantionMonitor = TreeExpantionMonitor.install(myLeftTree);
+ myRightTreeExpantionMonitor = TreeExpantionMonitor.install(myRightTree, myProject);
+ myLeftTreeExpantionMonitor = TreeExpantionMonitor.install(myLeftTree, myProject);
myRightTreeMarker = new TreeModelBuilder.Marker() {
public boolean isMarked(PsiFile file) {
@@ -100,7 +99,7 @@ public class DependenciesPanel extends JPanel {
final StringBuffer denyRules = new StringBuffer();
final StringBuffer allowRules = new StringBuffer();
final TreePath selectionPath = myLeftTree.getSelectionPath();
- if (selectionPath == null){
+ if (selectionPath == null) {
return;
}
PackageDependenciesNode selectedNode = (PackageDependenciesNode)selectionPath.getLastPathComponent();
@@ -108,10 +107,10 @@ public class DependenciesPanel extends JPanel {
final StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject);
if (denyRules.length() + allowRules.length() > 0) {
statusBar.setInfo("The following rule" +
- ((denyRules.length() == 0 || allowRules.length() == 0) ? " is " : "s are ") +
- "violated: " +
- (denyRules.length() > 0 ? denyRules.toString() + (allowRules.length() > 0 ? "; " : "") : " ") +
- (allowRules.length() > 0 ? allowRules.toString() : " "));
+ ((denyRules.length() == 0 || allowRules.length() == 0) ? " is " : "s are ") +
+ "violated: " +
+ (denyRules.length() > 0 ? denyRules.toString() + (allowRules.length() > 0 ? "; " : "") : " ") +
+ (allowRules.length() > 0 ? allowRules.toString() : " "));
}
else {
@@ -130,7 +129,7 @@ public class DependenciesPanel extends JPanel {
myUsagesPanel.setToInitialPosition();
}
else {
- myUsagesPanel.findUsages(builder, searchIn, searchFor);
+ myUsagesPanel.findUsages(searchIn, searchFor);
}
}
});
@@ -150,23 +149,24 @@ public class DependenciesPanel extends JPanel {
}
private void traverseToLeaves(final PackageDependenciesNode treeNode, final StringBuffer denyRules, final StringBuffer allowRules) {
- for (int i = 0; i < treeNode.getChildCount(); i++) {
- traverseToLeaves((PackageDependenciesNode)treeNode.getChildAt(i), denyRules, allowRules);
- }
- if (myIllegalDependencies.containsKey(treeNode.getPsiElement())) {
- final Map> illegalDeps = myIllegalDependencies.get(treeNode.getPsiElement());
- for (Iterator iterator = illegalDeps.keySet().iterator(); iterator.hasNext();) {
- final DependencyRule rule = iterator.next();
- if (rule.isDenyRule()) {
- if (denyRules.indexOf(rule.getDisplayText()) == -1) {
- denyRules.append(rule.getDisplayText());
- denyRules.append("\n");
+ final Enumeration enumeration = treeNode.breadthFirstEnumeration();
+ while (enumeration.hasMoreElements()) {
+ PsiElement childPsiElement = ((PackageDependenciesNode)enumeration.nextElement()).getPsiElement();
+ if (myIllegalDependencies.containsKey(childPsiElement)) {
+ final Map> illegalDeps = myIllegalDependencies.get(childPsiElement);
+ for (Iterator iterator = illegalDeps.keySet().iterator(); iterator.hasNext();) {
+ final DependencyRule rule = iterator.next();
+ if (rule.isDenyRule()) {
+ if (denyRules.indexOf(rule.getDisplayText()) == -1) {
+ denyRules.append(rule.getDisplayText());
+ denyRules.append("\n");
+ }
}
- }
- else {
- if (allowRules.indexOf(rule.getDisplayText()) == -1) {
- allowRules.append(rule.getDisplayText());
- allowRules.append("\n");
+ else {
+ if (allowRules.indexOf(rule.getDisplayText()) == -1) {
+ allowRules.append(rule.getDisplayText());
+ allowRules.append("\n");
+ }
}
}
}
@@ -448,7 +448,12 @@ public class DependenciesPanel extends JPanel {
DependencyValidationManager.getInstance(myProject).closeContent(myContent);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
- new AnalyzeDependenciesHandler(myProject, myBuilder.getScope()).analyze();
+ if (myBuilder.isBackward()) {
+ new BackwardDependenciesHandler(myProject, myBuilder.getScope()).analyze();
+ }
+ else {
+ new AnalyzeDependenciesHandler(myProject, myBuilder.getScope()).analyze();
+ }
}
});
}
diff --git a/source/com/intellij/packageDependencies/ui/TreeExpantionMonitor.java b/source/com/intellij/packageDependencies/ui/TreeExpantionMonitor.java
index 1ee95cf925bc..690fc47a3ea5 100644
--- a/source/com/intellij/packageDependencies/ui/TreeExpantionMonitor.java
+++ b/source/com/intellij/packageDependencies/ui/TreeExpantionMonitor.java
@@ -1,34 +1,39 @@
package com.intellij.packageDependencies.ui;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiManager;
+
import javax.swing.*;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;
+import javax.swing.tree.DefaultMutableTreeNode;
import java.util.*;
public class TreeExpantionMonitor {
- public static TreeExpantionMonitor install(JTree tree) {
- return new TreeExpantionMonitor(tree);
+ public static TreeExpantionMonitor install(JTree tree, Project project) {
+ return new TreeExpantionMonitor(tree, project);
}
private Set myExpandedPaths = new HashSet();
- private List mySelectionPath = new ArrayList();
+ private List mySelectionNodes = new ArrayList();
private JTree myTree;
private boolean myFrozen = false;
+ private Project myProject;
-
- private TreeExpantionMonitor(JTree tree) {
+ private TreeExpantionMonitor(JTree tree, Project project) {
myTree = tree;
+ myProject = project;
myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
if (myFrozen) return;
- mySelectionPath = new ArrayList();
+ mySelectionNodes = new ArrayList();
TreePath[] paths = myTree.getSelectionPaths();
if (paths != null) {
for (int i = 0; i < paths.length; i++) {
- mySelectionPath.add(paths[i]);
+ mySelectionNodes.add((PackageDependenciesNode)paths[i].getLastPathComponent());
}
}
}
@@ -63,15 +68,28 @@ public class TreeExpantionMonitor {
myFrozen = true;
}
+
public void restore() {
- freeze();
- for (int i = 0; i < mySelectionPath.size(); i++) {
- TreePath treePath = mySelectionPath.get(i);
- myTree.getSelectionModel().addSelectionPath(treePath);
- }
- for (Iterator iterator = myExpandedPaths.iterator(); iterator.hasNext();) {
- myTree.expandPath(iterator.next());
- }
- myFrozen = false;
+ freeze();
+ for (int i = 0; i < mySelectionNodes.size(); i++) {
+ myTree.getSelectionModel().addSelectionPath(findPathByNode(mySelectionNodes.get(i)));
+ }
+ for (Iterator iterator = myExpandedPaths.iterator(); iterator.hasNext();) {
+ myTree.expandPath(iterator.next());
+ }
+ myFrozen = false;
+ }
+
+
+ private TreePath findPathByNode(final PackageDependenciesNode node) {
+ PsiManager manager = PsiManager.getInstance(myProject);
+ Enumeration enumeration = ((DefaultMutableTreeNode)myTree.getModel().getRoot()).breadthFirstEnumeration();
+ while (enumeration.hasMoreElements()) {
+ PackageDependenciesNode child = (PackageDependenciesNode)enumeration.nextElement();
+ if (manager.areElementsEquivalent(child.getPsiElement(), node.getPsiElement())) {
+ return new TreePath(child.getPath());
+ }
+ }
+ return null;
}
}
\ No newline at end of file
diff --git a/source/com/intellij/packageDependencies/ui/UsagesPanel.java b/source/com/intellij/packageDependencies/ui/UsagesPanel.java
index c2f8809a6c14..cbd88161c97a 100644
--- a/source/com/intellij/packageDependencies/ui/UsagesPanel.java
+++ b/source/com/intellij/packageDependencies/ui/UsagesPanel.java
@@ -9,8 +9,9 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.util.ColorProgressBar;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.project.Project;
-import com.intellij.packageDependencies.DependenciesBuilder;
import com.intellij.packageDependencies.FindDependencyUtil;
+import com.intellij.packageDependencies.BackwardDependenciesBuilder;
+import com.intellij.packageDependencies.DependenciesBuilder;
import com.intellij.psi.PsiFile;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.*;
@@ -24,23 +25,24 @@ public class UsagesPanel extends JPanel {
private static final Logger LOG = Logger.getInstance("#com.intellij.packageDependencies.ui.UsagesPanel");
private Project myProject;
-
+ private DependenciesBuilder myBuilder;
private ProgressIndicator myCurrentProgress;
private JComponent myCurrentComponent;
private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
- public UsagesPanel(Project project) {
+ public UsagesPanel(Project project, DependenciesBuilder builder) {
super(new BorderLayout());
myProject = project;
+ myBuilder = builder;
setToInitialPosition();
}
public void setToInitialPosition() {
cancelCurrentFindRequest();
- setToComponent(createLabel("Select where to search in left tree and what to search in right tree."));
+ setToComponent(createLabel(myBuilder.getInitialUsagesPosition()));
}
- public void findUsages(final DependenciesBuilder builder, final Set searchIn, final Set searchFor) {
+ public void findUsages(final Set searchIn, final Set searchFor) {
cancelCurrentFindRequest();
myAlarm.cancelAllRequests();
@@ -56,7 +58,11 @@ public class UsagesPanel extends JPanel {
public void run() {
UsageInfo[] usages = new UsageInfo[0];
try {
- usages = FindDependencyUtil.findDependencies(builder, searchIn, searchFor);
+ if (myBuilder.isBackward()){
+ usages = FindDependencyUtil.findBackwardDependencies(myBuilder, searchFor, searchIn);
+ } else {
+ usages = FindDependencyUtil.findDependencies(myBuilder, searchIn, searchFor);
+ }
}
catch (ProcessCanceledException e) {
}
@@ -93,7 +99,7 @@ public class UsagesPanel extends JPanel {
try {
Usage[] usages = UsageInfoToUsageConverter.convert(usageInfos);
UsageViewPresentation presentation = new UsageViewPresentation();
- presentation.setCodeUsagesString("Usages of the right tree scope selection in the left tree scope selection");
+ presentation.setCodeUsagesString(myBuilder.getRootNodeNameInUsageView());
UsageView usageView = myProject.getComponent(UsageViewManager.class).createUsageView(new UsageTarget[0],
usages, presentation);
setToComponent(usageView.getComponent());
@@ -181,4 +187,4 @@ public class UsagesPanel extends JPanel {
public JLabel myTextLabel;
public JPanel myPanel;
}
-}
\ No newline at end of file
+}