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
|
package test
|
||||||
|
|
||||||
public final fun test(): R|kotlin/Unit| {
|
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.*
|
import second.*
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
<!NO_COMPANION_OBJECT!>Some<!>.foo()
|
Some.foo()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,9 +288,9 @@ class FirCallResolver(
|
|||||||
qualifiedAccess.source,
|
qualifiedAccess.source,
|
||||||
qualifiedAccess.typeArguments,
|
qualifiedAccess.typeArguments,
|
||||||
nonFatalDiagnosticFromExpression,
|
nonFatalDiagnosticFromExpression,
|
||||||
|
session,
|
||||||
components
|
components
|
||||||
)
|
)?.let { return it }
|
||||||
?.let { return it }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = basicResult
|
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.expressions.builder.buildResolvedQualifier
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
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.createCurrentScopeList
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDeprecated
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDeprecated
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.typeForQualifier
|
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.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||||
@@ -45,7 +45,7 @@ fun BodyResolveComponents.resolveRootPartOfQualifier(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (scope in createCurrentScopeList()) {
|
for (scope in createCurrentScopeList()) {
|
||||||
scope.getSingleClassifier(name)?.let {
|
scope.getSingleVisibleClassifier(session, this, name)?.let {
|
||||||
if (it is FirRegularClassSymbol) {
|
if (it is FirRegularClassSymbol) {
|
||||||
val isVisible = session.visibilityChecker.isVisible(
|
val isVisible = session.visibilityChecker.isVisible(
|
||||||
it.fir,
|
it.fir,
|
||||||
@@ -88,6 +88,7 @@ fun FirResolvedQualifier.continueQualifier(
|
|||||||
source: KtSourceElement?,
|
source: KtSourceElement?,
|
||||||
typeArguments: List<FirTypeProjection>,
|
typeArguments: List<FirTypeProjection>,
|
||||||
nonFatalDiagnosticsFromExpression: List<ConeDiagnostic>?,
|
nonFatalDiagnosticsFromExpression: List<ConeDiagnostic>?,
|
||||||
|
session: FirSession,
|
||||||
components: BodyResolveComponents,
|
components: BodyResolveComponents,
|
||||||
): FirResolvedQualifier? {
|
): FirResolvedQualifier? {
|
||||||
val name = namedReference.name
|
val name = namedReference.name
|
||||||
@@ -95,7 +96,7 @@ fun FirResolvedQualifier.continueQualifier(
|
|||||||
val firClass = outerClassSymbol.fir
|
val firClass = outerClassSymbol.fir
|
||||||
if (firClass !is FirClass) return null
|
if (firClass !is FirClass) return null
|
||||||
return firClass.scopeProvider.getNestedClassifierScope(firClass, components.session, components.scopeSession)
|
return firClass.scopeProvider.getNestedClassifierScope(firClass, components.session, components.scopeSession)
|
||||||
?.getSingleClassifier(name)
|
?.getSingleVisibleClassifier(session, components, name)
|
||||||
?.takeIf { it is FirClassLikeSymbol<*> }
|
?.takeIf { it is FirClassLikeSymbol<*> }
|
||||||
?.let { nestedClassSymbol ->
|
?.let { nestedClassSymbol ->
|
||||||
buildResolvedQualifier {
|
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.FakeOverrideTypeCalculator
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirFakeOverrideGenerator
|
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.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.fir.visibilityChecker
|
import org.jetbrains.kotlin.fir.visibilityChecker
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
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
|
||||||
@@ -75,6 +77,37 @@ internal fun FirScope.processFunctionsAndConstructorsByName(
|
|||||||
|
|
||||||
private data class SymbolWithSubstitutor(val symbol: FirClassifierSymbol<*>, val substitutor: ConeSubstitutor)
|
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(
|
private fun FirScope.getFirstClassifierOrNull(
|
||||||
callInfo: CallInfo,
|
callInfo: CallInfo,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
@@ -85,25 +118,7 @@ private fun FirScope.getFirstClassifierOrNull(
|
|||||||
var result: SymbolWithSubstitutor? = null
|
var result: SymbolWithSubstitutor? = null
|
||||||
processClassifiersByNameWithSubstitution(callInfo.name) { symbol, substitutor ->
|
processClassifiersByNameWithSubstitution(callInfo.name) { symbol, substitutor ->
|
||||||
val classifierDeclaration = symbol.fir
|
val classifierDeclaration = symbol.fir
|
||||||
var isSuccessCandidate = true
|
val isSuccessCandidate = !classifierDeclaration.isInvisibleOrHidden(session, bodyResolveComponents)
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
when {
|
when {
|
||||||
isSuccessCandidate && !isSuccessResult -> {
|
isSuccessCandidate && !isSuccessResult -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user