[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")
@@ -94,12 +94,15 @@ internal fun Context.psiToIr(
get() = generatorContext.irBuiltIns
}
val friendModules = emptyMap<String, Collection<String>>() // TODO: provide friend modules
KonanIrLinker(
moduleDescriptor,
translationContext,
messageLogger,
generatorContext.irBuiltIns,
symbolTable,
friendModules,
forwardDeclarationsModuleDescriptor,
stubGenerator,
irProviderForCEnumsAndCStructs,
@@ -23,11 +23,9 @@ import org.jetbrains.kotlin.backend.common.overrides.FileLocalAwareLinker
import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinaryNameAndType
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.UserVisibleIrModulesSupport
import org.jetbrains.kotlin.backend.konan.CachedLibraries
import org.jetbrains.kotlin.backend.common.serialization.encodings.FunctionFlags
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.UserVisibleIrModulesSupport
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.InlineFunctionOriginInfo
import org.jetbrains.kotlin.backend.konan.descriptors.ClassLayoutBuilder
import org.jetbrains.kotlin.backend.konan.descriptors.findPackage
import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary
@@ -43,13 +41,10 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.types.getPublicSignature
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -60,13 +55,13 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.backend.common.serialization.proto.IrFile as ProtoFile
import org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclaration as ProtoDeclaration
import sun.misc.Unsafe
import org.jetbrains.kotlin.backend.common.serialization.proto.IrClass as ProtoClass
import org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclaration as ProtoDeclaration
import org.jetbrains.kotlin.backend.common.serialization.proto.IrField as ProtoField
import org.jetbrains.kotlin.backend.common.serialization.proto.IrFile as ProtoFile
import org.jetbrains.kotlin.backend.common.serialization.proto.IrFunction as ProtoFunction
import org.jetbrains.kotlin.backend.common.serialization.proto.IrProperty as ProtoProperty
import org.jetbrains.kotlin.backend.common.serialization.proto.IrField as ProtoField
import sun.misc.Unsafe
private val unsafe = with(Unsafe::class.java.getDeclaredField("theUnsafe")) {
isAccessible = true
@@ -313,13 +308,14 @@ internal class KonanIrLinker(
messageLogger: IrMessageLogger,
builtIns: IrBuiltIns,
symbolTable: SymbolTable,
friendModules: Map<String, Collection<String>>,
private val forwardModuleDescriptor: ModuleDescriptor?,
private val stubGenerator: DeclarationStubGenerator,
private val cenumsProvider: IrProviderForCEnumAndCStructStubs,
exportedDependencies: List<ModuleDescriptor>,
private val cachedLibraries: CachedLibraries,
private val lazyIrForCaches: Boolean,
override val userVisibleIrModulesSupport: UserVisibleIrModulesSupport
override val userVisibleIrModulesSupport: UserVisibleIrModulesSupport,
) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, exportedDependencies) {
companion object {
@@ -335,7 +331,7 @@ internal class KonanIrLinker(
private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserializer(it) }
override val fakeOverrideBuilder: FakeOverrideBuilder =
FakeOverrideBuilder(this, symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), KonanFakeOverrideClassFilter)
FakeOverrideBuilder(this, symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), friendModules, KonanFakeOverrideClassFilter)
val nonCachedLibraryModuleDeserializers = mutableMapOf<ModuleDescriptor, KonanModuleDeserializer>()
val cachedLibraryModuleDeserializers = mutableMapOf<ModuleDescriptor, KonanCachedLibraryModuleDeserializer>()
@@ -656,7 +652,7 @@ internal class KonanIrLinker(
override fun tryReferencingPropertyByLocalSignature(parent: IrDeclaration, idSignature: IdSignature) =
if (idSignature.isPubliclyVisible) null else symbolDeserializer.referencePropertyByLocalSignature(idSignature)
},
symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), KonanFakeOverrideClassFilter)
symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), emptyMap(), KonanFakeOverrideClassFilter)
val declarationDeserializer = IrDeclarationDeserializer(
builtIns,