mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
parallelize java slow marker pass a bit
This commit is contained in:
+48
-29
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon.impl;
|
||||
|
||||
import com.intellij.codeHighlighting.Pass;
|
||||
import com.intellij.codeInsight.daemon.*;
|
||||
import com.intellij.concurrency.JobLauncher;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -26,7 +27,10 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer;
|
||||
import com.intellij.openapi.editor.markup.SeparatorPlacement;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
@@ -40,16 +44,15 @@ import com.intellij.psi.util.PsiExpressionTrimRenderer;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.FunctionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
|
||||
protected final DaemonCodeAnalyzerSettings myDaemonSettings;
|
||||
@@ -163,7 +166,9 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
|
||||
public void collectSlowLineMarkers(@NotNull final List<PsiElement> elements, @NotNull final Collection<LineMarkerInfo> result) {
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
|
||||
Collection<PsiMethod> methods = new THashSet<>();
|
||||
List<Computable<List<LineMarkerInfo>>> tasks = new ArrayList<>();
|
||||
|
||||
MultiMap<PsiClass, PsiMethod> byClass = MultiMap.create();
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0; i < elements.size(); i++) {
|
||||
PsiElement element = elements.get(i);
|
||||
@@ -172,30 +177,40 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)parent;
|
||||
if (PsiUtil.canBeOverriden(method)) {
|
||||
methods.add(method);
|
||||
PsiClass psiClass = method.getContainingClass();
|
||||
if (PsiUtil.canBeOverriden(method) && psiClass != null) {
|
||||
byClass.putValue(psiClass, method);
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiClass && !(parent instanceof PsiTypeParameter)) {
|
||||
collectInheritingClasses((PsiClass)parent, result);
|
||||
tasks.add(() -> collectInheritingClasses((PsiClass)parent));
|
||||
}
|
||||
}
|
||||
if (!methods.isEmpty()) {
|
||||
collectSiblingInheritedMethods(methods, result);
|
||||
collectOverridingMethods(methods, result);
|
||||
for (PsiClass psiClass : byClass.keySet()) {
|
||||
List<PsiMethod> methods = new ArrayList<>(byClass.get(psiClass));
|
||||
tasks.add(() -> collectSiblingInheritedMethods(methods));
|
||||
tasks.add(() -> collectOverridingMethods(methods));
|
||||
}
|
||||
|
||||
Object lock = new Object();
|
||||
ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
|
||||
JobLauncher.getInstance().invokeConcurrentlyUnderProgress(tasks, indicator, true, computable -> {
|
||||
List<LineMarkerInfo> infos = computable.compute();
|
||||
synchronized (lock) {
|
||||
result.addAll(infos);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private static void collectSiblingInheritedMethods(@NotNull final Collection<PsiMethod> methods,
|
||||
@NotNull Collection<LineMarkerInfo> result) {
|
||||
private static List<LineMarkerInfo> collectSiblingInheritedMethods(@NotNull final Collection<PsiMethod> methods) {
|
||||
Map<PsiMethod, FindSuperElementsHelper.SiblingInfo> map = FindSuperElementsHelper.getSiblingInheritanceInfos(methods);
|
||||
for (PsiMethod method : map.keySet()) {
|
||||
return ContainerUtil.map(map.keySet(), method -> {
|
||||
PsiElement range = getMethodRange(method);
|
||||
ArrowUpLineMarkerInfo upInfo = new ArrowUpLineMarkerInfo(range, AllIcons.Gutter.ImplementingMethod, MarkerType.SIBLING_OVERRIDING_METHOD,
|
||||
Pass.UPDATE_OVERRIDDEN_MARKERS);
|
||||
LineMarkerInfo info = NavigateAction.setNavigateAction(upInfo, "Go to super method", IdeActions.ACTION_GOTO_SUPER);
|
||||
result.add(info);
|
||||
}
|
||||
Pass.UPDATE_OVERRIDDEN_MARKERS);
|
||||
return NavigateAction.setNavigateAction(upInfo, "Go to super method", IdeActions.ACTION_GOTO_SUPER);
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -216,22 +231,23 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
|
||||
return range;
|
||||
}
|
||||
|
||||
protected void collectInheritingClasses(@NotNull PsiClass aClass,
|
||||
@NotNull Collection<LineMarkerInfo> result) {
|
||||
protected List<LineMarkerInfo> collectInheritingClasses(@NotNull PsiClass aClass) {
|
||||
if (aClass.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
return;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) {
|
||||
return Collections.emptyList(); // It's useless to have overridden markers for object.
|
||||
}
|
||||
if (CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) return; // It's useless to have overridden markers for object.
|
||||
|
||||
PsiClass subClass = DirectClassInheritorsSearch.search(aClass).findFirst();
|
||||
if (subClass != null || FunctionalExpressionSearch.search(aClass).findFirst() != null) {
|
||||
final Icon icon;
|
||||
if (aClass.isInterface()) {
|
||||
if (!myImplementedOption.isEnabled()) return;
|
||||
if (!myImplementedOption.isEnabled()) return Collections.emptyList();
|
||||
icon = AllIcons.Gutter.ImplementedMethod;
|
||||
}
|
||||
else {
|
||||
if (!myOverriddenOption.isEnabled()) return;
|
||||
if (!myOverriddenOption.isEnabled()) return Collections.emptyList();
|
||||
icon = AllIcons.Gutter.OverridenMethod;
|
||||
}
|
||||
PsiElement range = aClass.getNameIdentifier();
|
||||
@@ -244,12 +260,13 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
|
||||
type.getNavigationHandler(),
|
||||
GutterIconRenderer.Alignment.RIGHT);
|
||||
NavigateAction.setNavigateAction(info, aClass.isInterface() ? "Go to implementation(s)" : "Go to subclass(es)", IdeActions.ACTION_GOTO_IMPLEMENTATION);
|
||||
result.add(info);
|
||||
return Collections.singletonList(info);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private void collectOverridingMethods(@NotNull final Collection<PsiMethod> methods, @NotNull Collection<LineMarkerInfo> result) {
|
||||
if (!myOverriddenOption.isEnabled() && !myImplementedOption.isEnabled()) return;
|
||||
private List<LineMarkerInfo> collectOverridingMethods(@NotNull final Collection<PsiMethod> methods) {
|
||||
if (!myOverriddenOption.isEnabled() && !myImplementedOption.isEnabled()) return Collections.emptyList();
|
||||
final Set<PsiMethod> overridden = new HashSet<>();
|
||||
Set<PsiClass> methodContainingClasses = new THashSet<>();
|
||||
for (PsiMethod method : methods) {
|
||||
@@ -283,14 +300,15 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
|
||||
}
|
||||
}
|
||||
|
||||
List<LineMarkerInfo> result = new ArrayList<>();
|
||||
for (PsiMethod method : overridden) {
|
||||
ProgressManager.checkCanceled();
|
||||
boolean overrides = !method.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
if (overrides) {
|
||||
if (!myOverriddenOption.isEnabled()) return;
|
||||
if (!myOverriddenOption.isEnabled()) return Collections.emptyList();
|
||||
}
|
||||
else {
|
||||
if (!myImplementedOption.isEnabled()) return;
|
||||
if (!myImplementedOption.isEnabled()) return Collections.emptyList();
|
||||
}
|
||||
PsiElement range = getMethodRange(method);
|
||||
final MarkerType type = MarkerType.OVERRIDDEN_METHOD;
|
||||
@@ -302,6 +320,7 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
|
||||
NavigateAction.setNavigateAction(info, overrides ? "Go to overriding methods" : "Go to implementation(s)", IdeActions.ACTION_GOTO_IMPLEMENTATION);
|
||||
result.add(info);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user