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 082f4e9ba51..8a3ca76a6b3 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 @@ internal class KtFe10CallResolver( 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 @@ internal class KtFe10CallResolver( 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 8b4029365b0..e4699d4d0c0 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 @@ -854,6 +854,22 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated extends A } } + @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") 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 fe3087348fb..de4d95ceded 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.utils.addToStdlib.safeAs 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 @@ internal class KtFirCallResolver( 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 @@ internal class KtFirCallResolver( private inline fun getCallInfo( psi: KtElement, + getErrorCallInfo: FirDiagnosticHolder.(psiToResolve: KtElement) -> List, getCallInfo: FirElement.( psiToResolve: KtElement, resolveCalleeExpressionOfFunctionCall: Boolean, @@ -121,6 +130,9 @@ internal class KtFirCallResolver( ?: 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 @@ internal class KtFirCallResolver( } 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 @@ internal class KtFirCallResolver( } override fun collectCallCandidates(psi: KtElement): List = 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 @@ internal class KtFirCallResolver( } } + + 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 7fb53629423..2973fe5be7b 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 @@ -854,6 +854,22 @@ public class FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated extends Ab } } + @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") 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 ca5b21ad062..d4446354cd4 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 @@ -854,6 +854,22 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated ext } } + @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") 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 00000000000..4df71a30206 --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.kt @@ -0,0 +1,2 @@ +val commonSettings: Int = + get() = 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 00000000000..e58ddba2ff8 --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/getterAssignment.txt @@ -0,0 +1,3 @@ +KtErrorCallInfo: + candidateCalls = [] + diagnostic = ERROR