diff --git a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/operators/OperatorReferenceSearcher.kt b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/operators/OperatorReferenceSearcher.kt index 69963d999c52..fff3210b2745 100644 --- a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/operators/OperatorReferenceSearcher.kt +++ b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/operators/OperatorReferenceSearcher.kt @@ -13,7 +13,10 @@ import org.jetbrains.kotlin.asJava.namedUnwrappedElement import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.base.analysis.KotlinBaseAnalysisBundle import org.jetbrains.kotlin.idea.base.psi.KotlinPsiHeuristics +import org.jetbrains.kotlin.idea.base.psi.isExpectDeclaration import org.jetbrains.kotlin.idea.base.util.restrictToKotlinSources +import org.jetbrains.kotlin.idea.search.ExpectActualUtils.actualsForExpected +import org.jetbrains.kotlin.idea.search.ExpectActualUtils.expectedDeclarationIfAny import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.forceResolveReferences import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.getReceiverTypeSearcherInfo import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions @@ -60,7 +63,14 @@ abstract class OperatorReferenceSearcher( protected fun processReferenceElement(element: TReferenceElement): Boolean { val reference = extractReference(element) ?: return true testLog { "Resolved ${logPresentation(element)}" } - return if (reference.isReferenceTo(targetDeclaration)) { + if (reference.isReferenceTo(targetDeclaration)) { + return consumer.process(reference) + } + + val currentTarget = reference.resolve() as? KtDeclaration ?: return true + if (targetDeclaration !is KtDeclaration) return true + return if ((targetDeclaration.expectedDeclarationIfAny() ?: targetDeclaration) == (currentTarget.expectedDeclarationIfAny() ?: currentTarget) + ) { consumer.process(reference) } else { true diff --git a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/AbstractFindUsagesMultiModuleFirTest.kt b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/AbstractFindUsagesMultiModuleFirTest.kt index d0a8723594dc..ad7a4f391ce3 100644 --- a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/AbstractFindUsagesMultiModuleFirTest.kt +++ b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/AbstractFindUsagesMultiModuleFirTest.kt @@ -20,13 +20,15 @@ abstract class AbstractFindUsagesMultiModuleFirTest : AbstractFindUsagesMultiMod ) } + override val ignoreLog: Boolean = true + override fun doTest(path: String) { IgnoreTests.runTestIfNotDisabledByFileDirective( getTestdataFile().toPath().resolve("directives.txt"), IgnoreTests.DIRECTIVES.IGNORE_K2, directivePosition = IgnoreTests.DirectivePosition.LAST_LINE_IN_FILE ) { - super.doTest(path) + super.doTestInternal(path) } } } \ No newline at end of file diff --git a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/FindUsagesMultiModuleFirTestGenerated.java b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/FindUsagesMultiModuleFirTestGenerated.java index 575f671c17bc..3deae8f70c47 100644 --- a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/FindUsagesMultiModuleFirTestGenerated.java +++ b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/findUsages/FindUsagesMultiModuleFirTestGenerated.java @@ -28,6 +28,16 @@ public class FindUsagesMultiModuleFirTestGenerated extends AbstractFindUsagesMul runTest("../../idea/tests/testData/multiModuleFindUsages/findActualInterface/"); } + @TestMetadata("findByConvention") + public void testFindByConvention() throws Exception { + runTest("../../idea/tests/testData/multiModuleFindUsages/findByConvention/"); + } + + @TestMetadata("findByConventionInPlatform") + public void testFindByConventionInPlatform() throws Exception { + runTest("../../idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/"); + } + @TestMetadata("findClassConstructors") public void testFindClassConstructors() throws Exception { runTest("../../idea/tests/testData/multiModuleFindUsages/findClassConstructors/"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/AbstractFindUsagesMultiModuleTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/AbstractFindUsagesMultiModuleTest.kt index 82d61281838c..bd5da288fc0f 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/AbstractFindUsagesMultiModuleTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/AbstractFindUsagesMultiModuleTest.kt @@ -7,6 +7,7 @@ import com.intellij.testFramework.UsefulTestCase import org.jetbrains.kotlin.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.findUsages.AbstractFindUsagesTest.Companion.FindUsageTestType import org.jetbrains.kotlin.idea.base.plugin.KotlinPluginMode +import org.jetbrains.kotlin.idea.base.test.IgnoreTests import org.jetbrains.kotlin.idea.base.test.InTextDirectivesUtils import org.jetbrains.kotlin.idea.multiplatform.setupMppProjectFromDirStructure import org.jetbrains.kotlin.idea.test.AbstractMultiModuleTest @@ -28,7 +29,19 @@ abstract class AbstractFindUsagesMultiModuleTest : AbstractMultiModuleTest() { file.text.contains("// ") } - protected open fun doTest(path: String) { + open val ignoreLog: Boolean = false + + open fun doTest(path: String) { + IgnoreTests.runTestIfNotDisabledByFileDirective( + getTestdataFile().toPath().resolve("directives.txt"), + IgnoreTests.DIRECTIVES.IGNORE_K1, + directivePosition = IgnoreTests.DirectivePosition.LAST_LINE_IN_FILE + ) { + doTestInternal(path) + } + } + + protected fun doTestInternal(path: String) { setupMppProjectFromDirStructure(File(path)) val virtualFile = mainFile.virtualFile!! @@ -67,6 +80,7 @@ abstract class AbstractFindUsagesMultiModuleTest : AbstractMultiModuleTest() { project, alwaysAppendFileName = true, testType = testType, + ignoreLog = ignoreLog ) } } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesMultiModuleTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesMultiModuleTestGenerated.java index 8c5f1a92395d..407c723ec59a 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesMultiModuleTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/findUsages/FindUsagesMultiModuleTestGenerated.java @@ -28,6 +28,16 @@ public class FindUsagesMultiModuleTestGenerated extends AbstractFindUsagesMultiM runTest("testData/multiModuleFindUsages/findActualInterface/"); } + @TestMetadata("findByConvention") + public void testFindByConvention() throws Exception { + runTest("testData/multiModuleFindUsages/findByConvention/"); + } + + @TestMetadata("findByConventionInPlatform") + public void testFindByConventionInPlatform() throws Exception { + runTest("testData/multiModuleFindUsages/findByConventionInPlatform/"); + } + @TestMetadata("findClassConstructors") public void testFindClassConstructors() throws Exception { runTest("testData/multiModuleFindUsages/findClassConstructors/"); diff --git a/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/common/common.kt b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/common/common.kt new file mode 100644 index 000000000000..76480e00a8d7 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/common/common.kt @@ -0,0 +1,9 @@ +// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtFunction +// OPTIONS: usages + +class DummyClass002 +expect operator fun DummyClass002.invoke() +fun testInvokeCommon(d: DummyClass002) { + d() + d.invoke() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/common/common.results.txt b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/common/common.results.txt new file mode 100644 index 000000000000..922e5a8df2dc --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/common/common.results.txt @@ -0,0 +1,6 @@ +[common.kt] Function call 8 d.invoke() +[common.kt] Implicit 'invoke' 7 d() +[js.kt] Function call 4 d.invoke() +[js.kt] Implicit 'invoke' 3 d() +[jvm.kt] Function call 4 d.invoke() +[jvm.kt] Implicit 'invoke' 3 d() \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/directives.txt b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/directives.txt new file mode 100644 index 000000000000..a8106f330558 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/directives.txt @@ -0,0 +1 @@ +// IGNORE_K1 diff --git a/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/js/js.kt b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/js/js.kt new file mode 100644 index 000000000000..2fe963fc9570 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/js/js.kt @@ -0,0 +1,5 @@ +actual operator fun DummyClass002.invoke() {} +fun testInvokeJs(d: DummyClass002) { + d() + d.invoke() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/jvm/jvm.kt b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/jvm/jvm.kt new file mode 100644 index 000000000000..6461dcf75ead --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConvention/jvm/jvm.kt @@ -0,0 +1,5 @@ +actual operator fun DummyClass002.invoke() {} +fun testInvokeJvm(d: DummyClass002) { + d() + d.invoke() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/common/common.kt b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/common/common.kt new file mode 100644 index 000000000000..eecd8087ca32 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/common/common.kt @@ -0,0 +1,6 @@ +class DummyClass002 +expect operator fun DummyClass002.invoke() +fun testInvokeCommon(d: DummyClass002) { + d() + d.invoke() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/directives.txt b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/directives.txt new file mode 100644 index 000000000000..a8106f330558 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/directives.txt @@ -0,0 +1 @@ +// IGNORE_K1 diff --git a/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/js/js.kt b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/js/js.kt new file mode 100644 index 000000000000..e3a502e564cf --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/js/js.kt @@ -0,0 +1,9 @@ +// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtFunction +// OPTIONS: usages, expected +actual operator fun DummyClass002.invoke() {} +fun testInvokeJs(d: DummyClass002) { + d() + d.invoke() +} + +// IGNORE_K1 \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/js/js.results.txt b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/js/js.results.txt new file mode 100644 index 000000000000..14f877aec68a --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/js/js.results.txt @@ -0,0 +1,6 @@ +[common.kt] Function call 5 d.invoke() +[common.kt] Implicit 'invoke' 4 d() +[js.kt] Function call 6 d.invoke() +[js.kt] Implicit 'invoke' 5 d() +[jvm.kt] Function call 4 d.invoke() +[jvm.kt] Implicit 'invoke' 3 d() \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/jvm/jvm.kt b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/jvm/jvm.kt new file mode 100644 index 000000000000..6461dcf75ead --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/multiModuleFindUsages/findByConventionInPlatform/jvm/jvm.kt @@ -0,0 +1,5 @@ +actual operator fun DummyClass002.invoke() {} +fun testInvokeJvm(d: DummyClass002) { + d() + d.invoke() +} \ No newline at end of file