diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/SyntheticPropertyAccessorReference.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/SyntheticPropertyAccessorReference.kt index 5a336fbc8f6..2a70271086a 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/SyntheticPropertyAccessorReference.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/SyntheticPropertyAccessorReference.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.references import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod import com.intellij.util.SmartList import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -47,6 +48,18 @@ sealed class SyntheticPropertyAccessorReference(expression: KtNameReferenceExpre return result } + override fun isReferenceTo(element: PsiElement?): Boolean { + if (element !is PsiMethod || !isAccessorName(element.name)) return false + return super.isReferenceTo(element) + } + + private fun isAccessorName(name: String): Boolean { + if (getter) { + return name.startsWith("get") || name.startsWith("is") + } + return name.startsWith("set") + } + override fun getRangeInElement() = TextRange(0, expression.textLength) override fun canRename() = true diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/referenceUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/referenceUtil.kt index ab3ca800d23..9dc57106298 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/referenceUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/referenceUtil.kt @@ -80,6 +80,9 @@ fun PsiReference.matchesTarget(candidateTarget: PsiElement): Boolean { is KtDestructuringDeclarationReference -> { if (candidateTarget !is KtNamedFunction && candidateTarget !is KtParameter && candidateTarget !is PsiMethod) return false } + is KtSimpleNameReference -> { + if (unwrappedCandidate is PsiMethod && !canBePsiMethodReference()) return false + } } val targets = unwrappedTargets @@ -124,6 +127,24 @@ fun PsiReference.matchesTarget(candidateTarget: PsiElement): Boolean { return false } +fun KtSimpleNameReference.canBePsiMethodReference(): Boolean { + // NOTE: Accessor references are handled separately, see SyntheticPropertyAccessorReference + if (element == (element.parent as? KtCallExpression)?.calleeExpression) return true + + val callableReference = element.getParentOfTypeAndBranch { callableReference } + if (callableReference != null) return true + + val binaryOperator = element.getParentOfTypeAndBranch { operationReference } + if (binaryOperator != null) return true + + val unaryOperator = element.getParentOfTypeAndBranch { operationReference } + if (unaryOperator != null) return true + + if (element.getNonStrictParentOfType() != null) return true + + return false +} + private fun PsiElement.isConstructorOf(unwrappedCandidate: PsiElement) = // call to Java constructor (this is PsiMethod && isConstructor && containingClass == unwrappedCandidate) || diff --git a/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.0.java b/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.0.java new file mode 100644 index 00000000000..4eb559ce720 --- /dev/null +++ b/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.0.java @@ -0,0 +1,7 @@ +// PSI_ELEMENT: com.intellij.psi.PsiMethod +// OPTIONS: usages +public class UnaryNot { + public UnaryNot not() { + return this; + } +} diff --git a/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.1.kt b/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.1.kt new file mode 100644 index 00000000000..bc1826ba337 --- /dev/null +++ b/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.1.kt @@ -0,0 +1,4 @@ +fun unaryClient() { + val u1 = UnaryNot() + val u2 = !u1 +} \ No newline at end of file diff --git a/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.log b/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.log new file mode 100644 index 00000000000..a39cf588e5f --- /dev/null +++ b/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.log @@ -0,0 +1,7 @@ +Checked type of u1 +Checked type of u2 +Resolved !u1 +Searched references to UnaryNot +Searched references to UnaryNot.not() in non-Java files +Searched references to u1 in non-Java files +Searched references to u2 in non-Java files diff --git a/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.results.txt b/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.results.txt new file mode 100644 index 00000000000..f79f41a9bdf --- /dev/null +++ b/idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.results.txt @@ -0,0 +1 @@ +Function call 3 val u2 = !u1 diff --git a/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java b/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java index 2d05e7b5f37..fb88f6553af 100644 --- a/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java @@ -1656,6 +1656,12 @@ public class FindUsagesTestGenerated extends AbstractFindUsagesTest { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/findUsages/java/findJavaMethodUsages/SyntheticProperties.0.java"); doTest(fileName); } + + @TestMetadata("UnaryNot.0.java") + public void testUnaryNot() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/findUsages/java/findJavaMethodUsages/UnaryNot.0.java"); + doTest(fileName); + } } @TestMetadata("idea/testData/findUsages/java/findJavaPropertyUsages")