From d33e64b383b9a542b362770b6e65453067f63c39 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 5 Nov 2012 16:49:11 +0100 Subject: [PATCH] IDEA-70470 "Highlight usages of element at caret" setting doesn't work nicely with static imports --- .../HighlightUsagesHandlerTest.groovy | 31 ++++++++- .../impl/IdentifierHighlighterPass.java | 67 ++++++++++++------- .../IdentifierHighlighterPassFactory.java | 11 +-- 3 files changed, 76 insertions(+), 33 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerTest.groovy index bdf29f475f6b..7fc39a366819 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerTest.groovy @@ -1,8 +1,9 @@ package com.intellij.codeInsight.highlighting; import com.intellij.JavaTestUtil -import com.intellij.codeInspection.sillyAssignment.SillyAssignmentInspection; -import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.codeInsight.daemon.impl.IdentifierHighlighterPassFactory +import com.intellij.codeInspection.sillyAssignment.SillyAssignmentInspection +import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NonNls; @@ -185,6 +186,32 @@ class Bar { assertRangeText 'foo', 'foo', 'foo' //import highlighted twice: for each overloaded usage target } + public void "test identifier highlighter for static imports"() { + myFixture.addClass(""" +class Foo { + static void foo(int a) {} + static void foo(int a, int b) {} +}""") + myFixture.configureByText 'Bar.java', ''' +import static Foo.foo; + +class Bar { + { + foo(1); + } +} +''' + IdentifierHighlighterPassFactory.ourTestingIdentifierHighlighting = true + try { + def infos = myFixture.doHighlighting() + //import highlighted twice: for each overloaded usage target + assert infos.findAll { it.severity == HighlightSeverity.INFORMATION && myFixture.file.text.substring(it.startOffset, it.endOffset) == 'foo' }.size() == 3 + } + finally { + IdentifierHighlighterPassFactory.ourTestingIdentifierHighlighting = false + } + } + @Override protected String getBasePath() { return JavaTestUtil.relativeJavaTestDataPath diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java index 0271381014e6..ec81144977cf 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java @@ -39,10 +39,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiReference; +import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; @@ -110,31 +107,49 @@ public class IdentifierHighlighterPass extends TextEditorHighlightingPass { } if (myTarget != null) { - final ReadWriteAccessDetector detector = ReadWriteAccessDetector.findDetector(myTarget); - final FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(myTarget.getProject())).getFindUsagesManager(); - final FindUsagesHandler findUsagesHandler = findUsagesManager.getFindUsagesHandler(myTarget, true); - final LocalSearchScope scope = new LocalSearchScope(myFile); - Collection refs = findUsagesHandler != null - ? findUsagesHandler.findReferencesToHighlight(myTarget, scope) - : ReferencesSearch.search(myTarget, scope).findAll(); - for (PsiReference psiReference : refs) { - final List textRanges = HighlightUsagesHandler.getRangesToHighlight(psiReference); - if (detector == null || detector.getReferenceAccess(myTarget, psiReference) == ReadWriteAccessDetector.Access.Read) { - myReadAccessRanges.addAll(textRanges); - } - else { - myWriteAccessRanges.addAll(textRanges); + highlightTargetUsages(myTarget); + } else { + PsiReference ref = TargetElementUtilBase.findReference(myEditor); + if (ref instanceof PsiPolyVariantReference) { + ResolveResult[] results = ((PsiPolyVariantReference)ref).multiResolve(false); + if (results.length > 0) { + for (ResolveResult result : results) { + PsiElement target = result.getElement(); + if (target != null) { + highlightTargetUsages(target); + } + } } } - final TextRange declRange = HighlightUsagesHandler.getNameIdentifierRange(myFile, myTarget); - if (declRange != null) { - if (detector != null && detector.isDeclarationWriteAccess(myTarget)) { - myWriteAccessRanges.add(declRange); - } - else { - myReadAccessRanges.add(declRange); - } + } + } + + private void highlightTargetUsages(@NotNull PsiElement target) { + final ReadWriteAccessDetector detector = ReadWriteAccessDetector.findDetector(target); + final FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(target.getProject())).getFindUsagesManager(); + final FindUsagesHandler findUsagesHandler = findUsagesManager.getFindUsagesHandler(target, true); + final LocalSearchScope scope = new LocalSearchScope(myFile); + Collection refs = findUsagesHandler != null + ? findUsagesHandler.findReferencesToHighlight(target, scope) + : ReferencesSearch.search(target, scope).findAll(); + for (PsiReference psiReference : refs) { + final List textRanges = HighlightUsagesHandler.getRangesToHighlight(psiReference); + if (detector == null || detector.getReferenceAccess(target, psiReference) == ReadWriteAccessDetector.Access.Read) { + myReadAccessRanges.addAll(textRanges); + } + else { + myWriteAccessRanges.addAll(textRanges); + } + } + + final TextRange declRange = HighlightUsagesHandler.getNameIdentifierRange(myFile, target); + if (declRange != null) { + if (detector != null && detector.isDeclarationWriteAccess(target)) { + myWriteAccessRanges.add(declRange); + } + else { + myReadAccessRanges.add(declRange); } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPassFactory.java index 1e18f2e6ce6d..87ce15ff1b49 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPassFactory.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPassFactory.java @@ -32,6 +32,8 @@ import org.jetbrains.annotations.NotNull; * @author yole */ public class IdentifierHighlighterPassFactory extends AbstractProjectComponent implements TextEditorHighlightingPassFactory { + public static boolean ourTestingIdentifierHighlighting = false; + public IdentifierHighlighterPassFactory(Project project, TextEditorHighlightingPassRegistrar highlightingPassRegistrar) { super(project); highlightingPassRegistrar.registerTextEditorHighlightingPass(this, null, new int[]{Pass.UPDATE_ALL}, false, -1); @@ -41,11 +43,10 @@ public class IdentifierHighlighterPassFactory extends AbstractProjectComponent i public TextEditorHighlightingPass createHighlightingPass(@NotNull final PsiFile file, @NotNull final Editor editor) { if (editor.isOneLineMode()) return null; - if (!CodeInsightSettings.getInstance().HIGHLIGHT_IDENTIFIER_UNDER_CARET || - ApplicationManager.getApplication().isHeadlessEnvironment()) { - return null; + if (CodeInsightSettings.getInstance().HIGHLIGHT_IDENTIFIER_UNDER_CARET && + (!ApplicationManager.getApplication().isHeadlessEnvironment() || ourTestingIdentifierHighlighting)) { + return new IdentifierHighlighterPass(file.getProject(), file, editor); } - - return new IdentifierHighlighterPass(file.getProject(), file, editor); + return null; } }