[Analysis API FIR] fix call resolution on error elements
diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10CallResolver.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10CallResolver.kt
index 082f4e9..8a3ca76 100644
--- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10CallResolver.kt
+++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10CallResolver.kt
@@ -124,6 +124,10 @@
             Errors.UNRESOLVED_REFERENCE,
         )
 
+        private val syntaxErrors = setOf(
+            Errors.ASSIGNMENT_IN_EXPRESSION_CONTEXT,
+        )
+
         val diagnosticWithResolvedCallsAtPosition1 = setOf(
             Errors.OVERLOAD_RESOLUTION_AMBIGUITY,
             Errors.NONE_APPLICABLE,
@@ -640,6 +644,7 @@
         diagnostics: Diagnostics = context.diagnostics
     ) = diagnostics.firstOrNull { diagnostic ->
         if (diagnostic.severity != Severity.ERROR) return@firstOrNull false
+        if (diagnostic.factory in syntaxErrors) return@firstOrNull true
         val isResolutionError = diagnostic.factory in resolutionFailureErrors
         val isCallArgError = diagnostic.factory in callArgErrors
         val reportedPsi = diagnostic.psiElement
diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java
index 8b40293..e4699d4 100644
--- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java
+++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java
@@ -855,6 +855,22 @@
     }
 
     @Nested
