From e3219cc5b6c8ad6503c8822f7240bf49a38fefa4 Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Tue, 21 Dec 2021 16:01:07 +0300 Subject: [PATCH] FIR IDE: Avoid resolving elvis operator, because it doesn't make sense There are intrinsics to which elvis operator's usages are resolved; however, we do not want to expose those intrinsics through the high-level resolve --- .../components/KtFe10CallResolver.kt | 2 ++ .../KtFe10ResolveCallTestGenerated.java | 36 +++++++++++++++++++ .../api/fir/components/KtFirCallResolver.kt | 3 +- .../FirResolveCallTestGenerated.java | 36 +++++++++++++++++++ .../base/components/AbstractKtCallResolver.kt | 13 ++++++- .../unresolvableOperator_elvis_1.kt | 5 +++ .../unresolvableOperator_elvis_1.txt | 1 + .../unresolvableOperator_elvis_2.kt | 5 +++ .../unresolvableOperator_elvis_2.txt | 1 + .../unresolvableOperator_eqeqeq_1.kt | 5 +++ .../unresolvableOperator_eqeqeq_1.txt | 1 + .../unresolvableOperator_eqeqeq_2.kt | 5 +++ .../unresolvableOperator_eqeqeq_2.txt | 1 + .../unresolvableOperator_excleqeq_1.kt | 5 +++ .../unresolvableOperator_excleqeq_1.txt | 1 + .../unresolvableOperator_excleqeq_2.kt | 5 +++ .../unresolvableOperator_excleqeq_2.txt | 1 + 17 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_1.kt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_1.txt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_2.kt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_2.txt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_1.kt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_1.txt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_2.kt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_2.txt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_1.kt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_1.txt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_2.kt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_2.txt 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 f7b75f64c51..1725f5d33de 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 @@ -119,6 +119,8 @@ 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 + val parentBinaryExpression = psi.parentOfType() val lhs = KtPsiUtil.deparenthesize(parentBinaryExpression?.left) val unwrappedPsi = KtPsiUtil.deparenthesize(psi as? KtExpression) ?: psi diff --git a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/descriptors/test/components/callResolver/KtFe10ResolveCallTestGenerated.java b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/descriptors/test/components/callResolver/KtFe10ResolveCallTestGenerated.java index bffc2936d1e..0007a4d68e0 100644 --- a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/descriptors/test/components/callResolver/KtFe10ResolveCallTestGenerated.java +++ b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/descriptors/test/components/callResolver/KtFe10ResolveCallTestGenerated.java @@ -648,6 +648,42 @@ public class KtFe10ResolveCallTestGenerated extends AbstractKtFe10ResolveCallTes runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/smartCastImplicitExtensionReceiver.kt"); } + @Test + @TestMetadata("unresolvableOperator_elvis_1.kt") + public void testUnresolvableOperator_elvis_1() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_1.kt"); + } + + @Test + @TestMetadata("unresolvableOperator_elvis_2.kt") + public void testUnresolvableOperator_elvis_2() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_2.kt"); + } + + @Test + @TestMetadata("unresolvableOperator_eqeqeq_1.kt") + public void testUnresolvableOperator_eqeqeq_1() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_1.kt"); + } + + @Test + @TestMetadata("unresolvableOperator_eqeqeq_2.kt") + public void testUnresolvableOperator_eqeqeq_2() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_2.kt"); + } + + @Test + @TestMetadata("unresolvableOperator_excleqeq_1.kt") + public void testUnresolvableOperator_excleqeq_1() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_1.kt"); + } + + @Test + @TestMetadata("unresolvableOperator_excleqeq_2.kt") + public void testUnresolvableOperator_excleqeq_2() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_2.kt"); + } + @Test @TestMetadata("unresolvedSuperReference.kt") public void testUnresolvedSuperReference() throws Exception { 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 df03d86cd7c..ab29f4a85a1 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 @@ -69,7 +69,8 @@ internal class KtFirCallResolver( } override fun resolveCall(psi: KtElement): KtCallInfo? = withValidityAssertion { - if (psi is KtBinaryExpression && psi.operationToken in nonCallBinaryOperator) return null + if (psi.isNotResolvable()) return null + val containingCallExpressionForCalleeExpression = psi.getContainingCallExpressionForCalleeExpression() val containingBinaryExpressionForLhs = psi.getContainingBinaryExpressionForIncompleteLhs() val containingUnaryExpressionForIncOrDec = psi.getContainingUnaryIncOrDecExpression() diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/callResolver/FirResolveCallTestGenerated.java b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/callResolver/FirResolveCallTestGenerated.java index d74d2a9f346..6b34b972a7c 100644 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/callResolver/FirResolveCallTestGenerated.java +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/callResolver/FirResolveCallTestGenerated.java @@ -648,6 +648,42 @@ public class FirResolveCallTestGenerated extends AbstractFirResolveCallTest { runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/smartCastImplicitExtensionReceiver.kt"); } + @Test + @TestMetadata("unresolvableOperator_elvis_1.kt") + public void testUnresolvableOperator_elvis_1() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_1.kt"); + } + + @Test + @TestMetadata("unresolvableOperator_elvis_2.kt") + public void testUnresolvableOperator_elvis_2() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_2.kt"); + } + + @Test + @TestMetadata("unresolvableOperator_eqeqeq_1.kt") + public void testUnresolvableOperator_eqeqeq_1() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_1.kt"); + } + + @Test + @TestMetadata("unresolvableOperator_eqeqeq_2.kt") + public void testUnresolvableOperator_eqeqeq_2() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_2.kt"); + } + + @Test + @TestMetadata("unresolvableOperator_excleqeq_1.kt") + public void testUnresolvableOperator_excleqeq_1() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_1.kt"); + } + + @Test + @TestMetadata("unresolvableOperator_excleqeq_2.kt") + public void testUnresolvableOperator_excleqeq_2() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_2.kt"); + } + @Test @TestMetadata("unresolvedSuperReference.kt") public void testUnresolvedSuperReference() throws Exception { 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 a195923e2f4..b2ea43f2fa1 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 @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.analysis.api.calls.KtCompoundAccess import org.jetbrains.kotlin.analysis.api.calls.KtExplicitReceiverValue import org.jetbrains.kotlin.analysis.api.components.KtCallResolver import org.jetbrains.kotlin.analysis.api.impl.barebone.parentOfType +import org.jetbrains.kotlin.lexer.KtSingleValueToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* @@ -44,6 +45,16 @@ abstract class AbstractKtCallResolver : KtCallResolver() { } protected companion object { - val nonCallBinaryOperator = setOf(KtTokens.ELVIS, KtTokens.EQEQEQ, KtTokens.EXCLEQEQEQ) + 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/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_1.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_1.kt new file mode 100644 index 00000000000..6d639fdac7f --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_1.kt @@ -0,0 +1,5 @@ +class A + +fun test(a: A, b: A) { + a ?: b +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_1.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_1.txt new file mode 100644 index 00000000000..19765bd501b --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_1.txt @@ -0,0 +1 @@ +null diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_2.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_2.kt new file mode 100644 index 00000000000..88fb2cc7f6b --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_2.kt @@ -0,0 +1,5 @@ +class A + +fun test(a: A, b: A) { + a ?: b +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_2.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_2.txt new file mode 100644 index 00000000000..19765bd501b --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_elvis_2.txt @@ -0,0 +1 @@ +null diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_1.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_1.kt new file mode 100644 index 00000000000..28678a2ca4e --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_1.kt @@ -0,0 +1,5 @@ +class A + +fun test(a: A, b: A) { + a === b +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_1.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_1.txt new file mode 100644 index 00000000000..19765bd501b --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_1.txt @@ -0,0 +1 @@ +null diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_2.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_2.kt new file mode 100644 index 00000000000..b414f0339ec --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_2.kt @@ -0,0 +1,5 @@ +class A + +fun test(a: A, b: A) { + a === b +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_2.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_2.txt new file mode 100644 index 00000000000..19765bd501b --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_eqeqeq_2.txt @@ -0,0 +1 @@ +null diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_1.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_1.kt new file mode 100644 index 00000000000..81c2f24a336 --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_1.kt @@ -0,0 +1,5 @@ +class A + +fun test(a: A, b: A) { + a !== b +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_1.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_1.txt new file mode 100644 index 00000000000..19765bd501b --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_1.txt @@ -0,0 +1 @@ +null diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_2.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_2.kt new file mode 100644 index 00000000000..f0b0ea02066 --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_2.kt @@ -0,0 +1,5 @@ +class A + +fun test(a: A, b: A) { + a !== b +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_2.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_2.txt new file mode 100644 index 00000000000..19765bd501b --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/unresolvableOperator_excleqeq_2.txt @@ -0,0 +1 @@ +null