FIR: add visibility filtering for qualifier resolve #KT-51621 Fixed
This commit is contained in:
+1
-1
@@ -2,5 +2,5 @@ FILE: test.kt
|
||||
package test
|
||||
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
R|kotlin/Unit|.R|first/Some.foo|()
|
||||
Q|first/Some|.R|first/Some.foo|()
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,5 +22,5 @@ import first.*
|
||||
import second.*
|
||||
|
||||
fun test() {
|
||||
<!NO_COMPANION_OBJECT!>Some<!>.foo()
|
||||
Some.foo()
|
||||
}
|
||||
|
||||
@@ -288,9 +288,9 @@ class FirCallResolver(
|
||||
qualifiedAccess.source,
|
||||
qualifiedAccess.typeArguments,
|
||||
nonFatalDiagnosticFromExpression,
|
||||
session,
|
||||
components
|
||||
)
|
||||
?.let { return it }
|
||||
)?.let { return it }
|
||||
}
|
||||
|
||||
var result = basicResult
|
||||
|
||||
@@ -13,11 +13,11 @@ import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.getSingleVisibleClassifier
|
||||
import org.jetbrains.kotlin.fir.resolve.createCurrentScopeList
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDeprecated
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.resolve.typeForQualifier
|
||||
import org.jetbrains.kotlin.fir.scopes.getSingleClassifier
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||
@@ -45,7 +45,7 @@ fun BodyResolveComponents.resolveRootPartOfQualifier(
|
||||
}
|
||||
|
||||
for (scope in createCurrentScopeList()) {
|
||||
scope.getSingleClassifier(name)?.let {
|
||||
scope.getSingleVisibleClassifier(session, this, name)?.let {
|
||||
if (it is FirRegularClassSymbol) {
|
||||
val isVisible = session.visibilityChecker.isVisible(
|
||||
it.fir,
|
||||
@@ -88,6 +88,7 @@ fun FirResolvedQualifier.continueQualifier(
|
||||
source: KtSourceElement?,
|
||||
typeArguments: List<FirTypeProjection>,
|
||||
nonFatalDiagnosticsFromExpression: List<ConeDiagnostic>?,
|
||||
session: FirSession,
|
||||
components: BodyResolveComponents,
|
||||
): FirResolvedQualifier? {
|
||||
val name = namedReference.name
|
||||
@@ -95,7 +96,7 @@ fun FirResolvedQualifier.continueQualifier(
|
||||
val firClass = outerClassSymbol.fir
|
||||
if (firClass !is FirClass) return null
|
||||
return firClass.scopeProvider.getNestedClassifierScope(firClass, components.session, components.scopeSession)
|
||||
?.getSingleClassifier(name)
|
||||
?.getSingleVisibleClassifier(session, components, name)
|
||||
?.takeIf { it is FirClassLikeSymbol<*> }
|
||||
?.let { nestedClassSymbol ->
|
||||
buildResolvedQualifier {
|
||||
|
||||
+34
-19
@@ -19,10 +19,12 @@ import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirFakeOverrideGenerator
|
||||
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
|
||||
import org.jetbrains.kotlin.fir.scopes.scopeForClass
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
||||
|
||||
private operator fun <T> Pair<T, *>?.component1() = this?.first
|
||||
@@ -75,6 +77,37 @@ internal fun FirScope.processFunctionsAndConstructorsByName(
|
||||
|
||||
private data class SymbolWithSubstitutor(val symbol: FirClassifierSymbol<*>, val substitutor: ConeSubstitutor)
|
||||
|
||||
fun FirScope.getSingleVisibleClassifier(
|
||||
session: FirSession,
|
||||
bodyResolveComponents: BodyResolveComponents,
|
||||
name: Name
|
||||
): FirClassifierSymbol<*>? = mutableSetOf<FirClassifierSymbol<*>>().apply {
|
||||
processClassifiersByName(name) { classifierSymbol ->
|
||||
if (!classifierSymbol.fir.isInvisibleOrHidden(session, bodyResolveComponents)) {
|
||||
this.add(classifierSymbol)
|
||||
}
|
||||
}
|
||||
}.singleOrNull()
|
||||
|
||||
private fun FirDeclaration.isInvisibleOrHidden(session: FirSession, bodyResolveComponents: BodyResolveComponents): Boolean {
|
||||
if (this is FirMemberDeclaration) {
|
||||
if (!session.visibilityChecker.isVisible(
|
||||
this,
|
||||
session,
|
||||
bodyResolveComponents.file,
|
||||
bodyResolveComponents.containingDeclarations,
|
||||
dispatchReceiver = null,
|
||||
isCallToPropertySetter = false
|
||||
)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
val deprecation = symbol.getDeprecationForCallSite()
|
||||
return deprecation != null && deprecation.deprecationLevel == DeprecationLevelValue.HIDDEN
|
||||
}
|
||||
|
||||
private fun FirScope.getFirstClassifierOrNull(
|
||||
callInfo: CallInfo,
|
||||
session: FirSession,
|
||||
@@ -85,25 +118,7 @@ private fun FirScope.getFirstClassifierOrNull(
|
||||
var result: SymbolWithSubstitutor? = null
|
||||
processClassifiersByNameWithSubstitution(callInfo.name) { symbol, substitutor ->
|
||||
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
|
||||
}
|
||||
val isSuccessCandidate = !classifierDeclaration.isInvisibleOrHidden(session, bodyResolveComponents)
|
||||
|
||||
when {
|
||||
isSuccessCandidate && !isSuccessResult -> {
|
||||
|
||||
Reference in New Issue
Block a user