[Commonizer] Remove old mergers

This commit is contained in:
sebastian.sellmair
2021-04-09 10:34:09 +02:00
parent 14161c8250
commit d0f8395556
10 changed files with 0 additions and 514 deletions
@@ -1,99 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.commonizer.mergedtree
import kotlinx.metadata.KmTypeParameter
import org.jetbrains.kotlin.commonizer.CommonizerParameters
import org.jetbrains.kotlin.commonizer.CommonizerTarget
import org.jetbrains.kotlin.commonizer.LeafCommonizerTarget
import org.jetbrains.kotlin.commonizer.ModulesProvider.ModuleInfo
import org.jetbrains.kotlin.commonizer.mergedtree.mergers.*
import org.jetbrains.kotlin.commonizer.mergedtree.mergers.ClassesToProcess
import org.jetbrains.kotlin.commonizer.mergedtree.mergers.ModuleMerger
import org.jetbrains.kotlin.commonizer.mergedtree.mergers.PropertyMerger
import org.jetbrains.kotlin.commonizer.mergedtree.mergers.RootMerger
import org.jetbrains.kotlin.commonizer.mergedtree.mergers.TargetMerger
import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver
import org.jetbrains.kotlin.storage.StorageManager
/**
* N.B. Limitations on C/Obj-C interop.
*
* [Case 1]: An interop library with two fragments for two targets. The first fragment has a forward declaration of classifier A.
* The second one has a definition of class A. Both fragments have a top-level callable (ex: function)
* with the same signature that refers to type "A" as its return type.
*
* What will happen: Forward declarations will be ignored during building CIR merged tree. So the node for class A
* will contain CirClass "A" for the second target only. This node will not succeed in commonization, and no common class
* declaration will be produced. As a result the top-level callable will not be commonized, as it refers to the type "A"
* that is not formally commonized.
*
* This is not strictly correct: The classifier "A" exists in both targets though in different form. So if the user
* would write shared source code that uses "A" and the callable, then this code would successfully compile against both targets.
*
* The reason why commonization of such classifiers is not supported yet is that this is quite a rare case that requires
* a complex implementation with potential performance penalty.
*
* [Case 2]: A library with two fragments for two targets. The first fragment is interop. The second one is not.
* Similarly to case 1, the 1st fragment has a forward declaration of a classifier, and the 2nd has a real classifier.
*
* At the moment, this is an exotic case. It could happen if someone tries to commonize an MPP library for Native and non-Native
* targets (which is not supported yet), or a Native library where one fragment is produced via C-interop tool and the other one
* is compiled from Kotlin/Native source code (not sure this should be supported at all).
*/
class CirTreeMergeResult(
val root: CirRootNode,
val missingModuleInfos: Map<CommonizerTarget, Collection<ModuleInfo>>
)
internal class CirTargetMergingContext(
val storageManager: StorageManager,
val classifiers: CirKnownClassifiers,
val parameters: CommonizerParameters,
val targetIndex: Int,
val typeResolver: CirTypeResolver
) {
val targets = parameters.targetProviders.size
}
internal fun CirTargetMergingContext.create(classEntry: ClassesToProcess.ClassEntry): CirTargetMergingContext = when (classEntry) {
is ClassesToProcess.ClassEntry.RegularClassEntry -> create(classEntry.clazz.typeParameters)
is ClassesToProcess.ClassEntry.EnumEntry -> this
}
internal fun CirTargetMergingContext.create(typeParameters: List<KmTypeParameter>): CirTargetMergingContext {
val newTypeResolver = typeResolver.create(typeParameters)
return if (newTypeResolver !== typeResolver)
CirTargetMergingContext(storageManager, classifiers, parameters, targetIndex, newTypeResolver)
else
this
}
fun mergeCirTree(
storageManager: StorageManager,
classifiers: CirKnownClassifiers,
parameters: CommonizerParameters
): CirTreeMergeResult {
val rootMerger = RootMerger(
targetMerger = TargetMerger(
moduleMerger = ModuleMerger(
packageMerger = PackageMerger(
propertyMerger = PropertyMerger,
functionMerger = FunctionMerger,
classMerger = ClassMerger(
classConstructorMerger = ClassConstructorMerger,
propertyMerger = PropertyMerger,
functionMerger = FunctionMerger,
),
typeAliasMerger = TypeAliasMerger
)
)
)
)
return rootMerger.processRoot(storageManager, classifiers, parameters)
}
@@ -1,30 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.commonizer.mergedtree.mergers
import kotlinx.metadata.KmConstructor
import org.jetbrains.kotlin.commonizer.mergedtree.*
import org.jetbrains.kotlin.commonizer.mergedtree.CirTargetMergingContext
import org.jetbrains.kotlin.commonizer.mergedtree.buildClassConstructorNode
import org.jetbrains.kotlin.commonizer.metadata.CirDeserializers
internal object ClassConstructorMerger {
fun processClassConstructor(
context: CirTargetMergingContext,
classNode: CirClassNode,
constructor: KmConstructor
) = with(context) {
val approximationKey = ConstructorApproximationKey(constructor, context.typeResolver)
val constructorNode: CirClassConstructorNode = classNode.constructors.getOrPut(approximationKey) {
buildClassConstructorNode(storageManager, targets, classifiers, classNode.commonDeclaration)
}
constructorNode.targetDeclarations[context.targetIndex] = CirDeserializers.constructor(
source = constructor,
containingClass = classNode.targetDeclarations[context.targetIndex]!!,
typeResolver = context.typeResolver
)
}
}
@@ -1,80 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.commonizer.mergedtree.mergers
import kotlinx.metadata.Flag
import kotlinx.metadata.KmClass
import org.jetbrains.kotlin.commonizer.mergedtree.*
import org.jetbrains.kotlin.commonizer.mergedtree.CirTargetMergingContext
import org.jetbrains.kotlin.commonizer.mergedtree.buildClassNode
import org.jetbrains.kotlin.commonizer.metadata.CirDeserializers
internal class ClassMerger(
private val classConstructorMerger: ClassConstructorMerger?,
private val propertyMerger: PropertyMerger?,
private val functionMerger: FunctionMerger?
) {
fun processClass(
context: CirTargetMergingContext,
ownerNode: CirNodeWithMembers<*, *>,
classEntry: ClassesToProcess.ClassEntry,
classesToProcess: ClassesToProcess
): Unit = with(context) {
val classId = classEntry.classId
val className = classId.relativeNameSegments.last()
val maybeClassOwnerNode: CirClassNode? = ownerNode as? CirClassNode
val classNode: CirClassNode = ownerNode.classes.getOrPut(className) {
buildClassNode(storageManager, targets, classifiers, maybeClassOwnerNode?.commonDeclaration, classId)
}
val clazz: KmClass?
val isEnumEntry: Boolean
classNode.targetDeclarations[context.targetIndex] = when (classEntry) {
is ClassesToProcess.ClassEntry.RegularClassEntry -> {
clazz = classEntry.clazz
isEnumEntry = Flag.Class.IS_ENUM_ENTRY(clazz.flags)
CirDeserializers.clazz(className, clazz, context.typeResolver)
}
is ClassesToProcess.ClassEntry.EnumEntry -> {
clazz = null
isEnumEntry = true
CirDeserializers.defaultEnumEntry(
name = className,
annotations = classEntry.annotations,
enumClassId = classEntry.enumClassId,
enumClass = classEntry.enumClass,
typeResolver = context.typeResolver
)
}
}
if (!isEnumEntry) {
clazz?.constructors?.forEach { constructor ->
// TODO: nowhere to read constructor type parameters from
//val constructorContext = context.create(constructor.typeParameters)
classConstructorMerger?.processClassConstructor(context, classNode, constructor)
}
}
clazz?.properties?.forEach { property ->
val propertyContext = context.create(property.typeParameters)
propertyMerger?.processProperty(propertyContext, classNode, property)
}
clazz?.functions?.forEach { function ->
val functionContext = context.create(function.typeParameters)
functionMerger?.processFunction(functionContext, classNode, function)
}
classesToProcess.forEachClassInScope(parentClassId = classId) { nestedClassEntry ->
val nestedClassContext = context.create(nestedClassEntry)
processClass(nestedClassContext, classNode, nestedClassEntry, classesToProcess)
}
}
}
@@ -1,43 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.commonizer.mergedtree.mergers
import kotlinx.metadata.KmFunction
import org.jetbrains.kotlin.commonizer.mergedtree.*
import org.jetbrains.kotlin.commonizer.mergedtree.CirTargetMergingContext
import org.jetbrains.kotlin.commonizer.mergedtree.buildFunctionNode
import org.jetbrains.kotlin.commonizer.metadata.CirDeserializers
import org.jetbrains.kotlin.commonizer.utils.isFakeOverride
import org.jetbrains.kotlin.commonizer.utils.isKniBridgeFunction
import org.jetbrains.kotlin.commonizer.utils.isTopLevelDeprecatedFunction
internal object FunctionMerger {
fun processFunction(
context: CirTargetMergingContext,
ownerNode: CirNodeWithMembers<*, *>,
function: KmFunction
) = with(context) {
if (function.isFakeOverride()
|| function.isKniBridgeFunction()
|| function.isTopLevelDeprecatedFunction(isTopLevel = ownerNode !is CirClassNode)
) {
return
}
val maybeClassOwnerNode: CirClassNode? = ownerNode as? CirClassNode
val approximationKey = FunctionApproximationKey(function, context.typeResolver)
val functionNode: CirFunctionNode = ownerNode.functions.getOrPut(approximationKey) {
buildFunctionNode(storageManager, targets, classifiers, maybeClassOwnerNode?.commonDeclaration)
}
functionNode.targetDeclarations[context.targetIndex] = CirDeserializers.function(
name = approximationKey.name,
source = function,
containingClass = maybeClassOwnerNode?.targetDeclarations?.get(context.targetIndex),
typeResolver = context.typeResolver
)
}
}
@@ -1,42 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.commonizer.mergedtree.mergers
import kotlinx.metadata.KmModuleFragment
import kotlinx.metadata.klib.KlibModuleMetadata
import kotlinx.metadata.klib.fqName
import org.jetbrains.kotlin.commonizer.cir.CirModule
import org.jetbrains.kotlin.commonizer.cir.CirName
import org.jetbrains.kotlin.commonizer.cir.CirPackageName
import org.jetbrains.kotlin.commonizer.mergedtree.CirModuleNode
import org.jetbrains.kotlin.commonizer.mergedtree.CirRootNode
import org.jetbrains.kotlin.commonizer.mergedtree.CirTargetMergingContext
import org.jetbrains.kotlin.commonizer.mergedtree.buildModuleNode
import org.jetbrains.kotlin.commonizer.utils.foldToMap
internal class ModuleMerger(
private val packageMerger: PackageMerger
) {
fun processModule(
context: CirTargetMergingContext,
rootNode: CirRootNode,
module: KlibModuleMetadata
): Unit = with(context) {
val moduleName: CirName = CirName.create(module.name)
val moduleNode: CirModuleNode = rootNode.modules.getOrPut(moduleName) {
buildModuleNode(storageManager, targets)
}
moduleNode.targetDeclarations[context.targetIndex] = CirModule.create(moduleName)
val groupedFragments: Map<CirPackageName, Collection<KmModuleFragment>> = module.fragments.foldToMap { fragment ->
fragment.fqName?.let(CirPackageName.Companion::create) ?: error("A fragment without FQ name in module $moduleName: $fragment")
}
groupedFragments.forEach { (packageName, fragments) ->
packageMerger.processFragments(context, moduleNode, fragments, packageName)
}
}
}
@@ -1,58 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.commonizer.mergedtree.mergers
import kotlinx.metadata.KmModuleFragment
import kotlinx.metadata.KmTypeParameter
import org.jetbrains.kotlin.commonizer.cir.CirPackage
import org.jetbrains.kotlin.commonizer.cir.CirPackageName
import org.jetbrains.kotlin.commonizer.mergedtree.*
import org.jetbrains.kotlin.commonizer.mergedtree.CirTargetMergingContext
import org.jetbrains.kotlin.commonizer.mergedtree.buildPackageNode
internal class PackageMerger(
private val propertyMerger: PropertyMerger?,
private val functionMerger: FunctionMerger?,
private val classMerger: ClassMerger?,
private val typeAliasMerger: TypeAliasMerger?
) {
fun processFragments(
context: CirTargetMergingContext,
moduleNode: CirModuleNode,
fragments: Collection<KmModuleFragment>,
packageName: CirPackageName
): Unit = with(context) {
val packageNode: CirPackageNode = moduleNode.packages.getOrPut(packageName) {
buildPackageNode(storageManager, targets)
}
packageNode.targetDeclarations[context.targetIndex] = CirPackage.create(packageName)
val classesToProcess = ClassesToProcess()
fragments.forEach { fragment ->
classesToProcess.addClassesFromFragment(fragment)
fragment.pkg?.let { pkg ->
pkg.properties.forEach { property ->
val propertyContext = context.create(property.typeParameters)
propertyMerger?.processProperty(propertyContext, packageNode, property)
}
pkg.functions.forEach { function ->
val functionContext = context.create(function.typeParameters)
functionMerger?.processFunction(functionContext, packageNode, function)
}
pkg.typeAliases.forEach { typeAlias ->
val typeAliasContext = context.create(typeAlias.typeParameters)
typeAliasMerger?.processTypeAlias(typeAliasContext, packageNode, typeAlias)
}
}
}
classesToProcess.forEachClassInScope(parentClassId = null) { classEntry ->
val classContext = context.create(classEntry)
classMerger?.processClass(classContext, packageNode, classEntry, classesToProcess)
}
}
}
@@ -1,37 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.commonizer.mergedtree.mergers
import kotlinx.metadata.KmProperty
import org.jetbrains.kotlin.commonizer.mergedtree.*
import org.jetbrains.kotlin.commonizer.mergedtree.CirTargetMergingContext
import org.jetbrains.kotlin.commonizer.mergedtree.buildPropertyNode
import org.jetbrains.kotlin.commonizer.metadata.CirDeserializers
import org.jetbrains.kotlin.commonizer.utils.isFakeOverride
internal object PropertyMerger {
fun processProperty(
context: CirTargetMergingContext,
ownerNode: CirNodeWithMembers<*, *>,
property: KmProperty
) = with(context) {
if (property.isFakeOverride())
return
val maybeClassOwnerNode: CirClassNode? = ownerNode as? CirClassNode
val approximationKey = PropertyApproximationKey(property, context.typeResolver)
val propertyNode: CirPropertyNode = ownerNode.properties.getOrPut(approximationKey) {
buildPropertyNode(storageManager, targets, classifiers, maybeClassOwnerNode?.commonDeclaration)
}
propertyNode.targetDeclarations[context.targetIndex] = CirDeserializers.property(
name = approximationKey.name,
source = property,
containingClass = maybeClassOwnerNode?.targetDeclarations?.get(context.targetIndex),
typeResolver = context.typeResolver
)
}
}
@@ -1,53 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.commonizer.mergedtree.mergers
import org.jetbrains.kotlin.commonizer.*
import org.jetbrains.kotlin.commonizer.mergedtree.*
import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver
import org.jetbrains.kotlin.storage.StorageManager
internal class RootMerger(
private val targetMerger: TargetMerger
) {
fun processRoot(
storageManager: StorageManager,
classifiers: CirKnownClassifiers,
parameters: CommonizerParameters
): CirTreeMergeResult {
val rootNode: CirRootNode = buildRootNode(storageManager, parameters.targetProviders.size)
val commonModuleNames = parameters.getCommonModuleNames()
val missingModuleInfosByTargets = mutableMapOf<CommonizerTarget, Collection<ModulesProvider.ModuleInfo>>()
parameters.targetProviders.filterNotNull().forEachIndexed { targetIndex, targetProvider ->
val allModuleInfos = targetProvider.modulesProvider.loadModuleInfos()
val (commonModuleInfos, missingModuleInfos) = allModuleInfos.partition { it.name in commonModuleNames }
val typeResolver = CirTypeResolver.create(
providedClassifiers = CirProvidedClassifiers.of(
CirProvidedClassifiers.by(targetProvider.modulesProvider),
parameters.dependencyClassifiers(targetProvider.target)
)
)
targetMerger.processTarget(
CirTargetMergingContext(
storageManager, classifiers, parameters, targetIndex, typeResolver
), rootNode, targetProvider, commonModuleInfos
)
missingModuleInfosByTargets[targetProvider.target] = missingModuleInfos
parameters.progressLogger?.invoke("Loaded declarations for ${targetProvider.target.prettyName}")
System.gc()
}
return CirTreeMergeResult(
root = rootNode,
missingModuleInfos = missingModuleInfosByTargets
)
}
}
@@ -1,37 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.commonizer.mergedtree.mergers
import kotlinx.metadata.klib.KlibModuleMetadata
import org.jetbrains.kotlin.commonizer.ModulesProvider
import org.jetbrains.kotlin.commonizer.TargetProvider
import org.jetbrains.kotlin.commonizer.cir.CirRoot
import org.jetbrains.kotlin.commonizer.mergedtree.CirRootNode
import org.jetbrains.kotlin.commonizer.mergedtree.CirTargetMergingContext
import org.jetbrains.kotlin.commonizer.metadata.utils.SerializedMetadataLibraryProvider
internal class TargetMerger(
private val moduleMerger: ModuleMerger
) {
fun processTarget(
context: CirTargetMergingContext,
rootNode: CirRootNode,
targetProvider: TargetProvider,
commonModuleInfos: Collection<ModulesProvider.ModuleInfo>
): Unit = with(context) {
rootNode.targetDeclarations[targetIndex] = CirRoot.create(targetProvider.target)
if (commonModuleInfos.isEmpty()) {
return
}
commonModuleInfos.forEach { moduleInfo ->
val metadata = targetProvider.modulesProvider.loadModuleMetadata(moduleInfo.name)
val module = KlibModuleMetadata.read(SerializedMetadataLibraryProvider(metadata))
moduleMerger.processModule(context, rootNode, module)
}
}
}
@@ -1,35 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.commonizer.mergedtree.mergers
import kotlinx.metadata.KmTypeAlias
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
import org.jetbrains.kotlin.commonizer.cir.CirName
import org.jetbrains.kotlin.commonizer.mergedtree.CirPackageNode
import org.jetbrains.kotlin.commonizer.mergedtree.CirTargetMergingContext
import org.jetbrains.kotlin.commonizer.mergedtree.CirTypeAliasNode
import org.jetbrains.kotlin.commonizer.mergedtree.buildTypeAliasNode
import org.jetbrains.kotlin.commonizer.metadata.CirDeserializers
internal object TypeAliasMerger {
fun processTypeAlias(
context: CirTargetMergingContext,
packageNode: CirPackageNode,
typeAlias: KmTypeAlias
) = with(context) {
val typeAliasName = CirName.create(typeAlias.name)
val typeAliasId = CirEntityId.create(packageNode.packageName, typeAliasName)
val typeAliasNode: CirTypeAliasNode = packageNode.typeAliases.getOrPut(typeAliasName) {
buildTypeAliasNode(storageManager, targets, classifiers, typeAliasId)
}
typeAliasNode.targetDeclarations[context.targetIndex] = CirDeserializers.typeAlias(
name = typeAliasName,
source = typeAlias,
typeResolver = context.typeResolver
)
}
}