mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
[performance] IDEA-326893 Do not trigger parsing of injected fragments from InjectedReferencesContributor
GitOrigin-RevId: 71dab268fabd42786d1330898c23fd9fe06e70ea
This commit is contained in:
committed by
intellij-monorepo-bot
parent
e6645e1a7a
commit
10167ae72d
@@ -88,6 +88,13 @@ public class FilePathReferenceProvider extends PsiReferenceProvider {
|
||||
}.getAllReferences();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsHints(@NotNull PsiElement element, PsiReferenceService.@NotNull Hints hints) {
|
||||
if (hints == PsiReferenceService.Hints.HIGHLIGHTED_REFERENCES) return false;
|
||||
|
||||
return super.acceptsHints(element, hints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsTarget(@NotNull PsiElement target) {
|
||||
return target instanceof PsiFileSystemItem || target instanceof PsiDirectoryContainer;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.lang;
|
||||
|
||||
import com.intellij.lang.annotation.Annotator;
|
||||
import com.intellij.lang.annotation.ContributedReferencesAnnotator;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.util.KeyedLazyInstance;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
public final class ContributedReferencesAnnotators extends LanguageExtension<Annotator> {
|
||||
public static final @NonNls ExtensionPointName<KeyedLazyInstance<Annotator>> EP_NAME =
|
||||
public final class ContributedReferencesAnnotators extends LanguageExtension<ContributedReferencesAnnotator> {
|
||||
public static final @NonNls ExtensionPointName<KeyedLazyInstance<ContributedReferencesAnnotator>> EP_NAME =
|
||||
ExtensionPointName.create("com.intellij.contributedReferencesAnnotator");
|
||||
|
||||
public static final ContributedReferencesAnnotators INSTANCE = new ContributedReferencesAnnotators();
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.lang.annotation;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ContributedReferencesAnnotator {
|
||||
void annotate(@NotNull PsiElement element,
|
||||
@NotNull List<PsiReference> references,
|
||||
@NotNull AnnotationHolder holder);
|
||||
}
|
||||
@@ -43,6 +43,13 @@ public abstract class PsiReferenceService {
|
||||
public static class Hints {
|
||||
public static final Hints NO_HINTS = new Hints();
|
||||
|
||||
/**
|
||||
* Passed during highlighting to query only reference providers that may provide references that should be underlined.
|
||||
*
|
||||
* @see com.intellij.codeInsight.highlighting.HighlightedReference
|
||||
*/
|
||||
public static final Hints HIGHLIGHTED_REFERENCES = new Hints();
|
||||
|
||||
public final @Nullable PsiElement target;
|
||||
public final @Nullable Integer offsetInElement;
|
||||
|
||||
|
||||
@@ -1,242 +0,0 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.daemon.impl;
|
||||
|
||||
import com.intellij.analysis.AnalysisBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder;
|
||||
import com.intellij.lang.ContributedReferencesAnnotators;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.annotation.Annotation;
|
||||
import com.intellij.lang.annotation.Annotator;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesScheme;
|
||||
import com.intellij.openapi.paths.WebReference;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
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.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
import com.intellij.util.containers.ConcurrentFactoryMap;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass.SHOULD_HIGHLIGHT_FILTER;
|
||||
|
||||
final class ContributedReferenceHighlightingPass extends ProgressableTextEditorHighlightingPass {
|
||||
final boolean myUpdateAll;
|
||||
final @NotNull ProperTextRange myPriorityRange;
|
||||
|
||||
final List<HighlightInfo> myHighlights = new ArrayList<>();
|
||||
final EditorColorsScheme myGlobalScheme;
|
||||
|
||||
ContributedReferenceHighlightingPass(@NotNull PsiFile file,
|
||||
@NotNull Document document,
|
||||
int startOffset,
|
||||
int endOffset,
|
||||
boolean updateAll,
|
||||
@NotNull ProperTextRange priorityRange,
|
||||
@Nullable Editor editor,
|
||||
@NotNull HighlightInfoProcessor highlightInfoProcessor) {
|
||||
super(file.getProject(), document, getPresentableNameText(), file, editor, TextRange.create(startOffset, endOffset), true,
|
||||
highlightInfoProcessor);
|
||||
myUpdateAll = updateAll;
|
||||
myPriorityRange = priorityRange;
|
||||
|
||||
PsiUtilCore.ensureValid(file);
|
||||
|
||||
// initial guess to show correct progress in the traffic light icon
|
||||
setProgressLimit(document.getTextLength() / 2); // approx number of PSI elements = file length/2
|
||||
myGlobalScheme = editor != null ? editor.getColorsScheme() : EditorColorsManager.getInstance().getGlobalScheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<HighlightInfo> getInfos() {
|
||||
return new ArrayList<>(myHighlights);
|
||||
}
|
||||
|
||||
private static @Nls String getPresentableNameText() {
|
||||
return AnalysisBundle.message("pass.contributed.references");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectInformationWithProgress(@NotNull ProgressIndicator progress) {
|
||||
ApplicationManager.getApplication().assertIsNonDispatchThread();
|
||||
List<HighlightInfo> resultInside = new ArrayList<>(100);
|
||||
List<HighlightInfo> resultOutside = new ArrayList<>(100);
|
||||
|
||||
List<Divider.DividedElements> allDivided = new ArrayList<>();
|
||||
Divider.divideInsideAndOutsideAllRoots(myFile, myRestrictRange, myPriorityRange, SHOULD_HIGHLIGHT_FILTER,
|
||||
new CommonProcessors.CollectProcessor<>(allDivided));
|
||||
|
||||
List<PsiElement> contributedReferenceHostsInside = allDivided.stream()
|
||||
.flatMap(d -> d.inside.stream())
|
||||
.filter(WebReference::isWebReferenceWorthy)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<PsiElement> contributedReferenceHostsOutside = allDivided.stream()
|
||||
.flatMap(d -> d.outside.stream())
|
||||
.filter(WebReference::isWebReferenceWorthy)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
setProgressLimit(contributedReferenceHostsInside.size() + contributedReferenceHostsOutside.size());
|
||||
|
||||
processContributedReferencesHosts(contributedReferenceHostsInside, highlightInfo -> {
|
||||
queueInfoToUpdateIncrementally(highlightInfo, getId());
|
||||
synchronized (myHighlights) {
|
||||
resultInside.add(highlightInfo);
|
||||
}
|
||||
});
|
||||
|
||||
boolean priorityIntersectionHasElements = myPriorityRange.intersectsStrict(myRestrictRange);
|
||||
if ((!contributedReferenceHostsInside.isEmpty() || !resultInside.isEmpty()) && priorityIntersectionHasElements) { // do not apply when there were no elements to highlight
|
||||
myHighlightInfoProcessor.highlightsInsideVisiblePartAreProduced(myHighlightingSession, getEditor(), resultInside, myPriorityRange, myRestrictRange, getId());
|
||||
}
|
||||
|
||||
processContributedReferencesHosts(contributedReferenceHostsOutside, highlightInfo -> {
|
||||
queueInfoToUpdateIncrementally(highlightInfo, getId());
|
||||
synchronized (myHighlights) {
|
||||
resultOutside.add(highlightInfo);
|
||||
}
|
||||
});
|
||||
|
||||
myHighlights.addAll(resultInside);
|
||||
myHighlights.addAll(resultOutside);
|
||||
|
||||
resultOutside.addAll(resultInside);
|
||||
|
||||
myHighlightInfoProcessor.highlightsOutsideVisiblePartAreProduced(myHighlightingSession, getEditor(),
|
||||
resultOutside, myPriorityRange,
|
||||
myRestrictRange, getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyInformationWithProgress() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
private void processContributedReferencesHosts(@NotNull List<PsiElement> contributedReferenceHosts,
|
||||
@NotNull Consumer<? super HighlightInfo> outInfos) {
|
||||
if (contributedReferenceHosts.isEmpty()) return;
|
||||
|
||||
ContributedReferencesHighlightVisitor visitor = new ContributedReferencesHighlightVisitor(myProject);
|
||||
|
||||
HighlightInfoFilter[] filters = HighlightInfoFilter.EXTENSION_POINT_NAME.getExtensions();
|
||||
EditorColorsScheme actualScheme = getColorsScheme() == null ? EditorColorsManager.getInstance().getGlobalScheme() : getColorsScheme();
|
||||
HighlightInfoHolder holder = new HighlightInfoHolder(myFile, filters) {
|
||||
@Override
|
||||
public @NotNull TextAttributesScheme getColorsScheme() {
|
||||
return actualScheme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(@Nullable HighlightInfo info) {
|
||||
boolean added = super.add(info);
|
||||
if (info != null && added) {
|
||||
outInfos.accept(info);
|
||||
}
|
||||
return added;
|
||||
}
|
||||
};
|
||||
|
||||
visitor.analyze(holder, () -> {
|
||||
for (int i = 0; i < contributedReferenceHosts.size(); i++) {
|
||||
PsiElement contributedReferenceHost = contributedReferenceHosts.get(i);
|
||||
|
||||
visitor.visit(contributedReferenceHost);
|
||||
|
||||
advanceProgress(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void queueInfoToUpdateIncrementally(@NotNull HighlightInfo info, int group) {
|
||||
myHighlightInfoProcessor.infoIsAvailable(myHighlightingSession, info, myPriorityRange, myRestrictRange, group);
|
||||
}
|
||||
}
|
||||
|
||||
final class ContributedReferencesHighlightVisitor {
|
||||
private AnnotationHolderImpl myAnnotationHolder;
|
||||
|
||||
private final Map<Language, List<Annotator>> myAnnotators;
|
||||
|
||||
private final DumbService myDumbService;
|
||||
private final boolean myBatchMode;
|
||||
private boolean myDumb;
|
||||
|
||||
ContributedReferencesHighlightVisitor(@NotNull Project project) {
|
||||
this(project, false);
|
||||
}
|
||||
|
||||
private ContributedReferencesHighlightVisitor(@NotNull Project project,
|
||||
boolean batchMode) {
|
||||
myDumbService = DumbService.getInstance(project);
|
||||
myBatchMode = batchMode;
|
||||
myAnnotators = ConcurrentFactoryMap.createMap(language -> createAnnotators(language));
|
||||
}
|
||||
|
||||
public void analyze(@NotNull HighlightInfoHolder holder, @NotNull Runnable action) {
|
||||
myDumb = myDumbService.isDumb();
|
||||
|
||||
myAnnotationHolder = new AnnotationHolderImpl(holder.getAnnotationSession(), myBatchMode) {
|
||||
@Override
|
||||
void queueToUpdateIncrementally() {
|
||||
if (!isEmpty()) {
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0; i < size(); i++) {
|
||||
Annotation annotation = get(i);
|
||||
holder.add(HighlightInfo.fromAnnotation(annotation, myBatchMode));
|
||||
}
|
||||
clear();
|
||||
}
|
||||
}
|
||||
};
|
||||
try {
|
||||
action.run();
|
||||
myAnnotationHolder.assertAllAnnotationsCreated();
|
||||
}
|
||||
finally {
|
||||
myAnnotators.clear();
|
||||
myAnnotationHolder = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(@NotNull PsiElement element) {
|
||||
runAnnotators(element);
|
||||
}
|
||||
|
||||
private void runAnnotators(@NotNull PsiElement element) {
|
||||
List<Annotator> annotators = myAnnotators.get(element.getLanguage());
|
||||
if (!annotators.isEmpty()) {
|
||||
AnnotationHolderImpl holder = myAnnotationHolder;
|
||||
holder.myCurrentElement = element;
|
||||
for (Annotator annotator : annotators) {
|
||||
if (!myDumb || DumbService.isDumbAware(annotator)) {
|
||||
ProgressManager.checkCanceled();
|
||||
holder.myCurrentAnnotator = annotator;
|
||||
annotator.annotate(element, holder);
|
||||
|
||||
holder.queueToUpdateIncrementally();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static @NotNull List<Annotator> createAnnotators(@NotNull Language language) {
|
||||
return ContributedReferencesAnnotators.INSTANCE.allForLanguageOrAny(language);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.daemon.impl;
|
||||
|
||||
import com.intellij.codeHighlighting.*;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.ProperTextRange;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
final class ContributedReferenceHighlightingPassFactory implements TextEditorHighlightingPassFactory,
|
||||
TextEditorHighlightingPassFactoryRegistrar {
|
||||
@Override
|
||||
public void registerHighlightingPassFactory(@NotNull TextEditorHighlightingPassRegistrar registrar, @NotNull Project project) {
|
||||
boolean serialized = ((TextEditorHighlightingPassRegistrarImpl)registrar).isSerializeCodeInsightPasses();
|
||||
int[] runAfterCompletionOf = serialized ? new int[]{Pass.UPDATE_ALL} : null;
|
||||
int[] runAfterStartingOf = serialized ? null : new int[]{Pass.UPDATE_ALL};
|
||||
registrar.registerTextEditorHighlightingPass(new ContributedReferenceHighlightingPassFactory(),
|
||||
runAfterCompletionOf, runAfterStartingOf, false, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull Editor editor) {
|
||||
TextRange textRange = FileStatusMap.getDirtyTextRange(editor.getDocument(), file, Pass.UPDATE_ALL);
|
||||
if (textRange == null) {
|
||||
return new ProgressableTextEditorHighlightingPass.EmptyPass(file.getProject(), editor.getDocument());
|
||||
}
|
||||
|
||||
if (Registry.is("annotate.hyperlinks.in.general.pass")) {
|
||||
return new ProgressableTextEditorHighlightingPass.EmptyPass(file.getProject(), editor.getDocument());
|
||||
}
|
||||
|
||||
ProperTextRange visibleRange = HighlightingSessionImpl.getFromCurrentIndicator(file).getVisibleRange();
|
||||
return new ContributedReferenceHighlightingPass(file, editor.getDocument(), textRange.getStartOffset(), textRange.getEndOffset(), true,
|
||||
visibleRange, editor, new DefaultHighlightInfoProcessor());
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,8 @@ package com.intellij.codeInsight.highlighting;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.lang.annotation.AnnotationBuilder;
|
||||
import com.intellij.lang.annotation.AnnotationHolder;
|
||||
import com.intellij.lang.annotation.Annotator;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.lang.ContributedReferencesAnnotators;
|
||||
import com.intellij.lang.annotation.*;
|
||||
import com.intellij.model.psi.PsiSymbolReferenceService;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
@@ -17,34 +15,31 @@ import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.paths.WebReference;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.PsiReferenceService;
|
||||
import com.intellij.psi.PsiReferenceService.Hints;
|
||||
import com.intellij.psi.util.CachedValueProvider.Result;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class HyperlinkAnnotator implements Annotator {
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public final class HyperlinkAnnotator implements Annotator {
|
||||
|
||||
private static final Key<@Nls String> messageKey = Key.create("hyperlink.message");
|
||||
|
||||
private final boolean enabled;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public HyperlinkAnnotator() {
|
||||
this(Registry.is("annotate.hyperlinks.in.general.pass"));
|
||||
}
|
||||
|
||||
public HyperlinkAnnotator(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
|
||||
if (!enabled) return;
|
||||
|
||||
if (holder.isBatchMode()) return;
|
||||
|
||||
for (PsiHighlightedReference reference : PsiSymbolReferenceService.getService().getReferences(element, PsiHighlightedReference.class)) {
|
||||
TextRange range = reference.getAbsoluteRange();
|
||||
String message = reference.highlightMessage();
|
||||
@@ -52,34 +47,72 @@ public class HyperlinkAnnotator implements Annotator {
|
||||
: holder.newAnnotation(reference.highlightSeverity(), message);
|
||||
reference.highlightReference(annotationBuilder.range(range)).create();
|
||||
}
|
||||
|
||||
if (WebReference.isWebReferenceWorthy(element)) {
|
||||
for (PsiReference reference : element.getReferences()) {
|
||||
if (reference instanceof WebReference) {
|
||||
String message = holder.getCurrentAnnotationSession().getUserData(messageKey);
|
||||
if (message == null) {
|
||||
message = getMessage();
|
||||
holder.getCurrentAnnotationSession().putUserData(messageKey, message);
|
||||
}
|
||||
TextRange range = reference.getRangeInElement().shiftRight(element.getTextRange().getStartOffset());
|
||||
holder.newAnnotation(HighlightSeverity.INFORMATION, message)
|
||||
.range(range)
|
||||
.textAttributes(CodeInsightColors.INACTIVE_HYPERLINK_ATTRIBUTES)
|
||||
.create();
|
||||
}
|
||||
else if (reference instanceof HighlightedReference) {
|
||||
if (reference.isSoft() && !((HighlightedReference)reference).isHighlightedWhenSoft()) continue;
|
||||
annotateContributedReferences(element, holder);
|
||||
}
|
||||
}
|
||||
|
||||
TextRange rangeInElement = reference.getRangeInElement();
|
||||
if (rangeInElement.isEmpty()) continue;
|
||||
private static void annotateContributedReferences(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
|
||||
List<PsiReference> references = getReferences(element);
|
||||
|
||||
TextRange range = rangeInElement.shiftRight(element.getTextRange().getStartOffset());
|
||||
holder.newSilentAnnotation(HighlightInfoType.HIGHLIGHTED_REFERENCE_SEVERITY)
|
||||
.range(range)
|
||||
.textAttributes(DefaultLanguageHighlighterColors.HIGHLIGHTED_REFERENCE)
|
||||
.create();
|
||||
if (!annotateHyperlinks(element, holder, references)) {
|
||||
return; // found web references and it is single reference there
|
||||
}
|
||||
|
||||
List<ContributedReferencesAnnotator> annotators =
|
||||
ContributedReferencesAnnotators.INSTANCE.allForLanguageOrAny(holder.getCurrentAnnotationSession().getFile().getLanguage());
|
||||
|
||||
for (ContributedReferencesAnnotator annotator : annotators) {
|
||||
annotator.annotate(element, references, holder);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PsiReference> getReferences(@NotNull PsiElement element) {
|
||||
return CachedValuesManager.getCachedValue(element, () -> {
|
||||
List<PsiReference> references = PsiReferenceService.getService().getReferences(element, Hints.HIGHLIGHTED_REFERENCES);
|
||||
if (references.isEmpty()) {
|
||||
references = Collections.emptyList();
|
||||
}
|
||||
return Result.create(references, PsiModificationTracker.MODIFICATION_COUNT);
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean annotateHyperlinks(@NotNull PsiElement element,
|
||||
@NotNull AnnotationHolder holder,
|
||||
@NotNull List<PsiReference> references) {
|
||||
for (PsiReference reference : references) {
|
||||
if (reference instanceof WebReference) {
|
||||
String message = holder.getCurrentAnnotationSession().getUserData(messageKey);
|
||||
if (message == null) {
|
||||
message = getMessage();
|
||||
holder.getCurrentAnnotationSession().putUserData(messageKey, message);
|
||||
}
|
||||
TextRange range = reference.getRangeInElement().shiftRight(element.getTextRange().getStartOffset());
|
||||
holder.newAnnotation(HighlightSeverity.INFORMATION, message)
|
||||
.range(range)
|
||||
.textAttributes(CodeInsightColors.INACTIVE_HYPERLINK_ATTRIBUTES)
|
||||
.create();
|
||||
|
||||
if (references.size() == 1) return false;
|
||||
}
|
||||
else if (reference instanceof HighlightedReference) {
|
||||
if (reference.isSoft() && !((HighlightedReference)reference).isHighlightedWhenSoft()) continue;
|
||||
|
||||
TextRange rangeInElement = reference.getRangeInElement();
|
||||
if (rangeInElement.isEmpty()) continue;
|
||||
|
||||
TextRange range = rangeInElement.shiftRight(element.getTextRange().getStartOffset());
|
||||
holder.newSilentAnnotation(HighlightInfoType.HIGHLIGHTED_REFERENCE_SEVERITY)
|
||||
.range(range)
|
||||
.textAttributes(DefaultLanguageHighlighterColors.HIGHLIGHTED_REFERENCE)
|
||||
.create();
|
||||
|
||||
if (references.size() == 1) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@@ -87,7 +120,7 @@ public class HyperlinkAnnotator implements Annotator {
|
||||
@ApiStatus.Internal
|
||||
public static String getMessage() {
|
||||
String message = IdeBundle.message("open.url.in.browser.tooltip");
|
||||
Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(IdeActions.ACTION_GOTO_DECLARATION);
|
||||
Shortcut[] shortcuts = requireNonNull(KeymapManager.getInstance()).getActiveKeymap().getShortcuts(IdeActions.ACTION_GOTO_DECLARATION);
|
||||
String shortcutText = "";
|
||||
Shortcut mouseShortcut = ContainerUtil.find(shortcuts, shortcut -> !shortcut.isKeyboard());
|
||||
if (mouseShortcut != null) {
|
||||
@@ -105,10 +138,3 @@ public class HyperlinkAnnotator implements Annotator {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
final class HyperlinkContributedReferenceAnnotator extends HyperlinkAnnotator {
|
||||
@SuppressWarnings("PublicConstructorInNonPublicClass")
|
||||
public HyperlinkContributedReferenceAnnotator() {
|
||||
super(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
</extensionPoint>
|
||||
|
||||
<extensionPoint name="contributedReferencesAnnotator" beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
|
||||
<with attribute="implementationClass" implements="com.intellij.lang.annotation.Annotator"/>
|
||||
<with attribute="implementationClass" implements="com.intellij.lang.annotation.ContributedReferencesAnnotator"/>
|
||||
</extensionPoint>
|
||||
|
||||
<extensionPoint name="externalAnnotator" beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
|
||||
|
||||
@@ -1110,8 +1110,7 @@
|
||||
|
||||
<annotator language="TEXT" implementationClass="com.intellij.codeInsight.highlighting.LargeFilesAnnotator"/>
|
||||
|
||||
<annotator language="" implementationClass="com.intellij.codeInsight.highlighting.HyperlinkAnnotator"/>
|
||||
<contributedReferencesAnnotator language="" implementationClass="com.intellij.codeInsight.highlighting.HyperlinkContributedReferenceAnnotator" order="first"/>
|
||||
<annotator language="" implementationClass="com.intellij.codeInsight.highlighting.HyperlinkAnnotator" order="last"/>
|
||||
|
||||
<problemsViewPanelProvider implementation="com.intellij.analysis.problemsView.toolWindow.ProblemsViewHighlightingPanelProvider"/>
|
||||
<problemsViewPanelProvider implementation="com.intellij.analysis.problemsView.toolWindow.ProblemsViewProjectErrorsPanelProvider"/>
|
||||
@@ -1540,14 +1539,9 @@
|
||||
<editorFactoryListener implementation="com.intellij.codeInsight.inline.completion.listeners.InlineCompletionEditorListener"/>
|
||||
<actionPromoter implementation="com.intellij.codeInsight.inline.completion.InlineActionsPromoter"/>
|
||||
|
||||
<registryKey key="annotate.hyperlinks.in.general.pass"
|
||||
defaultValue="true"
|
||||
description="Enables old behavior of HyperlinkAnnotator to run as part of GeneralHighlightingPass"/>
|
||||
|
||||
<highlightingPassFactory implementation="com.intellij.codeInsight.daemon.impl.GeneralHighlightingPassFactory"/>
|
||||
<highlightingPassFactory implementation="com.intellij.codeInsight.daemon.impl.ChameleonSyntaxHighlightingPass$Factory"/>
|
||||
<highlightingPassFactory implementation="com.intellij.codeInsight.daemon.impl.InjectedGeneralHighlightingPassFactory"/>
|
||||
<highlightingPassFactory implementation="com.intellij.codeInsight.daemon.impl.ContributedReferenceHighlightingPassFactory"/>
|
||||
<highlightingPassFactory implementation="com.intellij.codeInsight.daemon.impl.LineMarkersPassFactory"/>
|
||||
<highlightingPassFactory implementation="com.intellij.codeInsight.daemon.impl.SlowLineMarkersPassFactory"/>
|
||||
<highlightingPassFactory implementation="com.intellij.codeInsight.daemon.impl.ShowIntentionsPassFactory"/>
|
||||
|
||||
@@ -48,11 +48,19 @@ public class InjectedReferencesContributor extends PsiReferenceContributor {
|
||||
@Override
|
||||
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
|
||||
registrar.registerReferenceProvider(PlatformPatterns.psiElement(), new PsiReferenceProvider() {
|
||||
|
||||
@Override
|
||||
public PsiReference @NotNull [] getReferencesByElement(@NotNull final PsiElement element, @NotNull final ProcessingContext context) {
|
||||
return getInjectionInfo(element).first;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsHints(@NotNull PsiElement element, PsiReferenceService.@NotNull Hints hints) {
|
||||
if (hints == PsiReferenceService.Hints.HIGHLIGHTED_REFERENCES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.acceptsHints(element, hints);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassRe
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PropertiesClassReferenceContributor extends PsiReferenceContributor {
|
||||
public final class PropertiesClassReferenceContributor extends PsiReferenceContributor {
|
||||
@Override
|
||||
public void registerReferenceProviders(@NotNull final PsiReferenceRegistrar registrar) {
|
||||
JavaClassReferenceProvider CLASS_REFERENCE_PROVIDER = new JavaClassReferenceProvider() {
|
||||
@@ -38,6 +38,13 @@ public class PropertiesClassReferenceContributor extends PsiReferenceContributor
|
||||
return target instanceof PsiClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsHints(@NotNull PsiElement element, PsiReferenceService.@NotNull Hints hints) {
|
||||
if (hints == PsiReferenceService.Hints.HIGHLIGHTED_REFERENCES) return false;
|
||||
|
||||
return super.acceptsHints(element, hints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference @NotNull [] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
|
||||
String text = element.getText();
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.lang.properties.references.PropertyReference;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.PsiReferenceProvider;
|
||||
import com.intellij.psi.PsiReferenceService;
|
||||
import com.intellij.psi.impl.source.jsp.jspXml.JspXmlTagBase;
|
||||
import com.intellij.psi.templateLanguages.OuterLanguageElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -65,6 +66,13 @@ public class PropertiesReferenceProvider extends PsiReferenceProvider {
|
||||
return PsiTreeUtil.getChildOfAnyType(element, OuterLanguageElement.class, JspXmlTagBase.class) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsHints(@NotNull PsiElement element, PsiReferenceService.@NotNull Hints hints) {
|
||||
if (!myProvider.acceptsHint(hints)) return false;
|
||||
|
||||
return super.acceptsHints(element, hints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsTarget(@NotNull PsiElement target) {
|
||||
return myProvider.acceptsTarget(target);
|
||||
|
||||
@@ -41,6 +41,13 @@ public class PropertiesUastReferenceContributor extends PsiReferenceContributor
|
||||
return target instanceof PsiFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsHint(@NotNull PsiReferenceService.Hints hints) {
|
||||
if (hints == PsiReferenceService.Hints.HIGHLIGHTED_REFERENCES) return false;
|
||||
|
||||
return super.acceptsHint(hints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference @NotNull [] getReferencesForInjectionHost(@NotNull UExpression uExpression,
|
||||
@NotNull PsiLanguageInjectionHost host,
|
||||
|
||||
@@ -7,10 +7,7 @@ import com.intellij.codeInspection.restriction.StringFlowUtil;
|
||||
import com.intellij.lang.properties.references.PropertyReference;
|
||||
import com.intellij.lang.properties.references.PropertyReferenceBase;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiLanguageInjectionHost;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.UastInjectionHostReferenceProvider;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.*;
|
||||
@@ -28,6 +25,12 @@ class UastPropertiesReferenceProvider extends UastInjectionHostReferenceProvider
|
||||
return PropertyReferenceBase.isPropertyPsi(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsHint(@NotNull PsiReferenceService.Hints hints) {
|
||||
if (hints == PsiReferenceService.Hints.HIGHLIGHTED_REFERENCES) return false;
|
||||
|
||||
return super.acceptsHint(hints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference @NotNull [] getReferencesForInjectionHost(@NotNull UExpression element,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi
|
||||
|
||||
import com.intellij.psi.PsiReferenceService.Hints
|
||||
import com.intellij.util.ProcessingContext
|
||||
import org.jetbrains.uast.UElement
|
||||
|
||||
@@ -11,4 +12,6 @@ abstract class UastReferenceProvider(open val supportedUElementTypes: List<Class
|
||||
abstract fun getReferencesByElement(element: UElement, context: ProcessingContext): Array<PsiReference>
|
||||
|
||||
open fun acceptsTarget(target: PsiElement): Boolean = true
|
||||
|
||||
open fun acceptsHint(hints: Hints): Boolean = true
|
||||
}
|
||||
@@ -16,4 +16,10 @@ internal class UastReferenceProviderAdapter(private val supportedUElementTypes:
|
||||
override fun acceptsTarget(target: PsiElement): Boolean {
|
||||
return provider.acceptsTarget(target)
|
||||
}
|
||||
|
||||
override fun acceptsHints(element: PsiElement, hints: PsiReferenceService.Hints): Boolean {
|
||||
if (!provider.acceptsHint(hints)) return false
|
||||
|
||||
return super.acceptsHints(element, hints)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user