inspection tool window: new tree reverted according leaks

This commit is contained in:
Dmitry Batkovich
2016-02-24 14:26:44 +03:00
parent 52e7bb7360
commit 9b850d3996
37 changed files with 1193 additions and 1154 deletions
@@ -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<RefElement> getPossibleChildren(final RefElementNode refElementNode, RefElement refElement) {
final List<InspectionTreeNode> pathToRoot = new ArrayList<>();
InspectionTreeNode currentNode = refElementNode;
while (currentNode != null) {
pathToRoot.add(currentNode);
currentNode = (InspectionTreeNode)currentNode.getParent();
}
final TreeNode[] pathToRoot = refElementNode.getPath();
final HashSet<RefElement> newChildren = new HashSet<RefElement>();
@@ -404,10 +402,12 @@ public class DeadHTMLComposer extends HTMLComposerImpl {
return newChildren;
}
private static boolean notInPath(List<InspectionTreeNode> 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;
}
}
@@ -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;
@@ -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);
@@ -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) {
@@ -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", "<code>" + name + "</code>") + ".";
return InspectionsBundle.message("inspection.unused.assignment.problem.descriptor1", "<code>"+name+"</code>") + ".";
}
@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 <default>" +
"\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"
+ " -<default>\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
@@ -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;
}
@@ -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<ScopeToolState> getTools(Tools tools) {
public Iterable<? extends ScopeToolState> 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<T, UserObjectContainer<T>> computeContainer,
final boolean showStructure) {
final List<InspectionTreeNode> content = new ArrayList<>();
final Map<String, Map<String, InspectionPackageNode>> module2PackageMap = new HashMap<>();
final List<InspectionTreeNode> content = new ArrayList<InspectionTreeNode>();
final Map<String, Map<String, InspectionPackageNode>> module2PackageMap = new HashMap<String, Map<String, InspectionPackageNode>>();
boolean supportStructure = showStructure;
for (String packageName : packageContents.keySet()) {
final Set<T> 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<String, InspectionPackageNode> 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<String, InspectionPackageNode> 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<RefElementNode> parentNodes = new LinkedHashSet<>();
final Set<RefElementNode> parentNodes = new LinkedHashSet<RefElementNode>();
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<ProblemDescriptionNode> nodes = new ArrayList<>();
traverseDepth(parentNode, n -> {
if (n instanceof ProblemDescriptionNode) {
nodes.add((ProblemDescriptionNode)n);
final List<ProblemDescriptionNode> nodes = new ArrayList<ProblemDescriptionNode>();
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<InspectionTreeNode>() {
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<InspectionTreeNode> 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<InspectionTreeNode> 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<InspectionTreeNode> traverse) {
Collection<InspectionTreeNode> 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<InspectionTreeNode> traverse) {
if (!traverse.test(node)) return false;
Collection<InspectionTreeNode> 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;
}
}
@@ -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<String, Set<RefEntity>> contents,
@NotNull final Map<RefEntity, CommonProblemDescriptor[]> problems,
DefaultTreeModel model) {
//ApplicationManager.getApplication().assertIsDispatchThread();
LOG.assertTrue(ApplicationManager.getApplication().isReadAccessAllowed());
ApplicationManager.getApplication().assertIsDispatchThread();
final InspectionToolWrapper toolWrapper = toolNode.getToolWrapper();
Function<RefEntity, UserObjectContainer<RefEntity>> computeContainer = new Function<RefEntity, UserObjectContainer<RefEntity>>() {
@@ -125,7 +117,7 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider
List<InspectionTreeNode> 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]);
}
@@ -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<RefEntity> selection = new ArrayList<RefEntity>(Arrays.asList(invoker.getTreeBuilder().getSelectedRefElements()));
List<RefEntity> selection = new ArrayList<RefEntity>(Arrays.asList(invoker.getTree().getSelectedElements()));
PsiDocumentManager.getInstance(invoker.getProject()).commitAllDocuments();
Collections.sort(selection, new Comparator<RefEntity>() {
@Override
@@ -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<ScopeToolState> getTools(Tools tools) {
public Iterable<? extends ScopeToolState> 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<RefEntity> selectedElements = new ArrayList<RefEntity>();
final Map<RefEntity, CommonProblemDescriptor[]> 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<String, Set<RefEntity>> contents,
@NotNull final Map<RefEntity, CommonProblemDescriptor[]> problems,
final DefaultTreeModel model) {
InspectionToolWrapper toolWrapper = toolNode.getValue();
InspectionToolWrapper toolWrapper = toolNode.getToolWrapper();
final Map<String, Set<OfflineProblemDescriptor>> filteredContent = getFilteredContent(context, toolWrapper);
if (filteredContent != null && !filteredContent.values().isEmpty()) {
final Function<OfflineProblemDescriptor, UserObjectContainer<OfflineProblemDescriptor>> computeContainer =
@@ -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<String> 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();
}
@@ -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();
}
}
@@ -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<RefEntity, CommonProblemDescriptor[]> myProblemElements =
Collections.synchronizedMap(new THashMap<RefEntity, CommonProblemDescriptor[]>());
private final Map<String, Set<RefEntity>> myContents =
Collections.synchronizedMap(new com.intellij.util.containers.HashMap<String, Set<RefEntity>>()); // keys can be null
private final Map<RefEntity, CommonProblemDescriptor[]> myProblemElements = Collections.synchronizedMap(new THashMap<RefEntity, CommonProblemDescriptor[]>());
private final Map<String, Set<RefEntity>> myContents = Collections.synchronizedMap(new com.intellij.util.containers.HashMap<String, Set<RefEntity>>()); // keys can be null
private final Set<RefModule> myModulesProblems = Collections.synchronizedSet(new THashSet<RefModule>());
private final Map<CommonProblemDescriptor, RefEntity> myProblemToElements =
Collections.synchronizedMap(new THashMap<CommonProblemDescriptor, RefEntity>());
private final Map<CommonProblemDescriptor, RefEntity> myProblemToElements = Collections.synchronizedMap(new THashMap<CommonProblemDescriptor, RefEntity>());
private DescriptorComposer myComposer;
private final Map<RefEntity, Set<QuickFix>> myQuickFixActions =
Collections.synchronizedMap(new com.intellij.util.containers.HashMap<RefEntity, Set<QuickFix>>());
private final Map<RefEntity, CommonProblemDescriptor[]> myIgnoredElements =
Collections.synchronizedMap(new com.intellij.util.containers.HashMap<RefEntity, CommonProblemDescriptor[]>());
private final Map<RefEntity, Set<QuickFix>> myQuickFixActions = Collections.synchronizedMap(new com.intellij.util.containers.HashMap<RefEntity, Set<QuickFix>>());
private final Map<RefEntity, CommonProblemDescriptor[]> myIgnoredElements = Collections.synchronizedMap(new com.intellij.util.containers.HashMap<RefEntity, CommonProblemDescriptor[]>());
private Map<RefEntity, CommonProblemDescriptor[]> 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<RefEntity, CommonProblemDescriptor[]> problems = new HashMap<RefEntity, CommonProblemDescriptor[]>();
problems.put(refElement, descriptors);
final Map<String, Set<RefEntity>> contents = new HashMap<String, Set<RefEntity>>();
final String groupName = refElement.getRefManager().getGroupName((RefElement)refElement);
Set<RefEntity> content = contents.get(groupName);
if (content == null) {
content = new HashSet<RefEntity>();
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<RefEntity, CommonProblemDescriptor[]> problems = new HashMap<RefEntity, CommonProblemDescriptor[]>();
problems.put(refElement, descriptors);
final Map<String, Set<RefEntity>> contents = new HashMap<String, Set<RefEntity>>();
final String groupName = refElement.getRefManager().getGroupName((RefElement)refElement);
Set<RefEntity> content = contents.get(groupName);
if (content == null) {
content = new HashSet<RefEntity>();
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<CommonProblemDescriptor> equality = new Equality<CommonProblemDescriptor>() {
@@ -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<QuickFix> localQuickFixes = getQuickFixActions().get(refEntity);
final QuickFix[] fixes = problem.getFixes();
if (isIgnoreProblem(fixes, localQuickFixes, idx)) {
if (isIgnoreProblem(fixes, localQuickFixes, idx)){
getProblemToElements().remove(problem);
Map<RefEntity, CommonProblemDescriptor[]> 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<QuickFix> fixes, int idx) {
private static boolean isIgnoreProblem(QuickFix[] problemFixes, Set<QuickFix> 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<RefEntity, CommonProblemDescriptor[]> descriptorMap,
@Nullable CommonProblemDescriptor[] allowedDescriptors) {
final Set<CommonProblemDescriptor> allowedDescriptorSet =
allowedDescriptors == null ? null : ContainerUtil.newHashSet(allowedDescriptors);
final Set<CommonProblemDescriptor> allowedDescriptorSet = allowedDescriptors == null ? null : ContainerUtil.newHashSet(allowedDescriptors);
Map<Class, QuickFixAction> 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<CommonProblemDescriptor> allAvailable = new HashSet<CommonProblemDescriptor>();
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<CommonProblemDescriptor> descriptors) {
private static boolean containsDescriptor(@NotNull CommonProblemDescriptor descriptor, Collection<CommonProblemDescriptor> 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);
@@ -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<String> {
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<String> {
public boolean appearsBold() {
return true;
}
@Override
public String toString() {
return getGroupTitle();
}
}
@@ -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<Module> {
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<Module> {
public String toString() {
return getName();
}
}
}
@@ -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<InspectionToolWrapper> {
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<InspectionToolWrapper> {
@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<InspectionToolWrapper> {
return TOOL;
}
public boolean isTooBigForOnlineRefresh() {
if (!myTooBigForOnlineRefresh) {
myTooBigForOnlineRefresh = getProblemCount() > 1000;
}
return myTooBigForOnlineRefresh;
}
}
@@ -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();
@@ -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<String> {
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();
}
}
@@ -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<Boolean> PREVIEW_EDITOR_IS_REUSED_KEY = Key.create("inspection.tool.window.preview.editor.is.reused.");
private final Project myProject;
private InspectionTreeBuilder myTreeBuilder;
private final ConcurrentMap<HighlightDisplayLevel, ConcurrentMap<String, InspectionGroupNode>> myGroups =
ContainerUtil.newConcurrentMap();
private final InspectionTree myTree;
private final ConcurrentMap<HighlightDisplayLevel, ConcurrentMap<String, InspectionGroupNode>> 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<InspectionTreeNode> 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<String, Tools> 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<String, Tools> 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<String, InspectionGroupNode> map = myGroups.get(errorLevel);
if (map == null) {
map = ConcurrencyUtil.cacheOrGet(myGroups, errorLevel, ContainerUtil.newConcurrentMap());
map = ConcurrencyUtil.cacheOrGet(myGroups, errorLevel, ContainerUtil.<String, InspectionGroupNode>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<InspectionTreeNode> 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<PsiElement> psiElements = new ArrayList<PsiElement>();
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<InspectionProfile> profiles = new HashSet<InspectionProfile>();
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()) {
@@ -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<InspectionTreeNode> {
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<InspectionTre
if (node1 instanceof OfflineRefElementNode && node2 instanceof OfflineRefElementNode ||
node1 instanceof OfflineProblemDescriptorNode && node2 instanceof OfflineProblemDescriptorNode) {
final Object userObject1 = node1.getValue();
final Object userObject2 = node2.getValue();
final Object userObject1 = node1.getUserObject();
final Object userObject2 = node2.getUserObject();
if (userObject1 instanceof OfflineProblemDescriptor && userObject2 instanceof OfflineProblemDescriptor) {
final OfflineProblemDescriptor descriptor1 = (OfflineProblemDescriptor)userObject1;
final OfflineProblemDescriptor descriptor2 = (OfflineProblemDescriptor)userObject2;
@@ -105,7 +104,7 @@ public class InspectionResultsViewComparator implements Comparator<InspectionTre
}
if (node1 instanceof RefElementNode && node2 instanceof RefElementNode){ //sort by filename and inside file by start offset
return compareEntities(((RefElementNode)node1).getRefElement(), ((RefElementNode)node2).getRefElement());
return compareEntities(((RefElementNode)node1).getElement(), ((RefElementNode)node2).getElement());
}
if (node1 instanceof ProblemDescriptionNode && node2 instanceof ProblemDescriptionNode) {
final CommonProblemDescriptor descriptor1 = ((ProblemDescriptionNode)node1).getDescriptor();
@@ -124,17 +123,17 @@ public class InspectionResultsViewComparator implements Comparator<InspectionTre
if (node1 instanceof RefElementNode && node2 instanceof ProblemDescriptionNode) {
final CommonProblemDescriptor descriptor = ((ProblemDescriptionNode)node2).getDescriptor();
if (descriptor instanceof ProblemDescriptor) {
return compareEntity(((RefElementNode)node1).getRefElement(), ((ProblemDescriptor)descriptor).getPsiElement());
return compareEntity(((RefElementNode)node1).getElement(), ((ProblemDescriptor)descriptor).getPsiElement());
}
return compareEntities(((RefElementNode)node1).getRefElement(), ((ProblemDescriptionNode)node2).getRefElement());
return compareEntities(((RefElementNode)node1).getElement(), ((ProblemDescriptionNode)node2).getElement());
}
if (node2 instanceof RefElementNode && node1 instanceof ProblemDescriptionNode) {
final CommonProblemDescriptor descriptor = ((ProblemDescriptionNode)node1).getDescriptor();
if (descriptor instanceof ProblemDescriptor) {
return -compareEntity(((RefElementNode)node2).getRefElement(), ((ProblemDescriptor)descriptor).getPsiElement());
return -compareEntity(((RefElementNode)node2).getElement(), ((ProblemDescriptor)descriptor).getPsiElement());
}
return -compareEntities(((RefElementNode)node2).getRefElement(), ((ProblemDescriptionNode)node1).getRefElement());
return -compareEntities(((RefElementNode)node2).getElement(), ((ProblemDescriptionNode)node1).getElement());
}
LOG.error("node1: " + node1 + ", node2: " + node2);
@@ -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,7 +13,8 @@
* 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.InspectionsBundle;
import com.intellij.icons.AllIcons;
@@ -21,12 +22,11 @@ import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.util.PlatformUtils;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* @author Dmitry Batkovich
* @author max
*/
public class InspectionRootNode extends InspectionTreeNode {
private static final Icon APP_ICON = PlatformUtils.isJetBrainsProduct()
@@ -35,21 +35,19 @@ public class InspectionRootNode extends InspectionTreeNode {
private final Project myProject;
public InspectionRootNode(Project project) {
super(project, project);
super(project);
myProject = project;
}
public String toString() {
return isEmpty() ? InspectionsBundle.message("inspection.empty.root.node.text") :
myProject.getName();
}
private boolean isEmpty() {
return getChildren().isEmpty();
return getChildCount() == 0;
}
@Nullable
@Override
public Icon getIcon(boolean expanded) {
return APP_ICON;
@@ -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,25 +13,34 @@
* 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.codeHighlighting.HighlightDisplayLevel;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.project.Project;
import javax.swing.*;
/**
* @author Dmitry Batkovich
* User: anna
* Date: Mar 15, 2005
*/
public class InspectionSeverityGroupNode extends InspectionTreeNode<HighlightDisplayLevel> {
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<HighlightDis
}
public String toString() {
return StringUtil.capitalize(getSeverityLevel().toString().toLowerCase());
return StringUtil.capitalize(myLevel.toString().toLowerCase());
}
public HighlightDisplayLevel getSeverityLevel() {
HighlightDisplayLevel value = getValue();
LOG.assertTrue(value != null);
return value;
return myLevel;
}
public Project getProject() {
return myProject;
}
}
@@ -25,8 +25,6 @@ import com.intellij.codeInspection.ex.InspectionRVContentProvider;
import com.intellij.codeInspection.ex.QuickFixAction;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.reference.RefModule;
import com.intellij.codeInspection.ui.tree.InspectionNode;
import com.intellij.codeInspection.ui.tree.InspectionTreeNode;
import com.intellij.openapi.vcs.FileStatus;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
@@ -0,0 +1,459 @@
/*
* 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.
*/
/*
* Created by IntelliJ IDEA.
* User: max
* Date: Nov 4, 2001
* Time: 5:19:35 PM
*/
package com.intellij.codeInspection.ui;
import com.intellij.codeInspection.CommonProblemDescriptor;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ex.*;
import com.intellij.codeInspection.reference.RefElement;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeComparator;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.util.*;
public class InspectionTree extends Tree {
private final HashSet<Object> 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<Object>();
myExpandedUserObjects.add(project);
TreeUtil.installActions(this);
new TreeSpeedSearch(this, new Convertor<TreePath, String>() {
@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<RefEntity> result = new ArrayList<RefEntity>();
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<RefEntity> 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<CommonProblemDescriptor> descriptors = new LinkedHashSet<CommonProblemDescriptor>();
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<InspectionTreeNode> result = new HashSet<>();
MultiMap<InspectionTreeNode, InspectionTreeNode> rootDependencies = new MultiMap<>();
for (TreePath path : paths) {
final InspectionTreeNode node = (InspectionTreeNode)path.getLastPathComponent();
final Collection<InspectionTreeNode> 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<CommonProblemDescriptor> 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<TreeNode> 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<Object> newPath = new ArrayList<Object>();
newPath.add(getModel().getRoot());
restorePath(newPath, 1);
return new TreePath(newPath.toArray(new InspectionTreeNode[newPath.size()]));
}
private void restorePath(ArrayList<Object> 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;
}
}
@@ -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();
}
}
}
@@ -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
@@ -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;
}
@@ -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;
}
};
@@ -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<Icon>() {
@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;
}
}
@@ -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];
@@ -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<AnAction> createActions() {
final List<AnAction> result = new ArrayList<AnAction>();
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<PsiElement> files = new HashSet<PsiElement>();
final Project project = myView.getProject();
final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(project);
@@ -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;
@@ -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<InspectionTreeNode> myNodesToSuppress = new HashSet<>();
private final Set<InspectionTreeNode> myNodesToSuppress = new HashSet<InspectionTreeNode>();
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<InspectionTreeNode> 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;
}
@@ -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<TreePath, String>() {
@Override
public String convert(TreePath o) {
return InspectionsConfigTreeComparator.getDisplayTextToSort(o.getLastPathComponent().toString());
}
});
}
@TestOnly
public InspectionTreeBuilder getBuilder() {
return myBuilder;
}
}
@@ -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<InspectionTreeNode> 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<DefaultMutableTreeNode> result = new HashSet<>();
MultiMap<DefaultMutableTreeNode, DefaultMutableTreeNode> rootDependencies = new MultiMap<>();
for (TreePath path : paths) {
final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
final Collection<DefaultMutableTreeNode> 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<InspectionTreeNode> items = getSelectedItems();
if (items.isEmpty()) return CommonProblemDescriptor.EMPTY_ARRAY;
final LinkedHashSet<CommonProblemDescriptor> descriptors = new LinkedHashSet<CommonProblemDescriptor>();
getSelectedItems().forEach(n -> traverseDescriptors(n, descriptors));
return descriptors.toArray(new CommonProblemDescriptor[descriptors.size()]);
}
private static void traverseDescriptors(InspectionTreeNode node, LinkedHashSet<CommonProblemDescriptor> descriptors) {
if (node instanceof ProblemDescriptionNode) {
if (node.isValid() && !node.isResolved()) {
final CommonProblemDescriptor descriptor = ((ProblemDescriptionNode)node).getDescriptor();
if (descriptor != null) {
descriptors.add(descriptor);
}
}
}
Collection<InspectionTreeNode> children = node.getChildren();
children.forEach(n -> traverseDescriptors(n, descriptors));
}
public void removeAllNodes() {
((InspectionRootNode)getTreeStructure().getRootElement()).removeAllChildren();
}
public RefEntity[] getSelectedRefElements() {
List<RefEntity> result = new ArrayList<RefEntity>();
for (InspectionTreeNode node : getSelectedItems()) {
addElementsInNode(node, result);
}
return result.toArray(new RefEntity[result.size()]);
}
private static void addElementsInNode(InspectionTreeNode node, List<RefEntity> 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<InspectionTreeNode> children = node.getChildren();
children.forEach(child -> addElementsInNode(child, out));
}
public GlobalInspectionContextImpl getContext() {
return myContext;
}
}
@@ -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<T> extends AbstractTreeNode<T> {
protected static final Logger LOG = Logger.getInstance(InspectionTreeNode.class);
private boolean myResolved; //accessed from EDT
private Set<InspectionTreeNode> 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<InspectionTreeNode> 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;
}
}
@@ -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<TreeStructureProvider> getProviders() {
return null;
}
}