From 21dffe46392a78c22de1a02f36b7ce4a119db94b Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Wed, 30 Aug 2023 12:21:32 +0200 Subject: [PATCH] KT-61568 [FIR][AA] Do not add redundant file scopes in `AllCandidatesResolver` `firResolveSession.getTowerContextProvider` should already contain all the relevant scopes, including default and importing scopes for the file Because of this, import and default scopes had presence over the more local scopes, and the resolve was performed incorrecty - top level candidates were given higher priority ^KT-61568 Fixed ^KTIJ-26824 Fixed --- ...eModuleResolveCandidatesTestGenerated.java | 6 ++ ...eModuleResolveCandidatesTestGenerated.java | 6 ++ ...eModuleResolveCandidatesTestGenerated.java | 6 ++ .../memberFunctionVsTopLevel.kt | 11 ++++ .../memberFunctionVsTopLevel.txt | 57 +++++++++++++++++++ .../api/fir/resolver/AllCandidatesResolver.kt | 11 ++-- 6 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionVsTopLevel.kt create mode 100644 analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionVsTopLevel.txt diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java index 77aeaaf744c..12dd71f93bc 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java @@ -435,6 +435,12 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated ext runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionCallWithTypeArgument.kt"); } + @Test + @TestMetadata("memberFunctionVsTopLevel.kt") + public void testMemberFunctionVsTopLevel() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionVsTopLevel.kt"); + } + @Test @TestMetadata("privateMember.kt") public void testPrivateMember() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java index d7d7aa1b488..47fb2fa68fc 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java @@ -435,6 +435,12 @@ public class FirIdeNormalAnalysisSourceModuleResolveCandidatesTestGenerated exte runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionCallWithTypeArgument.kt"); } + @Test + @TestMetadata("memberFunctionVsTopLevel.kt") + public void testMemberFunctionVsTopLevel() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionVsTopLevel.kt"); + } + @Test @TestMetadata("privateMember.kt") public void testPrivateMember() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java index c4a9a9c22e4..c444da9836d 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCandidatesTestGenerated.java @@ -435,6 +435,12 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCandidatesTestGenerat runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionCallWithTypeArgument.kt"); } + @Test + @TestMetadata("memberFunctionVsTopLevel.kt") + public void testMemberFunctionVsTopLevel() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionVsTopLevel.kt"); + } + @Test @TestMetadata("privateMember.kt") public void testPrivateMember() throws Exception { diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionVsTopLevel.kt b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionVsTopLevel.kt new file mode 100644 index 00000000000..4b4ccaef463 --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionVsTopLevel.kt @@ -0,0 +1,11 @@ +package test + +class A { + fun foo() {} + + fun usage() { + foo() + } +} + +fun foo() {} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionVsTopLevel.txt b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionVsTopLevel.txt new file mode 100644 index 00000000000..9d83cdad34e --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/memberFunctionVsTopLevel.txt @@ -0,0 +1,57 @@ +KtApplicableCallCandidateInfo: + candidate = KtSimpleFunctionCall: + isImplicitInvoke = false + partiallyAppliedSymbol = KtPartiallyAppliedSymbol: + dispatchReceiver = KtImplicitReceiverValue: + symbol = KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: test/A + classKind: CLASS + companionObject: null + contextReceivers: [] + isActual: false + isData: false + isExpect: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: FINAL + name: A + origin: SOURCE + superTypes: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Any + ] + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + type = test.A + extensionReceiver = null + signature = KtFunctionLikeSignature: + receiverType = null + returnType = kotlin.Unit + symbol = test/A.foo(: test.A): kotlin.Unit + valueParameters = [] + callableIdIfNonLocal = test/A.foo + typeArgumentsMapping = {} + argumentMapping = {} + isInBestCandidates = true + +KtApplicableCallCandidateInfo: + candidate = KtSimpleFunctionCall: + isImplicitInvoke = false + partiallyAppliedSymbol = KtPartiallyAppliedSymbol: + dispatchReceiver = null + extensionReceiver = null + signature = KtFunctionLikeSignature: + receiverType = null + returnType = kotlin.Unit + symbol = test/foo(): kotlin.Unit + valueParameters = [] + callableIdIfNonLocal = test/foo + typeArgumentsMapping = {} + argumentMapping = {} + isInBestCandidates = false diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/AllCandidatesResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/AllCandidatesResolver.kt index 4896231fab1..9f725f72ace 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/AllCandidatesResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/AllCandidatesResolver.kt @@ -68,8 +68,7 @@ class AllCandidatesResolver(private val firSession: FirSession) { ): List { initializeBodyResolveContext(firResolveSession, element) - val firFile = element.containingKtFile.getOrBuildFirFile(firResolveSession) - return bodyResolveComponents.context.withFile(firFile, bodyResolveComponents) { + return run { bodyResolveComponents.callResolver .collectAllCandidates(qualifiedAccess, calleeName, bodyResolveComponents.context.containers, resolutionContext) .apply { postProcessCandidates() } @@ -84,9 +83,8 @@ class AllCandidatesResolver(private val firSession: FirSession) { ): List { initializeBodyResolveContext(firResolveSession, element) - val firFile = element.containingKtFile.getOrBuildFirFile(firResolveSession) val constructedType = delegatedConstructorCall.constructedTypeRef.coneType as ConeClassLikeType - return bodyResolveComponents.context.withFile(firFile, bodyResolveComponents) { + return run { bodyResolveComponents.callResolver .resolveDelegatingConstructorCall(delegatedConstructorCall, constructedType, derivedClassLookupTag) bodyResolveComponents.collector.allCandidates @@ -103,6 +101,11 @@ class AllCandidatesResolver(private val firSession: FirSession) { val containingDeclarations = element.parentsOfType().map { it.resolveToFirSymbol(firResolveSession).fir }.toList().asReversed() bodyResolveComponents.context.containers.addAll(containingDeclarations) + + // `towerContext` from above should already contain all the scopes for the file, + // so we just set it manually without calling `withFile` + val firFile = element.containingKtFile.getOrBuildFirFile(firResolveSession) + bodyResolveComponents.context.file = firFile } private fun List.postProcessCandidates() {