FIR. Add visibility/deprecation filtering to getFirstClassifierOrNull
This commit is contained in:
+41
-11
@@ -22,20 +22,20 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirFakeOverrideGenerator
|
|||||||
import org.jetbrains.kotlin.fir.scopes.scopeForClass
|
import org.jetbrains.kotlin.fir.scopes.scopeForClass
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
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 <T> Pair<T, *>?.component1() = this?.first
|
private operator fun <T> Pair<T, *>?.component1() = this?.first
|
||||||
private operator fun <T> Pair<*, T>?.component2() = this?.second
|
private operator fun <T> Pair<*, T>?.component2() = this?.second
|
||||||
|
|
||||||
internal fun FirScope.processConstructorsByName(
|
internal fun FirScope.processConstructorsByName(
|
||||||
name: Name,
|
callInfo: CallInfo,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
bodyResolveComponents: BodyResolveComponents,
|
bodyResolveComponents: BodyResolveComponents,
|
||||||
includeInnerConstructors: Boolean,
|
includeInnerConstructors: Boolean,
|
||||||
processor: (FirCallableSymbol<*>) -> Unit
|
processor: (FirCallableSymbol<*>) -> Unit
|
||||||
) {
|
) {
|
||||||
// TODO: Handle case with two or more accessible classifiers
|
val classifierInfo = getFirstClassifierOrNull(callInfo, session, bodyResolveComponents)
|
||||||
val classifierInfo = getFirstClassifierOrNull(name)
|
|
||||||
if (classifierInfo != null) {
|
if (classifierInfo != null) {
|
||||||
val (matchedClassifierSymbol, substitutor) = classifierInfo
|
val (matchedClassifierSymbol, substitutor) = classifierInfo
|
||||||
val matchedClassSymbol = matchedClassifierSymbol as? FirClassLikeSymbol<*>
|
val matchedClassSymbol = matchedClassifierSymbol as? FirClassLikeSymbol<*>
|
||||||
@@ -58,30 +58,60 @@ internal fun FirScope.processConstructorsByName(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun FirScope.processFunctionsAndConstructorsByName(
|
internal fun FirScope.processFunctionsAndConstructorsByName(
|
||||||
name: Name,
|
callInfo: CallInfo,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
bodyResolveComponents: BodyResolveComponents,
|
bodyResolveComponents: BodyResolveComponents,
|
||||||
includeInnerConstructors: Boolean,
|
includeInnerConstructors: Boolean,
|
||||||
processor: (FirCallableSymbol<*>) -> Unit
|
processor: (FirCallableSymbol<*>) -> Unit
|
||||||
) {
|
) {
|
||||||
processConstructorsByName(
|
processConstructorsByName(
|
||||||
name, session, bodyResolveComponents,
|
callInfo, session, bodyResolveComponents,
|
||||||
includeInnerConstructors = includeInnerConstructors,
|
includeInnerConstructors = includeInnerConstructors,
|
||||||
processor
|
processor
|
||||||
)
|
)
|
||||||
|
|
||||||
processFunctionsByName(name, processor)
|
processFunctionsByName(callInfo.name, processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirScope.getFirstClassifierOrNull(name: Name): Pair<FirClassifierSymbol<*>, ConeSubstitutor>? {
|
private fun FirScope.getFirstClassifierOrNull(
|
||||||
|
callInfo: CallInfo,
|
||||||
|
session: FirSession,
|
||||||
|
bodyResolveComponents: BodyResolveComponents
|
||||||
|
): Pair<FirClassifierSymbol<*>, ConeSubstitutor>? {
|
||||||
|
var successful = false
|
||||||
|
var ambiguity = false
|
||||||
var result: Pair<FirClassifierSymbol<*>, ConeSubstitutor>? = null
|
var result: Pair<FirClassifierSymbol<*>, ConeSubstitutor>? = null
|
||||||
processClassifiersByNameWithSubstitution(name) { symbol, substitution ->
|
processClassifiersByNameWithSubstitution(callInfo.name) { symbol, substitution ->
|
||||||
if (result == null) {
|
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
|
result = symbol to substitution
|
||||||
|
} else {
|
||||||
|
ambiguity = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result.takeUnless { ambiguity }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processSyntheticConstructors(
|
private fun processSyntheticConstructors(
|
||||||
|
|||||||
+2
-2
@@ -143,7 +143,7 @@ class MemberScopeTowerLevel(
|
|||||||
return processMembers(processor) { consumer ->
|
return processMembers(processor) { consumer ->
|
||||||
withMemberCallLookup(lookupTracker, info) { lookupCtx ->
|
withMemberCallLookup(lookupTracker, info) { lookupCtx ->
|
||||||
this.processFunctionsAndConstructorsByName(
|
this.processFunctionsAndConstructorsByName(
|
||||||
info.name, session, bodyResolveComponents,
|
info, session, bodyResolveComponents,
|
||||||
includeInnerConstructors = true,
|
includeInnerConstructors = true,
|
||||||
processor = {
|
processor = {
|
||||||
lookupCtx.recordCallableMemberLookup(it)
|
lookupCtx.recordCallableMemberLookup(it)
|
||||||
@@ -313,7 +313,7 @@ class ScopeTowerLevel(
|
|||||||
var empty = true
|
var empty = true
|
||||||
session.lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames)
|
session.lookupTracker?.recordCallLookup(info, scope.scopeOwnerLookupNames)
|
||||||
scope.processFunctionsAndConstructorsByName(
|
scope.processFunctionsAndConstructorsByName(
|
||||||
info.name,
|
info,
|
||||||
session,
|
session,
|
||||||
bodyResolveComponents,
|
bodyResolveComponents,
|
||||||
includeInnerConstructors = includeInnerConstructors
|
includeInnerConstructors = includeInnerConstructors
|
||||||
|
|||||||
+3
-3
@@ -35,7 +35,7 @@ import lib1Case2.*
|
|||||||
import kotlin.text.*
|
import kotlin.text.*
|
||||||
|
|
||||||
fun case2() {
|
fun case2() {
|
||||||
<!DEBUG_INFO_CALL("fqName: kotlin.text.Regex.Regex; typeCall: function")!>Regex("")<!>
|
<!DEBUG_INFO_CALL("fqName: fqName is unknown; typeCall: unresolved")!><!OVERLOAD_RESOLUTION_AMBIGUITY!>Regex<!>("")<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILE: Lib2.kt
|
// FILE: Lib2.kt
|
||||||
@@ -68,7 +68,7 @@ import libCase3.*
|
|||||||
import kotlin.text.*
|
import kotlin.text.*
|
||||||
|
|
||||||
fun case3() {
|
fun case3() {
|
||||||
<!DEBUG_INFO_CALL("fqName: kotlin.text.Regex.Regex; typeCall: function")!>Regex("")<!>
|
<!DEBUG_INFO_CALL("fqName: libCase3.Regex.Companion.invoke; typeCall: variable&invoke")!>Regex("")<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILE: Lib3.kt
|
// FILE: Lib3.kt
|
||||||
@@ -95,7 +95,7 @@ import lib1Case4.*
|
|||||||
import kotlin.text.*
|
import kotlin.text.*
|
||||||
|
|
||||||
fun case4() {
|
fun case4() {
|
||||||
<!DEBUG_INFO_CALL("fqName: kotlin.text.Regex.Regex; typeCall: function")!>Regex("")<!>
|
<!DEBUG_INFO_CALL("fqName: lib1Case4.Regex.Companion.invoke; typeCall: variable&invoke")!>Regex("")<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILE: Lib4.kt
|
// FILE: Lib4.kt
|
||||||
|
|||||||
Reference in New Issue
Block a user