From 86cc57ac39a46a57e6f778f5d58bd34dae0e9abc Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 13 Jan 2023 13:45:29 +0100 Subject: [PATCH] [AA] allow navigation from '==' to the `equals` method of lhs --- ...ceModuleReferenceResolveTestGenerated.java | 18 +++++++++++++ .../references/FirReferenceResolveHelper.kt | 26 +++++++++++++++++++ ...ceModuleReferenceResolveTestGenerated.java | 18 +++++++++++++ ...ceModuleReferenceResolveTestGenerated.java | 18 +++++++++++++ ...ceModuleReferenceResolveTestGenerated.java | 18 +++++++++++++ ...ceModuleReferenceResolveTestGenerated.java | 18 +++++++++++++ .../referenceResolve/EqualsOperator.kt | 5 ++++ .../referenceResolve/EqualsOperator.txt | 2 ++ .../referenceResolve/EqualsOperatorNoInfix.kt | 5 ++++ .../EqualsOperatorNoInfix.txt | 2 ++ .../referenceResolve/NotEqualsOperator.kt | 5 ++++ .../referenceResolve/NotEqualsOperator.txt | 2 ++ 12 files changed, 137 insertions(+) create mode 100644 analysis/analysis-api/testData/referenceResolve/EqualsOperator.kt create mode 100644 analysis/analysis-api/testData/referenceResolve/EqualsOperator.txt create mode 100644 analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.kt create mode 100644 analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.txt create mode 100644 analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.kt create mode 100644 analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.txt diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java index 3fdce464261..55dfce40fbf 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -160,6 +160,18 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte runTest("analysis/analysis-api/testData/referenceResolve/EnumValues.kt"); } + @Test + @TestMetadata("EqualsOperator.kt") + public void testEqualsOperator() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/EqualsOperator.kt"); + } + + @Test + @TestMetadata("EqualsOperatorNoInfix.kt") + public void testEqualsOperatorNoInfix() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.kt"); + } + @Test @TestMetadata("explicitFunctionalInterfaceInvoke_globalVal.kt") public void testExplicitFunctionalInterfaceInvoke_globalVal() throws Exception { @@ -352,6 +364,12 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte runTest("analysis/analysis-api/testData/referenceResolve/NamedClassObject.kt"); } + @Test + @TestMetadata("NotEqualsOperator.kt") + public void testNotEqualsOperator() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.kt"); + } + @Test @TestMetadata("PackageReference.kt") public void testPackageReference() throws Exception { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt index 8b54dccb0fa..962c7e109a0 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt @@ -30,8 +30,10 @@ import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.dfa.unwrapSmartcastExpression import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnmatchedTypeArgumentsError +import org.jetbrains.kotlin.fir.resolve.scope import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.transformers.FirImportResolveTransformer +import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope import org.jetbrains.kotlin.fir.scopes.processClassifiersByName import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol @@ -46,6 +48,7 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector import org.jetbrains.kotlin.psi.psiUtil.unwrapNullability +import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.utils.addIfNotNull internal object FirReferenceResolveHelper { @@ -216,10 +219,33 @@ internal object FirReferenceResolveHelper { getSymbolByDelegatedConstructorCall(expression, adjustedResolutionExpression, fir, session, symbolBuilder) is FirResolvable -> getSymbolsByResolvable(fir, expression, session, symbolBuilder) is FirNamedArgumentExpression -> getSymbolsByNameArgumentExpression(expression, analysisSession, symbolBuilder) + is FirEqualityOperatorCall -> getSymbolsByEqualsName(fir, session, analysisSession, symbolBuilder) else -> handleUnknownFirElement(expression, analysisSession, session, symbolBuilder) } } + private fun getSymbolsByEqualsName( + expression: FirEqualityOperatorCall, + session: FirSession, + analysisSession: KtFirAnalysisSession, + symbolBuilder: KtSymbolByFirBuilder + ): Collection { + val lhs = expression.arguments.firstOrNull() ?: return emptyList() + val scope = lhs.typeRef.coneType.scope( + session, + analysisSession.getScopeSessionFor(analysisSession.useSiteSession), + FakeOverrideTypeCalculator.DoNothing + ) ?: return emptyList() + return buildList { + scope.processFunctionsByName(OperatorNameConventions.EQUALS) { functionSymbol -> + val parameterSymbol = functionSymbol.valueParameterSymbols.singleOrNull() + if (parameterSymbol != null && parameterSymbol.fir.returnTypeRef.isNullableAny) { + add(functionSymbol.buildSymbol(symbolBuilder)) + } + } + } + } + private fun getSymbolByDelegatedConstructorCall( expression: KtSimpleNameExpression, adjustedResolutionExpression: KtElement, diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java index d033a5e6338..fedec52db2f 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -160,6 +160,18 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex runTest("analysis/analysis-api/testData/referenceResolve/EnumValues.kt"); } + @Test + @TestMetadata("EqualsOperator.kt") + public void testEqualsOperator() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/EqualsOperator.kt"); + } + + @Test + @TestMetadata("EqualsOperatorNoInfix.kt") + public void testEqualsOperatorNoInfix() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.kt"); + } + @Test @TestMetadata("explicitFunctionalInterfaceInvoke_globalVal.kt") public void testExplicitFunctionalInterfaceInvoke_globalVal() throws Exception { @@ -352,6 +364,12 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex runTest("analysis/analysis-api/testData/referenceResolve/NamedClassObject.kt"); } + @Test + @TestMetadata("NotEqualsOperator.kt") + public void testNotEqualsOperator() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.kt"); + } + @Test @TestMetadata("PackageReference.kt") public void testPackageReference() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerated.java index eea1d36c204..401a8a37dfd 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerated.java @@ -160,6 +160,18 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate runTest("analysis/analysis-api/testData/referenceResolve/EnumValues.kt"); } + @Test + @TestMetadata("EqualsOperator.kt") + public void testEqualsOperator() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/EqualsOperator.kt"); + } + + @Test + @TestMetadata("EqualsOperatorNoInfix.kt") + public void testEqualsOperatorNoInfix() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.kt"); + } + @Test @TestMetadata("explicitFunctionalInterfaceInvoke_globalVal.kt") public void testExplicitFunctionalInterfaceInvoke_globalVal() throws Exception { @@ -352,6 +364,12 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate runTest("analysis/analysis-api/testData/referenceResolve/NamedClassObject.kt"); } + @Test + @TestMetadata("NotEqualsOperator.kt") + public void testNotEqualsOperator() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.kt"); + } + @Test @TestMetadata("PackageReference.kt") public void testPackageReference() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java index 046bafdec3e..617371f27ae 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -160,6 +160,18 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten runTest("analysis/analysis-api/testData/referenceResolve/EnumValues.kt"); } + @Test + @TestMetadata("EqualsOperator.kt") + public void testEqualsOperator() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/EqualsOperator.kt"); + } + + @Test + @TestMetadata("EqualsOperatorNoInfix.kt") + public void testEqualsOperatorNoInfix() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.kt"); + } + @Test @TestMetadata("explicitFunctionalInterfaceInvoke_globalVal.kt") public void testExplicitFunctionalInterfaceInvoke_globalVal() throws Exception { @@ -352,6 +364,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten runTest("analysis/analysis-api/testData/referenceResolve/NamedClassObject.kt"); } + @Test + @TestMetadata("NotEqualsOperator.kt") + public void testNotEqualsOperator() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.kt"); + } + @Test @TestMetadata("PackageReference.kt") public void testPackageReference() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java index df792d8647c..d02ee6a6d42 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -160,6 +160,18 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate runTest("analysis/analysis-api/testData/referenceResolve/EnumValues.kt"); } + @Test + @TestMetadata("EqualsOperator.kt") + public void testEqualsOperator() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/EqualsOperator.kt"); + } + + @Test + @TestMetadata("EqualsOperatorNoInfix.kt") + public void testEqualsOperatorNoInfix() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.kt"); + } + @Test @TestMetadata("explicitFunctionalInterfaceInvoke_globalVal.kt") public void testExplicitFunctionalInterfaceInvoke_globalVal() throws Exception { @@ -352,6 +364,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate runTest("analysis/analysis-api/testData/referenceResolve/NamedClassObject.kt"); } + @Test + @TestMetadata("NotEqualsOperator.kt") + public void testNotEqualsOperator() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.kt"); + } + @Test @TestMetadata("PackageReference.kt") public void testPackageReference() throws Exception { diff --git a/analysis/analysis-api/testData/referenceResolve/EqualsOperator.kt b/analysis/analysis-api/testData/referenceResolve/EqualsOperator.kt new file mode 100644 index 00000000000..380705012c2 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/EqualsOperator.kt @@ -0,0 +1,5 @@ +package test + +class A(val n: Any) { + override infix fun equals(other: Any?): Boolean = other is A && other.n == n +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/referenceResolve/EqualsOperator.txt b/analysis/analysis-api/testData/referenceResolve/EqualsOperator.txt new file mode 100644 index 00000000000..8a9614f8a88 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/EqualsOperator.txt @@ -0,0 +1,2 @@ +Resolved to: +0: (in kotlin.Any) open operator fun equals(other: kotlin.Any?): kotlin.Boolean \ No newline at end of file diff --git a/analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.kt b/analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.kt new file mode 100644 index 00000000000..e3794182015 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.kt @@ -0,0 +1,5 @@ +package test + +class A(val n: Any) { + override fun equals(other: Any?): Boolean = other is A && other.n == n +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.txt b/analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.txt new file mode 100644 index 00000000000..8a9614f8a88 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/EqualsOperatorNoInfix.txt @@ -0,0 +1,2 @@ +Resolved to: +0: (in kotlin.Any) open operator fun equals(other: kotlin.Any?): kotlin.Boolean \ No newline at end of file diff --git a/analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.kt b/analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.kt new file mode 100644 index 00000000000..c3d3a2a36a8 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.kt @@ -0,0 +1,5 @@ +package test + +class A(val n: Any) { + override infix fun equals(other: Any?): Boolean = other is A && other.n != n +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.txt b/analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.txt new file mode 100644 index 00000000000..1d4fe854d1f --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/NotEqualsOperator.txt @@ -0,0 +1,2 @@ +Resolved to: +0: (in kotlin.Any) open operator fun equals(other: kotlin.Any?): kotlin.Boolean