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 905014f23f0..082f4e9ba51 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 @@ -145,7 +145,7 @@ internal class KtFe10CallResolver( get() = analysisSession.token override fun resolveCall(psi: KtElement): KtCallInfo? = with(analysisContext.analyze(psi, AnalysisMode.PARTIAL_WITH_DIAGNOSTICS)) { - if (psi.isNotResolvable()) return null + if (!canBeResolvedAsCall(psi)) return null val parentBinaryExpression = psi.parentOfType() val lhs = KtPsiUtil.deparenthesize(parentBinaryExpression?.left) @@ -177,7 +177,7 @@ internal class KtFe10CallResolver( override fun collectCallCandidates(psi: KtElement): List = with(analysisContext.analyze(psi, AnalysisMode.PARTIAL_WITH_DIAGNOSTICS)) { - if (psi.isNotResolvable()) return emptyList() + if (!canBeResolvedAsCall(psi)) return emptyList() val resolvedKtCallInfo = resolveCall(psi) val bestCandidateDescriptors = 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 47f328f328e..8b4029365b0 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,34 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated extends A } } + @Nested + @TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls") + @TestDataPath("$PROJECT_ROOT") + public class NonCalls { + @Test + public void testAllFilesPresentInNonCalls() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("ifExpression.kt") + public void testIfExpression() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.kt"); + } + + @Test + @TestMetadata("literalExpression.kt") + public void testLiteralExpression() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.kt"); + } + + @Test + @TestMetadata("whenExpression.kt") + public void testWhenExpression() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.kt"); + } + } + @Nested @TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/withTestCompilerPluginEnabled") @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 11646a8066d..fe3087348fb 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 @@ -86,18 +86,20 @@ internal class KtFirCallResolver( result } - override fun resolveCall(psi: KtElement): KtCallInfo? = wrapError(psi) { - val ktCallInfos = getCallInfo(psi) { psiToResolve, resolveCalleeExpressionOfFunctionCall, resolveFragmentOfCall -> - listOfNotNull( - toKtCallInfo( - psiToResolve, - resolveCalleeExpressionOfFunctionCall, - resolveFragmentOfCall + override fun resolveCall(psi: KtElement): KtCallInfo? { + return wrapError(psi) { + val ktCallInfos = getCallInfo(psi) { psiToResolve, resolveCalleeExpressionOfFunctionCall, resolveFragmentOfCall -> + listOfNotNull( + toKtCallInfo( + psiToResolve, + resolveCalleeExpressionOfFunctionCall, + resolveFragmentOfCall + ) ) - ) + } + check(ktCallInfos.size <= 1) { "Should only return 1 KtCallInfo" } + ktCallInfos.singleOrNull() } - check(ktCallInfos.size <= 1) { "Should only return 1 KtCallInfo" } - ktCallInfos.singleOrNull() } private inline fun getCallInfo( @@ -108,7 +110,7 @@ internal class KtFirCallResolver( resolveFragmentOfCall: Boolean ) -> List ): List { - if (psi.isNotResolvable()) return emptyList() + if (!canBeResolvedAsCall(psi)) return emptyList() val containingCallExpressionForCalleeExpression = psi.getContainingCallExpressionForCalleeExpression() val containingBinaryExpressionForLhs = psi.getContainingBinaryExpressionForIncompleteLhs() 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 f269761c4ef..7fb53629423 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,34 @@ public class FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated extends Ab } } + @Nested + @TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls") + @TestDataPath("$PROJECT_ROOT") + public class NonCalls { + @Test + public void testAllFilesPresentInNonCalls() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("ifExpression.kt") + public void testIfExpression() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.kt"); + } + + @Test + @TestMetadata("literalExpression.kt") + public void testLiteralExpression() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.kt"); + } + + @Test + @TestMetadata("whenExpression.kt") + public void testWhenExpression() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.kt"); + } + } + @Nested @TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/withTestCompilerPluginEnabled") @TestDataPath("$PROJECT_ROOT") diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/AbstractKtCallResolver.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/AbstractKtCallResolver.kt index 97600d1c640..815cb6342a9 100644 --- a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/AbstractKtCallResolver.kt +++ b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/AbstractKtCallResolver.kt @@ -45,17 +45,19 @@ abstract class AbstractKtCallResolver : KtCallResolver() { return KtPsiUtil.deparenthesize(safeQualifiedExpression.receiverExpression) == KtPsiUtil.deparenthesize(this) } + protected fun canBeResolvedAsCall(ktElement: KtElement): Boolean = when (ktElement) { + is KtBinaryExpression -> ktElement.operationToken !in nonCallBinaryOperator + is KtOperationReferenceExpression -> ktElement.operationSignTokenType !in nonCallBinaryOperator + is KtCallElement -> true + is KtConstructorCalleeExpression -> true + is KtDotQualifiedExpression -> true + is KtNameReferenceExpression -> true + is KtOperationExpression -> true + is KtArrayAccessExpression -> true + else -> false + } + protected companion object { private val nonCallBinaryOperator: Set = setOf(KtTokens.ELVIS, KtTokens.EQEQEQ, KtTokens.EXCLEQEQEQ) - - /** - * We don't want to resolve the operators from the [AbstractKtCallResolver.nonCallBinaryOperator] list, because it's either - * not possible or not desirable. - */ - fun KtElement.isNotResolvable(): Boolean { - return this is KtBinaryExpression && operationToken in nonCallBinaryOperator || - this is KtOperationReferenceExpression && operationSignTokenType in nonCallBinaryOperator - } - } } \ No newline at end of file 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 25cb9c5aa8e..ca5b21ad062 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 @@ -853,4 +853,32 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated ext runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/assignments/insidePlusAssignTarget.kt"); } } + + @Nested + @TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls") + @TestDataPath("$PROJECT_ROOT") + public class NonCalls { + @Test + public void testAllFilesPresentInNonCalls() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls"), Pattern.compile("^(.+)\\.kt$"), null, true, "withTestCompilerPluginEnabled"); + } + + @Test + @TestMetadata("ifExpression.kt") + public void testIfExpression() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.kt"); + } + + @Test + @TestMetadata("literalExpression.kt") + public void testLiteralExpression() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.kt"); + } + + @Test + @TestMetadata("whenExpression.kt") + public void testWhenExpression() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.kt"); + } + } } diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.kt new file mode 100644 index 00000000000..84be83c0ca5 --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.kt @@ -0,0 +1,3 @@ +fun main() { + val x = if (true) 1 else 2 +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.txt new file mode 100644 index 00000000000..19765bd501b --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/ifExpression.txt @@ -0,0 +1 @@ +null diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.kt new file mode 100644 index 00000000000..02b537dcdef --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.kt @@ -0,0 +1,3 @@ +fun main() { + val x = 1 +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.txt new file mode 100644 index 00000000000..19765bd501b --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/literalExpression.txt @@ -0,0 +1 @@ +null diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.kt new file mode 100644 index 00000000000..cf324aef57c --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.kt @@ -0,0 +1,3 @@ +fun main() { + val x = when (true) { else -> 2 } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.txt new file mode 100644 index 00000000000..19765bd501b --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/nonCalls/whenExpression.txt @@ -0,0 +1 @@ +null diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.txt index 3b4bc902b98..02441791a38 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvedSuperReference.txt @@ -1,3 +1,3 @@ KtErrorCallInfo: candidateCalls = [] - diagnostic = ERROR + diagnostic = ERROR \ No newline at end of file