From 14037f099cf46bec532de34cd2bf6434f51335f9 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 14 Jul 2016 13:40:28 +0200 Subject: [PATCH] correctly find usages of overridden Java method through synthetic accessors #KT-12869 Fixed --- ...KotlinOverridingMethodReferenceSearcher.kt | 25 ++++++++++++++----- .../OverriddenMethodSyntheticAccessor.0.java | 10 ++++++++ .../OverriddenMethodSyntheticAccessor.1.kt | 4 +++ ...rriddenMethodSyntheticAccessor.results.txt | 2 ++ .../findUsages/FindUsagesTestGenerated.java | 6 +++++ 5 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.0.java create mode 100644 idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.1.kt create mode 100644 idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.results.txt diff --git a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinOverridingMethodReferenceSearcher.kt b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinOverridingMethodReferenceSearcher.kt index 4ea33a82574..dbe49f297f7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinOverridingMethodReferenceSearcher.kt +++ b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinOverridingMethodReferenceSearcher.kt @@ -25,6 +25,7 @@ import com.intellij.psi.search.searches.MethodReferencesSearch import com.intellij.util.Processor import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.idea.references.KtSimpleNameReference +import org.jetbrains.kotlin.idea.references.SyntheticPropertyAccessorReference import org.jetbrains.kotlin.idea.references.readWriteAccess import org.jetbrains.kotlin.idea.search.restrictToKotlinSources import org.jetbrains.kotlin.idea.util.runReadActionInSmartMode @@ -67,17 +68,29 @@ class KotlinOverridingMethodReferenceSearcher : MethodUsagesSearcher() { strictSignatureSearch: Boolean): MethodTextOccurrenceProcessor { return object: MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, *methods) { override fun processInexactReference(ref: PsiReference, refElement: PsiElement?, method: PsiMethod, consumer: Processor): Boolean { - if (refElement !is KtCallableDeclaration) return true + val isGetter = JvmAbi.isGetterName(method.name) + + fun isWrongAccessorReference(): Boolean { + if (ref is KtSimpleNameReference) { + val readWriteAccess = ref.expression.readWriteAccess(true) + return readWriteAccess.isRead != isGetter && readWriteAccess.isWrite == isGetter + } + if (ref is SyntheticPropertyAccessorReference) { + return (ref is SyntheticPropertyAccessorReference.Getter) != isGetter + } + return false + } + + if (refElement !is KtCallableDeclaration) { + if (isWrongAccessorReference()) return true + return super.processInexactReference(ref, refElement, method, consumer) + } var lightMethods = refElement.toLightMethods() .filterNot { it.hasModifierProperty(PsiModifier.FINAL) } .ifEmpty { return true } if (refElement is KtProperty || refElement is KtParameter) { - val isGetter = JvmAbi.isGetterName(method.name) - if (ref is KtSimpleNameReference) { - val readWriteAccess = ref.expression.readWriteAccess(true) - if (readWriteAccess.isRead != isGetter && readWriteAccess.isWrite == isGetter) return true - } + if (isWrongAccessorReference()) return true lightMethods = lightMethods.filter { JvmAbi.isGetterName(it.name) == isGetter } } diff --git a/idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.0.java b/idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.0.java new file mode 100644 index 00000000000..ee942bf2250 --- /dev/null +++ b/idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.0.java @@ -0,0 +1,10 @@ +// PSI_ELEMENT: com.intellij.psi.PsiMethod +// OPTIONS: usages +public interface AI { + String getFoo(); + + public class A implements AI { + @Override + public String getFoo() {return "";} + } +} diff --git a/idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.1.kt b/idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.1.kt new file mode 100644 index 00000000000..10e551503cc --- /dev/null +++ b/idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.1.kt @@ -0,0 +1,4 @@ +fun AI.A.bar() { + getFoo() // Found + foo // Not found +} diff --git a/idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.results.txt b/idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.results.txt new file mode 100644 index 00000000000..2326dd3fcb4 --- /dev/null +++ b/idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.results.txt @@ -0,0 +1,2 @@ +Function call 2 getFoo() // Found +Value read 3 foo // Not found diff --git a/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java b/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java index add77406acd..e8c57c58477 100644 --- a/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java @@ -1452,6 +1452,12 @@ public class FindUsagesTestGenerated extends AbstractFindUsagesTest { doTest(fileName); } + @TestMetadata("OverriddenMethodSyntheticAccessor.0.java") + public void testOverriddenMethodSyntheticAccessor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/findUsages/java/findJavaMethodUsages/OverriddenMethodSyntheticAccessor.0.java"); + doTest(fileName); + } + @TestMetadata("SyntheticProperties.0.java") public void testSyntheticProperties() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.0.java");