K2: fix visibility checks for static overrides via imported from static

#KT-53441 In Progress
This commit is contained in:
Mikhail Glukhikh
2022-10-27 12:11:21 +02:00
committed by Space Team
parent cc1a094b6c
commit f070401bb5
13 changed files with 107 additions and 43 deletions
@@ -72,6 +72,25 @@ abstract class FirVisibilityChecker : FirSessionComponent {
}
}
fun isClassLikeVisible(
declaration: FirClassLikeDeclaration,
session: FirSession,
useSiteFile: FirFile,
containingDeclarations: List<FirDeclaration>,
): Boolean {
return isVisible(
declaration,
session,
useSiteFile,
containingDeclarations,
dispatchReceiver = null,
isCallToPropertySetter = false,
staticQualifierClassForCallable = null,
skipCheckForContainingClassVisibility = false,
supertypeSupplier = SupertypeSupplier.Default
)
}
fun isVisible(
declaration: FirMemberDeclaration,
session: FirSession,
@@ -79,6 +98,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
containingDeclarations: List<FirDeclaration>,
dispatchReceiver: ReceiverValue?,
isCallToPropertySetter: Boolean = false,
staticQualifierClassForCallable: FirRegularClass? = null,
// There's no need to check if containing class is visible in case we check if a member might be overridden in a subclass
// because visibility for its supertype that contain overridden member is being checked when resolving the type reference.
// Such flag is not necessary in FE1.0, since there are full structure of fake overrides and containing declaration for overridden
@@ -108,8 +128,14 @@ abstract class FirVisibilityChecker : FirSessionComponent {
supertypeSupplier
) ?: return true
return generateSequence(parentClass) { it.containingNonLocalClass(session) }.all { parent ->
val classLikeToCheck =
if (staticQualifierClassForCallable?.isSubClass(parent.symbol.toLookupTag(), session, supertypeSupplier) == true) {
staticQualifierClassForCallable
} else {
parent
}
isSpecificDeclarationVisible(
parent,
classLikeToCheck,
session,
useSiteFile,
containingDeclarations,
@@ -61,9 +61,14 @@ abstract class FirAbstractImportingScope(
for (import in imports) {
val importedName = name ?: import.importedName ?: continue
if (isExcluded(import, importedName)) continue
val staticsScope = import.resolvedParentClassId?.let(::getStaticsScope)
val parentClassId = import.resolvedParentClassId
val staticsScope = parentClassId?.let { getStaticsScope(it) }
if (staticsScope != null) {
staticsScope.processFunctionsByName(importedName, processor)
staticsScope.processFunctionsByName(importedName) {
if (it.isStatic) processor(it.fir.buildImportedCopy(parentClassId).symbol)
else processor(it)
}
} else if (importedName.isSpecial || importedName.identifier.isNotEmpty()) {
for (symbol in provider.getTopLevelFunctionSymbols(import.packageFqName, importedName)) {
processor(symbol)
@@ -76,9 +81,18 @@ abstract class FirAbstractImportingScope(
for (import in imports) {
val importedName = name ?: import.importedName ?: continue
if (isExcluded(import, importedName)) continue
val staticsScope = import.resolvedParentClassId?.let(::getStaticsScope)
val parentClassId = import.resolvedParentClassId
val staticsScope = parentClassId?.let { getStaticsScope(it) }
if (staticsScope != null) {
staticsScope.processPropertiesByName(importedName, processor)
staticsScope.processPropertiesByName(importedName) {
if (it is FirPropertySymbol) {
if (it.isStatic) processor(it.fir.buildImportedCopy(parentClassId).symbol)
else processor(it)
} else {
processor(it)
}
}
} else if (importedName.isSpecial || importedName.identifier.isNotEmpty()) {
for (symbol in provider.getTopLevelPropertySymbols(import.packageFqName, importedName)) {
processor(symbol)
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationDataKey
import org.jetbrains.kotlin.fir.declarations.FirDeclarationDataRegistry
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildPropertyCopy
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunctionCopy
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
@@ -26,13 +23,7 @@ class FirObjectImportedCallableScope(
) : FirContainingNamesAwareScope() {
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
objectUseSiteScope.processFunctionsByName(name) wrapper@{ symbol ->
val function = symbol.fir
val syntheticFunction = buildSimpleFunctionCopy(function) {
origin = FirDeclarationOrigin.ImportedFromObjectOrStatic
this.symbol = FirNamedFunctionSymbol(CallableId(importedClassId, name))
}.apply {
importedFromObjectOrStaticData = ImportedFromObjectOrStaticData(importedClassId, function)
}
val syntheticFunction = symbol.fir.buildImportedCopy(importedClassId)
processor(syntheticFunction.symbol)
}
}
@@ -43,14 +34,7 @@ class FirObjectImportedCallableScope(
processor(symbol)
return@wrapper
}
val property = symbol.fir
val syntheticProperty = buildPropertyCopy(property) {
origin = FirDeclarationOrigin.ImportedFromObjectOrStatic
this.symbol = FirPropertySymbol(CallableId(importedClassId, name))
this.delegateFieldSymbol = null
}.apply {
importedFromObjectOrStaticData = ImportedFromObjectOrStaticData(importedClassId, property)
}
val syntheticProperty = symbol.fir.buildImportedCopy(importedClassId)
processor(syntheticProperty.symbol)
}
}
@@ -60,6 +44,25 @@ class FirObjectImportedCallableScope(
override fun getClassifierNames(): Set<Name> = emptySet()
}
internal fun FirSimpleFunction.buildImportedCopy(importedClassId: ClassId): FirSimpleFunction {
return buildSimpleFunctionCopy(this) {
origin = FirDeclarationOrigin.ImportedFromObjectOrStatic
this.symbol = FirNamedFunctionSymbol(CallableId(importedClassId, name))
}.apply {
importedFromObjectOrStaticData = ImportedFromObjectOrStaticData(importedClassId, this@buildImportedCopy)
}
}
internal fun FirProperty.buildImportedCopy(importedClassId: ClassId): FirProperty {
return buildPropertyCopy(this) {
origin = FirDeclarationOrigin.ImportedFromObjectOrStatic
this.symbol = FirPropertySymbol(CallableId(importedClassId, name))
this.delegateFieldSymbol = null
}.apply {
importedFromObjectOrStaticData = ImportedFromObjectOrStaticData(importedClassId, this@buildImportedCopy)
}
}
private object ImportedFromObjectOrStaticClassIdKey : FirDeclarationDataKey()
class ImportedFromObjectOrStaticData<D : FirCallableDeclaration>(