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
This commit is contained in:
Roman Golyshev
2023-08-30 12:21:32 +02:00
committed by Space Team
parent 826297979d
commit 21dffe4639
6 changed files with 93 additions and 4 deletions
@@ -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 {
@@ -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 {
@@ -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 {
@@ -0,0 +1,11 @@
package test
class A {
fun foo() {}
fun usage() {
<expr>foo()</expr>
}
}
fun foo() {}
@@ -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(<dispatch receiver>: 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
@@ -68,8 +68,7 @@ class AllCandidatesResolver(private val firSession: FirSession) {
): List<OverloadCandidate> {
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<OverloadCandidate> {
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<KtDeclaration>().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<OverloadCandidate>.postProcessCandidates() {