+    @TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode")
+    @TestDataPath("$PROJECT_ROOT")
+    public class InvalidCode {
+        @Test
+        public void testAllFilesPresentInInvalidCode() throws Exception {
+            KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode"), Pattern.compile("^(.+)\\.kt$"), null, true);
+        }
+
+        @Test
+        @TestMetadata("getterAssignment.kt")
+        public void testGetterAssignment() throws Exception {
+            runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.kt");
+        }
+    }
+
+    @Nested
     @TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls")
     @TestDataPath("$PROJECT_ROOT")
     public class NonCalls {
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt
index fe30873..de4d95c 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt
@@ -6,6 +6,7 @@
 package org.jetbrains.kotlin.analysis.api.fir.components
 
 import org.jetbrains.kotlin.analysis.api.calls.*
+import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic
 import org.jetbrains.kotlin.analysis.api.diagnostics.KtNonBoundToPsiErrorDiagnostic
 import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
 import org.jetbrains.kotlin.analysis.api.fir.getCandidateSymbols
@@ -71,6 +72,7 @@
 import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
 import org.jetbrains.kotlin.analysis.utils.errors.shouldIjPlatformExceptionBeRethrown
 import org.jetbrains.kotlin.analysis.utils.errors.withPsiEntry
+import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
 
 internal class KtFirCallResolver(
     override val analysisSession: KtFirAnalysisSession,
@@ -88,15 +90,21 @@
 
     override fun resolveCall(psi: KtElement): KtCallInfo? {
         return wrapError(psi) {
-            val ktCallInfos = getCallInfo(psi) { psiToResolve, resolveCalleeExpressionOfFunctionCall, resolveFragmentOfCall ->
-                listOfNotNull(
-                    toKtCallInfo(
-                        psiToResolve,
-                        resolveCalleeExpressionOfFunctionCall,
-                        resolveFragmentOfCall
+            val ktCallInfos = getCallInfo(
+                psi,
+                getErrorCallInfo = { psiToResolve ->
+                    listOf(KtErrorCallInfo(emptyList(), createKtDiagnostic(psiToResolve), token))
+                },
+                getCallInfo = { psiToResolve, resolveCalleeExpressionOfFunctionCall, resolveFragmentOfCall ->
+                    listOfNotNull(
+                        toKtCallInfo(
+                            psiToResolve,
+                            resolveCalleeExpressionOfFunctionCall,
+                            resolveFragmentOfCall
+                        )
                     )
-                )
-            }
+                }
+            )
             check(ktCallInfos.size <= 1) { "Should only return 1 KtCallInfo" }
             ktCallInfos.singleOrNull()
         }
@@ -104,6 +112,7 @@
 
     private inline fun <T> getCallInfo(
         psi: KtElement,
+        getErrorCallInfo: FirDiagnosticHolder.(psiToResolve: KtElement) -> List<T>,
         getCallInfo: FirElement.(
             psiToResolve: KtElement,
             resolveCalleeExpressionOfFunctionCall: Boolean,
@@ -121,6 +130,9 @@
             ?: containingUnaryExpressionForIncOrDec
             ?: psi
         val fir = psiToResolve.getOrBuildFir(analysisSession.firResolveSession) ?: return emptyList()
+        if (fir is FirDiagnosticHolder) {
+            return fir.getErrorCallInfo(psiToResolve)
+        }
         return fir.getCallInfo(
             psiToResolve,
             psiToResolve == containingCallExpressionForCalleeExpression,
@@ -163,8 +175,7 @@
                     }
                     is FirErrorNamedReference -> {
                         val diagnostic = calleeReference.diagnostic
-                        val ktDiagnostic = (source?.let { diagnostic.asKtDiagnostic(it, psi.toKtPsiSourceElement()) }
-                            ?: KtNonBoundToPsiErrorDiagnostic(factoryName = null, diagnostic.reason, token))
+                        val ktDiagnostic = calleeReference.createKtDiagnostic(psi)
 
                         if (diagnostic is ConeHiddenCandidateError)
                             return KtErrorCallInfo(emptyList(), ktDiagnostic, token)
@@ -793,13 +804,17 @@
     }
 
     override fun collectCallCandidates(psi: KtElement): List<KtCallCandidateInfo> = wrapError(psi) {
-        getCallInfo(psi) { psiToResolve, resolveCalleeExpressionOfFunctionCall, resolveFragmentOfCall ->
-            collectCallCandidates(
-                psiToResolve,
-                resolveCalleeExpressionOfFunctionCall,
-                resolveFragmentOfCall
-            )
-        }
+        getCallInfo(
+            psi,
+            getErrorCallInfo = { emptyList() },
+            getCallInfo = { psiToResolve, resolveCalleeExpressionOfFunctionCall, resolveFragmentOfCall ->
+                collectCallCandidates(
+                    psiToResolve,
+                    resolveCalleeExpressionOfFunctionCall,
+                    resolveFragmentOfCall
+                )
+            }
+        )
     }
 
     // TODO: Refactor common code with FirElement.toKtCallInfo() when other FirResolvables are handled
@@ -1185,4 +1200,9 @@
         }
 
     }
+
+    private fun FirDiagnosticHolder.createKtDiagnostic(psi: KtElement?): KtDiagnostic {
+        return (source?.let { diagnostic.asKtDiagnostic(it, psi?.toKtPsiSourceElement()) }
+            ?: KtNonBoundToPsiErrorDiagnostic(factoryName = null, diagnostic.reason, token))
+    }
 }
diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java
index 7fb5362..2973fe5 100644
--- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java
+++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java
@@ -855,6 +855,22 @@
     }
 
     @Nested
+    @TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode")
+    @TestDataPath("$PROJECT_ROOT")
+    public class InvalidCode {
+        @Test
+        public void testAllFilesPresentInInvalidCode() throws Exception {
+            KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode"), Pattern.compile("^(.+)\\.kt$"), null, true);
+        }
+
+        @Test
+        @TestMetadata("getterAssignment.kt")
+        public void testGetterAssignment() throws Exception {
+            runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.kt");
+        }
+    }
+
+    @Nested
     @TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls")
     @TestDataPath("$PROJECT_ROOT")
     public class NonCalls {
diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java
index ca5b21a..d444635 100644
--- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java
+++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java
@@ -855,6 +855,22 @@
     }
 
     @Nested
+    @TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode")
+    @TestDataPath("$PROJECT_ROOT")
+    public class InvalidCode {
+        @Test
+        public void testAllFilesPresentInInvalidCode() throws Exception {
+            KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode"), Pattern.compile("^(.+)\\.kt$"), null, true, "withTestCompilerPluginEnabled");
+        }
+
+        @Test
+        @TestMetadata("getterAssignment.kt")
+        public void testGetterAssignment() throws Exception {
+            runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.kt");
+        }
+    }
+
+    @Nested
     @TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls")
     @TestDataPath("$PROJECT_ROOT")
     public class NonCalls {
diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.kt
new file mode 100644
index 0000000..4df71a3
--- /dev/null
+++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.kt
@@ -0,0 +1,2 @@
+val commonSettings: Int =
+    <expr>get()</expr> = 1
\ No newline at end of file
diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.txt
new file mode 100644
index 0000000..e58ddba
--- /dev/null
+++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.txt
@@ -0,0 +1,3 @@
+KtErrorCallInfo:
+  candidateCalls = []
+  diagnostic = ERROR<ASSIGNMENT_IN_EXPRESSION_CONTEXT: Assignments are not expressions, and only expressions are allowed in this context>