diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt
index 15da526d4d4..140ac09deda 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt
@@ -28,21 +28,6 @@ import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
-/**
- * Checks if the function call is an implicit invoke call with a simple qualified receiver, or looks like it.
- *
- * For example, `foo()` and `foo.bar()` have simple qualified receivers, while `foo!!()`, `{}()` and `(foo ?: bar)()` - don't.
- *
- * @return `true` if the function call has a simple qualified receiver and is an implicit invoke call,
- * or looks like it and resolves to the `invoke` function.
- */
-fun FirFunctionCall.isImplicitFunctionCall(): Boolean {
- if (extensionReceiver !is FirQualifiedAccessExpression && dispatchReceiver !is FirQualifiedAccessExpression) return false
-
- return this is FirImplicitInvokeCall ||
- calleeReference.getCandidateSymbols().any(FirBasedSymbol<*>::isInvokeFunction)
-}
-
/**
* Returns `true` if the symbol is for a function named `invoke`.
*/
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt
index fc3cd029df2..69ca1314f6c 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt
@@ -340,19 +340,13 @@ internal object FirReferenceResolveHelper {
if (expression is KtLabelReferenceExpression && fir is FirPropertyAccessExpression && fir.calleeReference is FirSuperReference) {
return listOfNotNull((fir.dispatchReceiver.typeRef as? FirResolvedTypeRef)?.toTargetSymbol(session, symbolBuilder))
}
- val calleeReference =
- if (fir is FirFunctionCall &&
- fir.isImplicitFunctionCall() &&
- expression is KtNameReferenceExpression
- ) {
- // we are resolving implicit invoke call, like
- // fun foo(a: () -> Unit) {
- // a()
- // }
- val receiver =
- fir.dispatchReceiver as? FirQualifiedAccessExpression ?: fir.extensionReceiver as FirQualifiedAccessExpression
- receiver.calleeReference
- } else fir.calleeReference
+ val implicitInvokeReceiver = if (fir is FirImplicitInvokeCall) {
+ fir.explicitReceiver as? FirQualifiedAccessExpression
+ } else {
+ null
+ }
+ val calleeReference = implicitInvokeReceiver?.calleeReference ?: fir.calleeReference
+
return calleeReference.toTargetSymbol(session, symbolBuilder, isInLabelReference = expression is KtLabelReferenceExpression)
}
diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirLibrarySourceReferenceResolveTestGenerated.java b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirLibrarySourceReferenceResolveTestGenerated.java
index 2629b03f648..e14e7ff1929 100644
--- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirLibrarySourceReferenceResolveTestGenerated.java
+++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirLibrarySourceReferenceResolveTestGenerated.java
@@ -142,6 +142,18 @@ public class FirLibrarySourceReferenceResolveTestGenerated extends AbstractRefer
runTest("analysis/analysis-api/testData/referenceResolve/EnumValues.kt");
}
+ @Test
+ @TestMetadata("explicitFunctionalInterfaceInvoke_globalVal.kt")
+ public void testExplicitFunctionalInterfaceInvoke_globalVal() throws Exception {
+ runTest("analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_globalVal.kt");
+ }
+
+ @Test
+ @TestMetadata("explicitFunctionalInterfaceInvoke_parameter.kt")
+ public void testExplicitFunctionalInterfaceInvoke_parameter() throws Exception {
+ runTest("analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_parameter.kt");
+ }
+
@Test
@TestMetadata("ExternalCompanionObject.kt")
public void testExternalCompanionObject() throws Exception {
@@ -508,6 +520,12 @@ public class FirLibrarySourceReferenceResolveTestGenerated extends AbstractRefer
runTest("analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor3.kt");
}
+ @Test
+ @TestMetadata("TopLevelObjectVsLocalClassConstructor4.kt")
+ public void testTopLevelObjectVsLocalClassConstructor4() throws Exception {
+ runTest("analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor4.kt");
+ }
+
@Test
@TestMetadata("TopLevelObjectVsLocalClassQualifier.kt")
public void testTopLevelObjectVsLocalClassQualifier() throws Exception {
diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirSourceReferenceResolveTestGenerated.java b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirSourceReferenceResolveTestGenerated.java
index c9f9c1bb1ae..66976ba111e 100644
--- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirSourceReferenceResolveTestGenerated.java
+++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirSourceReferenceResolveTestGenerated.java
@@ -142,6 +142,18 @@ public class FirSourceReferenceResolveTestGenerated extends AbstractReferenceRes
runTest("analysis/analysis-api/testData/referenceResolve/EnumValues.kt");
}
+ @Test
+ @TestMetadata("explicitFunctionalInterfaceInvoke_globalVal.kt")
+ public void testExplicitFunctionalInterfaceInvoke_globalVal() throws Exception {
+ runTest("analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_globalVal.kt");
+ }
+
+ @Test
+ @TestMetadata("explicitFunctionalInterfaceInvoke_parameter.kt")
+ public void testExplicitFunctionalInterfaceInvoke_parameter() throws Exception {
+ runTest("analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_parameter.kt");
+ }
+
@Test
@TestMetadata("ExternalCompanionObject.kt")
public void testExternalCompanionObject() throws Exception {
@@ -508,6 +520,12 @@ public class FirSourceReferenceResolveTestGenerated extends AbstractReferenceRes
runTest("analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor3.kt");
}
+ @Test
+ @TestMetadata("TopLevelObjectVsLocalClassConstructor4.kt")
+ public void testTopLevelObjectVsLocalClassConstructor4() throws Exception {
+ runTest("analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor4.kt");
+ }
+
@Test
@TestMetadata("TopLevelObjectVsLocalClassQualifier.kt")
public void testTopLevelObjectVsLocalClassQualifier() throws Exception {
diff --git a/analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor3.kt b/analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor3.kt
index c019a32b517..2d193ba432a 100644
--- a/analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor3.kt
+++ b/analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor3.kt
@@ -1,5 +1,3 @@
-// IGNORE_FIR
-
package test
object Conflict {
diff --git a/analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor4.kt b/analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor4.kt
new file mode 100644
index 00000000000..99897beaaa2
--- /dev/null
+++ b/analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor4.kt
@@ -0,0 +1,12 @@
+package test
+
+object Conflict
+
+operator fun Conflict.invoke() {}
+
+fun test() {
+ class Conflict(i: Int)
+
+ Conflict()
+}
+
diff --git a/analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor4.txt b/analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor4.txt
new file mode 100644
index 00000000000..a8a48eb0432
--- /dev/null
+++ b/analysis/analysis-api/testData/referenceResolve/TopLevelObjectVsLocalClassConstructor4.txt
@@ -0,0 +1,2 @@
+Resolved to:
+0: (in test) operator fun test.Conflict.invoke()
diff --git a/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_globalVal.kt b/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_globalVal.kt
new file mode 100644
index 00000000000..9529b77801c
--- /dev/null
+++ b/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_globalVal.kt
@@ -0,0 +1,9 @@
+fun interface A {
+ operator fun invoke()
+}
+
+val globalA: A = A {}
+
+fun foo() {
+ globalA.invoke()
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_globalVal.txt b/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_globalVal.txt
new file mode 100644
index 00000000000..0f2a2440d5c
--- /dev/null
+++ b/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_globalVal.txt
@@ -0,0 +1,2 @@
+Resolved to:
+0: (in A) operator fun invoke()
diff --git a/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_parameter.kt b/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_parameter.kt
new file mode 100644
index 00000000000..9b86b24818b
--- /dev/null
+++ b/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_parameter.kt
@@ -0,0 +1,7 @@
+fun interface A {
+ operator fun invoke()
+}
+
+fun foo(param: A) {
+ param.invoke()
+}
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_parameter.txt b/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_parameter.txt
new file mode 100644
index 00000000000..0f2a2440d5c
--- /dev/null
+++ b/analysis/analysis-api/testData/referenceResolve/explicitFunctionalInterfaceInvoke_parameter.txt
@@ -0,0 +1,2 @@
+Resolved to:
+0: (in A) operator fun invoke()