[IR] Implement checker for friendship of modules in fake override builder

- pass corresponding information to FO builder
 - implement check
 - fix KT-47192 and KT-48673
This commit is contained in:
Roman Artemev
2021-10-06 14:51:06 +03:00
committed by teamcityserver
parent ed8e7c754d
commit e6de812788
9 changed files with 56 additions and 33 deletions
@@ -458,7 +458,7 @@ val IrFunction.allParametersCount: Int
// This is essentially the same as FakeOverrideBuilder,
// but it bypasses SymbolTable.
// TODO: merge it with FakeOverrideBuilder.
private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy() {
private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy(emptyMap()) {
override fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction, compatibilityMode: Boolean) {
declaration.acquireSymbol(IrSimpleFunctionSymbolImpl())
@@ -22,9 +22,10 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.Variance
abstract class FakeOverrideBuilderStrategy {
abstract class FakeOverrideBuilderStrategy(private val friendModules: Map<String, Collection<String>>) {
open fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember =
buildFakeOverrideMember(superType, member, clazz)
buildFakeOverrideMember(superType, member, clazz, friendModules)
fun linkFakeOverride(fakeOverride: IrOverridableMember, compatibilityMode: Boolean) {
when (fakeOverride) {
@@ -38,7 +39,7 @@ abstract class FakeOverrideBuilderStrategy {
protected abstract fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty, compatibilityMode: Boolean)
}
private fun IrOverridableMember.isPrivateToThisModule(thisClass: IrClass, memberClass: IrClass): Boolean {
private fun IrOverridableMember.isPrivateToThisModule(thisClass: IrClass, memberClass: IrClass, friendModules: Map<String, Collection<String>>): Boolean {
if (visibility != DescriptorVisibilities.INTERNAL) return false
val thisModule = thisClass.fileOrNull?.module
val memberModule = memberClass.fileOrNull?.module
@@ -48,18 +49,31 @@ private fun IrOverridableMember.isPrivateToThisModule(thisClass: IrClass, member
if (thisModule == null || memberModule == null) return false
return !isInFriendModules(thisModule, memberModule)
return !isInFriendModules(thisModule, memberModule, friendModules)
}
@Suppress("UNUSED_PARAMETER")
private fun isInFriendModules(thisModule: IrModuleFragment, friendModule: IrModuleFragment): Boolean {
// TODO: check if [friendModule] is a friend of [thisModule]
// See: KT-47192
private fun isInFriendModules(
fromModule: IrModuleFragment,
toModule: IrModuleFragment,
friendModules: Map<String, Collection<String>>
): Boolean {
return false
if (friendModules.isEmpty()) return false
val fromModuleName = fromModule.name.asStringStripSpecialMarkers()
val fromFriends = friendModules[fromModuleName] ?: return false
val toModuleName = toModule.name.asStringStripSpecialMarkers()
return toModuleName in fromFriends
}
fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember {
return buildFakeOverrideMember(superType, member, clazz, emptyMap())
}
fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass, friendModules: Map<String, Collection<String>>): IrOverridableMember {
require(superType is IrSimpleType) { "superType is $superType, expected IrSimpleType" }
val classifier = superType.classifier
require(classifier is IrClassSymbol) { "superType classifier is not IrClassSymbol: $classifier" }
@@ -83,7 +97,7 @@ fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, claz
val copier = DeepCopyIrTreeWithSymbolsForFakeOverrides(substitutionMap)
val deepCopyFakeOverride = copier.copy(member, clazz) as IrOverridableMember
deepCopyFakeOverride.parent = clazz
if (deepCopyFakeOverride.isPrivateToThisModule(clazz, classifier.owner))
if (deepCopyFakeOverride.isPrivateToThisModule(clazz, classifier.owner, friendModules))
deepCopyFakeOverride.visibility = DescriptorVisibilities.INVISIBLE_FAKE
return deepCopyFakeOverride
@@ -68,11 +68,12 @@ class FakeOverrideBuilder(
val symbolTable: SymbolTable,
mangler: KotlinMangler.IrMangler,
typeSystem: IrTypeSystemContext,
friendModules: Map<String, Collection<String>>,
val platformSpecificClassFilter: FakeOverrideClassFilter = DefaultFakeOverrideClassFilter,
private val fakeOverrideDeclarationTable: DeclarationTable = FakeOverrideDeclarationTable(mangler) { builder, table ->
IdSignatureSerializer(builder, table)
}
) : FakeOverrideBuilderStrategy() {
) : FakeOverrideBuilderStrategy(friendModules) {
private val haveFakeOverrides = mutableSetOf<IrClass>()
private val irOverridingUtil = IrOverridingUtil(typeSystem, this)
@@ -277,6 +277,8 @@ fun loadIr(
JsIrLinker.JsFePluginContext(moduleDescriptor, symbolTable, typeTranslator, irBuiltIns)
}
val moduleFragmentToUniqueName = mutableMapOf<IrModuleFragment, String>()
val friendModules =
mapOf(psi2IrContext.moduleDescriptor.name.asString() to depsDescriptors.friendDependencies.map { it.library.uniqueName })
val irLinker =
JsIrLinker(
psi2IrContext.moduleDescriptor,
@@ -285,7 +287,8 @@ fun loadIr(
symbolTable,
feContext,
null,
depsDescriptors.loweredIcData
depsDescriptors.loweredIcData,
friendModules
)
val deserializedModuleFragments = sortDependencies(allDependencies, depsDescriptors.descriptors).map { klib ->
irLinker.deserializeIrModuleHeader(
@@ -345,6 +348,8 @@ fun loadIr(
result
}
val friendModules = mapOf(mainModuleLib.uniqueName to depsDescriptors.friendDependencies.map { it.library.uniqueName })
val irLinker =
JsIrLinker(
null,
@@ -353,7 +358,8 @@ fun loadIr(
symbolTable,
null,
null,
loweredIcData
loweredIcData,
friendModules
)
val moduleFragmentToUniqueName = mutableMapOf<IrModuleFragment, String>()
@@ -30,9 +30,10 @@ class JsIrLinker(
override val translationPluginContext: TranslationPluginContext?,
private val icData: ICData? = null,
private val loweredIcData: Map<ModuleDescriptor, SerializedIcData> = emptyMap(),
friendModules: Map<String, Collection<String>> = emptyMap()
) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, emptyList()) {
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JsManglerIr, IrTypeSystemContextImpl(builtIns))
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JsManglerIr, IrTypeSystemContextImpl(builtIns), friendModules)
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean =
moduleDescriptor === moduleDescriptor.builtIns.builtInsModule
@@ -233,7 +233,8 @@ fun makeSimpleFakeOverrideBuilder(
symbolTable,
JvmIrMangler,
typeSystemContext,
fakeOverrideDeclarationTable = PrePopulatedDeclarationTable(symbolDeserializer.deserializedSymbols)
fakeOverrideDeclarationTable = PrePopulatedDeclarationTable(symbolDeserializer.deserializedSymbols),
friendModules = emptyMap() // TODO: provide friend modules
)
}
@@ -41,7 +41,8 @@ class JvmIrLinker(
private val manglerDesc: JvmDescriptorMangler
) : KotlinIrLinker(currentModule, messageLogger, typeSystem.irBuiltIns, symbolTable, emptyList()) {
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JvmIrMangler, typeSystem)
// TODO: provide friend modules
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JvmIrMangler, typeSystem, emptyMap())
private val javaName = Name.identifier("java")