diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java index 48757fb1662c..97b090e80212 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/DefaultInspectionToolPresentation.java @@ -45,6 +45,7 @@ import com.intellij.util.containers.HashSet; import gnu.trove.Equality; import gnu.trove.THashMap; import gnu.trove.THashSet; +import gnu.trove.TObjectHashingStrategy; import org.jdom.Element; import org.jdom.IllegalDataException; import org.jetbrains.annotations.NonNls; @@ -65,13 +66,14 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro private InspectionNode myToolNode; private static final Object lock = new Object(); - private final Map myProblemElements = Collections.synchronizedMap(new THashMap()); - private final Map> myContents = Collections.synchronizedMap(new com.intellij.util.containers.HashMap>()); // keys can be null - private final Set myModulesProblems = Collections.synchronizedSet(new THashSet()); - private final Map myProblemToElements = Collections.synchronizedMap(new THashMap()); + private final Map myProblemElements = Collections.synchronizedMap(new THashMap( + TObjectHashingStrategy.IDENTITY)); + private final Map> myContents = Collections.synchronizedMap(new THashMap>(1)); // keys can be null + private final Set myModulesProblems = Collections.synchronizedSet(new THashSet(TObjectHashingStrategy.IDENTITY)); + private final Map myProblemToElements = Collections.synchronizedMap(new THashMap(TObjectHashingStrategy.IDENTITY)); private DescriptorComposer myComposer; - private final Map> myQuickFixActions = Collections.synchronizedMap(new com.intellij.util.containers.HashMap>()); - private final Map myIgnoredElements = Collections.synchronizedMap(new com.intellij.util.containers.HashMap()); + private final Map> myQuickFixActions = Collections.synchronizedMap(new THashMap>(TObjectHashingStrategy.IDENTITY)); + private final Map myIgnoredElements = Collections.synchronizedMap(new THashMap(TObjectHashingStrategy.IDENTITY)); private Map myOldProblemElements = null; protected static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.DescriptorProviderInspection"); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/ExcludedInspectionTreeNodesManager.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/ExcludedInspectionTreeNodesManager.java index b9ad4cfae9ad..5250c6566a2d 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/ExcludedInspectionTreeNodesManager.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/ExcludedInspectionTreeNodesManager.java @@ -17,9 +17,9 @@ package com.intellij.codeInspection.ui; import com.intellij.util.containers.FactoryMap; +import gnu.trove.THashSet; import org.jetbrains.annotations.Nullable; -import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -32,7 +32,7 @@ public class ExcludedInspectionTreeNodesManager { @Nullable @Override protected Set create(Class key) { - return new HashSet<>(); + return new THashSet<>(); } }; 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 9e488cac365a..bf4179b1cecc 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsViewComparator.java @@ -45,7 +45,7 @@ import com.intellij.psi.util.PsiUtilCore; import java.util.Comparator; public class InspectionResultsViewComparator implements Comparator { - private static final Logger LOG = Logger.getInstance("#" + InspectionResultsViewComparator.class.getName()); + private static final Logger LOG = Logger.getInstance(InspectionResultsViewComparator.class); public boolean areEqual(Object o1, Object o2) { return o1.getClass().equals(o2.getClass()) && compare(o1, o2) == 0; @@ -173,26 +173,11 @@ public class InspectionResultsViewComparator implements Comparator { return entity2 != null ? 1 : 0; } - private static int compareLineNumbers(final Object userObject, final OfflineProblemDescriptor descriptor) { - if (userObject instanceof RefElement) { - final RefElement refElement = (RefElement)userObject; - final PsiElement psiElement = refElement.getElement(); - if (psiElement != null) { - Document document = PsiDocumentManager.getInstance(psiElement.getProject()).getDocument(psiElement.getContainingFile()); - if (document != null) { - return descriptor.getLine() - document.getLineNumber(psiElement.getTextOffset()) -1; - } - } - } - return -1; - } - private static class InspectionResultsViewComparatorHolder { private static final InspectionResultsViewComparator ourInstance = new InspectionResultsViewComparator(); } public static InspectionResultsViewComparator getInstance() { - return InspectionResultsViewComparatorHolder.ourInstance; } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewPsiTreeChangeAdapter.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewPsiTreeChangeAdapter.java index a06da6a9f82f..e9f9dd781a6d 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewPsiTreeChangeAdapter.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewPsiTreeChangeAdapter.java @@ -20,6 +20,7 @@ import com.intellij.codeInspection.reference.RefEntity; import com.intellij.concurrency.JobSchedulerImpl; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.progress.util.ReadTask; import com.intellij.openapi.project.Project; @@ -44,6 +45,8 @@ import java.util.Set; * @author Dmitry Batkovich */ class InspectionViewPsiTreeChangeAdapter extends PsiTreeChangeAdapter { + private final static int MAX_UPDATES_FOR_CANCELLABLE_ACTION = 100; + private final InspectionResultsView myView; private final MergingUpdateQueue myUpdater; private final BoundedTaskExecutor myExecutor; @@ -74,60 +77,70 @@ class InspectionViewPsiTreeChangeAdapter extends PsiTreeChangeAdapter { } }); } - final Project project = view.getProject(); - synchronized (myView.getTreeStructureUpdateLock()) { - InspectionTreeNode root = myView.getTree().getRoot(); - boolean[] needUpdateUI = {false}; - processNodesIfNeed(root, (node) -> { - if (node instanceof CachedInspectionTreeNode) { - //indicator.checkCanceled(); - RefEntity element = ((CachedInspectionTreeNode)node).getElement(); - if (element instanceof RefElement) { - final SmartPsiElementPointer pointer = ((RefElement)element).getPointer(); - VirtualFile strictVirtualFile = pointer.getVirtualFile(); - if (strictVirtualFile == null || !strictVirtualFile.isValid()) { - final PsiFile file = pointer.getContainingFile(); - if (file != null && file.isValid()) { - strictVirtualFile = file.getVirtualFile(); + + final Runnable runnable = () -> { + synchronized (myView.getTreeStructureUpdateLock()) { + InspectionTreeNode root = myView.getTree().getRoot(); + boolean[] needUpdateUI = {false}; + processNodesIfNeed(root, (node) -> { + if (node instanceof CachedInspectionTreeNode) { + RefEntity element = ((CachedInspectionTreeNode)node).getElement(); + if (element instanceof RefElement) { + final SmartPsiElementPointer pointer = ((RefElement)element).getPointer(); + VirtualFile strictVirtualFile = pointer.getVirtualFile(); + if (strictVirtualFile == null || !strictVirtualFile.isValid()) { + final PsiFile file = pointer.getContainingFile(); + if (file != null && file.isValid()) { + strictVirtualFile = file.getVirtualFile(); + } } + if (strictVirtualFile == null || files.contains(strictVirtualFile)) { + ((CachedInspectionTreeNode)node).dropCache(project); + if (!needUpdateUI[0]) { + needUpdateUI[0] = true; + } + } + return false; } - if (strictVirtualFile == null || files.contains(strictVirtualFile)) { + else { ((CachedInspectionTreeNode)node).dropCache(project); if (!needUpdateUI[0]) { needUpdateUI[0] = true; } + return false; } - return false; - } - else { - ((CachedInspectionTreeNode)node).dropCache(project); - if (!needUpdateUI[0]) { - needUpdateUI[0] = true; - } - return false; - } - } - return true; - }); - if (needUpdateUI[0]) { - UIUtil.invokeLaterIfNeeded(() -> { - myView.invalidate(); - myView.repaint(); - if (myView.isUpdating()) { - myView.updateRightPanelLoading(); - } else { - myView.syncRightPanel(); } + return true; }); + if (needUpdateUI[0]) { + UIUtil.invokeLaterIfNeeded(() -> { + myView.invalidate(); + myView.repaint(); + if (myView.isUpdating()) { + myView.updateRightPanelLoading(); + } + else { + myView.syncRightPanel(); + } + }); + } } + }; + + if (updates.length > MAX_UPDATES_FOR_CANCELLABLE_ACTION) { + ProgressManager.getInstance().executeNonCancelableSection(runnable); + } else { + runnable.run(); } } @Override public void onCanceled(@NotNull ProgressIndicator indicator) { if (!myView.isDisposed()) { - ProgressIndicatorUtils.scheduleWithWriteActionPriority(myExecutor, this); + for (Update update : updates) { + myUpdater.queue(update); + } } } };