[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, // This is essentially the same as FakeOverrideBuilder,
// but it bypasses SymbolTable. // but it bypasses SymbolTable.
// TODO: merge it with FakeOverrideBuilder. // TODO: merge it with FakeOverrideBuilder.
private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy() { private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy(emptyMap()) {
override fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction, compatibilityMode: Boolean) { override fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction, compatibilityMode: Boolean) {
declaration.acquireSymbol(IrSimpleFunctionSymbolImpl()) declaration.acquireSymbol(IrSimpleFunctionSymbolImpl())
@@ -22,9 +22,10 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.TypeCheckerState import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.Variance 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 = 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) { fun linkFakeOverride(fakeOverride: IrOverridableMember, compatibilityMode: Boolean) {
when (fakeOverride) { when (fakeOverride) {
@@ -38,7 +39,7 @@ abstract class FakeOverrideBuilderStrategy {
protected abstract fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty, compatibilityMode: Boolean) 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 if (visibility != DescriptorVisibilities.INTERNAL) return false
val thisModule = thisClass.fileOrNull?.module val thisModule = thisClass.fileOrNull?.module
val memberModule = memberClass.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 if (thisModule == null || memberModule == null) return false
return !isInFriendModules(thisModule, memberModule) return !isInFriendModules(thisModule, memberModule, friendModules)
} }
@Suppress("UNUSED_PARAMETER") private fun isInFriendModules(
private fun isInFriendModules(thisModule: IrModuleFragment, friendModule: IrModuleFragment): Boolean { fromModule: IrModuleFragment,
// TODO: check if [friendModule] is a friend of [thisModule] toModule: IrModuleFragment,
// See: KT-47192 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 { 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" } require(superType is IrSimpleType) { "superType is $superType, expected IrSimpleType" }
val classifier = superType.classifier val classifier = superType.classifier
require(classifier is IrClassSymbol) { "superType classifier is not IrClassSymbol: $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 copier = DeepCopyIrTreeWithSymbolsForFakeOverrides(substitutionMap)
val deepCopyFakeOverride = copier.copy(member, clazz) as IrOverridableMember val deepCopyFakeOverride = copier.copy(member, clazz) as IrOverridableMember
deepCopyFakeOverride.parent = clazz deepCopyFakeOverride.parent = clazz
if (deepCopyFakeOverride.isPrivateToThisModule(clazz, classifier.owner)) if (deepCopyFakeOverride.isPrivateToThisModule(clazz, classifier.owner, friendModules))
deepCopyFakeOverride.visibility = DescriptorVisibilities.INVISIBLE_FAKE deepCopyFakeOverride.visibility = DescriptorVisibilities.INVISIBLE_FAKE
return deepCopyFakeOverride return deepCopyFakeOverride
@@ -68,11 +68,12 @@ class FakeOverrideBuilder(
val symbolTable: SymbolTable, val symbolTable: SymbolTable,
mangler: KotlinMangler.IrMangler, mangler: KotlinMangler.IrMangler,
typeSystem: IrTypeSystemContext, typeSystem: IrTypeSystemContext,
friendModules: Map<String, Collection<String>>,
val platformSpecificClassFilter: FakeOverrideClassFilter = DefaultFakeOverrideClassFilter, val platformSpecificClassFilter: FakeOverrideClassFilter = DefaultFakeOverrideClassFilter,
private val fakeOverrideDeclarationTable: DeclarationTable = FakeOverrideDeclarationTable(mangler) { builder, table -> private val fakeOverrideDeclarationTable: DeclarationTable = FakeOverrideDeclarationTable(mangler) { builder, table ->
IdSignatureSerializer(builder, table) IdSignatureSerializer(builder, table)
} }
) : FakeOverrideBuilderStrategy() { ) : FakeOverrideBuilderStrategy(friendModules) {
private val haveFakeOverrides = mutableSetOf<IrClass>() private val haveFakeOverrides = mutableSetOf<IrClass>()
private val irOverridingUtil = IrOverridingUtil(typeSystem, this) private val irOverridingUtil = IrOverridingUtil(typeSystem, this)
@@ -277,6 +277,8 @@ fun loadIr(
JsIrLinker.JsFePluginContext(moduleDescriptor, symbolTable, typeTranslator, irBuiltIns) JsIrLinker.JsFePluginContext(moduleDescriptor, symbolTable, typeTranslator, irBuiltIns)
} }
val moduleFragmentToUniqueName = mutableMapOf<IrModuleFragment, String>() val moduleFragmentToUniqueName = mutableMapOf<IrModuleFragment, String>()
val friendModules =
mapOf(psi2IrContext.moduleDescriptor.name.asString() to depsDescriptors.friendDependencies.map { it.library.uniqueName })
val irLinker = val irLinker =
JsIrLinker( JsIrLinker(
psi2IrContext.moduleDescriptor, psi2IrContext.moduleDescriptor,
@@ -285,7 +287,8 @@ fun loadIr(
symbolTable, symbolTable,
feContext, feContext,
null, null,
depsDescriptors.loweredIcData depsDescriptors.loweredIcData,
friendModules
) )
val deserializedModuleFragments = sortDependencies(allDependencies, depsDescriptors.descriptors).map { klib -> val deserializedModuleFragments = sortDependencies(allDependencies, depsDescriptors.descriptors).map { klib ->
irLinker.deserializeIrModuleHeader( irLinker.deserializeIrModuleHeader(
@@ -345,6 +348,8 @@ fun loadIr(
result result
} }
val friendModules = mapOf(mainModuleLib.uniqueName to depsDescriptors.friendDependencies.map { it.library.uniqueName })
val irLinker = val irLinker =
JsIrLinker( JsIrLinker(
null, null,
@@ -353,7 +358,8 @@ fun loadIr(
symbolTable, symbolTable,
null, null,
null, null,
loweredIcData loweredIcData,
friendModules
) )
val moduleFragmentToUniqueName = mutableMapOf<IrModuleFragment, String>() val moduleFragmentToUniqueName = mutableMapOf<IrModuleFragment, String>()
@@ -30,9 +30,10 @@ class JsIrLinker(
override val translationPluginContext: TranslationPluginContext?, override val translationPluginContext: TranslationPluginContext?,
private val icData: ICData? = null, private val icData: ICData? = null,
private val loweredIcData: Map<ModuleDescriptor, SerializedIcData> = emptyMap(), private val loweredIcData: Map<ModuleDescriptor, SerializedIcData> = emptyMap(),
friendModules: Map<String, Collection<String>> = emptyMap()
) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, emptyList()) { ) : 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 = override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean =
moduleDescriptor === moduleDescriptor.builtIns.builtInsModule moduleDescriptor === moduleDescriptor.builtIns.builtInsModule
@@ -233,7 +233,8 @@ fun makeSimpleFakeOverrideBuilder(
symbolTable, symbolTable,
JvmIrMangler, JvmIrMangler,
typeSystemContext, 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 private val manglerDesc: JvmDescriptorMangler
) : KotlinIrLinker(currentModule, messageLogger, typeSystem.irBuiltIns, symbolTable, emptyList()) { ) : 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") private val javaName = Name.identifier("java")
@@ -94,12 +94,15 @@ internal fun Context.psiToIr(
get() = generatorContext.irBuiltIns get() = generatorContext.irBuiltIns
} }
val friendModules = emptyMap<String, Collection<String>>() // TODO: provide friend modules
KonanIrLinker( KonanIrLinker(
moduleDescriptor, moduleDescriptor,
translationContext, translationContext,
messageLogger, messageLogger,
generatorContext.irBuiltIns, generatorContext.irBuiltIns,
symbolTable, symbolTable,
friendModules,
forwardDeclarationsModuleDescriptor, forwardDeclarationsModuleDescriptor,
stubGenerator, stubGenerator,
irProviderForCEnumsAndCStructs, 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.*
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinaryNameAndType 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.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.encodings.FunctionFlags
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.UserVisibleIrModulesSupport
import org.jetbrains.kotlin.backend.konan.* 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.ClassLayoutBuilder
import org.jetbrains.kotlin.backend.konan.descriptors.findPackage import org.jetbrains.kotlin.backend.konan.descriptors.findPackage
import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary 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.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
import org.jetbrains.kotlin.ir.expressions.IrBody 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.symbols.impl.IrPublicSymbolBase
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl import org.jetbrains.kotlin.ir.types.*
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.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor 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.name.Name
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.backend.common.serialization.proto.IrFile as ProtoFile import sun.misc.Unsafe
import org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclaration as ProtoDeclaration
import org.jetbrains.kotlin.backend.common.serialization.proto.IrClass as ProtoClass 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.IrFunction as ProtoFunction
import org.jetbrains.kotlin.backend.common.serialization.proto.IrProperty as ProtoProperty 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")) { private val unsafe = with(Unsafe::class.java.getDeclaredField("theUnsafe")) {
isAccessible = true isAccessible = true
@@ -313,13 +308,14 @@ internal class KonanIrLinker(
messageLogger: IrMessageLogger, messageLogger: IrMessageLogger,
builtIns: IrBuiltIns, builtIns: IrBuiltIns,
symbolTable: SymbolTable, symbolTable: SymbolTable,
friendModules: Map<String, Collection<String>>,
private val forwardModuleDescriptor: ModuleDescriptor?, private val forwardModuleDescriptor: ModuleDescriptor?,
private val stubGenerator: DeclarationStubGenerator, private val stubGenerator: DeclarationStubGenerator,
private val cenumsProvider: IrProviderForCEnumAndCStructStubs, private val cenumsProvider: IrProviderForCEnumAndCStructStubs,
exportedDependencies: List<ModuleDescriptor>, exportedDependencies: List<ModuleDescriptor>,
private val cachedLibraries: CachedLibraries, private val cachedLibraries: CachedLibraries,
private val lazyIrForCaches: Boolean, private val lazyIrForCaches: Boolean,
override val userVisibleIrModulesSupport: UserVisibleIrModulesSupport override val userVisibleIrModulesSupport: UserVisibleIrModulesSupport,
) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, exportedDependencies) { ) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, exportedDependencies) {
companion object { companion object {
@@ -335,7 +331,7 @@ internal class KonanIrLinker(
private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserializer(it) } private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserializer(it) }
override val fakeOverrideBuilder: FakeOverrideBuilder = 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 nonCachedLibraryModuleDeserializers = mutableMapOf<ModuleDescriptor, KonanModuleDeserializer>()
val cachedLibraryModuleDeserializers = mutableMapOf<ModuleDescriptor, KonanCachedLibraryModuleDeserializer>() val cachedLibraryModuleDeserializers = mutableMapOf<ModuleDescriptor, KonanCachedLibraryModuleDeserializer>()
@@ -656,7 +652,7 @@ internal class KonanIrLinker(
override fun tryReferencingPropertyByLocalSignature(parent: IrDeclaration, idSignature: IdSignature) = override fun tryReferencingPropertyByLocalSignature(parent: IrDeclaration, idSignature: IdSignature) =
if (idSignature.isPubliclyVisible) null else symbolDeserializer.referencePropertyByLocalSignature(idSignature) if (idSignature.isPubliclyVisible) null else symbolDeserializer.referencePropertyByLocalSignature(idSignature)
}, },
symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), KonanFakeOverrideClassFilter) symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), emptyMap(), KonanFakeOverrideClassFilter)
val declarationDeserializer = IrDeclarationDeserializer( val declarationDeserializer = IrDeclarationDeserializer(
builtIns, builtIns,