correctly find usages of overridden Java method through synthetic accessors
#KT-12869 Fixed
This commit is contained in:
+19
-6
@@ -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<PsiReference>): 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 }
|
||||
}
|
||||
|
||||
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
// PSI_ELEMENT: com.intellij.psi.PsiMethod
|
||||
// OPTIONS: usages
|
||||
public interface AI {
|
||||
String <caret>getFoo();
|
||||
|
||||
public class A implements AI {
|
||||
@Override
|
||||
public String getFoo() {return "";}
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fun AI.A.bar() {
|
||||
getFoo() // Found
|
||||
foo // Not found
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
Function call 2 getFoo() // Found
|
||||
Value read 3 foo // Not found
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user