diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionGroupNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionGroupNode.java index 556ff56bdcf0..64107c4ef2cc 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionGroupNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionGroupNode.java @@ -1,18 +1,4 @@ -/* - * 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. - * 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. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInspection.ui; @@ -22,22 +8,14 @@ import org.jetbrains.annotations.NotNull; * @author max */ public class InspectionGroupNode extends InspectionTreeNode { - @NotNull private final String[] myGroupPath; - - InspectionGroupNode(@NotNull String groupTitle, @NotNull String[] groupPath) { - super(groupTitle); - myGroupPath = groupPath; + InspectionGroupNode(@NotNull String subGroup) { + super(subGroup); } - String getGroupTitle() { + String getSubGroup() { return (String) getUserObject(); } - @NotNull - public String[] getGroupPath() { - return myGroupPath; - } - @Override public boolean appearsBold() { return true; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java index af1fd48c016e..93c5d3f646ba 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java @@ -47,12 +47,10 @@ import com.intellij.profile.codeInspection.ProjectInspectionProfileManager; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.*; -import com.intellij.util.ConcurrencyUtil; import com.intellij.util.EditSourceOnDoubleClickHandler; import com.intellij.util.ObjectUtils; import com.intellij.util.OpenSourceUtil; import com.intellij.util.concurrency.AppExecutorUtil; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; @@ -73,7 +71,6 @@ import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.util.*; import java.util.List; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutorService; public class InspectionResultsView extends JPanel implements Disposable, DataProvider, OccurenceNavigator { @@ -618,9 +615,7 @@ public class InspectionResultsView extends JPanel implements Disposable, DataPro HighlightDisplayLevel errorLevel, boolean groupedBySeverity, boolean isSingleInspectionRun) { - String groupName = - toolWrapper.getGroupDisplayName().isEmpty() ? InspectionProfileEntry.GENERAL_GROUP_NAME : toolWrapper.getGroupDisplayName(); - InspectionTreeNode parentNode = myTree.getToolParentNode(groupName, toolWrapper.getGroupPath(), errorLevel, groupedBySeverity, isSingleInspectionRun); + InspectionTreeNode parentNode = myTree.getToolParentNode(toolWrapper, errorLevel, groupedBySeverity, isSingleInspectionRun); InspectionNode toolNode = new InspectionNode(toolWrapper, myInspectionProfile); boolean showStructure = myGlobalInspectionContext.getUIOptions().SHOW_STRUCTURE; toolNode = myProvider.appendToolNodeContent(myGlobalInspectionContext, toolNode, parentNode, showStructure, groupedBySeverity); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java index 28abe7f2509c..c7c7c8a93da9 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java @@ -1,18 +1,4 @@ -/* - * 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. - * 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. - */ +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInspection.ui; @@ -54,7 +40,7 @@ public class InspectionResultsViewComparator implements Comparator mySeverityGroupNodes = ContainerUtil.newConcurrentMap(); - @NotNull private final ConcurrentMap> myGroups = ContainerUtil.newConcurrentMap(); + @NotNull private final ConcurrentMap> myGroups = ContainerUtil.newConcurrentMap(); @NotNull private InspectionTreeState myState = new InspectionTreeState(); private boolean myQueueUpdate; @@ -97,7 +99,7 @@ public class InspectionTree extends Tree { final TreePath commonPath = TreeUtil.findCommonPath(paths); for (Object n : commonPath.getPath()) { if (n instanceof InspectionGroupNode) { - return ((InspectionGroupNode)n).getGroupPath(); + return getGroupPath((InspectionGroupNode)n); } } return null; @@ -275,40 +277,48 @@ public class InspectionTree extends Tree { } @NotNull - InspectionTreeNode getToolParentNode(@NotNull String groupName, - @NotNull String[] groupPath, - HighlightDisplayLevel errorLevel, - boolean groupedBySeverity, - boolean isSingleInspectionRun) { + InspectionTreeNode getToolParentNode(@NotNull InspectionToolWrapper toolWrapper, + HighlightDisplayLevel errorLevel, + boolean groupedBySeverity, + boolean isSingleInspectionRun) { + //synchronize if (!groupedBySeverity && isSingleInspectionRun) { return getRoot(); } - if (groupName.isEmpty()) { + String[] groupPath = toolWrapper.getGroupPath(); + if (groupPath.length == 0) { + LOG.error("groupPath is empty for tool: " + toolWrapper.getShortName() + ", class: " + toolWrapper.getTool().getClass()); return getRelativeRootNode(groupedBySeverity, errorLevel); } - ConcurrentMap map = myGroups.get(errorLevel); + ConcurrentMap map = myGroups.get(errorLevel); if (map == null) { - map = ConcurrencyUtil.cacheOrGet(myGroups, errorLevel, ContainerUtil.newConcurrentMap()); + map = ConcurrencyUtil.cacheOrGet(myGroups, errorLevel, ConcurrentCollectionFactory.createMap(new TObjectHashingStrategy() { + @Override + public int computeHashCode(String[] object) { + return Arrays.hashCode(object); + } + + @Override + public boolean equals(String[] o1, String[] o2) { + return Arrays.equals(o1, o2); + } + })); } InspectionGroupNode group; if (groupedBySeverity) { - group = map.get(groupName); + group = map.get(groupPath); } else { group = null; - for (Map groupMap : myGroups.values()) { - if ((group = groupMap.get(groupName)) != null) break; + for (Map groupMap : myGroups.values()) { + if ((group = groupMap.get(groupPath)) != null) break; } } if (group == null) { if (isSingleInspectionRun) { return getRelativeRootNode(true, errorLevel); } - group = ConcurrencyUtil.cacheOrGet(map, groupName, new InspectionGroupNode(groupName, groupPath)); - InspectionResultsView view = myContext.getView(); - if (view != null && !view.isDisposed()) { - getRelativeRootNode(groupedBySeverity, errorLevel).insertByOrder(group, false); - } + group = map.computeIfAbsent(groupPath, this::insertGroupNode); } return group; } @@ -433,6 +443,38 @@ public class InspectionTree extends Tree { return myContext; } + private InspectionGroupNode insertGroupNode(@NotNull String[] groupPath) { + InspectionTreeNode currentNode = getRoot(); + + for (int groupIdx = 0; groupIdx < groupPath.length; groupIdx++) { + String subGroup = groupPath[groupIdx]; + + InspectionTreeNode next = null; + for (int i = 0; i < currentNode.getChildCount(); i++) { + TreeNode child = currentNode.getChildAt(i); + if (child instanceof InspectionGroupNode && ((InspectionGroupNode)child).getSubGroup().equals(subGroup)) { + next = (InspectionTreeNode)child; + break; + } + } + + if (next == null) { + for (int i = groupIdx; i < groupPath.length; i++) { + InspectionResultsView view = getContext().getView(); + if (view != null && !view.isDisposed()) { + currentNode = currentNode.insertByOrder(new InspectionGroupNode(groupPath[i]), false); + } + } + break; + } + else { + currentNode = next; + } + } + + return (InspectionGroupNode)currentNode; + } + private static void collectReadOnlyFiles(@NotNull Collection descriptors, @NotNull Set readOnlySink) { for (CommonProblemDescriptor descriptor : descriptors) { collectReadOnlyFiles(descriptor, readOnlySink); @@ -447,4 +489,16 @@ public class InspectionTree extends Tree { } } } + + @NotNull + private static String[] getGroupPath(@NotNull InspectionGroupNode node) { + List path = new ArrayList<>(2); + while (true) { + TreeNode parent = node.getParent(); + if (!(parent instanceof InspectionGroupNode)) break; + node = (InspectionGroupNode)parent; + path.add(node.getSubGroup()); + } + return ArrayUtil.toStringArray(path); + } }