From d05497638920125afd9dad5200874d9e489727f0 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Tue, 22 Feb 2022 23:16:25 +0300 Subject: [PATCH] FIR. Add visibility/deprecation filtering to getFirstClassifierOrNull --- .../resolve/calls/ConstructorProcessing.kt | 52 +++++++++++++++---- .../fir/resolve/calls/tower/TowerLevels.kt | 4 +- .../p-5/pos/6.3.fir.kt | 6 +-- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt index 9e618c62a1c..c5a9acd826d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt @@ -22,20 +22,20 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirFakeOverrideGenerator import org.jetbrains.kotlin.fir.scopes.scopeForClass import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.fir.visibilityChecker +import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue private operator fun Pair?.component1() = this?.first private operator fun Pair<*, T>?.component2() = this?.second internal fun FirScope.processConstructorsByName( - name: Name, + callInfo: CallInfo, session: FirSession, bodyResolveComponents: BodyResolveComponents, includeInnerConstructors: Boolean, processor: (FirCallableSymbol<*>) -> Unit ) { - // TODO: Handle case with two or more accessible classifiers - val classifierInfo = getFirstClassifierOrNull(name) + val classifierInfo = getFirstClassifierOrNull(callInfo, session, bodyResolveComponents) if (classifierInfo != null) { val (matchedClassifierSymbol, substitutor) = classifierInfo val matchedClassSymbol = matchedClassifierSymbol as? FirClassLikeSymbol<*> @@ -58,30 +58,60 @@ internal fun FirScope.processConstructorsByName( } internal fun FirScope.processFunctionsAndConstructorsByName( - name: Name, + callInfo: CallInfo, session: FirSession, bodyResolveComponents: BodyResolveComponents, includeInnerConstructors: Boolean, processor: (FirCallableSymbol<*>) -> Unit ) { processConstructorsByName( - name, session, bodyResolveComponents, + callInfo, session, bodyResolveComponents, includeInnerConstructors = includeInnerConstructors, processor ) - processFunctionsByName(name, processor) + processFunctionsByName(callInfo.name, processor) } -private fun FirScope.getFirstClassifierOrNull(name: Name): Pair, ConeSubstitutor>? { +private fun FirScope.getFirstClassifierOrNull( + callInfo: CallInfo, + session: FirSession, + bodyResolveComponents: BodyResolveComponents +): Pair, ConeSubstitutor>? { + var successful = false + var ambiguity = false var result: Pair, ConeSubstitutor>? = null - processClassifiersByNameWithSubstitution(name) { symbol, substitution -> - if (result == null) { + processClassifiersByNameWithSubstitution(callInfo.name) { symbol, substitution -> + val classifierDeclaration = symbol.fir + var isSuccessCandidate = true + if (classifierDeclaration is FirMemberDeclaration) { + if (!session.visibilityChecker.isVisible( + classifierDeclaration, + session, + bodyResolveComponents.file, + bodyResolveComponents.containingDeclarations, + dispatchReceiver = null, + isCallToPropertySetter = false + ) + ) { + isSuccessCandidate = false + } + } + + val deprecation = symbol.getDeprecationForCallSite() + if (deprecation != null && deprecation.deprecationLevel == DeprecationLevelValue.HIDDEN) { + isSuccessCandidate = false + } + + if (result == null || (!successful && isSuccessCandidate)) { + successful = isSuccessCandidate result = symbol to substitution + } else { + ambiguity = true } } - return result + return result.takeUnless { ambiguity } } private fun processSyntheticConstructors( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt index a9ad829b5fe..878081bedfe 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt @@ -143,7 +143,7 @@ class MemberScopeTowerLevel( return processMembers(processor) { consumer -> withMemberCallLookup(lookupTracker, info) { lookupCtx -> this.processFunctionsAndConstructorsByName( - info.name, session, bodyResolveComponents, + info, session, bodyResolveComponents, includeInnerConstructors = true, processor = { lookupCtx.recordCallableMemberLookup(it) @@ -313,7 +313,7 @@ class ScopeTowerLevel( var empty = true session.lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames) scope.processFunctionsAndConstructorsByName( - info.name, + info, session, bodyResolveComponents, includeInnerConstructors = includeInnerConstructors diff --git a/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/building-the-overload-candidate-set-ocs/call-without-an-explicit-receiver/p-5/pos/6.3.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/building-the-overload-candidate-set-ocs/call-without-an-explicit-receiver/p-5/pos/6.3.fir.kt index ec54c89b60e..bc4643d91ce 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/building-the-overload-candidate-set-ocs/call-without-an-explicit-receiver/p-5/pos/6.3.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/overload-resolution/building-the-overload-candidate-set-ocs/call-without-an-explicit-receiver/p-5/pos/6.3.fir.kt @@ -35,7 +35,7 @@ import lib1Case2.* import kotlin.text.* fun case2() { - Regex("") + Regex("") } // FILE: Lib2.kt @@ -68,7 +68,7 @@ import libCase3.* import kotlin.text.* fun case3() { - Regex("") + Regex("") } // FILE: Lib3.kt @@ -95,7 +95,7 @@ import lib1Case4.* import kotlin.text.* fun case4() { - Regex("") + Regex("") } // FILE: Lib4.kt