visible/slow line markers merged with line markers pass; instead of VisibleLineMarkersPass and SlowLineMarkerPass the LineMarkersPass now accepts priorityRange and restrictRange, just like GeneralHighlightingPass

This commit is contained in:
Alexey Kudravtsev
2016-08-08 15:20:40 +03:00
parent c93c87c937
commit 32c33fbbaf
31 changed files with 236 additions and 435 deletions
@@ -85,7 +85,7 @@ public class ExternalAnnotationsLineMarkerProvider extends LineMarkerProviderDes
return new LineMarkerInfo<PsiElement>(element, element.getTextRange(),
AllIcons.Gutter.ExtAnnotation,
Pass.UPDATE_ALL,
Pass.LINE_MARKERS,
ourTooltipProvider, MyIconGutterHandler.INSTANCE,
GutterIconRenderer.Alignment.RIGHT);
}
@@ -128,7 +128,7 @@ public class IconLineMarkerProvider extends LineMarkerProviderDescriptor {
};
return new LineMarkerInfo<PsiElement>(bindingElement, bindingElement.getTextRange(), icon,
Pass.UPDATE_ALL, null, navHandler,
Pass.LINE_MARKERS, null, navHandler,
GutterIconRenderer.Alignment.LEFT);
}
@@ -88,14 +88,14 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
if (!myImplementingOption.isEnabled()) return null;
icon = AllIcons.Gutter.ImplementingMethod;
}
return createSuperMethodLineMarkerInfo(element, icon, Pass.UPDATE_ALL);
return createSuperMethodLineMarkerInfo(element, icon, Pass.LINE_MARKERS);
}
}
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(element);
final PsiElement firstChild = element.getFirstChild();
if (interfaceMethod != null && firstChild != null && myLambdaOption.isEnabled()) {
return createSuperMethodLineMarkerInfo(firstChild, AllIcons.Gutter.ImplementingFunctionalInterface, Pass.UPDATE_ALL);
return createSuperMethodLineMarkerInfo(firstChild, AllIcons.Gutter.ImplementingFunctionalInterface, Pass.LINE_MARKERS);
}
if (myDaemonSettings.SHOW_METHOD_SEPARATORS && firstChild == null) {
@@ -125,7 +125,7 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
}
if (drawSeparator) {
LineMarkerInfo info = new LineMarkerInfo<>(element, element.getTextRange(), null, Pass.UPDATE_ALL,
LineMarkerInfo info = new LineMarkerInfo<>(element, element.getTextRange(), null, Pass.LINE_MARKERS,
FunctionUtil.<Object, String>nullConstant(), null,
GutterIconRenderer.Alignment.RIGHT);
EditorColorsScheme scheme = myColorsManager.getGlobalScheme();
@@ -207,7 +207,7 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
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);
Pass.LINE_MARKERS);
return NavigateAction.setNavigateAction(upInfo, "Go to super method", IdeActions.ACTION_GOTO_SUPER);
});
}
@@ -255,7 +255,7 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
}
MarkerType type = MarkerType.SUBCLASSED_CLASS;
LineMarkerInfo info = new LineMarkerInfo<>(range, range.getTextRange(),
icon, Pass.UPDATE_OVERRIDDEN_MARKERS, type.getTooltip(),
icon, Pass.LINE_MARKERS, type.getTooltip(),
type.getNavigationHandler(),
GutterIconRenderer.Alignment.RIGHT);
NavigateAction.setNavigateAction(info, aClass.isInterface() ? "Go to implementation(s)" : "Go to subclass(es)", IdeActions.ACTION_GOTO_IMPLEMENTATION);
@@ -301,7 +301,7 @@ public class JavaLineMarkerProvider extends LineMarkerProviderDescriptor {
final MarkerType type = MarkerType.OVERRIDDEN_METHOD;
final Icon icon = overrides ? AllIcons.Gutter.OverridenMethod : AllIcons.Gutter.ImplementedMethod;
LineMarkerInfo<PsiElement> info = new LineMarkerInfo<>(range, range.getTextRange(),
icon, Pass.UPDATE_OVERRIDDEN_MARKERS, type.getTooltip(),
icon, Pass.LINE_MARKERS, type.getTooltip(),
type.getNavigationHandler(),
GutterIconRenderer.Alignment.RIGHT);
NavigateAction.setNavigateAction(info, overrides ? "Go to overriding methods" : "Go to implementation(s)", IdeActions.ACTION_GOTO_IMPLEMENTATION);
@@ -94,7 +94,7 @@ public class RecursiveCallLineMarkerProvider extends LineMarkerProviderDescripto
super(methodCall,
methodCall.getTextRange(),
AllIcons.Gutter.RecursiveMethod,
Pass.UPDATE_OVERRIDDEN_MARKERS,
Pass.LINE_MARKERS,
FunctionUtil.<PsiMethodCallExpression, String>constant("Recursive call"),
null,
GutterIconRenderer.Alignment.RIGHT
@@ -873,7 +873,7 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
String msg = "provider.getLineMarkerInfo(" + element + ") called\n";
LineMarkerInfo<PsiComment> info = null;
if (element instanceof PsiComment) {
info = new LineMarkerInfo<>((PsiComment)element, element.getTextRange(), null, Pass.UPDATE_ALL, null, null, GutterIconRenderer.Alignment.LEFT);
info = new LineMarkerInfo<>((PsiComment)element, element.getTextRange(), null, Pass.LINE_MARKERS, null, null, GutterIconRenderer.Alignment.LEFT);
msg += " provider info: "+info + "\n";
}
log.append(msg);
@@ -295,8 +295,6 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
TIntArrayList toIgnore = new TIntArrayList();
if (!doTestLineMarkers()) {
toIgnore.add(Pass.UPDATE_OVERRIDDEN_MARKERS);
toIgnore.add(Pass.VISIBLE_LINE_MARKERS);
toIgnore.add(Pass.LINE_MARKERS);
}
@@ -309,8 +307,6 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
toIgnore.add(Pass.WHOLE_FILE_LOCAL_INSPECTIONS);
toIgnore.add(Pass.POPUP_HINTS);
toIgnore.add(Pass.UPDATE_ALL);
toIgnore.add(Pass.UPDATE_OVERRIDDEN_MARKERS);
toIgnore.add(Pass.VISIBLE_LINE_MARKERS);
}
boolean canChange = canChangeDocumentDuringHighlighting();
@@ -19,17 +19,11 @@ public interface Pass {
int UPDATE_FOLDING = 1;
int POPUP_HINTS = 3;
int UPDATE_ALL = 4;
int UPDATE_OVERRIDDEN_MARKERS = 6;
int LOCAL_INSPECTIONS = 7;
int EXTERNAL_TOOLS = 8;
int WOLF = 9;
int VISIBLE_LINE_MARKERS = 10;
int LINE_MARKERS = 11;
int WHOLE_FILE_LOCAL_INSPECTIONS = 12;
int LAST_PASS = WHOLE_FILE_LOCAL_INSPECTIONS;
/** @deprecated use {@link #UPDATE_OVERRIDDEN_MARKERS} (to be removed in IDEA 17) */
@SuppressWarnings({"unused", "SpellCheckingInspection"})
int UPDATE_OVERRIDEN_MARKERS = UPDATE_OVERRIDDEN_MARKERS;
}
@@ -61,11 +61,7 @@ public abstract class TextEditorHighlightingPassRegistrar {
* Registers the factory for the new highlighting pass.
* Factory will be asked to create the highlighting pass every time IDEA tries to highlight the file.
*
* @param factory
* @param anchor
* @param anchorPassId id of the anchor pass. Predefined pass Ids are declared in {@link com.intellij.codeHighlighting.Pass}
* @param needAdditionalIntentionsPass
* @param inPostHighlightingPass
* @param anchorPassId id of the anchor pass. Predefined pass Ids are declared in {@link Pass}
* @return the id of the new pass which e.g. can be used as an anchor for the other pass.
*/
public int registerTextEditorHighlightingPass(final TextEditorHighlightingPassFactory factory,
@@ -88,7 +84,7 @@ public abstract class TextEditorHighlightingPassRegistrar {
case LAST:
//todo
ids = new int[]{Pass.UPDATE_ALL,
Pass.UPDATE_FOLDING, Pass.UPDATE_OVERRIDDEN_MARKERS,
Pass.UPDATE_FOLDING, Pass.LINE_MARKERS,
Pass.EXTERNAL_TOOLS,
Pass.LOCAL_INSPECTIONS, Pass.POPUP_HINTS};
break;
@@ -19,23 +19,14 @@
*/
package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeHighlighting.Pass;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
public abstract class VisibleHighlightingPassFactory extends AbstractProjectComponent {
public VisibleHighlightingPassFactory(Project project) {
super(project);
}
public abstract class VisibleHighlightingPassFactory {
@NotNull
public static ProperTextRange calculateVisibleRange(@NotNull Editor editor) {
Rectangle rect = editor.getScrollingModel().getVisibleArea();
@@ -48,18 +39,4 @@ public abstract class VisibleHighlightingPassFactory extends AbstractProjectComp
return new ProperTextRange(visibleStart, Math.max(visibleEnd, visibleStart));
}
@Nullable
protected static TextRange calculateRangeToProcess(Editor editor) {
TextRange dirtyTextRange = FileStatusMap.getDirtyTextRange(editor, Pass.UPDATE_ALL);
if (dirtyTextRange == null) return null;
TextRange visibleRange = calculateVisibleRange(editor);
TextRange textRange = dirtyTextRange.intersection(visibleRange);
if (textRange == null || textRange.isEmpty() || textRange.equals(dirtyTextRange)) {
return null; // no sense in highlighting the same region twice
}
return textRange;
}
}
@@ -276,12 +276,11 @@ public class MarkupModelImpl extends UserDataHolderBase implements MarkupModelEx
endOffset = Math.max(startOffset, endOffset);
return IntervalTreeImpl
.mergingOverlappingIterator(myHighlighterTree, new TextRangeInterval(startOffset, endOffset), myHighlighterTreeForLines,
roundToLineBoundaries(startOffset, endOffset), RangeHighlighterEx.BY_AFFECTED_START_OFFSET);
roundToLineBoundaries(getDocument(), startOffset, endOffset), RangeHighlighterEx.BY_AFFECTED_START_OFFSET);
}
@NotNull
private TextRangeInterval roundToLineBoundaries(int startOffset, int endOffset) {
Document document = getDocument();
public static TextRangeInterval roundToLineBoundaries(@NotNull Document document, int startOffset, int endOffset) {
int textLength = document.getTextLength();
int lineStartOffset = startOffset <= 0 ? 0 : startOffset > textLength ? textLength : document.getLineStartOffset(document.getLineNumber(startOffset));
int lineEndOffset = endOffset <= 0 ? 0 : endOffset >= textLength ? textLength : document.getLineEndOffset(document.getLineNumber(endOffset));
@@ -69,9 +69,8 @@ public class LineMarkerInfo<T extends PsiElement> {
elementRef = new WeakReference<T>(element);
myNavigationHandler = navHandler;
startOffset = range.getStartOffset();
this.updatePass = updatePass;
endOffset = range.getEndOffset();
this.updatePass = 11; //Pass.LINE_MARKERS;
}
/**
@@ -43,8 +43,6 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.editor.impl.DocumentMarkupModel;
import com.intellij.openapi.editor.markup.MarkupModel;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
@@ -100,7 +98,6 @@ import java.util.concurrent.TimeoutException;
public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements PersistentStateComponent<Element>, Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl");
private static final Key<List<LineMarkerInfo>> MARKERS_IN_EDITOR_DOCUMENT_KEY = Key.create("MARKERS_IN_EDITOR_DOCUMENT");
private static final Key<List<HighlightInfo>> FILE_LEVEL_HIGHLIGHTS = Key.create("FILE_LEVEL_HIGHLIGHTS");
private final Project myProject;
private final DaemonCodeAnalyzerSettings mySettings;
@@ -712,14 +709,10 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements Pers
@NotNull
public static List<LineMarkerInfo> getLineMarkers(@NotNull Document document, @NotNull Project project) {
ApplicationManager.getApplication().assertIsDispatchThread();
MarkupModel markup = DocumentMarkupModel.forDocument(document, project, true);
return ObjectUtils.notNull(markup.getUserData(MARKERS_IN_EDITOR_DOCUMENT_KEY), Collections.emptyList());
}
static void setLineMarkers(@NotNull Document document, @NotNull List<LineMarkerInfo> lineMarkers, @NotNull Project project) {
ApplicationManager.getApplication().assertIsDispatchThread();
MarkupModel markup = DocumentMarkupModel.forDocument(document, project, true);
markup.putUserData(MARKERS_IN_EDITOR_DOCUMENT_KEY, lineMarkers);
List<LineMarkerInfo> result = new ArrayList<>();
LineMarkersUtil.processLineMarkers(project, document, new TextRange(0, document.getTextLength()), -1,
new CommonProcessors.CollectProcessor<>(result));
return result;
}
void setLastIntentionHint(@NotNull Project project,
@@ -29,7 +29,6 @@ import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
@@ -43,38 +42,41 @@ import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.injected.InjectedFileViewProvider;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.util.FunctionUtil;
import com.intellij.util.PairConsumer;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.*;
public class LineMarkersPass extends TextEditorHighlightingPass implements LineMarkersProcessor, DumbAware {
public class LineMarkersPass extends TextEditorHighlightingPass implements DumbAware {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.LineMarkersPass");
private volatile Collection<LineMarkerInfo> myMarkers = Collections.emptyList();
@NotNull private final PsiFile myFile;
@Nullable private final Editor myEditor;
@NotNull private final TextRange myBounds;
@NotNull private final TextRange myPriorityBounds;
@NotNull private final TextRange myRestrictRange;
LineMarkersPass(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull Document document,
@NotNull TextRange bounds) {
@NotNull TextRange priorityBounds,
@NotNull TextRange restrictRange) {
super(project, document, false);
myFile = file;
myEditor = editor;
myBounds = bounds;
myPriorityBounds = priorityBounds;
myRestrictRange = restrictRange;
}
@NotNull
@@ -87,7 +89,7 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
@Override
public void doApplyInformationToEditor() {
try {
LineMarkersUtil.setLineMarkersToEditor(myProject, getDocument(), myBounds, myMarkers, Pass.UPDATE_ALL);
LineMarkersUtil.setLineMarkersToEditor(myProject, getDocument(), myRestrictRange, myMarkers, getId());
}
catch (IndexNotReadyException ignored) {
}
@@ -96,52 +98,60 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
@Override
public void doCollectInformation(@NotNull ProgressIndicator progress) {
final List<LineMarkerInfo> lineMarkers = new ArrayList<>();
final FileViewProvider viewProvider = myFile.getViewProvider();
final Set<Language> relevantLanguages = viewProvider.getLanguages();
for (Language language : relevantLanguages) {
PsiElement psiRoot = viewProvider.getPsi(language);
if (!HighlightingLevelManager.getInstance(myProject).shouldHighlight(psiRoot)) continue;
List<PsiElement> elements = CollectHighlightsUtil.getElementsInRange(psiRoot, myBounds.getStartOffset(), myBounds.getEndOffset());
if (elements.isEmpty()) {
elements = Collections.singletonList(psiRoot);
}
final List<LineMarkerProvider> providers = getMarkerProviders(language, myProject);
addLineMarkers(elements, providers, lineMarkers, progress);
collectLineMarkersForInjected(lineMarkers, elements, this, myFile, progress);
for (PsiFile root : myFile.getViewProvider().getAllFiles()) {
List<PsiElement> inside = new ArrayList<>();
List<ProperTextRange> insideRanges = new ArrayList<>();
List<PsiElement> outside = new ArrayList<>();
List<ProperTextRange> outsideRanges = new ArrayList<>();
HighlightingLevelManager highlightingLevelManager = HighlightingLevelManager.getInstance(myProject);
Divider.divideInsideAndOutside(root, myRestrictRange.getStartOffset(), myRestrictRange.getEndOffset(), myPriorityBounds,
inside, insideRanges, outside, outsideRanges, false,
psiFile -> psiFile == root && highlightingLevelManager.shouldHighlight(psiFile));
Collection<LineMarkerProvider> providers = getMarkerProviders(root.getLanguage(), myProject);
List<LineMarkerProvider> providersList = new ArrayList<>(providers);
queryProviders(inside, root, providersList, (element, info) -> {
lineMarkers.add(info);
ApplicationManager.getApplication()
.invokeLater(() -> LineMarkersUtil.addLineMarkerToEditorIncrementally(myProject, getDocument(), info),
myProject.getDisposed());
});
queryProviders(outside, root, providersList, (element, info) -> lineMarkers.add(info));
}
myMarkers = mergeLineMarkers(lineMarkers, myEditor);
myMarkers = mergeLineMarkers(lineMarkers, getDocument());
if (LOG.isDebugEnabled()) {
LOG.debug("LineMarkersPass.doCollectInformation. lineMarkers: " + lineMarkers+"; merged: "+myMarkers);
}
}
@NotNull
static List<LineMarkerInfo> mergeLineMarkers(@NotNull List<LineMarkerInfo> markers, @Nullable Editor editor) {
private static List<LineMarkerInfo> mergeLineMarkers(@NotNull List<LineMarkerInfo> markers, @NotNull Document document) {
List<MergeableLineMarkerInfo> forMerge = new ArrayList<>();
final Iterator<LineMarkerInfo> iterator = markers.iterator();
while (iterator.hasNext()) {
final LineMarkerInfo marker = iterator.next();
TIntObjectHashMap<List<MergeableLineMarkerInfo>> sameLineMarkers = new TIntObjectHashMap<>();
for (int i = markers.size() - 1; i >= 0; i--) {
LineMarkerInfo marker = markers.get(i);
if (marker instanceof MergeableLineMarkerInfo) {
iterator.remove();
forMerge.add((MergeableLineMarkerInfo)marker);
MergeableLineMarkerInfo mergeable = (MergeableLineMarkerInfo)marker;
forMerge.add(mergeable);
markers.remove(i);
int line = document.getLineNumber(marker.startOffset);
List<MergeableLineMarkerInfo> infos = sameLineMarkers.get(line);
if (infos == null) {
infos = new ArrayList<>();
sameLineMarkers.put(line, infos);
}
infos.add(mergeable);
}
}
if (forMerge.isEmpty() || editor == null) return markers;
if (forMerge.isEmpty()) return markers;
List<LineMarkerInfo> result = new ArrayList<>(markers);
TIntObjectHashMap<List<MergeableLineMarkerInfo>> sameLineMarkers = new TIntObjectHashMap<>();
for (MergeableLineMarkerInfo info : forMerge) {
int line = editor.getDocument().getLineNumber(info.startOffset);
List<MergeableLineMarkerInfo> infos = sameLineMarkers.get(line);
if (infos == null) {
infos = new ArrayList<>();
sameLineMarkers.put(line, infos);
}
infos.add(info);
}
for (Object v : sameLineMarkers.getValues()) {
List<MergeableLineMarkerInfo> infos = (List<MergeableLineMarkerInfo>)v;
@@ -160,12 +170,12 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
|| settings.isEnabled((LineMarkerProviderDescriptor)provider));
}
@Override
public void addLineMarkers(@NotNull List<PsiElement> elements,
@NotNull final List<LineMarkerProvider> providers,
@NotNull final List<LineMarkerInfo> result,
@NotNull ProgressIndicator progress) throws ProcessCanceledException {
private static void queryProviders(@NotNull List<PsiElement> elements,
@NotNull PsiFile containingFile,
@NotNull List<LineMarkerProvider> providers,
@NotNull PairConsumer<PsiElement, LineMarkerInfo> consumer) {
ApplicationManager.getApplication().assertReadAccessAllowed();
Set<PsiFile> visitedInjectedFiles = new THashSet<>();
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < elements.size(); i++) {
PsiElement element = elements.get(i);
@@ -186,34 +196,57 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
continue;
}
if (info != null) {
result.add(info);
consumer.consume(element, info);
}
}
queryLineMarkersForInjected(element, containingFile, visitedInjectedFiles, consumer);
}
List<LineMarkerInfo> slowLineMarkers = new ArrayList<>();
//noinspection ForLoopReplaceableByForEach
for (int j = 0; j < providers.size(); j++) {
ProgressManager.checkCanceled();
LineMarkerProvider provider = providers.get(j);
try {
provider.collectSlowLineMarkers(elements, slowLineMarkers);
}
catch (ProcessCanceledException | IndexNotReadyException e) {
throw e;
}
catch (Exception e) {
LOG.error(e);
continue;
}
if (!slowLineMarkers.isEmpty()) {
//noinspection ForLoopReplaceableByForEach
for (int k = 0; k < slowLineMarkers.size(); k++) {
LineMarkerInfo slowInfo = slowLineMarkers.get(k);
PsiElement element = slowInfo.getElement();
consumer.consume(element, slowInfo);
}
slowLineMarkers.clear();
}
}
}
static void collectLineMarkersForInjected(@NotNull final List<LineMarkerInfo> result,
@NotNull List<PsiElement> elements,
@NotNull final LineMarkersProcessor processor,
@NotNull final PsiFile file,
@NotNull final ProgressIndicator progress) {
final InjectedLanguageManager manager = InjectedLanguageManager.getInstance(file.getProject());
private static void queryLineMarkersForInjected(@NotNull PsiElement element,
@NotNull final PsiFile containingFile,
@NotNull Set<PsiFile> visitedInjectedFiles,
@NotNull final PairConsumer<PsiElement, LineMarkerInfo> consumer) {
if (containingFile.getViewProvider() instanceof InjectedFileViewProvider) return;
final InjectedLanguageManager manager = InjectedLanguageManager.getInstance(containingFile.getProject());
final Set<PsiFile> injectedFiles = new THashSet<>();
final PsiLanguageInjectionHost.InjectedPsiVisitor collectingVisitor = (injectedPsi, places) -> injectedFiles.add(injectedPsi);
InjectedLanguageManagerImpl.getInstanceImpl(file.getProject()).processInjectableElements(elements, element -> {
InjectedLanguageUtil.enumerate(element, file, false, collectingVisitor);
return true;
});
final List<LineMarkerInfo> injectedMarkers = new ArrayList<>();
for (PsiFile injectedPsi : injectedFiles) {
InjectedLanguageUtil.enumerate(element, containingFile, false, (injectedPsi, places) -> {
if (!visitedInjectedFiles.add(injectedPsi)) return; // there may be several concatenated literals making the one injected file
final Project project = injectedPsi.getProject();
Document document = PsiDocumentManager.getInstance(project).getCachedDocument(injectedPsi);
if (!(document instanceof DocumentWindow)) return;
List<PsiElement> injElements = CollectHighlightsUtil.getElementsInRange(injectedPsi, 0, injectedPsi.getTextLength());
final List<LineMarkerProvider> providers = getMarkerProviders(injectedPsi.getLanguage(), project);
processor.addLineMarkers(injElements, providers, injectedMarkers, progress);
for (final LineMarkerInfo injectedMarker : injectedMarkers) {
queryProviders(injElements, injectedPsi, providers, (injectedElement, injectedMarker) -> {
GutterIconRenderer gutterRenderer = injectedMarker.createGutterRenderer();
TextRange injectedRange = new TextRange(injectedMarker.startOffset, injectedMarker.endOffset);
List<TextRange> editables = manager.intersectWithAllEditableFragments(injectedPsi, injectedRange);
@@ -222,14 +255,13 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
Icon icon = gutterRenderer == null ? null : gutterRenderer.getIcon();
GutterIconNavigationHandler<PsiElement> navigationHandler = injectedMarker.getNavigationHandler();
LineMarkerInfo<PsiElement> converted =
new LineMarkerInfo<>(injectedMarker.getElement(), hostRange, icon, injectedMarker.updatePass,
element -> injectedMarker.getLineMarkerTooltip(), navigationHandler,
new LineMarkerInfo<>(injectedElement, hostRange, icon, injectedMarker.updatePass,
e -> injectedMarker.getLineMarkerTooltip(), navigationHandler,
GutterIconRenderer.Alignment.RIGHT);
result.add(converted);
consumer.consume(injectedElement, converted);
}
}
injectedMarkers.clear();
}
});
});
}
@NotNull
@@ -238,7 +270,7 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
// binary file? see IDEADEV-2809
return Collections.emptyList();
}
LineMarkersPass pass = new LineMarkersPass(file.getProject(), file, null, document, file.getTextRange());
LineMarkersPass pass = new LineMarkersPass(file.getProject(), file, document, file.getTextRange(), file.getTextRange());
pass.doCollectInformation(new EmptyProgressIndicator());
return pass.myMarkers;
}
@@ -249,7 +281,7 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
startFrom,
startFrom.getTextRange(),
null,
Pass.UPDATE_ALL,
Pass.LINE_MARKERS,
FunctionUtil.<Object, String>nullConstant(),
null,
GutterIconRenderer.Alignment.RIGHT
@@ -262,6 +294,6 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
@Override
public String toString() {
return super.toString() + "; myBounds: "+myBounds;
return super.toString() + "; myBounds: " + myPriorityBounds;
}
}
@@ -21,8 +21,11 @@ import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory;
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.impl.MarkupModelImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NonNls;
@@ -35,7 +38,7 @@ import org.jetbrains.annotations.Nullable;
public class LineMarkersPassFactory extends AbstractProjectComponent implements TextEditorHighlightingPassFactory {
public LineMarkersPassFactory(Project project, TextEditorHighlightingPassRegistrar highlightingPassRegistrar) {
super(project);
highlightingPassRegistrar.registerTextEditorHighlightingPass(this, new int[]{Pass.VISIBLE_LINE_MARKERS}, new int[]{Pass.UPDATE_ALL}, false, Pass.LINE_MARKERS);
highlightingPassRegistrar.registerTextEditorHighlightingPass(this, null, new int[]{Pass.UPDATE_ALL}, false, Pass.LINE_MARKERS);
}
@Override
@@ -48,13 +51,20 @@ public class LineMarkersPassFactory extends AbstractProjectComponent implements
@Override
@Nullable
public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) {
TextRange textRange = calculateRangeToProcessForSyntaxPass(editor);
if (textRange == null) return new ProgressableTextEditorHighlightingPass.EmptyPass(myProject, editor.getDocument());
return new LineMarkersPass(myProject, file, editor, editor.getDocument(), textRange);
TextRange restrictRange = calculateRangeToProcessForSyntaxPass(editor);
Document document = editor.getDocument();
if (restrictRange == null) return new ProgressableTextEditorHighlightingPass.EmptyPass(myProject, document);
ProperTextRange visibleRange = VisibleHighlightingPassFactory.calculateVisibleRange(editor);
return new LineMarkersPass(myProject, file, document, expandRangeToCoverWholeLines(document, visibleRange), expandRangeToCoverWholeLines(document, restrictRange));
}
@Nullable
private static TextRange calculateRangeToProcessForSyntaxPass(Editor editor) {
return FileStatusMap.getDirtyTextRange(editor, Pass.UPDATE_ALL);
}
static TextRange expandRangeToCoverWholeLines(@NotNull Document document, TextRange textRange) {
if (textRange == null) return null;
return MarkupModelImpl.roundToLineBoundaries(document, textRange.getStartOffset(), textRange.getEndOffset());
}
}
@@ -29,18 +29,36 @@ import com.intellij.openapi.editor.markup.MarkupModel;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
class LineMarkersUtil {
private static final Logger LOG = Logger.getInstance(LineMarkersUtil.class);
static boolean processLineMarkers(@NotNull Project project,
@NotNull Document document,
@NotNull Segment bounds,
int group, // -1 for all
@NotNull Processor<LineMarkerInfo> processor) {
MarkupModelEx markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, true);
return markupModel.processRangeHighlightersOverlappingWith(bounds.getStartOffset(), bounds.getEndOffset(),
highlighter -> {
LineMarkerInfo info = getLineMarkerInfo(highlighter);
if (info == null) return true;
if (group != -1 && info.updatePass != group) return true;
return processor.process(info);
}
);
}
static void setLineMarkersToEditor(@NotNull Project project,
@NotNull Document document,
@NotNull Segment bounds,
@@ -48,25 +66,15 @@ class LineMarkersUtil {
int group) {
ApplicationManager.getApplication().assertIsDispatchThread();
List<LineMarkerInfo> oldMarkers = DaemonCodeAnalyzerImpl.getLineMarkers(document, project);
List<LineMarkerInfo> result = new ArrayList<>(Math.max(markers.size(), oldMarkers.size()));
MarkupModel markupModel = DocumentMarkupModel.forDocument(document, project, true);
MarkupModelEx markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, true);
HighlightersRecycler toReuse = new HighlightersRecycler();
for (LineMarkerInfo info : oldMarkers) {
RangeHighlighter highlighter = info.highlighter;
boolean toRemove = !highlighter.isValid() ||
info.updatePass == group &&
TextRange.containsRange(bounds, highlighter);
if (toRemove) {
toReuse.recycleHighlighter(highlighter);
}
else {
result.add(info);
}
}
processLineMarkers(project, document, bounds, group, info -> {
toReuse.recycleHighlighter(info.highlighter);
return true;
});
if (LOG.isDebugEnabled()) {
List<LineMarkerInfo> oldMarkers = DaemonCodeAnalyzerImpl.getLineMarkers(document, project);
LOG.debug("LineMarkersUtil.setLineMarkersToEditor(markers: "+markers+", group: " + group+
"); oldMarkers: "+oldMarkers+"; reused: "+toReuse.forAllInGarbageBin().size());
}
@@ -83,37 +91,60 @@ class LineMarkersUtil {
if (!TextRange.containsRange(bounds, elementRange)) {
continue;
}
RangeHighlighter marker = toReuse.pickupHighlighterFromGarbageBin(info.startOffset, info.endOffset, HighlighterLayer.ADDITIONAL_SYNTAX);
if (marker == null) {
marker = markupModel.addRangeHighlighter(info.startOffset, info.endOffset, HighlighterLayer.ADDITIONAL_SYNTAX, null, HighlighterTargetArea.LINES_IN_RANGE);
}
final LineMarkerInfo.LineMarkerGutterIconRenderer newRenderer = (LineMarkerInfo.LineMarkerGutterIconRenderer)info.createGutterRenderer();
final LineMarkerInfo.LineMarkerGutterIconRenderer oldRenderer = marker.getGutterIconRenderer() instanceof LineMarkerInfo.LineMarkerGutterIconRenderer ? (LineMarkerInfo.LineMarkerGutterIconRenderer)marker.getGutterIconRenderer() : null;
final boolean rendererChanged = oldRenderer == null || newRenderer == null || !newRenderer.equals(oldRenderer);
final boolean lineSeparatorColorChanged = !Comparing.equal(marker.getLineSeparatorColor(), info.separatorColor);
final boolean lineSeparatorPlacementChanged = !Comparing.equal(marker.getLineSeparatorPlacement(), info.separatorPlacement);
if (rendererChanged || lineSeparatorColorChanged || lineSeparatorPlacementChanged) {
((MarkupModelEx)markupModel).changeAttributesInBatch((RangeHighlighterEx)marker, markerEx -> {
if (rendererChanged) {
markerEx.setGutterIconRenderer(newRenderer);
}
if (lineSeparatorColorChanged) {
markerEx.setLineSeparatorColor(info.separatorColor);
}
if (lineSeparatorPlacementChanged) {
markerEx.setLineSeparatorPlacement(info.separatorPlacement);
}
});
}
info.highlighter = marker;
result.add(info);
createOrReuseLineMarker(info, markupModel, toReuse);
}
for (RangeHighlighter highlighter : toReuse.forAllInGarbageBin()) {
highlighter.dispose();
}
}
DaemonCodeAnalyzerImpl.setLineMarkers(document, result, project);
private static final Key<LineMarkerInfo> LINE_MARKER_INFO = Key.create("LINE_MARKER_INFO");
private static RangeHighlighter createOrReuseLineMarker(@NotNull LineMarkerInfo info,
@NotNull MarkupModel markupModel,
@Nullable HighlightersRecycler toReuse) {
RangeHighlighter highlighter = toReuse == null ? null : toReuse.pickupHighlighterFromGarbageBin(info.startOffset, info.endOffset, HighlighterLayer.ADDITIONAL_SYNTAX);
if (highlighter == null) {
highlighter = markupModel.addRangeHighlighter(info.startOffset, info.endOffset, HighlighterLayer.ADDITIONAL_SYNTAX, null, HighlighterTargetArea.LINES_IN_RANGE);
}
highlighter.putUserData(LINE_MARKER_INFO, info);
LineMarkerInfo.LineMarkerGutterIconRenderer newRenderer = (LineMarkerInfo.LineMarkerGutterIconRenderer)info.createGutterRenderer();
LineMarkerInfo.LineMarkerGutterIconRenderer oldRenderer = highlighter.getGutterIconRenderer() instanceof LineMarkerInfo.LineMarkerGutterIconRenderer ? (LineMarkerInfo.LineMarkerGutterIconRenderer)highlighter.getGutterIconRenderer() : null;
boolean rendererChanged = oldRenderer == null || newRenderer == null || !newRenderer.equals(oldRenderer);
boolean lineSeparatorColorChanged = !Comparing.equal(highlighter.getLineSeparatorColor(), info.separatorColor);
boolean lineSeparatorPlacementChanged = !Comparing.equal(highlighter.getLineSeparatorPlacement(), info.separatorPlacement);
if (rendererChanged || lineSeparatorColorChanged || lineSeparatorPlacementChanged) {
((MarkupModelEx)markupModel).changeAttributesInBatch((RangeHighlighterEx)highlighter, markerEx -> {
if (rendererChanged) {
markerEx.setGutterIconRenderer(newRenderer);
}
if (lineSeparatorColorChanged) {
markerEx.setLineSeparatorColor(info.separatorColor);
}
if (lineSeparatorPlacementChanged) {
markerEx.setLineSeparatorPlacement(info.separatorPlacement);
}
});
}
info.highlighter = highlighter;
return highlighter;
}
static void addLineMarkerToEditorIncrementally(@NotNull Project project,
@NotNull Document document,
@NotNull LineMarkerInfo marker) {
ApplicationManager.getApplication().assertIsDispatchThread();
MarkupModelEx markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, true);
boolean allIsClear = markupModel.processRangeHighlightersOverlappingWith(marker.startOffset, marker.endOffset,
highlighter -> getLineMarkerInfo(highlighter) == null);
if (allIsClear) {
createOrReuseLineMarker(marker, markupModel, null);
}
}
private static LineMarkerInfo getLineMarkerInfo(@NotNull RangeHighlighter highlighter) {
return highlighter.getUserData(LINE_MARKER_INFO);
}
}
@@ -1,92 +0,0 @@
/*
* 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.
*/
package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.LineMarkerProvider;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingLevelManager;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
class SlowLineMarkersPass extends TextEditorHighlightingPass implements LineMarkersProcessor, DumbAware {
private final PsiFile myFile;
@NotNull private final Editor myEditor;
@NotNull private final TextRange myBounds;
private volatile Collection<LineMarkerInfo> myMarkers = Collections.emptyList();
public SlowLineMarkersPass(@NotNull Project project, @NotNull PsiFile file, @NotNull Editor editor, @NotNull TextRange bounds) {
super(project, editor.getDocument(), false);
myFile = file;
myEditor = editor;
myBounds = bounds;
}
@Override
public void doCollectInformation(@NotNull ProgressIndicator progress) {
final FileViewProvider viewProvider = myFile.getViewProvider();
final Set<Language> relevantLanguages = viewProvider.getLanguages();
List<LineMarkerInfo> markers = new SmartList<LineMarkerInfo>();
for (Language language : relevantLanguages) {
PsiElement psiRoot = viewProvider.getPsi(language);
if (psiRoot == null || !HighlightingLevelManager.getInstance(myProject).shouldHighlight(psiRoot)) continue;
List<PsiElement> elements = CollectHighlightsUtil.getElementsInRange(psiRoot, myBounds.getStartOffset(), myBounds.getEndOffset());
final List<LineMarkerProvider> providers = LineMarkersPass.getMarkerProviders(language, myProject);
addLineMarkers(elements, providers, markers, progress);
LineMarkersPass.collectLineMarkersForInjected(markers, elements, this, myFile, progress);
}
myMarkers = LineMarkersPass.mergeLineMarkers(markers, myEditor);
}
@Override
public void addLineMarkers(@NotNull List<PsiElement> elements,
@NotNull List<LineMarkerProvider> providers,
@NotNull List<LineMarkerInfo> result,
@NotNull ProgressIndicator progress) throws ProcessCanceledException {
for (LineMarkerProvider provider : providers) {
ProgressManager.checkCanceled();
provider.collectSlowLineMarkers(elements, result);
}
}
@Override
public void doApplyInformationToEditor() {
LineMarkersUtil.setLineMarkersToEditor(myProject, getDocument(), myBounds, myMarkers, getId());
DaemonCodeAnalyzerEx daemonCodeAnalyzer = DaemonCodeAnalyzerEx.getInstanceEx(myProject);
daemonCodeAnalyzer.getFileStatusMap().markFileUpToDate(getDocument(), getId());
}
}
@@ -1,64 +0,0 @@
/*
* Copyright 2000-2016 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.
*/
package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeHighlighting.DirtyScopeTrackingHighlightingPassFactory;
import com.intellij.codeHighlighting.Pass;
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author cdr
*/
public class SlowLineMarkersPassFactory extends AbstractProjectComponent implements DirtyScopeTrackingHighlightingPassFactory {
public SlowLineMarkersPassFactory(Project project, TextEditorHighlightingPassRegistrar highlightingPassRegistrar) {
super(project);
highlightingPassRegistrar.registerTextEditorHighlightingPass(this, null, new int[]{Pass.UPDATE_ALL}, false, Pass.UPDATE_OVERRIDDEN_MARKERS);
}
@Override
@NonNls
@NotNull
public String getComponentName() {
return "SlowLineMarkersPassFactory";
}
@Override
@Nullable
public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) {
TextRange textRange = calculateRangeToProcess(editor);
if (textRange == null) return null;
return new SlowLineMarkersPass(myProject, file, editor, textRange);
}
private static TextRange calculateRangeToProcess(Editor editor) {
return FileStatusMap.getDirtyTextRange(editor, Pass.UPDATE_OVERRIDDEN_MARKERS);
}
@Override
public int getPassId() {
return Pass.UPDATE_OVERRIDDEN_MARKERS;
}
}
@@ -1,55 +0,0 @@
/*
* 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.
*/
package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeHighlighting.Pass;
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory;
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author cdr
*/
public class VisibleLineMarkersPassFactory extends VisibleHighlightingPassFactory implements TextEditorHighlightingPassFactory {
public VisibleLineMarkersPassFactory(Project project, TextEditorHighlightingPassRegistrar highlightingPassRegistrar) {
super(project);
highlightingPassRegistrar.registerTextEditorHighlightingPass(this, null, null, false, Pass.VISIBLE_LINE_MARKERS);
}
@Override
@NonNls
@NotNull
public String getComponentName() {
return "VisibleLineMarkersPassFactory";
}
@Override
@Nullable
public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) {
TextRange textRange = calculateRangeToProcess(editor);
if (textRange == null) return null;
return new LineMarkersPass(file.getProject(), file, editor, editor.getDocument(), textRange);
}
}
@@ -81,7 +81,7 @@ public class RunLineMarkerProvider extends LineMarkerProviderDescriptor {
return tooltip.length() == 0 ? null : tooltip.toString();
};
return new LineMarkerInfo<PsiElement>(element, element.getTextRange(), icon, Pass.UPDATE_ALL,
return new LineMarkerInfo<PsiElement>(element, element.getTextRange(), icon, Pass.LINE_MARKERS,
tooltipProvider, null,
GutterIconRenderer.Alignment.CENTER) {
@Nullable
@@ -69,7 +69,7 @@ public final class ColorLineMarkerProvider implements LineMarkerProvider {
super(element,
element.getTextRange(),
new ColorIcon(12, color),
Pass.UPDATE_ALL,
Pass.LINE_MARKERS,
FunctionUtil.<Object, String>nullConstant(),
new GutterIconNavigationHandler<PsiElement>() {
@Override
@@ -134,10 +134,6 @@
<implementation-class>com.intellij.codeInsight.daemon.impl.LineMarkersPassFactory</implementation-class>
<skipForDefaultProject/>
</component>
<component>
<implementation-class>com.intellij.codeInsight.daemon.impl.VisibleLineMarkersPassFactory</implementation-class>
<skipForDefaultProject/>
</component>
<component>
<implementation-class>com.intellij.codeInsight.daemon.impl.ShowIntentionsPassFactory</implementation-class>
<skipForDefaultProject/>
@@ -182,11 +178,6 @@
<implementation-class>com.intellij.codeInsight.daemon.impl.ShowAutoImportPassFactory</implementation-class>
<skipForDefaultProject/>
</component>
<component>
<implementation-class>com.intellij.codeInsight.daemon.impl.SlowLineMarkersPassFactory</implementation-class>
<skipForDefaultProject/>
</component>
<component>
<implementation-class>com.intellij.util.indexing.FileBasedIndexProjectHandler</implementation-class>
</component>
@@ -25,8 +25,8 @@ import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
import com.intellij.ui.components.JBList;
import com.intellij.util.PathUtil;
import java.util.Collection;
import java.util.Iterator;
import java.util.Collections;
import java.util.List;
@TestDataPath("$CONTENT_ROOT/testData/navigation/descriptionType")
public class DescriptionTypeRelatedItemLineMarkerProviderTest extends JavaCodeInsightFixtureTestCase {
@@ -61,11 +61,11 @@ public class DescriptionTypeRelatedItemLineMarkerProviderTest extends JavaCodeIn
public void testIntentionDescription() {
myFixture.copyDirectoryToProject("intentionDescriptions", "intentionDescriptions");
final Collection<GutterMark> gutters = myFixture.findAllGutters("MyIntentionActionWithDescription.java");
List<GutterMark> gutters = myFixture.findAllGutters("MyIntentionActionWithDescription.java");
assertSize(2, gutters);
final Iterator<GutterMark> it = gutters.iterator();
DevKitGutterTargetsChecker.checkGutterTargets(it.next(), "Description", AllIcons.FileTypes.Html, "description.html");
DevKitGutterTargetsChecker.checkGutterTargets(it.next(), "Before/After Templates", AllIcons.Actions.Diff,
Collections.sort(gutters, (g1, g2) -> g1.getTooltipText().compareTo(g2.getTooltipText()));
DevKitGutterTargetsChecker.checkGutterTargets(gutters.get(1), "Description", AllIcons.FileTypes.Html, "description.html");
DevKitGutterTargetsChecker.checkGutterTargets(gutters.get(0), "Before/After Templates", AllIcons.Actions.Diff,
"after.java.template", "before.java.template");
}
}
@@ -85,7 +85,7 @@ public class GroovyLineMarkerProvider extends JavaLineMarkerProvider {
superMethod.getBody() != null && GrTraitUtil.isTrait(superMethod.getContainingClass());
final Icon icon = overrides ? AllIcons.Gutter.OverridingMethod : AllIcons.Gutter.ImplementingMethod;
final MarkerType type = GroovyMarkerTypes.OVERRIDING_PROPERTY_TYPE;
return new LineMarkerInfo<>(element, element.getTextRange(), icon, Pass.UPDATE_ALL, type.getTooltip(),
return new LineMarkerInfo<>(element, element.getTextRange(), icon, Pass.LINE_MARKERS, type.getTooltip(),
type.getNavigationHandler(),
GutterIconRenderer.Alignment.LEFT);
}
@@ -96,7 +96,7 @@ public class GroovyLineMarkerProvider extends JavaLineMarkerProvider {
hasSuperMethods((GrMethod)element.getParent())) {
final Icon icon = AllIcons.Gutter.OverridingMethod;
final MarkerType type = GroovyMarkerTypes.GR_OVERRIDING_METHOD;
return new LineMarkerInfo<>(element, element.getTextRange(), icon, Pass.UPDATE_ALL, type.getTooltip(),
return new LineMarkerInfo<>(element, element.getTextRange(), icon, Pass.LINE_MARKERS, type.getTooltip(),
type.getNavigationHandler(), GutterIconRenderer.Alignment.LEFT);
}
}
@@ -134,7 +134,7 @@ public class GroovyLineMarkerProvider extends JavaLineMarkerProvider {
}
LineMarkerInfo info =
new LineMarkerInfo<>(element, comment != null ? comment.getTextRange() : element.getTextRange(), null,
Pass.UPDATE_ALL, FunctionUtil.<Object, String>nullConstant(), null,
Pass.LINE_MARKERS, FunctionUtil.<Object, String>nullConstant(), null,
GutterIconRenderer.Alignment.RIGHT);
EditorColorsScheme scheme = myColorsManager.getGlobalScheme();
info.separatorColor = scheme.getColor(CodeInsightColors.METHOD_SEPARATORS_COLOR);
@@ -244,7 +244,7 @@ public class GroovyLineMarkerProvider extends JavaLineMarkerProvider {
final MarkerType type = element instanceof GrField ? GroovyMarkerTypes.OVERRIDEN_PROPERTY_TYPE
: GroovyMarkerTypes.GR_OVERRIDEN_METHOD;
LineMarkerInfo info = new LineMarkerInfo<>(range, range.getTextRange(), icon, Pass.UPDATE_OVERRIDDEN_MARKERS, type.getTooltip(),
LineMarkerInfo info = new LineMarkerInfo<>(range, range.getTextRange(), icon, Pass.LINE_MARKERS, type.getTooltip(),
type.getNavigationHandler(), GutterIconRenderer.Alignment.RIGHT);
result.add(info);
}
@@ -33,7 +33,6 @@ import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.Function;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory;
@@ -72,7 +71,7 @@ public class JavaFxRelatedItemLineMarkerProvider extends RelatedItemLineMarkerPr
if (targets.isEmpty()) return;
result.add(new RelatedItemLineMarkerInfo<PsiField>(field, field.getNameIdentifier().getTextRange(),
AllIcons.FileTypes.Xml, Pass.UPDATE_OVERRIDDEN_MARKERS, null,
AllIcons.FileTypes.Xml, Pass.LINE_MARKERS, null,
new JavaFXIdIconNavigationHandler(), GutterIconRenderer.Alignment.LEFT,
targets));
}
@@ -60,7 +60,7 @@ public class PyExecuteFileLineMarkerProvider implements LineMarkerProvider {
Icon icon = PlatformUtils.isPyCharmEducational() ? AllIcons.Actions.Execute : actions.get(0).getTemplatePresentation().getIcon();
final LineMarkerInfo<PsiElement> markerInfo = new LineMarkerInfo<PsiElement>(
file, file.getTextRange(), icon, Pass.UPDATE_OVERRIDDEN_MARKERS,
file, file.getTextRange(), icon, Pass.LINE_MARKERS,
e -> {
String text = "Execute '" + e.getContainingFile().getName() + "'";
return PlatformUtils.isPyCharmEducational() ? text : actions.get(0).getTemplatePresentation().getText();
@@ -25,7 +25,6 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.CollectionQuery;
import com.intellij.util.Function;
import com.intellij.util.Processor;
import com.intellij.util.Query;
import com.intellij.util.containers.HashSet;
import com.intellij.util.containers.MultiMap;
@@ -180,7 +179,7 @@ public class PyLineMarkerProvider implements LineMarkerProvider, PyLineSeparator
}
// TODO: show "implementing" instead of "overriding" icon for Python implementations of Java interface methods
return new LineMarkerInfo<PsiElement>(element, element.getTextRange().getStartOffset(), AllIcons.Gutter.OverridingMethod,
Pass.UPDATE_ALL,
Pass.LINE_MARKERS,
superClass == null ? null : new TooltipProvider("Overrides method in " + superClass.getName()),
ourSuperMethodNavigator);
}
@@ -200,7 +199,7 @@ public class PyLineMarkerProvider implements LineMarkerProvider, PyLineSeparator
final PyTargetExpression ancestorAttr = ancestor.findClassAttribute(name, false, null);
if (ancestorAttr != null) {
return new LineMarkerInfo<PsiElement>(element, element.getTextRange().getStartOffset(),
AllIcons.Gutter.OverridingMethod, Pass.UPDATE_ALL,
AllIcons.Gutter.OverridingMethod, Pass.LINE_MARKERS,
new TooltipProvider("Overrides attribute in " + ancestor.getName()),
ourSuperAttributeNavigator);
}
@@ -224,7 +223,7 @@ public class PyLineMarkerProvider implements LineMarkerProvider, PyLineSeparator
private static void collectInheritingClasses(final PyClass element, final Collection<LineMarkerInfo> result) {
if (PyClassInheritorsSearch.search(element, false).findFirst() != null) {
result
.add(new LineMarkerInfo<PyClass>(element, element.getTextOffset(), AllIcons.Gutter.OverridenMethod, Pass.UPDATE_OVERRIDDEN_MARKERS,
.add(new LineMarkerInfo<PyClass>(element, element.getTextOffset(), AllIcons.Gutter.OverridenMethod, Pass.LINE_MARKERS,
ourSubclassTooltipProvider, ourSubclassNavigator));
}
}
@@ -254,7 +253,7 @@ public class PyLineMarkerProvider implements LineMarkerProvider, PyLineSeparator
if (candidates.isEmpty()) break;
}
for (PyFunction func : overridden) {
result.add(new LineMarkerInfo<PyFunction>(func, func.getTextOffset(), AllIcons.Gutter.OverridenMethod, Pass.UPDATE_OVERRIDDEN_MARKERS,
result.add(new LineMarkerInfo<PyFunction>(func, func.getTextOffset(), AllIcons.Gutter.OverridenMethod, Pass.LINE_MARKERS,
ourOverridingMethodTooltipProvider,
ourOverridingMethodNavigator));
}
@@ -68,7 +68,7 @@ public class PyLineSeparatorUtil {
}
private static LineMarkerInfo<PsiElement> createLineSeparatorByElement(final PsiElement element) {
final LineMarkerInfo<PsiElement> info = new LineMarkerInfo<PsiElement>(element, element.getTextRange().getStartOffset(), null, Pass.UPDATE_ALL, null, null);
final LineMarkerInfo<PsiElement> info = new LineMarkerInfo<PsiElement>(element, element.getTextRange().getStartOffset(), null, Pass.LINE_MARKERS, null, null);
info.separatorColor = EditorColorsManager.getInstance().getGlobalScheme().getColor(CodeInsightColors.METHOD_SEPARATORS_COLOR);
info.separatorPlacement = SeparatorPlacement.TOP;
return info;
@@ -22,7 +22,6 @@ import com.intellij.codeInsight.daemon.LineMarkerProvider;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.psi.PsiElement;
import com.intellij.util.Function;
import com.intellij.util.PsiNavigateUtil;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.psi.PyFunction;
@@ -54,7 +53,7 @@ public class PyUserSkeletonsLineMarkerProvider implements LineMarkerProvider {
final PyElement skeleton = getUserSkeleton(element);
if (skeleton != null) {
result.add(new LineMarkerInfo<PsiElement>(
element, element.getTextRange(), ICON, Pass.UPDATE_OVERRIDDEN_MARKERS,
element, element.getTextRange(), ICON, Pass.LINE_MARKERS,
e -> "Has user skeleton",
new GutterIconNavigationHandler<PsiElement>() {
@Override
@@ -23,7 +23,6 @@ import com.intellij.icons.AllIcons;
import com.intellij.navigation.GotoRelatedItem;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.psi.PsiElement;
import com.intellij.util.Function;
import com.intellij.util.PsiNavigateUtil;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.psi.PyFunction;
@@ -50,7 +49,7 @@ public class PyiRelatedItemLineMarkerProvider extends RelatedItemLineMarkerProvi
if (pythonStub != null) {
final List<GotoRelatedItem> relatedItems = GotoRelatedItem.createItems(Collections.singletonList(pythonStub));
result.add(new RelatedItemLineMarkerInfo<PsiElement>(
element, element.getTextRange(), ICON, Pass.UPDATE_OVERRIDDEN_MARKERS,
element, element.getTextRange(), ICON, Pass.LINE_MARKERS,
element1 -> "Has stub item in " + pythonStub.getContainingFile().getName(), new GutterIconNavigationHandler<PsiElement>() {
@Override
public void navigate(MouseEvent e, PsiElement elt) {
@@ -191,7 +191,7 @@ public class NavigationGutterIconBuilder<T> {
final String tooltip = renderer.getTooltipText();
NotNullLazyValue<Collection<? extends GotoRelatedItem>> gotoTargets = createGotoTargetsThunk(myLazy, myGotoRelatedItemProvider,
evaluateAndForget(myTargets));
return new RelatedItemLineMarkerInfo<PsiElement>(element, element.getTextRange(), renderer.getIcon(), Pass.UPDATE_OVERRIDDEN_MARKERS,
return new RelatedItemLineMarkerInfo<PsiElement>(element, element.getTextRange(), renderer.getIcon(), Pass.LINE_MARKERS,
tooltip == null ? null : new ConstantFunction<PsiElement, String>(tooltip),
renderer.isNavigateAction() ? renderer : null, renderer.getAlignment(),
gotoTargets);
@@ -176,8 +176,6 @@ public abstract class HighlightingTestBase extends UsefulTestCase implements Ide
Pass.POPUP_HINTS,
Pass.UPDATE_ALL,
Pass.UPDATE_FOLDING,
Pass.UPDATE_OVERRIDDEN_MARKERS,
Pass.VISIBLE_LINE_MARKERS,
} : new int[]{Pass.EXTERNAL_TOOLS};
return CodeInsightTestFixtureImpl.instantiateAndRun(myTestFixture.getFile(), editor, ignore, false);
}