mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Don't reparse in the UI thread for the "Highlight Usages" pass
Just moving the handler creation to background is not enough, since java's HighlightSuppressedWarningsHandler requires editor visible range, which has to be calculated on EDT, so pre-calculate it first, and pass to the handler factory then. This fixes CPP-9373.
This commit is contained in:
+15
-2
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.highlighting;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.ProperTextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -24,18 +25,30 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiLiteralExpression;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class HighlightSuppressedWarningsFactory extends HighlightUsagesHandlerFactoryBase {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target) {
|
||||
public HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiElement target) {
|
||||
throw new UnsupportedOperationException("Use createHighlightUsagesHandler(editor, file, target, visibleRange)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target,
|
||||
@NotNull ProperTextRange visibleRange) {
|
||||
final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(target, PsiAnnotation.class);
|
||||
if (annotation != null && Comparing.strEqual(SuppressWarnings.class.getName(), annotation.getQualifiedName())) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile != null && !virtualFile.getFileType().isBinary()) {
|
||||
return new HighlightSuppressedWarningsHandler(editor, file, annotation, PsiTreeUtil.getParentOfType(target, PsiLiteralExpression.class));
|
||||
return new HighlightSuppressedWarningsHandler(editor, file, annotation,
|
||||
PsiTreeUtil.getParentOfType(target, PsiLiteralExpression.class), visibleRange);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
+8
-2
@@ -45,13 +45,19 @@ class HighlightSuppressedWarningsHandler extends HighlightUsagesHandlerBase<PsiL
|
||||
|
||||
private final PsiAnnotation myTarget;
|
||||
private final PsiLiteralExpression mySuppressedExpression;
|
||||
@NotNull
|
||||
private final ProperTextRange myPriorityRange;
|
||||
|
||||
HighlightSuppressedWarningsHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiAnnotation target, @Nullable PsiLiteralExpression suppressedExpression) {
|
||||
|
||||
HighlightSuppressedWarningsHandler(@NotNull Editor editor,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiAnnotation target,
|
||||
@Nullable PsiLiteralExpression suppressedExpression,
|
||||
@NotNull ProperTextRange priorityRange) {
|
||||
super(editor, file);
|
||||
myTarget = target;
|
||||
mySuppressedExpression = suppressedExpression;
|
||||
myPriorityRange = VisibleHighlightingPassFactory.calculateVisibleRange(myEditor);
|
||||
myPriorityRange = priorityRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+12
-10
@@ -37,6 +37,7 @@ import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ProperTextRange;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
@@ -58,32 +59,33 @@ public class IdentifierHighlighterPass extends TextEditorHighlightingPass {
|
||||
private final Collection<TextRange> myReadAccessRanges = Collections.synchronizedList(new ArrayList<>());
|
||||
private final Collection<TextRange> myWriteAccessRanges = Collections.synchronizedList(new ArrayList<>());
|
||||
private final int myCaretOffset;
|
||||
private final HighlightUsagesHandlerBase<PsiElement> myHighlightUsagesHandler;
|
||||
private final ProperTextRange myVisibleRange;
|
||||
|
||||
IdentifierHighlighterPass(@NotNull Project project, @NotNull PsiFile file, @NotNull Editor editor) {
|
||||
super(project, editor.getDocument(), false);
|
||||
myFile = file;
|
||||
myEditor = editor;
|
||||
myCaretOffset = myEditor.getCaretModel().getOffset();
|
||||
myHighlightUsagesHandler = HighlightUsagesHandler.createCustomHandler(myEditor, myFile);
|
||||
myVisibleRange = VisibleHighlightingPassFactory.calculateVisibleRange(myEditor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCollectInformation(@NotNull final ProgressIndicator progress) {
|
||||
if (myHighlightUsagesHandler != null) {
|
||||
List<PsiElement> targets = myHighlightUsagesHandler.getTargets();
|
||||
myHighlightUsagesHandler.computeUsages(targets);
|
||||
final List<TextRange> readUsages = myHighlightUsagesHandler.getReadUsages();
|
||||
final HighlightUsagesHandlerBase<PsiElement> highlightUsagesHandler = HighlightUsagesHandler.createCustomHandler(myEditor, myFile, myVisibleRange);
|
||||
if (highlightUsagesHandler != null) {
|
||||
List<PsiElement> targets = highlightUsagesHandler.getTargets();
|
||||
highlightUsagesHandler.computeUsages(targets);
|
||||
final List<TextRange> readUsages = highlightUsagesHandler.getReadUsages();
|
||||
for (TextRange readUsage : readUsages) {
|
||||
LOG.assertTrue(readUsage != null, "null text range from " + myHighlightUsagesHandler);
|
||||
LOG.assertTrue(readUsage != null, "null text range from " + highlightUsagesHandler);
|
||||
}
|
||||
myReadAccessRanges.addAll(readUsages);
|
||||
final List<TextRange> writeUsages = myHighlightUsagesHandler.getWriteUsages();
|
||||
final List<TextRange> writeUsages = highlightUsagesHandler.getWriteUsages();
|
||||
for (TextRange writeUsage : writeUsages) {
|
||||
LOG.assertTrue(writeUsage != null, "null text range from " + myHighlightUsagesHandler);
|
||||
LOG.assertTrue(writeUsage != null, "null text range from " + highlightUsagesHandler);
|
||||
}
|
||||
myWriteAccessRanges.addAll(writeUsages);
|
||||
if (!myHighlightUsagesHandler.highlightReferences()) return;
|
||||
if (!highlightUsagesHandler.highlightReferences()) return;
|
||||
}
|
||||
|
||||
int flags = TargetElementUtil.ELEMENT_NAME_ACCEPTED | TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED;
|
||||
|
||||
+15
-1
@@ -19,6 +19,7 @@ package com.intellij.codeInsight.highlighting;
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.TargetElementUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.IdentifierUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.VisibleHighlightingPassFactory;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.find.EditorSearchSession;
|
||||
import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
|
||||
@@ -28,6 +29,7 @@ import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
@@ -41,6 +43,7 @@ import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.ProperTextRange;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
@@ -152,8 +155,19 @@ public class HighlightUsagesHandler extends HighlightHandlerBase {
|
||||
|
||||
@Nullable
|
||||
public static <T extends PsiElement> HighlightUsagesHandlerBase<T> createCustomHandler(@NotNull Editor editor, @NotNull PsiFile file) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
ProperTextRange visibleRange = VisibleHighlightingPassFactory.calculateVisibleRange(editor);
|
||||
return createCustomHandler(editor, file, visibleRange);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see HighlightUsagesHandlerFactory#createHighlightUsagesHandler(Editor, PsiFile, ProperTextRange)
|
||||
*/
|
||||
@Nullable
|
||||
public static <T extends PsiElement> HighlightUsagesHandlerBase<T> createCustomHandler(@NotNull Editor editor, @NotNull PsiFile file,
|
||||
@NotNull ProperTextRange visibleRange) {
|
||||
for (HighlightUsagesHandlerFactory factory : Extensions.getExtensions(HighlightUsagesHandlerFactory.EP_NAME)) {
|
||||
final HighlightUsagesHandlerBase handler = factory.createHighlightUsagesHandler(editor, file);
|
||||
final HighlightUsagesHandlerBase handler = factory.createHighlightUsagesHandler(editor, file, visibleRange);
|
||||
if (handler != null) {
|
||||
//noinspection unchecked
|
||||
return handler;
|
||||
|
||||
+13
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.highlighting;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.util.ProperTextRange;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -32,4 +33,16 @@ public interface HighlightUsagesHandlerFactory {
|
||||
|
||||
@Nullable
|
||||
HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file);
|
||||
|
||||
|
||||
/**
|
||||
* @param visibleRange To avoid parsing in EDT, these factory methods should be called in a background thread
|
||||
* (as implementation use the PSI element under cursor to choose the specific handler).
|
||||
* However, some handlers require the editor visible range, which must be calculated in EDT,
|
||||
* so it's passed externally
|
||||
*/
|
||||
@Nullable
|
||||
default HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull ProperTextRange visibleRange) {
|
||||
return createHighlightUsagesHandler(editor, file);
|
||||
}
|
||||
}
|
||||
|
||||
+22
-2
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.highlighting;
|
||||
|
||||
import com.intellij.codeInsight.TargetElementUtil;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.ProperTextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -29,12 +30,31 @@ public abstract class HighlightUsagesHandlerFactoryBase implements HighlightUsag
|
||||
@Nullable
|
||||
@Override
|
||||
public final HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file) {
|
||||
int offset = TargetElementUtil.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset());
|
||||
PsiElement target = file.findElementAt(offset);
|
||||
PsiElement target = findTarget(editor, file);
|
||||
if (target == null) return null;
|
||||
return createHighlightUsagesHandler(editor, file, target);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public final HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file,
|
||||
@NotNull ProperTextRange visibleRange) {
|
||||
PsiElement target = findTarget(editor, file);
|
||||
if (target == null) return null;
|
||||
return createHighlightUsagesHandler(editor, file, target, visibleRange);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target);
|
||||
|
||||
@Nullable
|
||||
public HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target,
|
||||
@NotNull ProperTextRange visibleRange) {
|
||||
return createHighlightUsagesHandler(editor, file, target);
|
||||
}
|
||||
|
||||
private static PsiElement findTarget(@NotNull Editor editor, @NotNull PsiFile file) {
|
||||
int offset = TargetElementUtil.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset());
|
||||
return file.findElementAt(offset);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user