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() {