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
This commit is contained in:
Roman Golyshev
2021-12-21 16:01:07 +03:00
committed by teamcity
parent 702ab3408b
commit e3219cc5b6
17 changed files with 124 additions and 2 deletions
@@ -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<KtBinaryExpression>()
val lhs = KtPsiUtil.deparenthesize(parentBinaryExpression?.left)
val unwrappedPsi = KtPsiUtil.deparenthesize(psi as? KtExpression) ?: psi
@@ -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 {
@@ -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()
@@ -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 {
@@ -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<KtSingleValueToken> = 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
}
}
}
@@ -0,0 +1,5 @@
class A
fun test(a: A, b: A) {
<expr>a ?: b</expr>
}
@@ -0,0 +1,5 @@
class A
fun test(a: A, b: A) {
a <expr>?:</expr> b
}
@@ -0,0 +1,5 @@
class A
fun test(a: A, b: A) {
<expr>a === b</expr>
}
@@ -0,0 +1,5 @@
class A
fun test(a: A, b: A) {
a <expr>===</expr> b
}
@@ -0,0 +1,5 @@
class A
fun test(a: A, b: A) {
<expr>a !== b</expr>
}
@@ -0,0 +1,5 @@
class A
fun test(a: A, b: A) {
a <expr>!==</expr> b
}