From 9b850d3996f4754ceae0281088d635befb2bd52f Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 24 Feb 2016 14:26:07 +0300 Subject: [PATCH] inspection tool window: new tree reverted according leaks --- .../deadCode/DeadHTMLComposer.java | 24 +- .../DummyEntryPointsPresentation.java | 4 +- .../UnusedDeclarationPresentation.java | 4 +- .../codeInspection/ui/EntryPointsNode.java | 3 +- .../codeInspection/OfflineIRVTest.java | 107 ++-- .../actions/ViewOfflineResultsAction.java | 3 +- .../ex/InspectionRVContentProvider.java | 158 +++--- .../ex/InspectionRVContentProviderImpl.java | 22 +- .../codeInspection/ex/QuickFixAction.java | 10 +- .../OfflineInspectionRVContentProvider.java | 52 +- .../OfflineProblemDescriptorNode.java | 51 +- .../offlineViewer/OfflineRefElementNode.java | 24 +- .../ui/DefaultInspectionToolPresentation.java | 151 +++--- .../ui/{tree => }/InspectionGroupNode.java | 25 +- .../ui/{tree => }/InspectionModuleNode.java | 11 +- .../ui/{tree => }/InspectionNode.java | 25 +- .../codeInspection/ui/InspectionNodeInfo.java | 2 +- .../ui/{tree => }/InspectionPackageNode.java | 24 +- .../ui/InspectionResultsView.java | 306 ++++++------ .../ui/InspectionResultsViewComparator.java | 23 +- .../ui/{tree => }/InspectionRootNode.java | 14 +- .../InspectionSeverityGroupNode.java | 33 +- .../ui/InspectionToolPresentation.java | 2 - .../codeInspection/ui/InspectionTree.java | 459 ++++++++++++++++++ .../codeInspection/ui/InspectionTreeNode.java | 81 ++++ .../ui/InspectionViewNavigationPanel.java | 37 +- .../ui/{tree => }/ProblemDescriptionNode.java | 36 +- .../codeInspection/ui/QuickFixToolbar.java | 30 +- .../ui/{tree => }/RefElementNode.java | 43 +- .../ui/actions/ExportHTMLAction.java | 26 +- .../InspectionsOptionsToolbarAction.java | 15 +- .../ui/actions/InvokeQuickFixAction.java | 10 +- .../ui/actions/SuppressActionWrapper.java | 40 +- .../ui/tree/InspectionTree.java | 62 --- .../ui/tree/InspectionTreeBuilder.java | 205 -------- .../ui/tree/InspectionTreeNode.java | 160 ------ .../ui/tree/InspectionTreeStructure.java | 65 --- 37 files changed, 1193 insertions(+), 1154 deletions(-) rename platform/lang-impl/src/com/intellij/codeInspection/ui/{tree => }/InspectionGroupNode.java (64%) rename platform/lang-impl/src/com/intellij/codeInspection/ui/{tree => }/InspectionModuleNode.java (85%) rename platform/lang-impl/src/com/intellij/codeInspection/ui/{tree => }/InspectionNode.java (72%) rename platform/lang-impl/src/com/intellij/codeInspection/ui/{tree => }/InspectionPackageNode.java (62%) rename platform/lang-impl/src/com/intellij/codeInspection/ui/{tree => }/InspectionRootNode.java (87%) rename platform/lang-impl/src/com/intellij/codeInspection/ui/{tree => }/InspectionSeverityGroupNode.java (71%) create mode 100644 platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTree.java create mode 100644 platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java rename platform/lang-impl/src/com/intellij/codeInspection/ui/{tree => }/ProblemDescriptionNode.java (79%) rename platform/lang-impl/src/com/intellij/codeInspection/ui/{tree => }/RefElementNode.java (75%) delete mode 100644 platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTree.java delete mode 100644 platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeBuilder.java delete mode 100644 platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeNode.java delete mode 100644 platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeStructure.java diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java index 94fd4295f68b..88f56186fc8e 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/DeadHTMLComposer.java @@ -30,12 +30,15 @@ import com.intellij.codeInspection.ex.DescriptorComposer; import com.intellij.codeInspection.ex.HTMLComposerImpl; import com.intellij.codeInspection.reference.*; import com.intellij.codeInspection.ui.InspectionToolPresentation; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; -import com.intellij.codeInspection.ui.tree.RefElementNode; +import com.intellij.codeInspection.ui.InspectionTreeNode; +import com.intellij.codeInspection.ui.RefElementNode; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import java.util.*; +import javax.swing.tree.TreeNode; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; public class DeadHTMLComposer extends HTMLComposerImpl { private final InspectionToolPresentation myToolPresentation; @@ -360,12 +363,7 @@ public class DeadHTMLComposer extends HTMLComposerImpl { } public static Set getPossibleChildren(final RefElementNode refElementNode, RefElement refElement) { - final List pathToRoot = new ArrayList<>(); - InspectionTreeNode currentNode = refElementNode; - while (currentNode != null) { - pathToRoot.add(currentNode); - currentNode = (InspectionTreeNode)currentNode.getParent(); - } + final TreeNode[] pathToRoot = refElementNode.getPath(); final HashSet newChildren = new HashSet(); @@ -404,10 +402,12 @@ public class DeadHTMLComposer extends HTMLComposerImpl { return newChildren; } - private static boolean notInPath(List pathToRoot, RefElement refChild) { - for (InspectionTreeNode node : pathToRoot) { - if (node instanceof RefElementNode && node.getElement() == refChild) return false; + private static boolean notInPath(TreeNode[] pathToRoot, RefElement refChild) { + for (TreeNode aPathToRoot : pathToRoot) { + InspectionTreeNode node = (InspectionTreeNode)aPathToRoot; + if (node instanceof RefElementNode && ((RefElementNode)node).getElement() == refChild) return false; } + return true; } } diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsPresentation.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsPresentation.java index 620e7ba72de1..c9be5d934b3d 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsPresentation.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/DummyEntryPointsPresentation.java @@ -21,8 +21,8 @@ import com.intellij.codeInspection.InspectionsBundle; import com.intellij.codeInspection.ex.*; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; -import com.intellij.codeInspection.ui.tree.InspectionNode; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; +import com.intellij.codeInspection.ui.InspectionNode; +import com.intellij.codeInspection.ui.InspectionTreeNode; import com.intellij.codeInspection.util.RefFilter; import org.jetbrains.annotations.NotNull; diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java index 26d1aeb4a983..ad13714f3cc7 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java @@ -20,8 +20,6 @@ import com.intellij.codeInspection.*; import com.intellij.codeInspection.ex.*; import com.intellij.codeInspection.reference.*; import com.intellij.codeInspection.ui.*; -import com.intellij.codeInspection.ui.tree.InspectionNode; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; import com.intellij.codeInspection.util.RefFilter; import com.intellij.icons.AllIcons; import com.intellij.lang.annotation.HighlightSeverity; @@ -327,7 +325,7 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta @NotNull InspectionTreeNode parentNode, boolean showStructure) { final EntryPointsNode entryPointsNode = new EntryPointsNode(context); - InspectionToolWrapper dummyToolWrapper = entryPointsNode.getValue(); + InspectionToolWrapper dummyToolWrapper = entryPointsNode.getToolWrapper(); InspectionToolPresentation presentation = context.getPresentation(dummyToolWrapper); presentation.updateContent(); provider.appendToolNodeContent(context, entryPointsNode, node, showStructure); diff --git a/java/java-impl/src/com/intellij/codeInspection/ui/EntryPointsNode.java b/java/java-impl/src/com/intellij/codeInspection/ui/EntryPointsNode.java index f83573835b6d..b02ce22527bf 100644 --- a/java/java-impl/src/com/intellij/codeInspection/ui/EntryPointsNode.java +++ b/java/java-impl/src/com/intellij/codeInspection/ui/EntryPointsNode.java @@ -19,7 +19,6 @@ import com.intellij.codeInspection.deadCode.DummyEntryPointsEP; import com.intellij.codeInspection.ex.GlobalInspectionContextImpl; import com.intellij.codeInspection.ex.GlobalInspectionToolWrapper; import com.intellij.codeInspection.ex.InspectionToolWrapper; -import com.intellij.codeInspection.ui.tree.InspectionNode; import com.intellij.icons.AllIcons; import org.jetbrains.annotations.NotNull; @@ -30,7 +29,7 @@ import javax.swing.*; */ public class EntryPointsNode extends InspectionNode { public EntryPointsNode(@NotNull GlobalInspectionContextImpl context) { - super(createDummyWrapper(context), context.getProject()); + super(createDummyWrapper(context)); } private static InspectionToolWrapper createDummyWrapper(@NotNull GlobalInspectionContextImpl context) { diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/OfflineIRVTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/OfflineIRVTest.java index a33f1e6ffca4..186c44b0da03 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/OfflineIRVTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/OfflineIRVTest.java @@ -31,8 +31,8 @@ import com.intellij.codeInspection.ex.ToolsImpl; import com.intellij.codeInspection.offline.OfflineProblemDescriptor; import com.intellij.codeInspection.offlineViewer.OfflineViewParseUtil; import com.intellij.codeInspection.ui.InspectionResultsView; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; -import com.intellij.ide.util.treeView.AbstractTreeStructure; +import com.intellij.codeInspection.ui.InspectionTree; +import com.intellij.codeInspection.ui.InspectionTreeNode; import com.intellij.openapi.application.ex.PathManagerEx; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; @@ -49,14 +49,12 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; -import static com.intellij.codeInspection.ex.InspectionRVContentProvider.traverse; - public class OfflineIRVTest extends TestSourceBasedTestCase { private InspectionResultsView myView; private LocalInspectionToolWrapper myToolWrapper; private static String varMessage(String name) { - return InspectionsBundle.message("inspection.unused.assignment.problem.descriptor1", "" + name + "") + "."; + return InspectionsBundle.message("inspection.unused.assignment.problem.descriptor1", ""+name+"") + "."; } @Override @@ -133,69 +131,72 @@ public class OfflineIRVTest extends TestSourceBasedTestCase { public void testOfflineView() throws Exception { myView.getGlobalInspectionContext().getUIOptions().SHOW_STRUCTURE = true; - AbstractTreeStructure tree = updateTree(); - PlatformTestUtil.assertTreeStructureEquals(tree, getProject() + - "\n Probable bugs" + - "\n " + myToolWrapper + - "\n " + getModule().toString() + - "\n " + - "\n Test" + - "\n foo" + - "\n " + varMessage("j") + - "\n main" + - "\n " + varMessage("test") + - "\n f" + - "\n D" + - "\n b" + - "\n " + InspectionsBundle - .message("inspection.unused.assignment.problem.descriptor1", "'" + "r" + "'") + - "\n anonymous (java.lang.Runnable)" + - "\n run" + - "\n " + - varMessage("i") + - "\n ff" + - "\n " + varMessage("d") + - "\n " + varMessage("a") + - "\n"); + InspectionTree tree = updateTree(); + TreeUtil.expandAll(tree); + PlatformTestUtil.assertTreeEqual(tree, "-" + getProject() + "\n" + + " -Probable bugs\n" + + " -" + myToolWrapper + "\n" + + " -" + getModule().toString() + "\n" + + " -\n" + + " -Test\n" + + " -foo()\n" + + " " + varMessage("j") + "\n" + + " -main(String[])\n" + + " " + varMessage("test") + "\n" + + " -f()\n" + + " -D\n" + + " -b()\n" + + " " + InspectionsBundle.message("inspection.unused.assignment.problem.descriptor1", "'" + "r" + "'") + "\n" + + " -anonymous (java.lang.Runnable)\n" + + " -run()\n" + + " " + varMessage("i") + "\n" + + " -ff()\n" + + " " + varMessage("d") + "\n" + + " " + varMessage("a") + "\n"); myView.getGlobalInspectionContext().getUIOptions().SHOW_STRUCTURE = false; tree = updateTree(); - PlatformTestUtil.assertTreeStructureEquals(tree, getProject() + - "\n Probable bugs\n " + myToolWrapper + - "\n Test" + - "\n " + varMessage("j") + - "\n " + varMessage("test") + - "\n " + varMessage("i") + - "\n " + varMessage("d") + - "\n " + varMessage("a") + - "\n " + InspectionsBundle .message("inspection.unused.assignment.problem.descriptor1", "'" + "r" + "'") + "\n"); - TreeUtil.selectFirstNode(myView.getTreeBuilder().getTree()); - final InspectionTreeNode root = (InspectionTreeNode)myView.getTreeBuilder().getTreeStructure().getRootElement(); + PlatformTestUtil.assertTreeEqual(tree, "-" + getProject() + "\n" + + " -Probable bugs\n" + + " -" + myToolWrapper + "\n" + + " -Test\n" + + " " + varMessage("j") + "\n" + + " " + varMessage("test") + "\n" + + " " + varMessage("r") + "\n" + + " " + varMessage("i") + "\n" + + " " + varMessage("d") + "\n" + + " " + varMessage("a") + "\n"); + TreeUtil.selectFirstNode(tree); + final InspectionTreeNode root = (InspectionTreeNode)tree.getLastSelectedPathComponent(); root.ignoreElement(); - traverse(root, (n) -> { - assertTrue(n.isResolved()); - return true; + TreeUtil.traverse(root, new TreeUtil.Traverse() { + @Override + public boolean accept(final Object node) { + assertTrue(((InspectionTreeNode)node).isResolved()); + return true; + } }); myView.getGlobalInspectionContext().getUIOptions().FILTER_RESOLVED_ITEMS = true; tree = updateTree(); - PlatformTestUtil.assertTreeStructureEquals(tree, getProject() + "\n"); + PlatformTestUtil.assertTreeEqual(tree, getProject() + "\n"); myView.getGlobalInspectionContext().getUIOptions().FILTER_RESOLVED_ITEMS = false; tree = updateTree(); - PlatformTestUtil.assertTreeStructureEquals(tree, getProject() + "\n" - + " Probable bugs\n" - + " " + myToolWrapper + "\n" - + " Test\n" + PlatformTestUtil.assertTreeEqual(tree, "-" + getProject() + "\n" + + " -Probable bugs\n" + + " -" + myToolWrapper + "\n" + + " -Test\n" + " " + varMessage("j") + "\n" + " " + varMessage("test") + "\n" + + " " + varMessage("r") + "\n" + " " + varMessage("i") + "\n" + " " + varMessage("d") + "\n" - + " " + varMessage("a") + "\n" - + " " + InspectionsBundle - .message("inspection.unused.assignment.problem.descriptor1", "'" + "r" + "'") + "\n"); + + " " + varMessage("a") + "\n"); } - private AbstractTreeStructure updateTree() { + private InspectionTree updateTree() { myView.update(); - return myView.getTreeBuilder().getTreeStructure(); + final InspectionTree tree = myView.getTree(); + TreeUtil.expandAll(tree); + return tree; } @Override diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java index e9c73963c6db..08234f194ab8 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java @@ -47,6 +47,7 @@ import com.intellij.openapi.fileEditor.impl.LoadTextUtil; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Computable; @@ -225,7 +226,7 @@ public class ViewOfflineResultsAction extends AnAction { new OfflineInspectionRVContentProvider(resMap, project)); ((RefManagerImpl)context.getRefManager()).startOfflineView(); view.update(); - TreeUtil.selectFirstNode(view.getTreeBuilder().getTree()); + TreeUtil.selectFirstNode(view.getTree()); context.addView(view, title); return view; } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java index 2bf44371ed66..452a15737a50 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java @@ -24,21 +24,22 @@ import com.intellij.codeInspection.CommonProblemDescriptor; import com.intellij.codeInspection.QuickFix; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.ui.*; -import com.intellij.codeInspection.ui.tree.*; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; -import com.intellij.codeInspection.ui.tree.ProblemDescriptionNode; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.util.Function; +import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.MutableTreeNode; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; import java.util.*; -import java.util.function.Predicate; public abstract class InspectionRVContentProvider { private static final Logger LOG = Logger.getInstance("#" + InspectionRVContentProvider.class.getName()); @@ -68,14 +69,26 @@ public abstract class InspectionRVContentProvider { public abstract boolean checkReportedProblems(@NotNull GlobalInspectionContextImpl context, @NotNull InspectionToolWrapper toolWrapper); - public Collection getTools(Tools tools) { + public Iterable getTools(Tools tools) { return tools.getTools(); } - public boolean hasQuickFixes(InspectionTreeBuilder tree) { - for (CommonProblemDescriptor descriptor : tree.getSelectedDescriptors()) { - QuickFix[] fixes = descriptor.getFixes(); - if (fixes != null && fixes.length != 0) { + public boolean hasQuickFixes(InspectionTree tree) { + final TreePath[] treePaths = tree.getSelectionPaths(); + if (treePaths == null) return false; + for (TreePath selectionPath : treePaths) { + if (!TreeUtil.traverseDepth((TreeNode)selectionPath.getLastPathComponent(), new TreeUtil.Traverse() { + @Override + public boolean accept(final Object node) { + if (!((InspectionTreeNode)node).isValid()) return true; + if (node instanceof ProblemDescriptionNode) { + final CommonProblemDescriptor descriptor = ((ProblemDescriptionNode)node).getDescriptor(); + final QuickFix[] fixes = descriptor != null ? descriptor.getFixes() : null; + return fixes == null || fixes.length == 0; + } + return true; + } + })) { return true; } } @@ -83,7 +96,7 @@ public abstract class InspectionRVContentProvider { } @Nullable - public abstract QuickFixAction[] getQuickFixes(@NotNull InspectionToolWrapper toolWrapper, @NotNull InspectionTreeBuilder tree); + public abstract QuickFixAction[] getQuickFixes(@NotNull InspectionToolWrapper toolWrapper, @NotNull InspectionTree tree); public void appendToolNodeContent(@NotNull GlobalInspectionContextImpl context, @@ -121,8 +134,8 @@ public abstract class InspectionRVContentProvider { @NotNull InspectionToolWrapper toolWrapper, @NotNull Function> computeContainer, final boolean showStructure) { - final List content = new ArrayList<>(); - final Map> module2PackageMap = new HashMap<>(); + final List content = new ArrayList(); + final Map> module2PackageMap = new HashMap>(); boolean supportStructure = showStructure; for (String packageName : packageContents.keySet()) { final Set elements = packageContents.get(packageName); @@ -137,7 +150,7 @@ public abstract class InspectionRVContentProvider { } InspectionPackageNode pNode = packageNodes.get(packageName); if (pNode == null) { - pNode = new InspectionPackageNode(myProject, packageName); + pNode = new InspectionPackageNode(packageName); packageNodes.put(packageName, pNode); } appendDescriptor(context, toolWrapper, container, pNode, canPackageRepeat); @@ -148,7 +161,7 @@ public abstract class InspectionRVContentProvider { for (final String moduleName : module2PackageMap.keySet()) { final Map packageNodes = module2PackageMap.get(moduleName); for (InspectionPackageNode packageNode : packageNodes.values()) { - if (packageNode.getChildren().size() > 0) { + if (packageNode.getChildCount() > 0) { InspectionModuleNode moduleNode = moduleNodes.get(moduleName); if (moduleNode == null) { if (moduleName != null) { @@ -160,18 +173,16 @@ public abstract class InspectionRVContentProvider { else { //module content was removed ? continue; } - } - else { + } else { content.addAll(packageNodes.values()); break; } } if (packageNode.getPackageName() != null) { moduleNode.add(packageNode); - } - else { - for (InspectionTreeNode node : packageNode.getChildren()) { - moduleNode.add(node); + } else { + for(int i = packageNode.getChildCount() - 1; i >= 0; i--) { + moduleNode.add((MutableTreeNode)packageNode.getChildAt(i)); } } } @@ -182,20 +193,21 @@ public abstract class InspectionRVContentProvider { else { for (Map packageNodes : module2PackageMap.values()) { for (InspectionPackageNode pNode : packageNodes.values()) { - for (InspectionTreeNode childNode : pNode.getChildren()) { + for (int i = 0; i < pNode.getChildCount(); i++) { + final TreeNode childNode = pNode.getChildAt(i); if (childNode instanceof ProblemDescriptionNode) { content.add(pNode); break; } LOG.assertTrue(childNode instanceof RefElementNode, childNode.getClass().getName()); final RefElementNode elementNode = (RefElementNode)childNode; - final Set parentNodes = new LinkedHashSet<>(); + final Set parentNodes = new LinkedHashSet(); if (pNode.getPackageName() != null) { parentNodes.add(elementNode); - } - else { + } else { boolean hasElementNodeUnder = true; - for (Object grandChildNode : elementNode.getChildren()) { + for(int e = 0; e < elementNode.getChildCount(); e++) { + final TreeNode grandChildNode = elementNode.getChildAt(e); if (grandChildNode instanceof ProblemDescriptionNode) { hasElementNodeUnder = false; break; @@ -203,21 +215,22 @@ public abstract class InspectionRVContentProvider { LOG.assertTrue(grandChildNode instanceof RefElementNode); parentNodes.add((RefElementNode)grandChildNode); } - if (!hasElementNodeUnder) { content.add(elementNode); continue; } } for (RefElementNode parentNode : parentNodes) { - final List nodes = new ArrayList<>(); - traverseDepth(parentNode, n -> { - if (n instanceof ProblemDescriptionNode) { - nodes.add((ProblemDescriptionNode)n); + final List nodes = new ArrayList(); + TreeUtil.traverse(parentNode, new TreeUtil.Traverse() { + @Override + public boolean accept(final Object node) { + if (node instanceof ProblemDescriptionNode) { + nodes.add((ProblemDescriptionNode)node); + } + return true; } - return true; }); - if (nodes.isEmpty()) continue; //FilteringInspectionTool == DeadCode parentNode.removeAllChildren(); for (ProblemDescriptionNode node : nodes) { @@ -244,20 +257,20 @@ public abstract class InspectionRVContentProvider { final RefElementNode currentNode = firstLevel.get() ? nodeToBeAdded : container.createNode(presentation); final UserObjectContainer finalContainer = container; final RefElementNode finalPrevNode = prevNode; - traverseDepth(parentNode, new Predicate() { + TreeUtil.traverseDepth(parentNode, new TreeUtil.Traverse() { @Override - public boolean test(InspectionTreeNode node) { + public boolean accept(Object node) { if (node instanceof RefElementNode) { final RefElementNode refElementNode = (RefElementNode)node; final Object userObject = finalContainer.getUserObject(); - final Object object = refElementNode.getValue(); + final Object object = refElementNode.getUserObject(); if ((object == null || userObject.getClass().equals(object.getClass())) && finalContainer.areEqual(object, userObject)) { if (firstLevel.get()) { result.set(refElementNode); return false; } else { - refElementNode.add(finalPrevNode); + insertByIndex(finalPrevNode, refElementNode); result.set(nodeToBeAdded); return false; } @@ -266,14 +279,14 @@ public abstract class InspectionRVContentProvider { return true; } }); - if (!result.isNull()) return result.get(); + if(!result.isNull()) return result.get(); if (!firstLevel.get()) { - currentNode.add(prevNode); + insertByIndex(prevNode, currentNode); } final UserObjectContainer owner = container.getOwner(); if (owner == null) { - parentNode.add(currentNode); + insertByIndex(currentNode, parentNode); return nodeToBeAdded; } container = owner; @@ -283,68 +296,73 @@ public abstract class InspectionRVContentProvider { } @SuppressWarnings({"ConstantConditions"}) //class cast suppression - protected static void merge(InspectionTreeNode child, InspectionTreeNode parent, boolean merge) { + protected static void merge(@Nullable DefaultTreeModel model, InspectionTreeNode child, InspectionTreeNode parent, boolean merge) { if (merge) { - final Collection children = parent.getChildren(); - for (InspectionTreeNode current : children) { + for (int i = 0; i < parent.getChildCount(); i++) { + InspectionTreeNode current = (InspectionTreeNode)parent.getChildAt(i); if (child.getClass() != current.getClass()) { continue; } if (current instanceof InspectionPackageNode) { if (((InspectionPackageNode)current).getPackageName().compareTo(((InspectionPackageNode)child).getPackageName()) == 0) { - processDepth(child, current); + processDepth(model, child, current); return; } } else if (current instanceof RefElementNode) { - if (((RefElementNode)current).getRefElement().getName().compareTo(((RefElementNode)child).getRefElement().getName()) == 0) { - processDepth(child, current); + if (((RefElementNode)current).getElement().getName().compareTo(((RefElementNode)child).getElement().getName()) == 0) { + processDepth(model, child, current); return; } } else if (current instanceof InspectionNode) { - if (((InspectionNode)current).getToolWrapper().getShortName() - .compareTo(((InspectionNode)child).getToolWrapper().getShortName()) == 0) { - processDepth(child, current); + if (((InspectionNode)current).getToolWrapper().getShortName().compareTo(((InspectionNode)child).getToolWrapper().getShortName()) == 0) { + processDepth(model, child, current); return; } } else if (current instanceof InspectionModuleNode) { - if (current.getName().compareTo(child.getName()) == 0) { - processDepth(child, current); + if (((InspectionModuleNode)current).getName().compareTo(((InspectionModuleNode)child).getName()) == 0) { + processDepth(model, child, current); return; } } } } - add(child, parent); + add(model, child, parent); } - protected static void add(final InspectionTreeNode child, final InspectionTreeNode parent) { - parent.add(child); - } - - private static void processDepth(final InspectionTreeNode child, final InspectionTreeNode current) { - final Collection childChildren = child.getChildren(); - for (InspectionTreeNode node : childChildren.toArray(new InspectionTreeNode[child.getChildren().size()])) { - merge(node, current, true); + protected static void add(@Nullable final DefaultTreeModel model, final InspectionTreeNode child, final InspectionTreeNode parent) { + if (model == null) { + insertByIndex(child, parent); + } + else { + if (parent.getIndex(child) < 0) { + model.insertNodeInto(child, parent, child.getParent() == parent ? parent.getChildCount() - 1 : parent.getChildCount()); + } } } - public static boolean traverse(@NotNull final InspectionTreeNode node, @NotNull final Predicate traverse) { - Collection children = node.getChildren(); - for (InspectionTreeNode o : children) { - if (!traverse(o, traverse)) return false; + private static void insertByIndex(InspectionTreeNode child, InspectionTreeNode parent) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + parent.add(child); + return; } - return traverse.test(node); + final int i = TreeUtil.indexedBinarySearch(parent, child, InspectionResultsViewComparator.getInstance()); + if (i >= 0){ + parent.add(child); + return; + } + parent.insert(child, -i -1); } - public static boolean traverseDepth(@NotNull final InspectionTreeNode node, @NotNull final Predicate traverse) { - if (!traverse.test(node)) return false; - Collection children = node.getChildren(); - for (InspectionTreeNode o : children) { - if (!traverseDepth(o, traverse)) return false; + private static void processDepth(@Nullable DefaultTreeModel model, final InspectionTreeNode child, final InspectionTreeNode current) { + InspectionTreeNode[] children = new InspectionTreeNode[child.getChildCount()]; + for (int i = 0; i < children.length; i++) { + children[i] = (InspectionTreeNode)child.getChildAt(i); + } + for (InspectionTreeNode node : children) { + merge(model, node, current, true); } - return true; } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProviderImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProviderImpl.java index 0fad1d99ca9c..5db74ec6f5c6 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProviderImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProviderImpl.java @@ -23,11 +23,7 @@ package com.intellij.codeInspection.ex; import com.intellij.codeInspection.CommonProblemDescriptor; import com.intellij.codeInspection.reference.*; import com.intellij.codeInspection.ui.*; -import com.intellij.codeInspection.ui.tree.*; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; -import com.intellij.codeInspection.ui.tree.ProblemDescriptionNode; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; @@ -47,8 +43,6 @@ import java.util.Map; import java.util.Set; public class InspectionRVContentProviderImpl extends InspectionRVContentProvider { - private final static Logger LOG = Logger.getInstance(InspectionRVContentProviderImpl.class); - public InspectionRVContentProviderImpl(final Project project) { super(project); } @@ -75,7 +69,6 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider } } } - problemElements.remove(entity); iterator.remove(); } @@ -87,8 +80,8 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider @Override @Nullable - public QuickFixAction[] getQuickFixes(@NotNull final InspectionToolWrapper toolWrapper, @NotNull final InspectionTreeBuilder tree) { - final RefEntity[] refEntities = tree.getSelectedRefElements(); + public QuickFixAction[] getQuickFixes(@NotNull final InspectionToolWrapper toolWrapper, @NotNull final InspectionTree tree) { + final RefEntity[] refEntities = tree.getSelectedElements(); InspectionToolPresentation presentation = tree.getContext().getPresentation(toolWrapper); return refEntities.length == 0 ? null : presentation.getQuickFixes(refEntities, tree.getSelectedDescriptors()); } @@ -102,8 +95,7 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider @NotNull final Map> contents, @NotNull final Map problems, DefaultTreeModel model) { - //ApplicationManager.getApplication().assertIsDispatchThread(); - LOG.assertTrue(ApplicationManager.getApplication().isReadAccessAllowed()); + ApplicationManager.getApplication().assertIsDispatchThread(); final InspectionToolWrapper toolWrapper = toolNode.getToolWrapper(); Function> computeContainer = new Function>() { @@ -125,7 +117,7 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider List list = buildTree(context, contents, false, toolWrapper, computeContainer, showStructure); for (InspectionTreeNode node : list) { - merge(node, toolNode, true); + merge(model, node, toolNode, true); } if (presentation.isOldProblemsIncluded()) { @@ -140,10 +132,10 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider list = buildTree(context, presentation.getOldContent(), true, toolWrapper, computeContainer, showStructure); for (InspectionTreeNode node : list) { - merge(node, toolNode, true); + merge(model, node, toolNode, true); } } - merge(toolNode, parentNode, false); + merge(model, toolNode, parentNode, false); } @Override @@ -164,7 +156,7 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider if (context.getUIOptions().SHOW_ONLY_DIFF && presentation.getProblemStatus(problem) == FileStatus.NOT_CHANGED) { continue; } - elemNode.add(new ProblemDescriptionNode(refElement, problem, toolWrapper, presentation)); + elemNode.add(new ProblemDescriptionNode(refElement, problem, toolWrapper,presentation)); if (problems.length == 1) { elemNode.setProblem(problems[0]); } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java index dd72ac299e0f..abd82c1a8789 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java @@ -24,7 +24,7 @@ import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.reference.RefManagerImpl; import com.intellij.codeInspection.ui.InspectionResultsView; -import com.intellij.codeInspection.ui.tree.InspectionTreeBuilder; +import com.intellij.codeInspection.ui.InspectionTree; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -84,13 +84,13 @@ public class QuickFixAction extends AnAction { e.getPresentation().setVisible(false); e.getPresentation().setEnabled(false); - final InspectionTreeBuilder tree = view.getTreeBuilder(); + final InspectionTree tree = view.getTree(); final InspectionToolWrapper toolWrapper = tree.getSelectedToolWrapper(); if (!view.isSingleToolInSelection() || toolWrapper != myToolWrapper) { return; } - if (!isProblemDescriptorsAcceptable() && tree.getSelectedElements().size() > 0 || + if (!isProblemDescriptorsAcceptable() && tree.getSelectedElements().length > 0 || isProblemDescriptorsAcceptable() && tree.getSelectedDescriptors().length > 0) { e.getPresentation().setVisible(true); e.getPresentation().setEnabled(true); @@ -108,7 +108,7 @@ public class QuickFixAction extends AnAction { @Override public void actionPerformed(final AnActionEvent e) { final InspectionResultsView view = getInvoker(e); - final InspectionTreeBuilder tree = view.getTreeBuilder(); + final InspectionTree tree = view.getTree(); final CommonProblemDescriptor[] descriptors; if (isProblemDescriptorsAcceptable() && (descriptors = tree.getSelectedDescriptors()).length > 0) { doApplyFix(view.getProject(), descriptors, tree.getContext()); @@ -231,7 +231,7 @@ public class QuickFixAction extends AnAction { private static RefEntity[] getSelectedElements(AnActionEvent e) { final InspectionResultsView invoker = getInvoker(e); if (invoker == null) return new RefElement[0]; - List selection = new ArrayList(Arrays.asList(invoker.getTreeBuilder().getSelectedRefElements())); + List selection = new ArrayList(Arrays.asList(invoker.getTree().getSelectedElements())); PsiDocumentManager.getInstance(invoker.getProject()).commitAllDocuments(); Collections.sort(selection, new Comparator() { @Override diff --git a/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineInspectionRVContentProvider.java b/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineInspectionRVContentProvider.java index 746394fbb280..eef80b91ba6f 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineInspectionRVContentProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineInspectionRVContentProvider.java @@ -27,16 +27,17 @@ import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.reference.SmartRefElementPointer; import com.intellij.codeInspection.ui.*; -import com.intellij.codeInspection.ui.tree.*; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.util.Function; import com.intellij.util.containers.HashSet; +import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; import java.util.*; public class OfflineInspectionRVContentProvider extends InspectionRVContentProvider { @@ -56,34 +57,39 @@ public class OfflineInspectionRVContentProvider extends InspectionRVContentProvi } @Override - public Collection getTools(Tools tools) { + public Iterable getTools(Tools tools) { return Collections.singletonList(tools.getDefaultState()); } @Override @Nullable - public QuickFixAction[] getQuickFixes(@NotNull final InspectionToolWrapper toolWrapper, @NotNull final InspectionTreeBuilder tree) { + public QuickFixAction[] getQuickFixes(@NotNull final InspectionToolWrapper toolWrapper, @NotNull final InspectionTree tree) { + final TreePath[] treePaths = tree.getSelectionPaths(); + if (treePaths == null) return QuickFixAction.EMPTY; final List selectedElements = new ArrayList(); final Map actions = new HashMap<>(); - for (InspectionTreeNode n : tree.getSelectedItems()) { - traverseDepth(n, node -> { - if (!node.isValid()) return true; - if (node instanceof OfflineProblemDescriptorNode) { - final OfflineProblemDescriptorNode descriptorNode = (OfflineProblemDescriptorNode)node; - final RefEntity element = descriptorNode.getRefElement(); - selectedElements.add(element); - CommonProblemDescriptor[] descriptors = actions.get(element); - final CommonProblemDescriptor descriptor = descriptorNode.getDescriptor(); - final CommonProblemDescriptor[] descriptorAsArray = descriptor == null ? CommonProblemDescriptor.EMPTY_ARRAY - : new CommonProblemDescriptor[]{descriptor}; - actions.put(element, descriptors == null ? - descriptorAsArray : - DefaultInspectionToolPresentation.mergeDescriptors(descriptors, descriptorAsArray)); + for (TreePath selectionPath : treePaths) { + TreeUtil.traverseDepth((TreeNode)selectionPath.getLastPathComponent(), new TreeUtil.Traverse() { + @Override + public boolean accept(final Object node) { + if (!((InspectionTreeNode)node).isValid()) return true; + if (node instanceof OfflineProblemDescriptorNode) { + final OfflineProblemDescriptorNode descriptorNode = (OfflineProblemDescriptorNode)node; + final RefEntity element = descriptorNode.getElement(); + selectedElements.add(element); + CommonProblemDescriptor[] descriptors = actions.get(element); + final CommonProblemDescriptor descriptor = descriptorNode.getDescriptor(); + final CommonProblemDescriptor[] descriptorAsArray = descriptor == null ? CommonProblemDescriptor.EMPTY_ARRAY + : new CommonProblemDescriptor[]{descriptor}; + actions.put(element, descriptors == null ? + descriptorAsArray : + DefaultInspectionToolPresentation.mergeDescriptors(descriptors, descriptorAsArray)); + } + else if (node instanceof RefElementNode) { + selectedElements.add(((RefElementNode)node).getElement()); + } + return true; } - else if (node instanceof RefElementNode) { - selectedElements.add(((RefElementNode)node).getRefElement()); - } - return true; }); } @@ -109,7 +115,7 @@ public class OfflineInspectionRVContentProvider extends InspectionRVContentProvi @NotNull final Map> contents, @NotNull final Map problems, final DefaultTreeModel model) { - InspectionToolWrapper toolWrapper = toolNode.getValue(); + InspectionToolWrapper toolWrapper = toolNode.getToolWrapper(); final Map> filteredContent = getFilteredContent(context, toolWrapper); if (filteredContent != null && !filteredContent.values().isEmpty()) { final Function> computeContainer = diff --git a/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java b/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java index f3100d875d94..8a976c5bbcfa 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineProblemDescriptorNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +/* + * User: anna + * Date: 09-Jan-2007 + */ package com.intellij.codeInspection.offlineViewer; import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil; @@ -26,7 +31,7 @@ import com.intellij.codeInspection.offline.OfflineProblemDescriptor; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.ui.InspectionToolPresentation; -import com.intellij.codeInspection.ui.tree.ProblemDescriptionNode; +import com.intellij.codeInspection.ui.ProblemDescriptionNode; import com.intellij.lang.Language; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.util.Computable; @@ -41,13 +46,10 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -/** - * @author Dmitry Batkovich - */ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode { - public OfflineProblemDescriptorNode(OfflineProblemDescriptor descriptor, - @NotNull LocalInspectionToolWrapper toolWrapper, - @NotNull InspectionToolPresentation presentation) { + OfflineProblemDescriptorNode(@NotNull OfflineProblemDescriptor descriptor, + @NotNull LocalInspectionToolWrapper toolWrapper, + @NotNull InspectionToolPresentation presentation) { super(descriptor, toolWrapper, presentation); } @@ -65,30 +67,28 @@ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode { @Override @Nullable - public RefEntity getRefElement() { - Object value = getValue(); - if (value instanceof CommonProblemDescriptor) { + public RefEntity getElement() { + if (userObject instanceof CommonProblemDescriptor) { return myElement; } - if (value == null) { + if (userObject == null) { return null; } - myElement = ((OfflineProblemDescriptor)value).getRefElement(myPresentation.getContext().getRefManager()); + myElement = ((OfflineProblemDescriptor)userObject).getRefElement(myPresentation.getContext().getRefManager()); return myElement; } @Override @Nullable public CommonProblemDescriptor getDescriptor() { - Object value = getValue(); - if (value == null) return null; - if (value instanceof CommonProblemDescriptor) { - return (CommonProblemDescriptor)value; + if (userObject == null) return null; + if (userObject instanceof CommonProblemDescriptor) { + return (CommonProblemDescriptor)userObject; } final InspectionManager inspectionManager = InspectionManager.getInstance(myPresentation.getContext().getProject()); - final OfflineProblemDescriptor offlineProblemDescriptor = (OfflineProblemDescriptor)value; - final RefEntity element = getRefElement(); + final OfflineProblemDescriptor offlineProblemDescriptor = (OfflineProblemDescriptor)userObject; + final RefEntity element = getElement(); if (myToolWrapper instanceof LocalInspectionToolWrapper) { if (element instanceof RefElement) { final PsiElement psiElement = ((RefElement)element).getElement(); @@ -102,7 +102,7 @@ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode { if (descriptor != null) return descriptor; } } - setValue(null); + setUserObject(null); return null; } final List hints = offlineProblemDescriptor.getHints(); @@ -117,7 +117,7 @@ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode { descriptor = inspectionManager.createProblemDescriptor(psiElement, offlineProblemDescriptor.getDescription(), false, quickFixes, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } - setValue(descriptor); + setUserObject(descriptor); return descriptor; } CommonProblemDescriptor descriptor = @@ -126,7 +126,7 @@ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode { if (quickFixes != null) { descriptor = inspectionManager.createProblemDescriptor(offlineProblemDescriptor.getDescription(), quickFixes); } - setValue(descriptor); + setUserObject(descriptor); return descriptor; } @@ -154,7 +154,7 @@ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode { final PsiNamedElement member = localTool.getProblemElement(descriptor.getPsiElement()); if (psiElement instanceof PsiFile || member != null && member.equals(psiElement)) { if (curIdx == idx) { - setValue(descriptor); + setUserObject(descriptor); return descriptor; } curIdx++; @@ -197,9 +197,8 @@ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode { } public String toString() { - Object value = getValue(); - if (value instanceof OfflineProblemDescriptor) { - return ((OfflineProblemDescriptor)value).getDescription(); + if (userObject instanceof OfflineProblemDescriptor) { + return ((OfflineProblemDescriptor)userObject).getDescription(); } return super.toString(); } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineRefElementNode.java b/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineRefElementNode.java index 30ad827553cb..50f3a78b8e10 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineRefElementNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineRefElementNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2009 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,18 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +/* + * User: anna + * Date: 05-Jan-2007 + */ package com.intellij.codeInspection.offlineViewer; import com.intellij.codeInspection.offline.OfflineProblemDescriptor; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.ui.InspectionToolPresentation; -import com.intellij.codeInspection.ui.tree.RefElementNode; +import com.intellij.codeInspection.ui.RefElementNode; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -/** - * @author Dmitry Batkovich - */ public class OfflineRefElementNode extends RefElementNode { public OfflineRefElementNode(@NotNull OfflineProblemDescriptor descriptor, @NotNull InspectionToolPresentation presentation) { super(descriptor, presentation); @@ -32,29 +34,21 @@ public class OfflineRefElementNode extends RefElementNode { @Override @Nullable - public RefEntity getRefElement() { - Object userObject = getValue(); + public RefEntity getElement() { if (userObject instanceof RefEntity) { return (RefEntity)userObject; } if (userObject == null) return null; final RefEntity refElement = ((OfflineProblemDescriptor)userObject).getRefElement(myToolPresentation.getContext().getRefManager()); - setValue(refElement); + setUserObject(refElement); return refElement; } @Nullable public OfflineProblemDescriptor getDescriptor() { - Object userObject = getValue(); if (userObject instanceof OfflineProblemDescriptor) { return (OfflineProblemDescriptor)userObject; } return null; } - - @Nullable - @Override - public String getTestPresentation() { - return toString(); - } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java index 9723fcd01c23..cc87a9c5bd14 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java @@ -23,8 +23,6 @@ import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.*; import com.intellij.codeInspection.ex.*; import com.intellij.codeInspection.reference.*; -import com.intellij.codeInspection.ui.tree.InspectionNode; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.components.PathMacroManager; import com.intellij.openapi.diagnostic.Logger; @@ -65,25 +63,23 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro @NotNull private final GlobalInspectionContextImpl myContext; private static String ourOutputPath; + private InspectionNode myToolNode; private static final Object lock = new Object(); - private final Map myProblemElements = - Collections.synchronizedMap(new THashMap()); - private final Map> myContents = - Collections.synchronizedMap(new com.intellij.util.containers.HashMap>()); // keys can be null + private final Map myProblemElements = Collections.synchronizedMap(new THashMap()); + private final Map> myContents = Collections.synchronizedMap(new com.intellij.util.containers.HashMap>()); // keys can be null private final Set myModulesProblems = Collections.synchronizedSet(new THashSet()); - private final Map myProblemToElements = - Collections.synchronizedMap(new THashMap()); + private final Map myProblemToElements = Collections.synchronizedMap(new THashMap()); private DescriptorComposer myComposer; - private final Map> myQuickFixActions = - Collections.synchronizedMap(new com.intellij.util.containers.HashMap>()); - private final Map myIgnoredElements = - Collections.synchronizedMap(new com.intellij.util.containers.HashMap()); + private final Map> myQuickFixActions = Collections.synchronizedMap(new com.intellij.util.containers.HashMap>()); + private final Map myIgnoredElements = Collections.synchronizedMap(new com.intellij.util.containers.HashMap()); private Map myOldProblemElements = null; protected static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.DescriptorProviderInspection"); private boolean isDisposed; + private final Object myToolLock = new Object(); + public DefaultInspectionToolPresentation(@NotNull InspectionToolWrapper toolWrapper, @NotNull GlobalInspectionContextImpl context) { myToolWrapper = toolWrapper; myContext = context; @@ -113,8 +109,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro startFindIdx = end; description = description.substring(0, matcher.start(1)) + " inspection settings " + description.substring(end); } - } - else { + } else { description = description.substring(0, descriptionEnd); } return description; @@ -180,7 +175,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro @Override public void exportResults(@NotNull final Element parentNode) { - getRefManager().iterate(new RefVisitor() { + getRefManager().iterate(new RefVisitor(){ @Override public void visitElement(@NotNull RefEntity elem) { exportResults(parentNode, elem); @@ -196,14 +191,12 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro @Override - public void addProblemElement(RefEntity refElement, @NotNull CommonProblemDescriptor... descriptions) { + public void addProblemElement(RefEntity refElement, @NotNull CommonProblemDescriptor... descriptions){ addProblemElement(refElement, true, descriptions); } @Override - public void addProblemElement(final RefEntity refElement, - boolean filterSuppressed, - @NotNull final CommonProblemDescriptor... descriptors) { + public void addProblemElement(final RefEntity refElement, boolean filterSuppressed, @NotNull final CommonProblemDescriptor... descriptors) { if (refElement == null) return; if (descriptors.length == 0) return; if (filterSuppressed) { @@ -235,37 +228,37 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro if (view == null || !(refElement instanceof RefElement)) { return; } - view.getLock().lock(); - try { - final InspectionNode toolNode; - final HighlightSeverity currentSeverity = getSeverity((RefElement)refElement); - toolNode = view.addTool(myToolWrapper, HighlightDisplayLevel.find(currentSeverity), context.getUIOptions().GROUP_BY_SEVERITY); - final Map problems = new HashMap(); - problems.put(refElement, descriptors); - final Map> contents = new HashMap>(); - final String groupName = refElement.getRefManager().getGroupName((RefElement)refElement); - Set content = contents.get(groupName); - if (content == null) { - content = new HashSet(); - contents.put(groupName, content); - } - content.add(refElement); - - view.getProvider().appendToolNodeContent(context, - toolNode, - (InspectionTreeNode)toolNode.getParent(), - context.getUIOptions().SHOW_STRUCTURE, - contents, - problems, - (DefaultTreeModel)view.getTreeBuilder().getTree().getModel()); - } - finally { - view.getLock().unlock(); - } UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { if (!isDisposed()) { + final InspectionNode toolNode; + synchronized (myToolLock) { + if (myToolNode == null) { + final HighlightSeverity currentSeverity = getSeverity((RefElement)refElement); + toolNode = view.addTool(myToolWrapper, HighlightDisplayLevel.find(currentSeverity), context.getUIOptions().GROUP_BY_SEVERITY); + } + else { + toolNode = myToolNode; + if (toolNode.isTooBigForOnlineRefresh()) { + return; + } + } + } + final Map problems = new HashMap(); + problems.put(refElement, descriptors); + final Map> contents = new HashMap>(); + final String groupName = refElement.getRefManager().getGroupName((RefElement)refElement); + Set content = contents.get(groupName); + if (content == null) { + content = new HashSet(); + contents.put(groupName, content); + } + content.add(refElement); + + view.getProvider().appendToolNodeContent(context, toolNode, + (InspectionTreeNode)toolNode.getParent(), context.getUIOptions().SHOW_STRUCTURE, + contents, problems, (DefaultTreeModel)view.getTree().getModel()); context.addView(view); } } @@ -275,7 +268,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro @NotNull public static CommonProblemDescriptor[] mergeDescriptors(@NotNull CommonProblemDescriptor[] problems1, - @NotNull CommonProblemDescriptor[] problems2) { + @NotNull CommonProblemDescriptor[] problems2) { CommonProblemDescriptor[] out = new CommonProblemDescriptor[problems1.length + problems2.length]; int o = problems1.length; Equality equality = new Equality() { @@ -306,6 +299,13 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro return Arrays.copyOfRange(out, 0, o); } + + public void setToolNode(InspectionNode toolNode) { + synchronized (myToolLock) { + myToolNode = toolNode; + } + } + protected boolean isDisposed() { return isDisposed; } @@ -324,8 +324,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro final File file = new File(fileName); final CharArrayWriter writer = new CharArrayWriter(); if (!file.exists()) { - writer.append("<").append(InspectionsBundle.message("inspection.problems")) - .append(" " + GlobalInspectionContextBase.LOCAL_TOOL_ATTRIBUTE + "=\"") + writer.append("<").append(InspectionsBundle.message("inspection.problems")).append(" " + GlobalInspectionContextBase.LOCAL_TOOL_ATTRIBUTE + "=\"") .append(Boolean.toString(myToolWrapper instanceof LocalInspectionToolWrapper)).append("\">\n"); } for (Object o : list) { @@ -333,8 +332,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro pathMacroManager.collapsePaths(element); JDOMUtil.writeElement(element, writer, "\n"); } - printWriter = - new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName, true), CharsetToolkit.UTF8_CHARSET))); + printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName, true), CharsetToolkit.UTF8_CHARSET))); printWriter.append("\n"); printWriter.append(writer.toString()); } @@ -387,7 +385,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro if (refEntity == null) return; final Set localQuickFixes = getQuickFixActions().get(refEntity); final QuickFix[] fixes = problem.getFixes(); - if (isIgnoreProblem(fixes, localQuickFixes, idx)) { + if (isIgnoreProblem(fixes, localQuickFixes, idx)){ getProblemToElements().remove(problem); Map problemElements = getProblemElements(); synchronized (lock) { @@ -410,7 +408,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro } } - private void ignoreProblemElement(RefEntity refEntity) { + private void ignoreProblemElement(RefEntity refEntity){ final CommonProblemDescriptor[] problemDescriptors = getProblemElements().remove(refEntity); getIgnoredElements().put(refEntity, problemDescriptors); } @@ -424,15 +422,15 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro getIgnoredElements().put(refEntity, ArrayUtil.append(descriptors, descriptor)); } - private static boolean isIgnoreProblem(QuickFix[] problemFixes, Set fixes, int idx) { + private static boolean isIgnoreProblem(QuickFix[] problemFixes, Set fixes, int idx){ if (problemFixes == null || fixes == null) { return true; } - if (problemFixes.length <= idx) { + if (problemFixes.length <= idx){ return true; } for (QuickFix fix : problemFixes) { - if (fix != problemFixes[idx] && !fixes.contains(fix)) { + if (fix != problemFixes[idx] && !fixes.contains(fix)){ return false; } } @@ -496,9 +494,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro } } - private void exportResults(@NotNull final CommonProblemDescriptor[] descriptors, - @NotNull RefEntity refEntity, - @NotNull Element parentNode) { + private void exportResults(@NotNull final CommonProblemDescriptor[] descriptors, @NotNull RefEntity refEntity, @NotNull Element parentNode) { for (CommonProblemDescriptor descriptor : descriptors) { @NonNls final String template = descriptor.getDescriptionTemplate(); int line = descriptor instanceof ProblemDescriptor ? ((ProblemDescriptor)descriptor).getLineNumber() : -1; @@ -512,7 +508,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro problemClassElement.addContent(myToolWrapper.getDisplayName()); final HighlightSeverity severity; - if (refEntity instanceof RefElement) { + if (refEntity instanceof RefElement){ final RefElement refElement = (RefElement)refEntity; severity = getSeverity(refElement); } @@ -521,7 +517,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro final HighlightDisplayLevel level = profile.getErrorLevel(HighlightDisplayKey.find(myToolWrapper.getShortName()), psiElement); severity = level.getSeverity(); } - + if (severity != null) { ProblemHighlightType problemHighlightType = descriptor instanceof ProblemDescriptor ? ((ProblemDescriptor)descriptor).getHighlightType() @@ -530,7 +526,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro problemClassElement.setAttribute("severity", severity.myName); problemClassElement.setAttribute("attribute_key", attributeKey); } - + element.addContent(problemClassElement); if (myToolWrapper instanceof GlobalInspectionToolWrapper) { final GlobalInspectionTool globalInspectionTool = ((GlobalInspectionToolWrapper)myToolWrapper).getTool(); @@ -555,8 +551,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro } catch (IllegalDataException e) { //noinspection HardCodedStringLiteral,UseOfSystemOutOrSystemErr - System.out - .println("Cannot save results for " + refEntity.getName() + ", inspection which caused problem: " + myToolWrapper.getShortName()); + System.out.println("Cannot save results for " + refEntity.getName() + ", inspection which caused problem: " + myToolWrapper.getShortName()); } } } @@ -585,10 +580,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro return false; } if (!getProblemElements().isEmpty()) return true; - return !isDisposed() && - context.getUIOptions().SHOW_DIFF_WITH_PREVIOUS_RUN && - myOldProblemElements != null && - !myOldProblemElements.isEmpty(); + return !isDisposed() && context.getUIOptions().SHOW_DIFF_WITH_PREVIOUS_RUN && myOldProblemElements != null && !myOldProblemElements.isEmpty(); } @Override @@ -658,8 +650,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro public QuickFixAction[] extractActiveFixes(@NotNull RefEntity[] refElements, @NotNull Map descriptorMap, @Nullable CommonProblemDescriptor[] allowedDescriptors) { - final Set allowedDescriptorSet = - allowedDescriptors == null ? null : ContainerUtil.newHashSet(allowedDescriptors); + final Set allowedDescriptorSet = allowedDescriptors == null ? null : ContainerUtil.newHashSet(allowedDescriptors); Map result = new com.intellij.util.containers.HashMap<>(); boolean isFirst = true; for (RefEntity refElement : refElements) { @@ -732,7 +723,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro if (refElement != null) { final QuickFix[] fixes = descriptor.getFixes(); for (int i = 0; i < fixes.length; i++) { - if (fixes[i] == fix) { + if (fixes[i] == fix){ ignoreProblem(refElement, descriptor, i); return; } @@ -767,8 +758,8 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro @NotNull public FileStatus getProblemStatus(@NotNull final CommonProblemDescriptor descriptor) { final GlobalInspectionContextImpl context = getContext(); - if (!isDisposed() && context.getUIOptions().SHOW_DIFF_WITH_PREVIOUS_RUN) { - if (myOldProblemElements != null) { + if (!isDisposed() && context.getUIOptions().SHOW_DIFF_WITH_PREVIOUS_RUN){ + if (myOldProblemElements != null){ final Set allAvailable = new HashSet(); for (CommonProblemDescriptor[] descriptors : myOldProblemElements.values()) { if (descriptors != null) { @@ -783,18 +774,18 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro return FileStatus.NOT_CHANGED; } - private static boolean containsDescriptor(@NotNull CommonProblemDescriptor descriptor, Collection descriptors) { + private static boolean containsDescriptor(@NotNull CommonProblemDescriptor descriptor, Collection descriptors){ PsiElement element = null; - if (descriptor instanceof ProblemDescriptor) { + if (descriptor instanceof ProblemDescriptor){ element = ((ProblemDescriptor)descriptor).getPsiElement(); } for (CommonProblemDescriptor problemDescriptor : descriptors) { - if (problemDescriptor instanceof ProblemDescriptor) { - if (!Comparing.equal(element, ((ProblemDescriptor)problemDescriptor).getPsiElement())) { + if (problemDescriptor instanceof ProblemDescriptor){ + if (!Comparing.equal(element, ((ProblemDescriptor)problemDescriptor).getPsiElement())){ continue; } } - if (Comparing.strEqual(problemDescriptor.getDescriptionTemplate(), descriptor.getDescriptionTemplate())) { + if (Comparing.strEqual(problemDescriptor.getDescriptionTemplate(), descriptor.getDescriptionTemplate())){ return true; } } @@ -806,8 +797,8 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro @Override public FileStatus getElementStatus(final RefEntity element) { final GlobalInspectionContextImpl context = getContext(); - if (!isDisposed() && context.getUIOptions().SHOW_DIFF_WITH_PREVIOUS_RUN) { - if (myOldProblemElements != null) { + if (!isDisposed() && context.getUIOptions().SHOW_DIFF_WITH_PREVIOUS_RUN){ + if (myOldProblemElements != null){ final boolean old = RefUtil.contains(element, myOldProblemElements.keySet()); final boolean current = RefUtil.contains(element, getProblemElements().keySet()); return calcStatus(old, current); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionGroupNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionGroupNode.java similarity index 64% rename from platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionGroupNode.java rename to platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionGroupNode.java index bf3de633309b..a1f9394c11b1 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionGroupNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionGroupNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.codeInspection.ui.tree; -import com.intellij.openapi.project.Project; +package com.intellij.codeInspection.ui; + import com.intellij.util.IconUtil; import com.intellij.util.ui.EmptyIcon; import org.jetbrains.annotations.NotNull; @@ -23,19 +23,17 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; /** - * @author Dmitry Batkovich + * @author max */ -public class InspectionGroupNode extends InspectionTreeNode { +class InspectionGroupNode extends InspectionTreeNode { private static final Icon EMPTY = new EmptyIcon(0, IconUtil.getEmptyIcon(false).getIconHeight()); - public InspectionGroupNode(@NotNull String groupTitle, @NotNull Project project) { - super(project, groupTitle); + InspectionGroupNode(@NotNull String groupTitle) { + super(groupTitle); } - public String getGroupTitle() { - String title = getValue(); - LOG.assertTrue(title != null); - return title; + String getGroupTitle() { + return (String) getUserObject(); } @Override @@ -47,9 +45,4 @@ public class InspectionGroupNode extends InspectionTreeNode { public boolean appearsBold() { return true; } - - @Override - public String toString() { - return getGroupTitle(); - } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionModuleNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionModuleNode.java similarity index 85% rename from platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionModuleNode.java rename to platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionModuleNode.java index d15436dda338..7d02ed967cef 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionModuleNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionModuleNode.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.codeInspection.ui.tree; +package com.intellij.codeInspection.ui; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; @@ -21,12 +21,13 @@ import com.intellij.openapi.module.ModuleType; import javax.swing.*; /** - * @author Dmitry Batkovich + * User: anna + * Date: 09-Jan-2006 */ -public class InspectionModuleNode extends InspectionTreeNode { +public class InspectionModuleNode extends InspectionTreeNode{ private final Module myModule; public InspectionModuleNode(final Module module) { - super(module.getProject(), module); + super(module); myModule = module; } @@ -42,4 +43,4 @@ public class InspectionModuleNode extends InspectionTreeNode { public String toString() { return getName(); } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNode.java similarity index 72% rename from platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionNode.java rename to platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNode.java index 8d58fe1243dc..bde4f550e5aa 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.codeInspection.ui.tree; + +package com.intellij.codeInspection.ui; import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.icons.AllIcons; -import com.intellij.openapi.project.Project; import com.intellij.ui.LayeredIcon; import com.intellij.util.IconUtil; import org.jetbrains.annotations.NotNull; @@ -25,13 +25,14 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; /** - * @author Dmitry Batkovich + * @author max */ -public class InspectionNode extends InspectionTreeNode { +public class InspectionNode extends InspectionTreeNode { public static final Icon TOOL = LayeredIcon.create(AllIcons.Toolwindows.ToolWindowInspection, IconUtil.getEmptyIcon(false)); + private boolean myTooBigForOnlineRefresh = false; - public InspectionNode(@NotNull InspectionToolWrapper toolWrapper, Project project) { - super(project, toolWrapper); + public InspectionNode(@NotNull InspectionToolWrapper toolWrapper) { + super(toolWrapper); } public String toString() { @@ -40,9 +41,7 @@ public class InspectionNode extends InspectionTreeNode { @NotNull public InspectionToolWrapper getToolWrapper() { - InspectionToolWrapper value = getValue(); - LOG.assertTrue(value != null); - return value; + return (InspectionToolWrapper)getUserObject(); } @Override @@ -50,4 +49,10 @@ public class InspectionNode extends InspectionTreeNode { return TOOL; } + public boolean isTooBigForOnlineRefresh() { + if (!myTooBigForOnlineRefresh) { + myTooBigForOnlineRefresh = getProblemCount() > 1000; + } + return myTooBigForOnlineRefresh; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java index 394ca9808c6e..f6afb1cca039 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNodeInfo.java @@ -52,7 +52,7 @@ public class InspectionNodeInfo extends JPanel { myProject = project; myTitle = new SimpleColoredComponent(); myCurrentProfile = (InspectionProfileImpl)InspectionProjectProfileManager.getInstance(project).getProjectProfileImpl(); - myKey = HighlightDisplayKey.findById(toolWrapper.getID()); + myKey = HighlightDisplayKey.find(toolWrapper.getID()); myName = toolWrapper.getDisplayName(); myButton = new JButton(); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionPackageNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionPackageNode.java similarity index 62% rename from platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionPackageNode.java rename to platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionPackageNode.java index 1712766544dd..45a7d4297178 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionPackageNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionPackageNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2009 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,36 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.codeInspection.ui.tree; -import com.intellij.openapi.project.Project; +package com.intellij.codeInspection.ui; + import com.intellij.util.PlatformIcons; import javax.swing.*; - /** - * @author Dmitry Batkovich + * @author max */ -public class InspectionPackageNode extends InspectionTreeNode { - private String myPackageName; +public class InspectionPackageNode extends InspectionTreeNode { - public InspectionPackageNode(Project project, String name) { - super(project, name); - myPackageName = name; + public InspectionPackageNode(String packageName) { + super(packageName); } public String getPackageName() { - return myPackageName; + return (String) getUserObject(); } @Override public Icon getIcon(boolean expanded) { return PlatformIcons.PACKAGE_ICON; } - - @Override - public String toString() { - return getPackageName(); - } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java index 4523d2527573..240b9a482e9d 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java @@ -28,8 +28,6 @@ import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.ui.actions.ExportHTMLAction; import com.intellij.codeInspection.ui.actions.InspectionsOptionsToolbarAction; import com.intellij.codeInspection.ui.actions.InvokeQuickFixAction; -import com.intellij.codeInspection.ui.tree.*; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; import com.intellij.icons.AllIcons; import com.intellij.ide.*; import com.intellij.ide.actions.ContextHelpAction; @@ -45,7 +43,6 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.ui.popup.JBPopup; -import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; @@ -53,24 +50,25 @@ import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.pom.Navigatable; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.psi.*; import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.*; import com.intellij.ui.components.JBLabel; +import com.intellij.usageView.UsageInfo; import com.intellij.usages.impl.UsagePreviewPanel; import com.intellij.util.ConcurrencyUtil; import com.intellij.util.EditSourceOnDoubleClickHandler; import com.intellij.util.OpenSourceUtil; -import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.*; +import com.intellij.util.ui.UIUtil; +import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.InputEvent; @@ -78,9 +76,9 @@ import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.util.*; +import java.util.HashSet; import java.util.List; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.locks.ReentrantLock; /** * @author max @@ -92,9 +90,8 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren private static final Key PREVIEW_EDITOR_IS_REUSED_KEY = Key.create("inspection.tool.window.preview.editor.is.reused."); private final Project myProject; - private InspectionTreeBuilder myTreeBuilder; - private final ConcurrentMap> myGroups = - ContainerUtil.newConcurrentMap(); + private final InspectionTree myTree; + private final ConcurrentMap> myGroups = ContainerUtil.newConcurrentMap(); private final OccurenceNavigator myOccurenceNavigator; private volatile InspectionProfile myInspectionProfile; private final AnalysisScope myScope; @@ -108,8 +105,6 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren private boolean myRerun; private volatile boolean myDisposed; - private final ReentrantLock myLock = new ReentrantLock(); - @NotNull private final InspectionRVContentProvider myProvider; private AnAction myIncludeAction; @@ -129,15 +124,14 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren myGlobalInspectionContext = globalInspectionContext; myProvider = provider; - myTreeBuilder = new InspectionTreeBuilder(project, globalInspectionContext); - Disposer.register(this, myTreeBuilder); + myTree = new InspectionTree(project, globalInspectionContext); initTreeListeners(); myOccurenceNavigator = initOccurenceNavigator(); mySplitter = new OnePixelSplitter(false, AnalysisUIOptions.getInstance(myProject).SPLITTER_PROPORTION); - mySplitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myTreeBuilder.getTree(), SideBorder.LEFT | SideBorder.RIGHT)); + mySplitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myTree, SideBorder.LEFT | SideBorder.RIGHT)); mySplitter.addPropertyChangeListener(evt -> { if (Splitter.PROP_PROPORTION.equals(evt.getPropertyName())) { @@ -147,59 +141,50 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren add(mySplitter, BorderLayout.CENTER); createActionsToolbar(); - myTreeBuilder.select(myTreeBuilder.getRootElement()); + TreeUtil.selectFirstNode(myTree); } private void initTreeListeners() { - final JTree tree = myTreeBuilder.getTree(); - tree.getSelectionModel().addTreeSelectionListener(e -> { - if (myDisposed) return; + myTree.getSelectionModel().addTreeSelectionListener(e -> { syncRightPanel(); if (isAutoScrollMode()) { - OpenSourceUtil.openSourcesFrom(DataManager.getInstance().getDataContext(this), false); + OpenSourceUtil.openSourcesFrom(DataManager.getInstance().getDataContext(InspectionResultsView.this), false); } }); - EditSourceOnDoubleClickHandler.install(tree); + EditSourceOnDoubleClickHandler.install(myTree); - tree.addKeyListener(new KeyAdapter() { + myTree.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { - if (myDisposed) return; if (e.getKeyCode() == KeyEvent.VK_ENTER) { OpenSourceUtil.openSourcesFrom(DataManager.getInstance().getDataContext(InspectionResultsView.this), false); } } }); - tree.addMouseListener(new PopupHandler() { + myTree.addMouseListener(new PopupHandler() { @Override public void invokePopup(Component comp, int x, int y) { - if (myDisposed) return; popupInvoked(comp, x, y); } }); - SmartExpander.installOn(tree); + SmartExpander.installOn(myTree); } - private OccurenceNavigatorSupport initOccurenceNavigator() { - return new OccurenceNavigatorSupport(myTreeBuilder.getTree()) { + private OccurenceNavigatorSupport initOccurenceNavigator(){ + return new OccurenceNavigatorSupport(myTree) { @Override @Nullable - protected Navigatable createDescriptorForNode(DefaultMutableTreeNode path) { - Object object = path.getUserObject(); - if (!(object instanceof InspectionTreeNode)) { - return null; - } - InspectionTreeNode node = (InspectionTreeNode)object; - if (node.isResolved()) { + protected Navigatable createDescriptorForNode(DefaultMutableTreeNode node) { + if (node instanceof InspectionTreeNode && ((InspectionTreeNode)node).isResolved()) { return null; } if (node instanceof RefElementNode) { final RefElementNode refNode = (RefElementNode)node; if (refNode.hasDescriptorsUnder()) return null; - final RefEntity element = refNode.getRefElement(); + final RefEntity element = refNode.getElement(); if (element == null || !element.isValid()) return null; final CommonProblemDescriptor problem = refNode.getProblem(); if (problem != null) { @@ -210,7 +195,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } } else if (node instanceof ProblemDescriptionNode) { - if (!node.isValid()) return null; + if (!((ProblemDescriptionNode)node).isValid()) return null; return navigate(((ProblemDescriptionNode)node).getDescriptor()); } return null; @@ -245,42 +230,50 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren @SuppressWarnings({"NonStaticInitializer"}) private JComponent createRightActionsToolbar() { - myIncludeAction = new AnAction(InspectionsBundle.message("inspections.result.view.include.action.text")) { + myIncludeAction = new AnAction(InspectionsBundle.message("inspections.result.view.include.action.text")){ { - registerCustomShortcutSet(CommonShortcuts.INSERT, myTreeBuilder.getTree()); + registerCustomShortcutSet(CommonShortcuts.INSERT, myTree); } @Override public void actionPerformed(AnActionEvent e) { - for (InspectionTreeNode node : myTreeBuilder.getSelectedItems()) { - node.amnesty(); + final TreePath[] paths = myTree.getSelectionPaths(); + if (paths != null) { + for (TreePath path : paths) { + ((InspectionTreeNode)path.getLastPathComponent()).amnesty(); + } } updateView(false); } @Override public void update(final AnActionEvent e) { - e.getPresentation().setEnabled(!myTreeBuilder.getSelectedItems().isEmpty() && + final TreePath[] paths = myTree.getSelectionPaths(); + e.getPresentation().setEnabled(paths != null && paths.length > 0 && !myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS); } }; myExcludeAction = new AnAction(InspectionsBundle.message("inspections.result.view.exclude.action.text")) { { - registerCustomShortcutSet(CommonShortcuts.getDelete(), myTreeBuilder.getTree()); + registerCustomShortcutSet(CommonShortcuts.getDelete(), myTree); } @Override public void actionPerformed(final AnActionEvent e) { - for (InspectionTreeNode node : myTreeBuilder.getSelectedItems()) { - node.ignoreElement(); + final TreePath[] paths = myTree.getSelectionPaths(); + if (paths != null) { + for (TreePath path : paths) { + ((InspectionTreeNode)path.getLastPathComponent()).ignoreElement(); + } } updateView(false); } @Override public void update(final AnActionEvent e) { - e.getPresentation().setEnabled(!myTreeBuilder.getSelectedItems().isEmpty()); + final TreePath[] path = myTree.getSelectionPaths(); + e.getPresentation().setEnabled(path != null && path.length > 0); } }; @@ -304,7 +297,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren final TreeExpander treeExpander = new TreeExpander() { @Override public void expandAll() { - myTreeBuilder.expandAll(null); + TreeUtil.expandAll(myTree); } @Override @@ -314,7 +307,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren @Override public void collapseAll() { - myTreeBuilder.collapseChildren(myTreeBuilder.getRootElement(), null); + TreeUtil.collapseAll(myTree, 0); } @Override @@ -322,8 +315,8 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren return true; } }; - group.add(actionsManager.createExpandAllAction(treeExpander, myTreeBuilder.getTree())); - group.add(actionsManager.createCollapseAllAction(treeExpander, myTreeBuilder.getTree())); + group.add(actionsManager.createExpandAllAction(treeExpander, myTree)); + group.add(actionsManager.createCollapseAllAction(treeExpander, myTree)); group.add(actionsManager.createPrevOccurenceAction(getOccurenceNavigator())); group.add(actionsManager.createNextOccurenceAction(getOccurenceNavigator())); group.add(myGlobalInspectionContext.createToggleAutoscrollAction()); @@ -342,7 +335,6 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren releaseEditor(myPreviewEditor); mySplitter.dispose(); myInspectionProfile = null; - myTreeBuilder = null; myDisposed = true; } @@ -383,40 +375,39 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren private void syncRightPanel() { final Editor oldEditor = myPreviewEditor; - final Collection selectedElements = myTreeBuilder.getSelectedItems(); - if (selectedElements.size() == 1) { - final InspectionTreeNode node = ContainerUtil.getFirstItem(selectedElements); - if (node instanceof RefElementNode) { - final RefElementNode refElementNode = (RefElementNode)node; - final RefEntity refSelected = refElementNode.getRefElement(); - showInRightPanel(refSelected); - } - else if (node instanceof ProblemDescriptionNode) { - final ProblemDescriptionNode - problemNode = (ProblemDescriptionNode)node; - showInRightPanel(problemNode.getRefElement()); - } - else if (node instanceof InspectionNode || node instanceof InspectionPackageNode || node instanceof InspectionModuleNode) { - showInRightPanel(null); - } - else if (node instanceof InspectionRootNode || - node instanceof InspectionGroupNode || - node instanceof InspectionSeverityGroupNode) { - mySplitter.setSecondComponent(new InspectionViewNavigationPanel(node, myTreeBuilder)); - } - else { - LOG.error("Unexpected node: " + node.getClass()); - } - } - else { - if (myTreeBuilder.getSelectedToolWrapper() == null) { + if (myTree.getSelectionModel().getSelectionCount() != 1) { + if (myTree.getSelectedToolWrapper() == null) { final JLabel multipleSelectionLabel = new JBLabel(InspectionViewNavigationPanel.getTitleText(false, false)); multipleSelectionLabel.setVerticalAlignment(SwingConstants.TOP); multipleSelectionLabel.setBorder(IdeBorderFactory.createEmptyBorder(5, 7, 0, 0)); mySplitter.setSecondComponent(multipleSelectionLabel); } else { - showInRightPanel(myTreeBuilder.getCommonSelectedElement()); + showInRightPanel(myTree.getCommonSelectedElement()); + } + } + else { + TreePath pathSelected = myTree.getSelectionModel().getLeadSelectionPath(); + if (pathSelected != null) { + final InspectionTreeNode node = (InspectionTreeNode)pathSelected.getLastPathComponent(); + if (node instanceof RefElementNode) { + final RefElementNode refElementNode = (RefElementNode)node; + final RefEntity refSelected = refElementNode.getElement(); + showInRightPanel(refSelected); + } + else if (node instanceof ProblemDescriptionNode) { + final ProblemDescriptionNode problemNode = (ProblemDescriptionNode)node; + showInRightPanel(problemNode.getElement()); + } + else if (node instanceof InspectionNode || node instanceof InspectionPackageNode || node instanceof InspectionModuleNode) { + showInRightPanel(null); + } + else if (node instanceof InspectionRootNode || node instanceof InspectionGroupNode || node instanceof InspectionSeverityGroupNode) { + mySplitter.setSecondComponent(new InspectionViewNavigationPanel(node, myTree)); + } + else { + LOG.error("Unexpected node: " + node.getClass()); + } } } if (oldEditor != null) { @@ -435,15 +426,15 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren setCursor(new Cursor(Cursor.WAIT_CURSOR)); final JPanel editorPanel = new JPanel(); editorPanel.setLayout(new BorderLayout()); - final int problemCount = myTreeBuilder.getSelectedProblemCount(); + final int problemCount = myTree.getSelectedProblemCount(); editorPanel.add(createBaseRightComponentFor(problemCount, refEntity), BorderLayout.CENTER); if (problemCount > 0) { - final InspectionToolWrapper tool = myTreeBuilder.getSelectedToolWrapper(); + final InspectionToolWrapper tool = myTree.getSelectedToolWrapper(); LOG.assertTrue(tool != null); - editorPanel.add(new QuickFixToolbar(myTreeBuilder, + editorPanel.add(new QuickFixToolbar(myTree, myProject, myPreviewEditor, - myProvider.getQuickFixes(tool, myTreeBuilder)), + myProvider.getQuickFixes(tool, myTree)), BorderLayout.NORTH); } mySplitter.setSecondComponent(editorPanel); @@ -461,7 +452,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren if (selectedEntity instanceof RefElement && !(((RefElement)selectedEntity).getElement() instanceof PsiDirectory)) { PsiElement selectedElement = ((RefElement)selectedEntity).getElement(); if (problemCount == 1) { - CommonProblemDescriptor[] descriptors = myTreeBuilder.getSelectedDescriptors(); + CommonProblemDescriptor[] descriptors = myTree.getSelectedDescriptors(); if (descriptors.length != 0) { final CommonProblemDescriptor descriptor = descriptors[0]; if (descriptor instanceof ProblemDescriptorBase) { @@ -504,23 +495,22 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren return myPreviewEditor.getComponent(); } else if (selectedEntity == null) { - return new InspectionNodeInfo(myTreeBuilder.getSelectedToolWrapper(), myProject); + return new InspectionNodeInfo(myTree.getSelectedToolWrapper(), myProject); } return new JPanel(); } @NotNull - public InspectionNode addTool(@NotNull final InspectionToolWrapper toolWrapper, - HighlightDisplayLevel errorLevel, - boolean groupedBySeverity) { + public InspectionNode addTool(@NotNull final InspectionToolWrapper toolWrapper, HighlightDisplayLevel errorLevel, boolean groupedBySeverity) { String groupName = toolWrapper.getGroupDisplayName().isEmpty() ? InspectionProfileEntry.GENERAL_GROUP_NAME : toolWrapper.getGroupDisplayName(); InspectionTreeNode parentNode = getToolParentNode(groupName, errorLevel, groupedBySeverity); - InspectionNode toolNode = new InspectionNode(toolWrapper, myProject); + InspectionNode toolNode = new InspectionNode(toolWrapper); boolean showStructure = myGlobalInspectionContext.getUIOptions().SHOW_STRUCTURE; myProvider.appendToolNodeContent(myGlobalInspectionContext, toolNode, parentNode, showStructure); InspectionToolPresentation presentation = myGlobalInspectionContext.getPresentation(toolWrapper); toolNode = presentation.createToolNode(myGlobalInspectionContext, toolNode, myProvider, parentNode, showStructure); + ((DefaultInspectionToolPresentation)presentation).setToolNode(toolNode); registerActionShortcuts(presentation); return toolNode; @@ -536,13 +526,8 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } private void clearTree() { - myLock.lock(); - try { - myTreeBuilder.removeAllNodes(); - mySeverityGroupNodes.clear(); - } finally { - myLock.unlock(); - } + myTree.removeAllNodes(); + mySeverityGroupNodes.clear(); } @Nullable @@ -554,43 +539,39 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren return myInspectionProfile; } - public boolean update() { + public boolean update(){ return updateView(true); } public boolean updateView(boolean strict) { - if (!strict && !myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS) { - myTreeBuilder.getTree().repaint(); + if (!strict && !myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS){ + myTree.repaint(); return false; } clearTree(); - return buildTree(); + boolean resultsFound = buildTree(); + myTree.restoreExpansionAndSelection(); + return resultsFound; } private boolean buildTree() { - myLock.lock(); - try { - InspectionProfile profile = myInspectionProfile; - boolean isGroupedBySeverity = myGlobalInspectionContext.getUIOptions().GROUP_BY_SEVERITY; - myGroups.clear(); - final Map tools = myGlobalInspectionContext.getTools(); - boolean resultsFound = false; - for (Tools currentTools : tools.values()) { - InspectionToolWrapper defaultToolWrapper = currentTools.getDefaultState().getTool(); - final HighlightDisplayKey key = HighlightDisplayKey.find(defaultToolWrapper.getShortName()); - for (ScopeToolState state : myProvider.getTools(currentTools)) { - InspectionToolWrapper toolWrapper = state.getTool(); - if (myProvider.checkReportedProblems(myGlobalInspectionContext, toolWrapper)) { - addTool(toolWrapper, ((InspectionProfileImpl)profile).getErrorLevel(key, state.getScope(myProject), myProject), - isGroupedBySeverity); - resultsFound = true; - } + InspectionProfile profile = myInspectionProfile; + boolean isGroupedBySeverity = myGlobalInspectionContext.getUIOptions().GROUP_BY_SEVERITY; + myGroups.clear(); + final Map tools = myGlobalInspectionContext.getTools(); + boolean resultsFound = false; + for (Tools currentTools : tools.values()) { + InspectionToolWrapper defaultToolWrapper = currentTools.getDefaultState().getTool(); + final HighlightDisplayKey key = HighlightDisplayKey.find(defaultToolWrapper.getShortName()); + for (ScopeToolState state : myProvider.getTools(currentTools)) { + InspectionToolWrapper toolWrapper = state.getTool(); + if (myProvider.checkReportedProblems(myGlobalInspectionContext, toolWrapper)) { + addTool(toolWrapper, ((InspectionProfileImpl)profile).getErrorLevel(key, state.getScope(myProject), myProject), isGroupedBySeverity); + resultsFound = true; } } - return resultsFound; - } finally { - myLock.unlock(); } + return resultsFound; } @NotNull @@ -600,9 +581,9 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } ConcurrentMap map = myGroups.get(errorLevel); if (map == null) { - map = ConcurrencyUtil.cacheOrGet(myGroups, errorLevel, ContainerUtil.newConcurrentMap()); + map = ConcurrencyUtil.cacheOrGet(myGroups, errorLevel, ContainerUtil.newConcurrentMap()); } - InspectionTreeNode group; + InspectionGroupNode group; if (groupedBySeverity) { group = map.get(groupName); } @@ -613,8 +594,8 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } } if (group == null) { - group = ConcurrencyUtil.cacheOrGet(map, groupName, new InspectionGroupNode(groupName, myProject)); - addChildAndUpdate(getRelativeRootNode(groupedBySeverity, errorLevel), group); + group = ConcurrencyUtil.cacheOrGet(map, groupName, new InspectionGroupNode(groupName)); + addChildNodeInEDT(getRelativeRootNode(groupedBySeverity, errorLevel), group); } return group; } @@ -627,20 +608,24 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren InspectionSeverityGroupNode newNode = new InspectionSeverityGroupNode(myProject, level); severityGroupNode = ConcurrencyUtil.cacheOrGet(mySeverityGroupNodes, level, newNode); if (severityGroupNode == newNode) { - InspectionRootNode root = (InspectionRootNode)myTreeBuilder.getRootElement(); - addChildAndUpdate(root, severityGroupNode); + InspectionTreeNode root = myTree.getRoot(); + addChildNodeInEDT(root, severityGroupNode); } } return severityGroupNode; } - return (InspectionTreeNode)myTreeBuilder.getRootElement(); + return myTree.getRoot(); } - private void addChildAndUpdate(@NotNull final InspectionTreeNode root, @NotNull final InspectionTreeNode severityGroupNode) { - if (!myDisposed) { - root.add(severityGroupNode); - } - myTreeBuilder.queueUpdateFrom(root, false); + private void addChildNodeInEDT(@NotNull final DefaultMutableTreeNode root, @NotNull final MutableTreeNode severityGroupNode) { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + if (!myDisposed) { + root.add(severityGroupNode); + } + } + }); } @@ -687,21 +672,25 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren public Object getData(String dataId) { if (PlatformDataKeys.HELP_ID.is(dataId)) return HELP_ID; if (DATA_KEY.is(dataId)) return this; - if (myTreeBuilder == null) return null; - Collection selected = myTreeBuilder.getSelectedItems(); - if (selected.isEmpty()) return null; + if (myTree == null) return null; + TreePath[] paths = myTree.getSelectionPaths(); - if (selected.size() > 1) { + if (paths == null || paths.length == 0) return null; + + if (paths.length > 1) { if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { return collectPsiElements(); } return null; } - Object selectedNode = ContainerUtil.getFirstItem(selected); + TreePath path = paths[0]; + + InspectionTreeNode selectedNode = (InspectionTreeNode)path.getLastPathComponent(); + if (selectedNode instanceof RefElementNode) { final RefElementNode refElementNode = (RefElementNode)selectedNode; - RefEntity refElement = refElementNode.getRefElement(); + RefEntity refElement = refElementNode.getElement(); if (refElement == null) return null; final RefEntity item = refElement.getRefManager().getRefinedElement(refElement); @@ -744,7 +733,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren @Nullable private Navigatable getSelectedNavigatable(final CommonProblemDescriptor descriptor, final PsiElement psiElement) { if (descriptor instanceof ProblemDescriptorBase) { - Navigatable navigatable = ((ProblemDescriptorBase)descriptor).getNavigatable(); + Navigatable navigatable = ((ProblemDescriptorBase) descriptor).getNavigatable(); if (navigatable != null) { return navigatable; } @@ -770,7 +759,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } private PsiElement[] collectPsiElements() { - RefEntity[] refElements = myTreeBuilder.getSelectedRefElements(); + RefEntity[] refElements = myTree.getSelectedElements(); List psiElements = new ArrayList(); for (RefEntity refElement : refElements) { PsiElement psiElement = refElement instanceof RefElement ? ((RefElement)refElement).getElement() : null; @@ -783,7 +772,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } private void popupInvoked(Component component, int x, int y) { - final TreePath path = myTreeBuilder.getTree().getLeadSelectionPath(); + final TreePath path = myTree.getLeadSelectionPath(); if (path == null) return; @@ -797,9 +786,9 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren actions.addSeparator(); - final InspectionToolWrapper toolWrapper = myTreeBuilder.getSelectedToolWrapper(); + final InspectionToolWrapper toolWrapper = myTree.getSelectedToolWrapper(); if (toolWrapper != null) { - final QuickFixAction[] quickFixes = myProvider.getQuickFixes(toolWrapper, myTreeBuilder); + final QuickFixAction[] quickFixes = myProvider.getQuickFixes(toolWrapper, myTree); if (quickFixes != null) { for (QuickFixAction quickFixe : quickFixes) { actions.add(quickFixe); @@ -825,8 +814,8 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } @NotNull - public InspectionTreeBuilder getTreeBuilder() { - return myTreeBuilder; + public InspectionTree getTree(){ + return myTree; } @NotNull @@ -840,7 +829,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } public boolean isSingleToolInSelection() { - return myTreeBuilder != null && myTreeBuilder.getSelectedToolWrapper() != null; + return myTree != null && myTree.getSelectedToolWrapper() != null; } public boolean isRerun() { @@ -851,7 +840,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren private InspectionProfile guessProfileToSelect(final InspectionProjectProfileManager profileManager) { final Set profiles = new HashSet(); - final RefEntity[] selectedElements = myTreeBuilder.getSelectedRefElements(); + final RefEntity[] selectedElements = myTree.getSelectedElements(); for (RefEntity selectedElement : selectedElements) { if (selectedElement instanceof RefElement) { final RefElement refElement = (RefElement)selectedElement; @@ -875,8 +864,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren final InputEvent event = e.getInputEvent(); if (event instanceof MouseEvent) { popup.showUnderneathOf(event.getComponent()); - } - else { + } else { popup.showInBestPositionFor(e.getDataContext()); } } @@ -909,7 +897,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren @Override public void actionPerformed(AnActionEvent e) { final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(myProject); - final InspectionToolWrapper toolWrapper = myTreeBuilder.getSelectedToolWrapper(); + final InspectionToolWrapper toolWrapper = myTree.getSelectedToolWrapper(); InspectionProfile inspectionProfile = myInspectionProfile; final boolean profileIsDefined = isProfileDefined(); if (!profileIsDefined) { @@ -918,10 +906,9 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren if (toolWrapper != null) { final HighlightDisplayKey key = HighlightDisplayKey.find(toolWrapper.getShortName()); //do not search for dead code entry point tool - if (key != null) { - if (new EditInspectionToolsSettingsAction(key) - .editToolSettings(myProject, (InspectionProfileImpl)inspectionProfile, profileIsDefined) - && profileIsDefined) { + if (key != null){ + if (new EditInspectionToolsSettingsAction(key).editToolSettings(myProject, (InspectionProfileImpl)inspectionProfile, profileIsDefined) + && profileIsDefined){ updateCurrentProfile(); } return; @@ -931,17 +918,13 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren updateCurrentProfile(); } } - } + } public void updateCurrentProfile() { final String name = myInspectionProfile.getName(); myInspectionProfile = (InspectionProfile)myInspectionProfile.getProfileManager().getProfile(name); } - public ReentrantLock getLock() { - return myLock; - } - private class RerunAction extends AnAction { public RerunAction(JComponent comp) { super(InspectionsBundle.message("inspection.action.rerun"), InspectionsBundle.message("inspection.action.rerun"), @@ -958,7 +941,6 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren public void actionPerformed(AnActionEvent e) { rerun(); } - private void rerun() { myRerun = true; if (myScope.isValid()) { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java index 25d75af8baba..b36ab755a9ac 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java @@ -32,9 +32,6 @@ import com.intellij.codeInspection.offlineViewer.OfflineProblemDescriptorNode; import com.intellij.codeInspection.offlineViewer.OfflineRefElementNode; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; -import com.intellij.codeInspection.ui.tree.*; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; -import com.intellij.codeInspection.ui.tree.ProblemDescriptionNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.util.Comparing; @@ -48,11 +45,13 @@ import com.intellij.psi.util.PsiUtilCore; import java.util.Comparator; -public class InspectionResultsViewComparator implements Comparator { +public class InspectionResultsViewComparator implements Comparator { private static final Logger LOG = Logger.getInstance("#" + InspectionResultsViewComparator.class.getName()); @Override - public int compare(InspectionTreeNode node1, InspectionTreeNode node2) { + public int compare(Object o1, Object o2) { + InspectionTreeNode node1 = (InspectionTreeNode)o1; + InspectionTreeNode node2 = (InspectionTreeNode)o2; if (node1 instanceof InspectionSeverityGroupNode && node2 instanceof InspectionSeverityGroupNode) { final InspectionSeverityGroupNode groupNode1 = (InspectionSeverityGroupNode)node1; @@ -88,8 +87,8 @@ public class InspectionResultsViewComparator implements Comparator { +public class InspectionSeverityGroupNode extends InspectionTreeNode{ + + private final HighlightDisplayLevel myLevel; + private final Project myProject; + public InspectionSeverityGroupNode(final Project project, final HighlightDisplayLevel level) { - super(project, level); + super(level); + myLevel = level; + myProject = project; } @Override public Icon getIcon(boolean expanded) { - return getValue().getIcon(); + return myLevel.getIcon(); } @Override @@ -40,12 +49,14 @@ public class InspectionSeverityGroupNode extends InspectionTreeNode myExpandedUserObjects; + @NotNull private final GlobalInspectionContextImpl myContext; + private SelectionPath mySelectionPath; + + public InspectionTree(@NotNull Project project, @NotNull GlobalInspectionContextImpl context) { + super(new InspectionRootNode(project)); + myContext = context; + + setCellRenderer(new CellRenderer()); + setShowsRootHandles(true); + UIUtil.setLineStyleAngled(this); + addTreeWillExpandListener(new ExpandListener()); + + myExpandedUserObjects = new HashSet(); + myExpandedUserObjects.add(project); + + TreeUtil.installActions(this); + new TreeSpeedSearch(this, new Convertor() { + @Override + public String convert(TreePath o) { + return InspectionsConfigTreeComparator.getDisplayTextToSort(o.getLastPathComponent().toString()); + } + }); + + addTreeSelectionListener(new TreeSelectionListener() { + @Override + public void valueChanged(TreeSelectionEvent e) { + TreePath newSelection = e.getNewLeadSelectionPath(); + if (newSelection != null) { + mySelectionPath = new SelectionPath(newSelection); + } + } + }); + } + + public void removeAllNodes() { + getRoot().removeAllChildren(); + nodeStructureChanged(getRoot()); + } + + public InspectionTreeNode getRoot() { + return (InspectionTreeNode)getModel().getRoot(); + } + + @Nullable + public InspectionToolWrapper getSelectedToolWrapper() { + final TreePath[] paths = getSelectionPaths(); + if (paths == null) return null; + InspectionToolWrapper toolWrapper = null; + for (TreePath path : paths) { + Object[] nodes = path.getPath(); + for (int j = nodes.length - 1; j >= 0; j--) { + Object node = nodes[j]; + if (node instanceof InspectionGroupNode) { + return null; + } + if (node instanceof InspectionNode) { + InspectionToolWrapper wrapper = ((InspectionNode)node).getToolWrapper(); + if (toolWrapper == null) { + toolWrapper = wrapper; + } + else if (toolWrapper != wrapper) { + return null; + } + break; + } + } + } + + return toolWrapper; + } + + @Nullable + public RefEntity getCommonSelectedElement() { + final Object node = getCommonSelectedNode(); + return node instanceof RefElementNode ? ((RefElementNode)node).getElement() : null; + } + + @Nullable + private Object getCommonSelectedNode() { + final TreePath[] paths = getSelectionPaths(); + if (paths == null) return null; + final Object[][] resolvedPaths = new Object[paths.length][]; + for (int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + resolvedPaths[i] = path.getPath(); + } + + Object currentCommonNode = null; + for (int i = 0; i < resolvedPaths[0].length; i++) { + final Object currentNode = resolvedPaths[0][i]; + for (int j = 1; j < resolvedPaths.length; j++) { + final Object o = resolvedPaths[j][i]; + if (!o.equals(currentNode)) { + return currentCommonNode; + } + } + currentCommonNode = currentNode; + } + return currentCommonNode; + } + + @NotNull + public RefEntity[] getSelectedElements() { + TreePath[] selectionPaths = getSelectionPaths(); + if (selectionPaths != null) { + InspectionToolWrapper toolWrapper = getSelectedToolWrapper(); + if (toolWrapper == null) return RefEntity.EMPTY_ELEMENTS_ARRAY; + + List result = new ArrayList(); + for (TreePath selectionPath : selectionPaths) { + final InspectionTreeNode node = (InspectionTreeNode)selectionPath.getLastPathComponent(); + addElementsInNode(node, result); + } + return result.toArray(new RefEntity[result.size()]); + } + return RefEntity.EMPTY_ELEMENTS_ARRAY; + } + + private static void addElementsInNode(InspectionTreeNode node, List out) { + if (!node.isValid()) return; + if (node instanceof RefElementNode) { + final RefEntity element = ((RefElementNode)node).getElement(); + if (!out.contains(element)) { + out.add(0, element); + } + } + if (node instanceof ProblemDescriptionNode) { + final RefEntity element = ((ProblemDescriptionNode)node).getElement(); + if (!out.contains(element)) { + out.add(0, element); + } + } + final Enumeration children = node.children(); + while (children.hasMoreElements()) { + InspectionTreeNode child = (InspectionTreeNode)children.nextElement(); + addElementsInNode(child, out); + } + } + + public CommonProblemDescriptor[] getSelectedDescriptors() { + if (getSelectionCount() == 0) return CommonProblemDescriptor.EMPTY_ARRAY; + final TreePath[] paths = getSelectionPaths(); + final LinkedHashSet descriptors = new LinkedHashSet(); + for (TreePath path : paths) { + Object node = path.getLastPathComponent(); + traverseDescriptors((InspectionTreeNode)node, descriptors); + } + return descriptors.toArray(new CommonProblemDescriptor[descriptors.size()]); + } + + public int getSelectedProblemCount() { + if (getSelectionCount() == 0) return 0; + final TreePath[] paths = getSelectionPaths(); + + Set result = new HashSet<>(); + MultiMap rootDependencies = new MultiMap<>(); + for (TreePath path : paths) { + + final InspectionTreeNode node = (InspectionTreeNode)path.getLastPathComponent(); + final Collection visitedChildren = rootDependencies.get(node); + for (InspectionTreeNode child : visitedChildren) { + result.remove(child); + } + + boolean needToAdd = true; + for (int i = 0; i < path.getPathCount() - 1; i++) { + final InspectionTreeNode parent = (InspectionTreeNode) path.getPathComponent(i); + rootDependencies.putValue(parent, node); + if (result.contains(parent)) { + needToAdd = false; + break; + } + } + + if (needToAdd) { + result.add(node); + } + } + + int count = 0; + for (InspectionTreeNode node : result) { + count += node.getProblemCount(); + } + return count; + } + + private static void traverseDescriptors(InspectionTreeNode node, LinkedHashSet descriptors){ + if (node instanceof ProblemDescriptionNode) { + if (node.isValid() && !node.isResolved()) { + final CommonProblemDescriptor descriptor = ((ProblemDescriptionNode)node).getDescriptor(); + if (descriptor != null) { + descriptors.add(descriptor); + } + } + } + for(int i = node.getChildCount() - 1; i >= 0; i--){ + traverseDescriptors((InspectionTreeNode)node.getChildAt(i), descriptors); + } + } + + private void nodeStructureChanged(InspectionTreeNode node) { + ((DefaultTreeModel)getModel()).nodeStructureChanged(node); + } + + private class ExpandListener implements TreeWillExpandListener { + @Override + public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException { + final InspectionTreeNode node = (InspectionTreeNode)event.getPath().getLastPathComponent(); + final Object userObject = node.getUserObject(); + //TODO: never re-sort + if (node.isValid() && !myExpandedUserObjects.contains(userObject)) { + sortChildren(node); + nodeStructureChanged(node); + } + myExpandedUserObjects.add(userObject); + // Smart expand + if (node.getChildCount() == 1) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + expandPath(new TreePath(node.getPath())); + } + }); + } + } + + @Override + public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException { + InspectionTreeNode node = (InspectionTreeNode)event.getPath().getLastPathComponent(); + myExpandedUserObjects.remove(node.getUserObject()); + } + } + + public void restoreExpansionAndSelection() { + restoreExpansionStatus((InspectionTreeNode)getModel().getRoot()); + if (mySelectionPath != null) { + mySelectionPath.restore(); + } + } + + private void restoreExpansionStatus(InspectionTreeNode node) { + if (myExpandedUserObjects.contains(node.getUserObject())) { + sortChildren(node); + TreeNode[] pathToNode = node.getPath(); + expandPath(new TreePath(pathToNode)); + Enumeration children = node.children(); + while (children.hasMoreElements()) { + InspectionTreeNode childNode = (InspectionTreeNode)children.nextElement(); + restoreExpansionStatus(childNode); + } + } + } + + private static class CellRenderer extends ColoredTreeCellRenderer { + /* private Project myProject; + InspectionManagerEx myManager; + public CellRenderer(Project project) { + myProject = project; + myManager = (InspectionManagerEx)InspectionManager.getInstance(myProject); + }*/ + + @Override + public void customizeCellRenderer(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + InspectionTreeNode node = (InspectionTreeNode)value; + + append(node.toString(), + patchAttr(node, appearsBold(node) ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES : getMainForegroundAttributes(node))); + + int problemCount = node.getProblemCount(); + if (!leaf) { + append(" " + InspectionsBundle.message("inspection.problem.descriptor.count", problemCount), patchAttr(node, SimpleTextAttributes.GRAYED_ATTRIBUTES)); + } + + if (!node.isValid()) { + append(" " + InspectionsBundle.message("inspection.invalid.node.text"), patchAttr(node, SimpleTextAttributes.ERROR_ATTRIBUTES)); + } else { + setIcon(node.getIcon(expanded)); + } + } + + public static SimpleTextAttributes patchAttr(InspectionTreeNode node, SimpleTextAttributes attributes) { + if (node.isResolved()) { + return new SimpleTextAttributes(attributes.getBgColor(), attributes.getFgColor(), attributes.getWaveColor(), attributes.getStyle() | SimpleTextAttributes.STYLE_STRIKEOUT); + } + return attributes; + } + + private static SimpleTextAttributes getMainForegroundAttributes(InspectionTreeNode node) { + SimpleTextAttributes foreground = SimpleTextAttributes.REGULAR_ATTRIBUTES; + if (node instanceof RefElementNode) { + RefEntity refElement = ((RefElementNode)node).getElement(); + + if (refElement instanceof RefElement) { + refElement = ((RefElement)refElement).getContainingEntry(); + if (((RefElement)refElement).isEntry() && ((RefElement)refElement).isPermanentEntry()) { + foreground = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, JBColor.blue); + } + } + + } + final FileStatus nodeStatus = node.getNodeStatus(); + if (nodeStatus != FileStatus.NOT_CHANGED){ + foreground = new SimpleTextAttributes(foreground.getBgColor(), nodeStatus.getColor(), foreground.getWaveColor(), foreground.getStyle()); + } + return foreground; + } + + private static boolean appearsBold(Object node) { + return ((InspectionTreeNode)node).appearsBold(); + } + } + + private void sortChildren(InspectionTreeNode node) { + final List children = TreeUtil.childrenToArray(node); + Collections.sort(children, InspectionResultsViewComparator.getInstance()); + node.removeAllChildren(); + TreeUtil.addChildrenTo(node, children); + ((DefaultTreeModel)getModel()).reload(node); + } + + private class SelectionPath { + private final Object[] myPath; + private final int[] myIndicies; + + public SelectionPath(TreePath path) { + myPath = path.getPath(); + myIndicies = new int[myPath.length]; + for (int i = 0; i < myPath.length - 1; i++) { + InspectionTreeNode node = (InspectionTreeNode)myPath[i]; + myIndicies[i + 1] = getChildIndex(node, (InspectionTreeNode)myPath[i + 1]); + } + } + + private int getChildIndex(InspectionTreeNode node, InspectionTreeNode child) { + int idx = 0; + Enumeration children = node.children(); + while (children.hasMoreElements()) { + InspectionTreeNode ch = (InspectionTreeNode)children.nextElement(); + if (ch == child) break; + idx++; + } + return idx; + } + + public void restore() { + getSelectionModel().removeSelectionPaths(getSelectionModel().getSelectionPaths()); + TreeUtil.selectPath(InspectionTree.this, restorePath()); + } + + private TreePath restorePath() { + ArrayList newPath = new ArrayList(); + + newPath.add(getModel().getRoot()); + restorePath(newPath, 1); + + return new TreePath(newPath.toArray(new InspectionTreeNode[newPath.size()])); + } + + private void restorePath(ArrayList newPath, int idx) { + if (idx >= myPath.length) return; + InspectionTreeNode oldNode = (InspectionTreeNode)myPath[idx]; + + InspectionTreeNode newRoot = (InspectionTreeNode)newPath.get(idx - 1); + + + InspectionResultsViewComparator comparator = InspectionResultsViewComparator.getInstance(); + Enumeration children = newRoot.children(); + while (children.hasMoreElements()) { + InspectionTreeNode child = (InspectionTreeNode)children.nextElement(); + if (comparator.compare(child, oldNode) == 0) { + newPath.add(child); + restorePath(newPath, idx + 1); + return; + } + } + + // Exactly same element not found. Trying to select somewhat near. + int count = newRoot.getChildCount(); + if (count > 0) { + if (myIndicies[idx] < count) { + newPath.add(newRoot.getChildAt(myIndicies[idx])); + } + else { + newPath.add(newRoot.getChildAt(count - 1)); + } + } + } + } + + @NotNull + public GlobalInspectionContextImpl getContext() { + return myContext; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java new file mode 100644 index 000000000000..d4d356396fc9 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.codeInspection.ui; + +import com.intellij.openapi.vcs.FileStatus; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import java.util.Enumeration; + +/** + * @author max + */ +public abstract class InspectionTreeNode extends DefaultMutableTreeNode { + private boolean myResolved; + protected InspectionTreeNode(Object userObject) { + super(userObject); + } + + @Nullable + public abstract Icon getIcon(boolean expanded); + + public int getProblemCount() { + int sum = 0; + Enumeration enumeration = children(); + while (enumeration.hasMoreElements()) { + InspectionTreeNode child = (InspectionTreeNode)enumeration.nextElement(); + sum += child.getProblemCount(); + } + return sum; + } + + public boolean isValid() { + return true; + } + + public boolean isResolved(){ + return myResolved; + } + + public boolean appearsBold() { + return false; + } + + public FileStatus getNodeStatus(){ + return FileStatus.NOT_CHANGED; + } + + public void ignoreElement() { + myResolved = true; + Enumeration enumeration = children(); + while (enumeration.hasMoreElements()) { + InspectionTreeNode child = (InspectionTreeNode)enumeration.nextElement(); + child.ignoreElement(); + } + } + + public void amnesty() { + myResolved = false; + Enumeration enumeration = children(); + while (enumeration.hasMoreElements()) { + InspectionTreeNode child = (InspectionTreeNode)enumeration.nextElement(); + child.amnesty(); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewNavigationPanel.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewNavigationPanel.java index afffa8dc2180..4579854165ee 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewNavigationPanel.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewNavigationPanel.java @@ -15,22 +15,23 @@ */ package com.intellij.codeInspection.ui; -import com.intellij.codeInspection.ui.tree.InspectionRootNode; -import com.intellij.codeInspection.ui.tree.InspectionTreeBuilder; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.components.JBLabel; +import com.intellij.ui.components.labels.LinkLabel; import com.intellij.util.ui.JBUI; +import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeNode; import java.awt.*; /** * @author Dmitry Batkovich */ public class InspectionViewNavigationPanel extends JPanel { - public InspectionViewNavigationPanel(InspectionTreeNode node, InspectionTreeBuilder treeBuilder) { + public InspectionViewNavigationPanel(InspectionTreeNode node, InspectionTree tree) { setLayout(new BorderLayout()); setBorder(IdeBorderFactory.createEmptyBorder(5, 7, 0, 0)); final String titleLabelText = getTitleText(node instanceof InspectionRootNode, true); @@ -39,23 +40,17 @@ public class InspectionViewNavigationPanel extends JPanel { links.setLayout(new BoxLayout(links, BoxLayout.Y_AXIS)); links.add(Box.createVerticalStrut(JBUI.scale(10))); add(BorderLayout.CENTER, links); - - //TODO fix it!! - // - // - //treeBuilder. - // - //for (int i = 0; i < node.getChildCount(); i++) { - // final TreeNode child = node.getChildAt(i); - // final LinkLabel link = new LinkLabel(child.toString(), null) { - // @Override - // public void doClick() { - // TreeUtil.selectInTree((DefaultMutableTreeNode)child, true, treeBuilder.getTree()); - // } - // }; - // link.setBorder(IdeBorderFactory.createEmptyBorder(1, 17, 3, 1)); - // links.add(link); - //} + for (int i = 0; i < node.getChildCount(); i++) { + final TreeNode child = node.getChildAt(i); + final LinkLabel link = new LinkLabel(child.toString(), null) { + @Override + public void doClick() { + TreeUtil.selectInTree((DefaultMutableTreeNode)child, true, tree); + } + }; + link.setBorder(IdeBorderFactory.createEmptyBorder(1, 17, 3, 1)); + links.add(link); + } } @NotNull diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/ProblemDescriptionNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java similarity index 79% rename from platform/lang-impl/src/com/intellij/codeInspection/ui/tree/ProblemDescriptionNode.java rename to platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java index 5fb290bf19fa..18e41a82f62c 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/ProblemDescriptionNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2009 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.codeInspection.ui.tree; + +package com.intellij.codeInspection.ui; import com.intellij.codeInspection.*; import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; -import com.intellij.codeInspection.ui.InspectionToolPresentation; import com.intellij.icons.AllIcons; import com.intellij.openapi.vcs.FileStatus; import com.intellij.psi.PsiElement; @@ -33,7 +33,7 @@ import static com.intellij.codeInspection.ProblemDescriptorUtil.APPEND_LINE_NUMB import static com.intellij.codeInspection.ProblemDescriptorUtil.TRIM_AT_TREE_END; /** - * @author Dmitry Batkovich + * @author max */ public class ProblemDescriptionNode extends InspectionTreeNode { protected RefEntity myElement; @@ -56,11 +56,11 @@ public class ProblemDescriptionNode extends InspectionTreeNode { } private ProblemDescriptionNode(@NotNull Object userObject, - RefEntity element, - CommonProblemDescriptor descriptor, - @NotNull InspectionToolWrapper toolWrapper, - @NotNull InspectionToolPresentation presentation) { - super(presentation.getContext().getProject(), userObject); + RefEntity element, + CommonProblemDescriptor descriptor, + @NotNull InspectionToolWrapper toolWrapper, + @NotNull InspectionToolPresentation presentation) { + super(userObject); myElement = element; myDescriptor = descriptor; myToolWrapper = toolWrapper; @@ -68,7 +68,7 @@ public class ProblemDescriptionNode extends InspectionTreeNode { } @Nullable - public RefEntity getRefElement() { + public RefEntity getElement() { return myElement; } @@ -106,30 +106,30 @@ public class ProblemDescriptionNode extends InspectionTreeNode { @Override public boolean isResolved() { - return myElement instanceof RefElement && getToolPresentation().isProblemResolved(myElement, getDescriptor()); + return myElement instanceof RefElement && getPresentation().isProblemResolved(myElement, getDescriptor()); } @Override public void ignoreElement() { - InspectionToolPresentation presentation = getToolPresentation(); - presentation.ignoreCurrentElementProblem(getRefElement(), getDescriptor()); + InspectionToolPresentation presentation = getPresentation(); + presentation.ignoreCurrentElementProblem(getElement(), getDescriptor()); } @Override public void amnesty() { - InspectionToolPresentation presentation = getToolPresentation(); - presentation.amnesty(getRefElement()); + InspectionToolPresentation presentation = getPresentation(); + presentation.amnesty(getElement()); } @NotNull - private InspectionToolPresentation getToolPresentation() { + private InspectionToolPresentation getPresentation() { return myPresentation; } @Override public FileStatus getNodeStatus() { - if (myElement instanceof RefElement) { - return getToolPresentation().getProblemStatus(myDescriptor); + if (myElement instanceof RefElement){ + return getPresentation().getProblemStatus(myDescriptor); } return FileStatus.NOT_CHANGED; } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixToolbar.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixToolbar.java index da7053efb141..059158a24326 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixToolbar.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixToolbar.java @@ -20,9 +20,6 @@ import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.codeInspection.ex.QuickFixAction; import com.intellij.codeInspection.ui.actions.SuppressActionWrapper; import com.intellij.codeInspection.ui.actions.occurrences.GoToSubsequentOccurrenceAction; -import com.intellij.codeInspection.ui.tree.InspectionTreeBuilder; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; -import com.intellij.codeInspection.ui.tree.RefElementNode; import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.*; @@ -34,12 +31,12 @@ import com.intellij.ui.ClickListener; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.MouseEvent; import java.util.*; @@ -52,16 +49,12 @@ import java.util.function.Supplier; public class QuickFixToolbar extends JPanel { private static final int MAX_FIX_COUNT = 2; - public QuickFixToolbar(@NotNull InspectionTreeBuilder tree1, + public QuickFixToolbar(@NotNull InspectionTree tree, @NotNull Project project, @Nullable Editor editor, @Nullable QuickFixAction[] fixes) { final boolean hasFixes = fixes != null && fixes.length != 0; - // - //TODO - // - final JTree tree = tree1.getTree(); - CommonProblemDescriptor[] descriptors = tree1.getSelectedDescriptors(); + CommonProblemDescriptor[] descriptors = tree.getSelectedDescriptors(); int problemCount = descriptors.length; final boolean multipleDescriptors = problemCount > 1; @@ -78,10 +71,10 @@ public class QuickFixToolbar extends JPanel { //fill(getBulbPlacement(hasFixes), QuickFixToolbar::createBulbIcon, panels); fill(getDescriptionLabelPlacement(multipleDescriptors), - () -> getLabel(fixes, tree.getSelectionCount() == 1 ? ContainerUtil.getFirstItem(tree1.getSelectedItems()) : null, problemCount), panels); + () -> getLabel(fixes, tree.getSelectionCount() == 1 ? (InspectionTreeNode)tree.getSelectionPath().getLastPathComponent() : null, problemCount), panels); fill(getFixesPlacement(hasFixes, multipleDescriptors), () -> createFixPanel(fixes), panels); - fill(getSuppressPlacement(multipleDescriptors), () -> createSuppressionCombo(tree1.getSelectedToolWrapper() - , ContainerUtil.getFirstItem(tree1.getSelectedItems()), project), panels); + fill(getSuppressPlacement(multipleDescriptors), () -> createSuppressionCombo(tree.getSelectedToolWrapper() + , tree.getSelectionPath(), project), panels); fill(multipleDescriptors && editor != null ? 1 : -1, () -> ActionManager.getInstance().createActionToolbar("", GoToSubsequentOccurrenceAction.createNextPreviousActions( editor, descriptors), true).getComponent(), panels); } @@ -105,8 +98,15 @@ public class QuickFixToolbar extends JPanel { return label; } + @NotNull + private static JLabel createBulbIcon() { + final JLabel label = new JLabel(AllIcons.Actions.IntentionBulb); + label.setBorder(IdeBorderFactory.createEmptyBorder(0, 10, 0, 0)); + return label; + } + private static JComponent createSuppressionCombo(@NotNull final InspectionToolWrapper toolWrapper, - @NotNull final InspectionTreeNode path, + @NotNull final TreePath path, @NotNull final Project project) { final ComboBoxAction action = new ComboBoxAction() { { @@ -117,7 +117,7 @@ public class QuickFixToolbar extends JPanel { @Override protected DefaultActionGroup createPopupActionGroup(JComponent button) { DefaultActionGroup group = new DefaultActionGroup(); - group.addAll(new SuppressActionWrapper(project, toolWrapper, Collections.singleton(path)).getChildren(null)); + group.addAll(new SuppressActionWrapper(project, toolWrapper, path).getChildren(null)); return group; } }; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/RefElementNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java similarity index 75% rename from platform/lang-impl/src/com/intellij/codeInspection/ui/tree/RefElementNode.java rename to platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java index 8c29a578a8ff..1c7642539d05 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/RefElementNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2009 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.codeInspection.ui.tree; + +package com.intellij.codeInspection.ui; import com.intellij.codeInspection.CommonProblemDescriptor; import com.intellij.codeInspection.InspectionsBundle; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; -import com.intellij.codeInspection.ui.InspectionToolPresentation; import com.intellij.openapi.util.Computable; import com.intellij.openapi.vcs.FileStatus; import com.intellij.ui.ComputableIcon; @@ -27,17 +27,19 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.tree.MutableTreeNode; /** - * @author Dmitry Batkovich + * @author max */ public class RefElementNode extends InspectionTreeNode { + private boolean myHasDescriptorsUnder = false; private CommonProblemDescriptor mySingleDescriptor = null; protected final InspectionToolPresentation myToolPresentation; private final ComputableIcon myIcon = new ComputableIcon(new Computable() { @Override public Icon compute() { - final RefEntity refEntity = getRefElement(); + final RefEntity refEntity = getElement(); if (refEntity == null) { return null; } @@ -46,7 +48,7 @@ public class RefElementNode extends InspectionTreeNode { }); public RefElementNode(@NotNull Object userObject, @NotNull InspectionToolPresentation presentation) { - super(presentation.getContext().getProject(), userObject); + super(userObject); myToolPresentation = presentation; } @@ -55,14 +57,12 @@ public class RefElementNode extends InspectionTreeNode { } public boolean hasDescriptorsUnder() { - return !getChildren().isEmpty(); + return myHasDescriptorsUnder; } @Nullable - public RefEntity getRefElement() { - RefEntity value = (RefEntity)getValue(); - LOG.assertTrue(value != null); - return value; + public RefEntity getElement() { + return (RefEntity)getUserObject(); } @Override @@ -72,7 +72,7 @@ public class RefElementNode extends InspectionTreeNode { } public String toString() { - final RefEntity element = getRefElement(); + final RefEntity element = getElement(); if (element == null || !element.isValid()) { return InspectionsBundle.message("inspection.reference.invalid"); } @@ -81,31 +81,39 @@ public class RefElementNode extends InspectionTreeNode { @Override public boolean isValid() { - final RefEntity refEntity = getRefElement(); + final RefEntity refEntity = getElement(); return refEntity != null && refEntity.isValid(); } @Override public boolean isResolved() { - return myToolPresentation.isElementIgnored(getRefElement()); + return myToolPresentation.isElementIgnored(getElement()); } @Override public void ignoreElement() { - myToolPresentation.ignoreCurrentElement(getRefElement()); + myToolPresentation.ignoreCurrentElement(getElement()); super.ignoreElement(); } @Override public void amnesty() { - myToolPresentation.amnesty(getRefElement()); + myToolPresentation.amnesty(getElement()); super.amnesty(); } @Override public FileStatus getNodeStatus() { - return myToolPresentation.getElementStatus(getRefElement()); + return myToolPresentation.getElementStatus(getElement()); + } + + @Override + public void add(MutableTreeNode newChild) { + super.add(newChild); + if (newChild instanceof ProblemDescriptionNode) { + myHasDescriptorsUnder = true; + } } public void setProblem(@NotNull CommonProblemDescriptor descriptor) { @@ -115,4 +123,5 @@ public class RefElementNode extends InspectionTreeNode { public CommonProblemDescriptor getProblem() { return mySingleDescriptor; } + } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java index 77cec941bf65..ab2348ac4b11 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/ExportHTMLAction.java @@ -29,10 +29,10 @@ import com.intellij.codeInspection.export.HTMLExportUtil; import com.intellij.codeInspection.export.HTMLExporter; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.reference.RefModule; +import com.intellij.codeInspection.ui.InspectionNode; import com.intellij.codeInspection.ui.InspectionResultsView; import com.intellij.codeInspection.ui.InspectionToolPresentation; -import com.intellij.codeInspection.ui.tree.InspectionNode; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; +import com.intellij.codeInspection.ui.InspectionTreeNode; import com.intellij.codeInspection.util.RefEntityAlphabeticalComparator; import com.intellij.icons.AllIcons; import com.intellij.ide.BrowserUtil; @@ -64,8 +64,6 @@ import java.io.File; import java.io.IOException; import java.util.*; -import static com.intellij.codeInspection.ex.InspectionRVContentProvider.traverse; - /** * User: anna * Date: 11-Jan-2006 @@ -123,12 +121,15 @@ public class ExportHTMLAction extends AnAction implements DumbAware { final HTMLExportFrameMaker maker = new HTMLExportFrameMaker(outputDirectoryName, myView.getProject()); maker.start(); try { - final InspectionTreeNode root = (InspectionTreeNode)myView.getTreeBuilder().getTreeStructure().getRootElement(); - traverse(root, (node) -> { - if (node instanceof InspectionNode) { - exportHTML(maker, (InspectionNode)node); + final InspectionTreeNode root = myView.getTree().getRoot(); + TreeUtil.traverse(root, new TreeUtil.Traverse() { + @Override + public boolean accept(final Object node) { + if (node instanceof InspectionNode) { + exportHTML(maker, (InspectionNode)node); + } + return true; } - return true; }); } catch (ProcessCanceledException e) { @@ -161,9 +162,11 @@ public class ExportHTMLAction extends AnAction implements DumbAware { private void dupm2XML(final String outputDirectoryName) { try { new File(outputDirectoryName).mkdirs(); - final InspectionTreeNode root = (InspectionTreeNode)myView.getTreeBuilder().getRootElement(); + final InspectionTreeNode root = myView.getTree().getRoot(); final IOException[] ex = new IOException[1]; - traverse(root, (node) -> { + TreeUtil.traverse(root, new TreeUtil.Traverse() { + @Override + public boolean accept(final Object node) { if (node instanceof InspectionNode) { InspectionNode toolNode = (InspectionNode)node; Element problems = new Element(PROBLEMS); @@ -185,6 +188,7 @@ public class ExportHTMLAction extends AnAction implements DumbAware { } } return true; + } }); if (ex[0] != null) { throw ex[0]; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionsOptionsToolbarAction.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionsOptionsToolbarAction.java index 46db5ef318a5..1d4635bf07c8 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionsOptionsToolbarAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionsOptionsToolbarAction.java @@ -12,7 +12,7 @@ import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.ui.InspectionResultsView; -import com.intellij.codeInspection.ui.tree.InspectionTreeBuilder; +import com.intellij.codeInspection.ui.InspectionTree; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -61,7 +61,7 @@ public class InspectionsOptionsToolbarAction extends AnAction { @Nullable private InspectionToolWrapper getSelectedToolWrapper() { - return myView.getTreeBuilder().getSelectedToolWrapper(); + return myView.getTree().getSelectedToolWrapper(); } @Override @@ -89,7 +89,7 @@ public class InspectionsOptionsToolbarAction extends AnAction { public List createActions() { final List result = new ArrayList(); - final InspectionTreeBuilder tree = myView.getTreeBuilder(); + final InspectionTree tree = myView.getTree(); final InspectionToolWrapper toolWrapper = tree.getSelectedToolWrapper(); if (toolWrapper == null) return result; final HighlightDisplayKey key = HighlightDisplayKey.find(toolWrapper.getShortName()); @@ -111,8 +111,8 @@ public class InspectionsOptionsToolbarAction extends AnAction { } @Nullable - private PsiElement getPsiElement(InspectionTreeBuilder tree) { - final RefEntity[] selectedElements = tree.getSelectedRefElements(); + private PsiElement getPsiElement(InspectionTree tree) { + final RefEntity[] selectedElements = tree.getSelectedElements(); final PsiElement psiElement; if (selectedElements.length > 0 && selectedElements[0] instanceof RefElement) { @@ -125,8 +125,7 @@ public class InspectionsOptionsToolbarAction extends AnAction { } }); - //TODO make it better - result.add(new SuppressActionWrapper(myView.getProject(), toolWrapper, tree.getSelectedItems())); + result.add(new SuppressActionWrapper(myView.getProject(), toolWrapper, tree.getSelectionPaths())); return result; @@ -149,7 +148,7 @@ public class InspectionsOptionsToolbarAction extends AnAction { model.commit(); myView.updateCurrentProfile(); } else { - final RefEntity[] selectedElements = myView.getTreeBuilder().getSelectedRefElements(); + final RefEntity[] selectedElements = myView.getTree().getSelectedElements(); final Set files = new HashSet(); final Project project = myView.getProject(); final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(project); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InvokeQuickFixAction.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InvokeQuickFixAction.java index bca03a485abe..21b9ae0c11b2 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InvokeQuickFixAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InvokeQuickFixAction.java @@ -44,16 +44,16 @@ public class InvokeQuickFixAction extends AnAction { AllIcons.Actions.CreateFromUsage); myView = view; registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_SHOW_INTENTION_ACTIONS).getShortcutSet(), - myView.getTreeBuilder().getTree()); + myView.getTree()); } @Override public void update(AnActionEvent e) { final Presentation presentation = e.getPresentation(); - InspectionToolWrapper toolWrapper = myView.getTreeBuilder().getSelectedToolWrapper(); + InspectionToolWrapper toolWrapper = myView.getTree().getSelectedToolWrapper(); final InspectionRVContentProvider provider = myView.getProvider(); if (toolWrapper != null && provider.isContentLoaded()) { - presentation.setEnabled(provider.hasQuickFixes(myView.getTreeBuilder())); + presentation.setEnabled(provider.hasQuickFixes(myView.getTree())); } else { presentation.setEnabled(false); @@ -78,9 +78,9 @@ public class InvokeQuickFixAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { - InspectionToolWrapper toolWrapper = myView.getTreeBuilder().getSelectedToolWrapper(); + InspectionToolWrapper toolWrapper = myView.getTree().getSelectedToolWrapper(); assert toolWrapper != null; - final QuickFixAction[] quickFixes = myView.getProvider().getQuickFixes(toolWrapper, myView.getTreeBuilder()); + final QuickFixAction[] quickFixes = myView.getProvider().getQuickFixes(toolWrapper, myView.getTree()); if (quickFixes == null || quickFixes.length == 0) { Messages.showInfoMessage(myView, "There are no applicable quickfixes", "Nothing found to fix"); return; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java index 0c69cb208c58..3b0399299785 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java @@ -23,13 +23,12 @@ package com.intellij.codeInspection.ui.actions; import com.intellij.codeInspection.*; import com.intellij.codeInspection.ex.GlobalInspectionContextImpl; import com.intellij.codeInspection.ex.InspectionManagerEx; -import com.intellij.codeInspection.ex.InspectionRVContentProvider; import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; -import com.intellij.codeInspection.ui.tree.InspectionTreeNode; -import com.intellij.codeInspection.ui.tree.ProblemDescriptionNode; -import com.intellij.codeInspection.ui.tree.RefElementNode; +import com.intellij.codeInspection.ui.InspectionTreeNode; +import com.intellij.codeInspection.ui.ProblemDescriptionNode; +import com.intellij.codeInspection.ui.RefElementNode; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -45,34 +44,41 @@ import com.intellij.psi.PsiManager; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.HashSet; +import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; import java.util.Arrays; -import java.util.Collection; import java.util.Comparator; import java.util.Set; public class SuppressActionWrapper extends ActionGroup { private final Project myProject; private final InspectionManagerEx myManager; - private final Set myNodesToSuppress = new HashSet<>(); + private final Set myNodesToSuppress = new HashSet(); private final InspectionToolWrapper myToolWrapper; private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.actions.SuppressActionWrapper"); public SuppressActionWrapper(@NotNull final Project project, @NotNull final InspectionToolWrapper toolWrapper, - @NotNull final Collection paths) { + @NotNull final TreePath... paths) { super(InspectionsBundle.message("suppress.inspection.problem"), false); myProject = project; myManager = (InspectionManagerEx)InspectionManager.getInstance(myProject); - - for (InspectionTreeNode path : paths) { - InspectionRVContentProvider.traverse(path, n -> { - if (n.getChildren().isEmpty()) { - myNodesToSuppress.add(n); + for (TreePath path : paths) { + final Object node = path.getLastPathComponent(); + if (!(node instanceof TreeNode)) continue; + TreeUtil.traverse((TreeNode)node, new TreeUtil.Traverse() { + @Override + public boolean accept(final Object node) { //fetch leaves + final InspectionTreeNode n = (InspectionTreeNode)node; + if (n.isLeaf()) { + myNodesToSuppress.add(n); + } + return true; } - return true; }); } myToolWrapper = toolWrapper; @@ -157,13 +163,13 @@ public class SuppressActionWrapper extends ActionGroup { CommonProblemDescriptor descriptor = null; if (node instanceof RefElementNode) { final RefElementNode elementNode = (RefElementNode)node; - final RefEntity element = elementNode.getRefElement(); + final RefEntity element = elementNode.getElement(); refElement = element instanceof RefElement ? (RefElement)element : null; descriptor = elementNode.getProblem(); } else if (node instanceof ProblemDescriptionNode) { final ProblemDescriptionNode descriptionNode = (ProblemDescriptionNode)node; - final RefEntity element = descriptionNode.getRefElement(); + final RefEntity element = descriptionNode.getElement(); refElement = element instanceof RefElement ? (RefElement)element : null; descriptor = descriptionNode.getDescriptor(); } @@ -193,9 +199,9 @@ public class SuppressActionWrapper extends ActionGroup { final PsiElement element = content.first; RefEntity refEntity = null; if (node instanceof RefElementNode) { - refEntity = ((RefElementNode)node).getRefElement(); + refEntity = ((RefElementNode)node).getElement(); } else if (node instanceof ProblemDescriptionNode) { - refEntity = ((ProblemDescriptionNode)node).getRefElement(); + refEntity = ((ProblemDescriptionNode)node).getElement(); } if (!suppress(element, content.second, mySuppressAction, refEntity)) break; } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTree.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTree.java deleted file mode 100644 index c5818db3fe15..000000000000 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTree.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2000-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInspection.ui.tree; - -import com.intellij.codeInspection.CommonProblemDescriptor; -import com.intellij.codeInspection.ex.GlobalInspectionContextImpl; -import com.intellij.codeInspection.ex.InspectionToolWrapper; -import com.intellij.codeInspection.reference.RefEntity; -import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeComparator; -import com.intellij.ui.TreeSpeedSearch; -import com.intellij.ui.treeStructure.Tree; -import com.intellij.util.containers.Convertor; -import com.intellij.util.ui.UIUtil; -import com.intellij.util.ui.tree.TreeUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.TestOnly; - -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreePath; - -/** - * @author Dmitry Batkovich - */ -public class InspectionTree extends Tree { - private InspectionTreeBuilder myBuilder; - - public InspectionTree(InspectionTreeBuilder builder) { - super(new DefaultTreeModel(new DefaultMutableTreeNode())); - myBuilder = builder; - - setShowsRootHandles(true); - UIUtil.setLineStyleAngled(this); - - TreeUtil.installActions(this); - new TreeSpeedSearch(this, new Convertor() { - @Override - public String convert(TreePath o) { - return InspectionsConfigTreeComparator.getDisplayTextToSort(o.getLastPathComponent().toString()); - } - }); - } - - @TestOnly - public InspectionTreeBuilder getBuilder() { - return myBuilder; - } -} - diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeBuilder.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeBuilder.java deleted file mode 100644 index 861f6d0618b2..000000000000 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeBuilder.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2000-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInspection.ui.tree; - -import com.intellij.codeInspection.CommonProblemDescriptor; -import com.intellij.codeInspection.ex.GlobalInspectionContextImpl; -import com.intellij.codeInspection.ex.InspectionToolWrapper; -import com.intellij.codeInspection.reference.RefEntity; -import com.intellij.codeInspection.ui.InspectionResultsViewComparator; -import com.intellij.ide.util.treeView.AbstractTreeBuilder; -import com.intellij.openapi.project.Project; -import com.intellij.util.containers.MultiMap; -import com.intellij.util.containers.hash.HashSet; -import org.jetbrains.annotations.Nullable; - -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreePath; -import java.util.*; - -/** - * @author Dmitry Batkovich - */ -public class InspectionTreeBuilder extends AbstractTreeBuilder { - private final GlobalInspectionContextImpl myContext; - - public InspectionTreeBuilder(Project project, - GlobalInspectionContextImpl context) { - myContext = context; - final InspectionTree tree = new InspectionTree(this); - init(tree, - (DefaultTreeModel)tree.getModel(), - new InspectionTreeStructure(project), - (n1, n2) -> InspectionResultsViewComparator.getInstance().compare((InspectionTreeNode)n1, (InspectionTreeNode)n2), - AbstractTreeBuilder.DEFAULT_UPDATE_INACTIVE); - } - - public Collection getSelectedItems() { - return getSelectedElements(InspectionTreeNode.class); - } - - @Nullable - public InspectionToolWrapper getSelectedToolWrapper() { - final TreePath[] paths = getTree().getSelectionPaths(); - if (paths == null) return null; - InspectionToolWrapper toolWrapper = null; - for (TreePath path : paths) { - Object[] nodes = path.getPath(); - for (int j = nodes.length - 1; j >= 0; j--) { - DefaultMutableTreeNode nodeWrapper = (DefaultMutableTreeNode)nodes[j]; - Object userObject = nodeWrapper.getUserObject(); - if (!(userObject instanceof InspectionTreeNode)) continue; - InspectionTreeNode node = (InspectionTreeNode)userObject; - if (node instanceof InspectionGroupNode) { - return null; - } - if (node instanceof InspectionNode) { - InspectionToolWrapper wrapper = ((InspectionNode)node).getToolWrapper(); - if (toolWrapper == null) { - toolWrapper = wrapper; - } - else if (toolWrapper != wrapper) { - return null; - } - break; - } - } - } - return toolWrapper; - } - - public RefEntity getCommonSelectedElement() { - final Object node = getCommonSelectedNode(); - return node instanceof RefElementNode ? ((RefElementNode)node).getRefElement() : null; - } - - @Nullable - private Object getCommonSelectedNode() { - final TreePath[] paths = getTree().getSelectionPaths(); - if (paths == null) return null; - final Object[][] resolvedPaths = new Object[paths.length][]; - for (int i = 0; i < paths.length; i++) { - TreePath path = paths[i]; - resolvedPaths[i] = path.getPath(); - } - - Object currentCommonNode = null; - for (int i = 0; i < resolvedPaths[0].length; i++) { - final Object currentNode = resolvedPaths[0][i]; - for (int j = 1; j < resolvedPaths.length; j++) { - final Object o = resolvedPaths[j][i]; - if (!o.equals(currentNode)) { - return currentCommonNode; - } - } - currentCommonNode = currentNode; - } - return currentCommonNode; - } - - public int getSelectedProblemCount() { - final TreePath[] paths = getTree().getSelectionPaths(); - if (paths == null || paths.length == 0) return 0; - Set result = new HashSet<>(); - MultiMap rootDependencies = new MultiMap<>(); - for (TreePath path : paths) { - final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent(); - final Collection visitedChildren = rootDependencies.get(node); - for (DefaultMutableTreeNode child : visitedChildren) { - result.remove(child); - } - - boolean needToAdd = true; - for (int i = 0; i < path.getPathCount() - 1; i++) { - final DefaultMutableTreeNode parent = (DefaultMutableTreeNode)path.getPathComponent(i); - rootDependencies.putValue(parent, node); - if (result.contains(parent)) { - needToAdd = false; - break; - } - } - - if (needToAdd) { - result.add(node); - } - } - - int count = 0; - for (DefaultMutableTreeNode node : result) { - Object userObject = node.getUserObject(); - if (userObject instanceof InspectionTreeNode) { - count += ((InspectionTreeNode)userObject).getProblemCount(); - } - } - return count; - } - - public CommonProblemDescriptor[] getSelectedDescriptors() { - Collection items = getSelectedItems(); - if (items.isEmpty()) return CommonProblemDescriptor.EMPTY_ARRAY; - final LinkedHashSet descriptors = new LinkedHashSet(); - getSelectedItems().forEach(n -> traverseDescriptors(n, descriptors)); - return descriptors.toArray(new CommonProblemDescriptor[descriptors.size()]); - } - - private static void traverseDescriptors(InspectionTreeNode node, LinkedHashSet descriptors) { - if (node instanceof ProblemDescriptionNode) { - if (node.isValid() && !node.isResolved()) { - final CommonProblemDescriptor descriptor = ((ProblemDescriptionNode)node).getDescriptor(); - if (descriptor != null) { - descriptors.add(descriptor); - } - } - } - Collection children = node.getChildren(); - children.forEach(n -> traverseDescriptors(n, descriptors)); - } - - public void removeAllNodes() { - ((InspectionRootNode)getTreeStructure().getRootElement()).removeAllChildren(); - } - - public RefEntity[] getSelectedRefElements() { - List result = new ArrayList(); - for (InspectionTreeNode node : getSelectedItems()) { - addElementsInNode(node, result); - } - return result.toArray(new RefEntity[result.size()]); - } - - private static void addElementsInNode(InspectionTreeNode node, List out) { - if (!node.isValid()) return; - if (node instanceof RefElementNode) { - final RefEntity element = ((RefElementNode)node).getRefElement(); - if (!out.contains(element)) { - out.add(0, element); - } - } - if (node instanceof ProblemDescriptionNode) { - final RefEntity element = ((ProblemDescriptionNode)node).getRefElement(); - if (!out.contains(element)) { - out.add(0, element); - } - } - Collection children = node.getChildren(); - children.forEach(child -> addElementsInNode(child, out)); - } - - public GlobalInspectionContextImpl getContext() { - return myContext; - } -} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeNode.java deleted file mode 100644 index 8bbc8733fb7f..000000000000 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeNode.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2000-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInspection.ui.tree; - -import com.intellij.codeInspection.InspectionsBundle; -import com.intellij.codeInspection.reference.RefElement; -import com.intellij.codeInspection.reference.RefEntity; -import com.intellij.codeInspection.ui.InspectionResultsViewComparator; -import com.intellij.ide.projectView.PresentationData; -import com.intellij.ide.util.treeView.AbstractTreeNode; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vcs.FileStatus; -import com.intellij.ui.JBColor; -import com.intellij.ui.SimpleTextAttributes; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import java.util.*; -import java.util.concurrent.ConcurrentSkipListSet; - -/** - * @author Dmitry Batkovich - */ -public abstract class InspectionTreeNode extends AbstractTreeNode { - protected static final Logger LOG = Logger.getInstance(InspectionTreeNode.class); - - private boolean myResolved; //accessed from EDT - private Set myChildren = new ConcurrentSkipListSet<>(InspectionResultsViewComparator.getInstance()); - - protected InspectionTreeNode(Project project, T value) { - super(project, value); - } - - public boolean isValid() { - return true; - } - - public boolean isResolved() { - return myResolved; - } - - public boolean appearsBold() { - return false; - } - - public FileStatus getNodeStatus() { - return FileStatus.NOT_CHANGED; - } - - public void ignoreElement() { - ApplicationManager.getApplication().assertIsDispatchThread(); - myResolved = true; - for (InspectionTreeNode node : getChildren()) { - node.ignoreElement(); - } - } - - public void amnesty() { - ApplicationManager.getApplication().assertIsDispatchThread(); - myResolved = false; - for (InspectionTreeNode node : getChildren()) { - node.amnesty(); - } - } - - public int getProblemCount() { - int sum = 0; - for (InspectionTreeNode node : getChildren()) { - sum += node.getProblemCount(); - } - return sum; - } - - public final void add(InspectionTreeNode node) { - myChildren.add(node); - node.setParent(this); - } - - @NotNull - @Override - public final Collection getChildren() { - return myChildren; - } - - public final void removeAllChildren() { - myChildren = new ConcurrentSkipListSet<>(InspectionResultsViewComparator.getInstance()); - } - - @Nullable - public Icon getIcon(boolean expanded) { - return null; - } - - @Override - protected final void update(PresentationData presentation) { - presentation.setIcon(getIcon(false)); - presentation.addText(toString(), - patchAttr(this, appearsBold() ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES : getMainForegroundAttributes(this))); - - int problemCount = getProblemCount(); - if (!getChildren().isEmpty()) { - presentation.addText(" " + InspectionsBundle.message("inspection.problem.descriptor.count", problemCount), - patchAttr(this, SimpleTextAttributes.GRAYED_ATTRIBUTES)); - } - - if (!isValid()) { - presentation - .addText(" " + InspectionsBundle.message("inspection.invalid.node.text"), patchAttr(this, SimpleTextAttributes.ERROR_ATTRIBUTES)); - } - else { - setIcon(getIcon(false)); - } - } - - //TODO Dmitry Batkovich - public static SimpleTextAttributes patchAttr(InspectionTreeNode node, SimpleTextAttributes attributes) { - if (node.isResolved()) { - return new SimpleTextAttributes(attributes.getBgColor(), attributes.getFgColor(), attributes.getWaveColor(), - attributes.getStyle() | SimpleTextAttributes.STYLE_STRIKEOUT); - } - return attributes; - } - - private static SimpleTextAttributes getMainForegroundAttributes(InspectionTreeNode node) { - SimpleTextAttributes foreground = SimpleTextAttributes.REGULAR_ATTRIBUTES; - if (node instanceof RefElementNode) { - RefEntity refElement = ((RefElementNode)node).getRefElement(); - - if (refElement instanceof RefElement) { - refElement = ((RefElement)refElement).getContainingEntry(); - if (((RefElement)refElement).isEntry() && ((RefElement)refElement).isPermanentEntry()) { - foreground = new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, JBColor.blue); - } - } - } - final FileStatus nodeStatus = node.getNodeStatus(); - if (nodeStatus != FileStatus.NOT_CHANGED) { - foreground = - new SimpleTextAttributes(foreground.getBgColor(), nodeStatus.getColor(), foreground.getWaveColor(), foreground.getStyle()); - } - return foreground; - } -} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeStructure.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeStructure.java deleted file mode 100644 index 1036c4c604ae..000000000000 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/tree/InspectionTreeStructure.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2000-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInspection.ui.tree; - -import com.intellij.codeInspection.ex.GlobalInspectionContextImpl; -import com.intellij.codeInspection.ex.InspectionProfileImpl; -import com.intellij.codeInspection.ex.InspectionRVContentProvider; -import com.intellij.ide.projectView.TreeStructureProvider; -import com.intellij.ide.util.treeView.AbstractTreeStructureBase; -import com.intellij.openapi.project.Project; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -/** - * @author Dmitry Batkovich - */ -public class InspectionTreeStructure extends AbstractTreeStructureBase { - private final Project myProject; - private final InspectionRootNode myRoot; - - public InspectionTreeStructure(Project project) { - super(project); - myProject = project; - myRoot = new InspectionRootNode(myProject); - } - - @Override - public Object getRootElement() { - return myRoot; - } - - @Override - public void commit() { - } - - @Override - public boolean hasSomethingToCommit() { - return false; - } - - @Override - public boolean isToBuildChildrenInBackground(Object element) { - return true; - } - - @Nullable - @Override - public List getProviders() { - return null; - } -}