diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java index 9e46c6668cb7..48f3cd0e4957 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionRVContentProvider.java @@ -23,12 +23,12 @@ package com.intellij.codeInspection.ex; import com.intellij.codeInspection.CommonProblemDescriptor; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.ui.*; +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.util.Function; -import com.intellij.util.containers.HashSet; import com.intellij.util.ui.tree.TreeUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.Nullable; @@ -165,7 +165,7 @@ public abstract class InspectionRVContentProvider { } LOG.assertTrue(childNode instanceof RefElementNode, childNode.getClass().getName()); final RefElementNode elementNode = (RefElementNode)childNode; - final Set parentNodes = new HashSet(); + final Set parentNodes = new LinkedHashSet(); if (pNode.getPackageName() != null) { parentNodes.add(elementNode); } else { @@ -231,18 +231,18 @@ public abstract class InspectionRVContentProvider { return refElementNode; } else { - refElementNode.add(prevNode); + insertByIndex(prevNode, refElementNode); return nodeToBeAdded; } } } } if (!firstLevel) { - currentNode.add(prevNode); + insertByIndex(prevNode, currentNode); } final UserObjectContainer owner = container.getOwner(); if (owner == null) { - parentNode.add(currentNode); + insertByIndex(currentNode, parentNode); return nodeToBeAdded; } container = owner; @@ -290,7 +290,7 @@ public abstract class InspectionRVContentProvider { protected static void add(@Nullable final DefaultTreeModel model, final InspectionTreeNode child, final InspectionTreeNode parent) { if (model == null) { - parent.add(child); + insertByIndex(child, parent); } else { if (parent.getIndex(child) < 0) { @@ -299,6 +299,19 @@ public abstract class InspectionRVContentProvider { } } + private static void insertByIndex(InspectionTreeNode child, InspectionTreeNode parent) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + parent.add(child); + return; + } + final int i = TreeUtil.indexedBinarySearch(parent, child, InspectionResultsViewComparator.getInstance()); + if (i >= 0){ + parent.add(child); + return; + } + parent.insert(child, -i -1); + } + 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++) { diff --git a/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java b/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java index 3990fe048820..60db62dae1c7 100644 --- a/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java +++ b/platform/platform-api/src/com/intellij/util/ui/tree/TreeUtil.java @@ -967,4 +967,24 @@ public final class TreeUtil { } } + public static int indexedBinarySearch(@NotNull TreeNode parent, @NotNull TreeNode key, Comparator comparator) { + int low = 0; + int high = parent.getChildCount() - 1; + + while (low <= high) { + int mid = (low + high) / 2; + TreeNode treeNode = parent.getChildAt(mid); + int cmp = comparator.compare(treeNode, key); + if (cmp < 0) { + low = mid + 1; + } + else if (cmp > 0) { + high = mid - 1; + } + else { + return mid; // key found + } + } + return -(low + 1); // key not found + } }