diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/TargetDependent.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/TargetDependent.kt index 6d07919357e..1e14e5f3bca 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/TargetDependent.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/TargetDependent.kt @@ -82,6 +82,8 @@ internal fun TargetDependent(keys: Iterable, factory: (tar return FactoryBasedTargetDependent(keys.toList(), factory) } +internal fun TargetDependent(vararg pairs: Pair) = pairs.toMap().toTargetDependent() + internal fun EagerTargetDependent(keys: Iterable, factory: (target: CommonizerTarget) -> T): TargetDependent { return keys.associateWith(factory).toTargetDependent() } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt index aacf5cec00f..6684d549f85 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiers.kt @@ -7,6 +7,10 @@ package org.jetbrains.kotlin.commonizer.mergedtree import org.jetbrains.kotlin.commonizer.ModulesProvider import org.jetbrains.kotlin.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.commonizer.mergedtree.ArtificialSupertypes.artificialSupertypes +import org.jetbrains.kotlin.commonizer.utils.CNAMES_STRUCTS_PACKAGE +import org.jetbrains.kotlin.commonizer.utils.OBJCNAMES_CLASSES_PACKAGE +import org.jetbrains.kotlin.commonizer.utils.OBJCNAMES_PROTOCOLS_PACKAGE import org.jetbrains.kotlin.commonizer.utils.isUnderKotlinNativeSyntheticPackages import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Visibilities @@ -88,8 +92,7 @@ object CirProvided { override val typeParameters: List get() = emptyList() override val visibility: Visibility get() = Visibilities.Public - override val supertypes: List - get() = emptyList() // TODO!! + override val supertypes: List = syntheticClassId.artificialSupertypes() } data class TypeAlias( @@ -129,3 +132,28 @@ object CirProvided { data class RegularTypeProjection(val variance: Variance, val type: Type) : TypeProjection } +/** + * Analog to "KlibResolvedModuleDescriptorsFactoryImpl.createForwardDeclarationsModule" which also + * automatically assumes relevant supertypes for forward declarations based upon the package they are in. + */ +private object ArtificialSupertypes { + private fun createType(classId: String): CirProvided.ClassType { + return CirProvided.ClassType( + classId = CirEntityId.create(classId), + outerType = null, arguments = emptyList(), isMarkedNullable = false + ) + } + + private val cOpaqueType = listOf(createType("kotlinx/cinterop/COpaque")) + private val objcObjectBase = listOf(createType("kotlinx/cinterop/ObjCObjectBase")) + private val objcCObject = listOf(createType("kotlinx/cinterop/ObjCObject")) + + fun CirEntityId.artificialSupertypes(): List { + return when (packageName) { + CNAMES_STRUCTS_PACKAGE -> cOpaqueType + OBJCNAMES_CLASSES_PACKAGE -> objcObjectBase + OBJCNAMES_PROTOCOLS_PACKAGE -> objcCObject + else -> emptyList() + } + } +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt index 65ddef7d243..12e70f1c2aa 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirProvidedClassifiersByModules.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.metadata.deserialization.* import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags import org.jetbrains.kotlin.types.Variance -internal class CirProvidedClassifiersByModules private constructor( +internal class CirProvidedClassifiersByModules internal constructor( private val hasForwardDeclarations: Boolean, private val classifiers: Map, ) : CirProvidedClassifiers { @@ -33,11 +33,8 @@ internal class CirProvidedClassifiersByModules private constructor( } override fun classifier(classifierId: CirEntityId) = - if (classifierId.packageName.isUnderKotlinNativeSyntheticPackages) { - if (hasForwardDeclarations) FALLBACK_FORWARD_DECLARATION_CLASS else null - } else { - classifiers[classifierId] - } + classifiers[classifierId] ?: if (hasForwardDeclarations && classifierId.packageName.isUnderKotlinNativeSyntheticPackages) + FALLBACK_FORWARD_DECLARATION_CLASS else null companion object { fun load(modulesProvider: ModulesProvider): CirProvidedClassifiers { diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformer.kt index af787e54f56..215034fef21 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformer.kt @@ -10,18 +10,13 @@ import org.jetbrains.kotlin.commonizer.mergedtree.* import org.jetbrains.kotlin.commonizer.mergedtree.CirNodeRelationship.Composite.Companion.plus import org.jetbrains.kotlin.commonizer.mergedtree.CirNodeRelationship.ParentNode import org.jetbrains.kotlin.commonizer.mergedtree.CirNodeRelationship.PreferredNode -import org.jetbrains.kotlin.commonizer.transformer.ArtificialSupertypes.artificialSupertypes -import org.jetbrains.kotlin.commonizer.utils.CNAMES_STRUCTS_PACKAGE -import org.jetbrains.kotlin.commonizer.utils.OBJCNAMES_CLASSES_PACKAGE -import org.jetbrains.kotlin.commonizer.utils.OBJCNAMES_PROTOCOLS_PACKAGE import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.storage.StorageManager internal class InlineTypeAliasCirNodeTransformer( private val storageManager: StorageManager, - private val classifiers: CirKnownClassifiers + private val classifiers: CirKnownClassifiers, ) : CirNodeTransformer { override fun invoke(root: CirRootNode) { root.modules.values.forEach(::invoke) @@ -70,7 +65,7 @@ internal class InlineTypeAliasCirNodeTransformer( val intoArtificialClass = ArtificialAliasedCirClass( pointingTypeAlias = fromTypeAlias, - pointedClass = fromAliasedClassNode?.targetDeclarations?.get(targetIndex) ?: fromTypeAlias.toArtificialCirClass() + pointedClass = fromAliasedClassNode?.targetDeclarations?.get(targetIndex) ?: fromTypeAlias.toArtificialCirClass(targetIndex) ) intoClassNode.targetDeclarations[targetIndex] = intoArtificialClass @@ -125,6 +120,23 @@ internal class InlineTypeAliasCirNodeTransformer( this.classes[typeAliasNode.classifierName] = classNode return classNode } + + private fun CirTypeAlias.toArtificialCirClass(targetIndex: Int): CirClass = CirClass.create( + annotations = emptyList(), name = name, typeParameters = typeParameters, supertypes = resolveSupertypes(targetIndex), + visibility = this.visibility, modality = Modality.FINAL, kind = ClassKind.CLASS, + companion = null, isCompanion = false, isData = false, isValue = false, isInner = false, isExternal = false + ) + + private fun CirTypeAlias.resolveSupertypes(targetIndex: Int): List { + if (expandedType.isMarkedNullable) return emptyList() + val resolver = SimpleCirSupertypesResolver( + classifiers = classifiers.classifierIndices[targetIndex], + dependencies = CirProvidedClassifiers.of( + classifiers.commonDependencies, classifiers.targetDependencies[targetIndex] + ) + ) + return resolver.supertypes(expandedType).toList() + } } private typealias ClassNodeIndex = Map @@ -143,38 +155,5 @@ private data class ArtificialAliasedCirClass( set(_) = throw UnsupportedOperationException("Can't set companion on artificial class (pointed by $pointingTypeAlias)") } -private fun CirTypeAlias.toArtificialCirClass(): CirClass = CirClass.create( - annotations = emptyList(), name = name, typeParameters = typeParameters, supertypes = artificialSupertypes(), - visibility = this.visibility, modality = Modality.FINAL, kind = ClassKind.CLASS, - companion = null, isCompanion = false, isData = false, isValue = false, isInner = false, isExternal = false -) -/** - * Analog to "KlibResolvedModuleDescriptorsFactoryImpl.createForwardDeclarationsModule" which also - * automatically assumes relevant supertypes for forward declarations based upon the package they are in. - */ -private object ArtificialSupertypes { - private fun createType(classId: String): CirClassType { - return CirClassType.createInterned( - classId = CirEntityId.create(classId), - outerType = null, visibility = Visibilities.Public, arguments = emptyList(), isMarkedNullable = false - ) - } - - private val cOpaqueType = listOf(createType("kotlinx/cinterop/COpaque")) - private val objcObjectBase = listOf(createType("kotlinx/cinterop/ObjCObjectBase")) - private val objcCObject = listOf(createType("kotlinx/cinterop/ObjCObject")) - - fun CirTypeAlias.artificialSupertypes(): List { - /* Not supported (yet). No real life examples known (yet), that would benefit */ - if (this.expandedType.isMarkedNullable) return emptyList() - - return when (underlyingType.classifierId.packageName) { - CNAMES_STRUCTS_PACKAGE -> cOpaqueType - OBJCNAMES_CLASSES_PACKAGE -> objcObjectBase - OBJCNAMES_PROTOCOLS_PACKAGE -> objcCObject - else -> emptyList() - } - } -} diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalClassAndTypeAliasCommonizationTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalClassAndTypeAliasCommonizationTest.kt index fa5501a704d..d7b0ca7511c 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalClassAndTypeAliasCommonizationTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/hierarchical/HierarchicalClassAndTypeAliasCommonizationTest.kt @@ -39,7 +39,7 @@ class HierarchicalClassAndTypeAliasCommonizationTest : AbstractInlineSourcesComm simpleSingleSourceTarget("d", "typealias X = Short") } - result.assertCommonized("(a, b)", "expect class X") + result.assertCommonized("(a, b)", "expect class X: Number") result.assertCommonized("(c, d)", "expect class X") result.assertCommonized("((a, b), (c, d))", "expect class X") } @@ -558,7 +558,7 @@ class HierarchicalClassAndTypeAliasCommonizationTest : AbstractInlineSourcesComm result.assertCommonized( "(c, d)", """ - expect class Proxy + expect class Proxy: Number typealias X = Proxy expect val x: X """.trimIndent() @@ -566,7 +566,7 @@ class HierarchicalClassAndTypeAliasCommonizationTest : AbstractInlineSourcesComm result.assertCommonized( "(a, b, c, d)", """ - expect class Proxy + expect class Proxy: Number typealias X = Proxy expect val x: X """.trimIndent() diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt index 8f48dcc5594..8dc0a7fece7 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt @@ -1,123 +1,202 @@ package org.jetbrains.kotlin.commonizer.transformer +import org.jetbrains.kotlin.commonizer.LeafCommonizerTarget import org.jetbrains.kotlin.commonizer.TargetDependent -import org.jetbrains.kotlin.commonizer.cir.* +import org.jetbrains.kotlin.commonizer.cir.CirClassType +import org.jetbrains.kotlin.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.commonizer.cir.CirName +import org.jetbrains.kotlin.commonizer.cir.CirPackageName +import org.jetbrains.kotlin.commonizer.mapValue import org.jetbrains.kotlin.commonizer.mergedtree.* +import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot +import org.jetbrains.kotlin.commonizer.tree.mergeCirTree +import org.jetbrains.kotlin.commonizer.utils.InlineSourceBuilder +import org.jetbrains.kotlin.commonizer.utils.KtInlineSourceCommonizerTestCase +import org.jetbrains.kotlin.commonizer.utils.createCirTree import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.storage.LockBasedStorageManager -import org.junit.Test -import kotlin.test.assertEquals -import kotlin.test.assertNotNull -class InlineTypeAliasCirNodeTransformerTest { +class InlineTypeAliasCirNodeTransformerTest : KtInlineSourceCommonizerTestCase() { - private val storageManager = LockBasedStorageManager("test") + fun `test inlining typealias to common dependencies`() { - private val classifiers = CirKnownClassifiers( - classifierIndices = TargetDependent.empty(), - targetDependencies = TargetDependent.empty(), - commonizedNodes = CirCommonizedClassifierNodes.default(), - commonDependencies = CirProvidedClassifiers.EMPTY - ) - - @Test - fun `test artificial supertypes - regular package`() { - val root = setup(CirEntityId.create("regular/package/__X")) - InlineTypeAliasCirNodeTransformer(storageManager, classifiers).invoke(root) - val artificialXClass = root.assertInlinedXClass - assertEquals( - emptyList(), artificialXClass.supertypes, - "Expected no artificial supertype for artificial class X" - ) - } - - @Test - fun `test artificial supertypes - cnames structs`() { - val root = setup(CirEntityId.create("cnames/structs/__X")) - InlineTypeAliasCirNodeTransformer(storageManager, classifiers).invoke(root) - val artificialXClass = root.assertInlinedXClass - - assertEquals( - setOf(CirEntityId.create("kotlinx/cinterop/COpaque")), - artificialXClass.supertypes.map { it as CirClassType }.map { it.classifierId }.toSet(), - "Expected 'COpaque' supertype being attached automatically" - ) - } - - @Test - fun `test artificial supertypes - objcnames classes`() { - val root = setup(CirEntityId.create("objcnames/classes/__X")) - InlineTypeAliasCirNodeTransformer(storageManager, classifiers).invoke(root) - val artificialXClass = root.assertInlinedXClass - - assertEquals( - setOf(CirEntityId.create("kotlinx/cinterop/ObjCObjectBase")), - artificialXClass.supertypes.map { it as CirClassType }.map { it.classifierId }.toSet(), - "Expected 'ObjCObjectBase' supertype being attached automatically" - ) - } - - @Test - fun `test artificial supertypes - objcnames protocols`() { - val root = setup(CirEntityId.create("objcnames/protocols/__X")) - InlineTypeAliasCirNodeTransformer(storageManager, classifiers).invoke(root) - val artificialXClass = root.assertInlinedXClass - - assertEquals( - setOf(CirEntityId.create("kotlinx/cinterop/ObjCObject")), - artificialXClass.supertypes.map { it as CirClassType }.map { it.classifierId }.toSet(), - "Expected 'ObjCObject' supertype being attached automatically" - ) - } - - private fun setup(typeAliasPointingTo: CirEntityId): CirRootNode { - val root = buildRootNode(storageManager, CirProvidedClassifiers.EMPTY, 1) - root.modules[CirName.create("test-module")] = buildModuleNode(storageManager, 1).apply { - packages[CirPackageName.create("under.test")] = buildPackageNode(storageManager, 2).apply { - - typeAliases[CirName.create("X")] = buildTypeAliasNode( - storageManager, 2, classifiers, CirEntityId.create("under/test/X") - ).apply { - val underlyingType = CirClassType.createInterned( - classId = typeAliasPointingTo, - outerType = null, visibility = Visibilities.Public, - arguments = emptyList(), isMarkedNullable = false - ) - targetDeclarations[0] = CirTypeAlias.create( - annotations = emptyList(), - name = CirName.create("X"), - typeParameters = emptyList(), - visibility = Visibilities.Public, - underlyingType = underlyingType, - expandedType = underlyingType - ) - } - - classes[CirName.create("X")] = buildClassNode( - storageManager, 2, classifiers, null, CirEntityId.create("under/test/X") - ).apply { - targetDeclarations[1] = CirClass.create( - name = CirName.create("X"), typeParameters = emptyList(), - supertypes = emptyList(), visibility = Visibilities.Public, - companion = null, isCompanion = false, isData = false, isExternal = false, - isInner = false, isValue = false, kind = ClassKind.CLASS, - modality = Modality.FINAL, annotations = emptyList(), - ) - } - } + fun InlineSourceBuilder.ModuleBuilder.withDependencies() = dependency { + source( + """ + package dep + class ClassA + class ClassB: ClassA() + """.trimIndent() + ) } - return root + val targetARoot = CirTreeRoot( + modules = listOf( + createCirTree { + withDependencies() + source( + """ + package pkg + import dep.* + class X : ClassA() + """.trimIndent() + ) + } + ) + ) + + val targetBRoot = CirTreeRoot( + modules = listOf( + createCirTree { + withDependencies() + source( + """ + package pkg + import dep.* + typealias X = ClassB + """.trimIndent() + ) + } + ) + ) + + val roots = TargetDependent( + LeafCommonizerTarget("a") to targetARoot, + LeafCommonizerTarget("b") to targetBRoot + ) + + val classifiers = CirKnownClassifiers( + classifierIndices = roots.mapValue(::CirClassifierIndex), + targetDependencies = roots.mapValue(CirTreeRoot::dependencies), + commonizedNodes = CirCommonizedClassifierNodes.default(), + commonDependencies = CirProvidedClassifiersByModules( + true, mapOf( + CirEntityId.create("dep/ClassA") to CirProvided.RegularClass( + typeParameters = emptyList(), + kind = ClassKind.CLASS, + visibility = Visibilities.Public, + supertypes = emptyList() + ), + CirEntityId.create("dep/ClassB") to CirProvided.RegularClass( + typeParameters = emptyList(), + kind = ClassKind.CLASS, + visibility = Visibilities.Public, + supertypes = listOf( + CirProvided.ClassType( + classId = CirEntityId.create("dep/ClassA"), + outerType = null, + arguments = emptyList(), + isMarkedNullable = false + ) + ) + ) + ) + ) + ) + + val mergedTree = mergeCirTree(LockBasedStorageManager.NO_LOCKS, classifiers, roots) + InlineTypeAliasCirNodeTransformer(LockBasedStorageManager.NO_LOCKS, classifiers).invoke(mergedTree) + + val pkg = mergedTree.modules.values.single().packages.getValue(CirPackageName.create("pkg")) + val xClassNode = kotlin.test.assertNotNull(pkg.classes[CirName.create("X")]) + val inlinedXClass = kotlin.test.assertNotNull(xClassNode.targetDeclarations[1]) + + kotlin.test.assertEquals( + setOf(CirEntityId.create("dep/ClassA")), + inlinedXClass.supertypes.map { (it as? CirClassType)?.classifierId }.toSet() + ) } - private val CirRootNode.xClassNode: CirClassNode - get() = modules.getValue(CirName.create("test-module")) - .packages.getValue(CirPackageName.create("under.test")) - .classes.getValue(CirName.create("X")) - private val CirRootNode.assertInlinedXClass: CirClass - get() = assertNotNull(xClassNode.targetDeclarations[0], "Missing inlined class 'X' at index 0") + fun `test inlining typealias to target dependencies`() { + + fun InlineSourceBuilder.ModuleBuilder.withDependencies() = dependency { + source( + """ + package dep + class ClassA + class ClassB: ClassA() + """.trimIndent() + ) + } + + val targetARoot = CirTreeRoot( + modules = listOf( + createCirTree { + withDependencies() + source( + """ + package pkg + import dep.* + class X : ClassA() + """.trimIndent() + ) + } + ) + ) + + val targetBRoot = CirTreeRoot( + dependencies = CirProvidedClassifiersByModules( + true, mapOf( + CirEntityId.create("dep/ClassA") to CirProvided.RegularClass( + typeParameters = emptyList(), + kind = ClassKind.CLASS, + visibility = Visibilities.Public, + supertypes = emptyList() + ), + CirEntityId.create("dep/ClassB") to CirProvided.RegularClass( + typeParameters = emptyList(), + kind = ClassKind.CLASS, + visibility = Visibilities.Public, + supertypes = listOf( + CirProvided.ClassType( + classId = CirEntityId.create("dep/ClassA"), + outerType = null, + arguments = emptyList(), + isMarkedNullable = false + ) + ) + ) + ) + ), + modules = listOf( + createCirTree { + withDependencies() + source( + """ + package pkg + import dep.* + typealias X = ClassB + """.trimIndent() + ) + } + ) + ) + + val roots = TargetDependent( + LeafCommonizerTarget("a") to targetARoot, + LeafCommonizerTarget("b") to targetBRoot + ) + + val classifiers = CirKnownClassifiers( + classifierIndices = roots.mapValue(::CirClassifierIndex), + targetDependencies = roots.mapValue(CirTreeRoot::dependencies), + commonizedNodes = CirCommonizedClassifierNodes.default(), + commonDependencies = CirProvidedClassifiers.EMPTY + ) + + val mergedTree = mergeCirTree(LockBasedStorageManager.NO_LOCKS, classifiers, roots) + InlineTypeAliasCirNodeTransformer(LockBasedStorageManager.NO_LOCKS, classifiers).invoke(mergedTree) + + val pkg = mergedTree.modules.values.single().packages.getValue(CirPackageName.create("pkg")) + val xClassNode = kotlin.test.assertNotNull(pkg.classes[CirName.create("X")]) + val inlinedXClass = kotlin.test.assertNotNull(xClassNode.targetDeclarations[1]) + + kotlin.test.assertEquals( + setOf(CirEntityId.create("dep/ClassA")), + inlinedXClass.supertypes.map { (it as? CirClassType)?.classifierId }.toSet() + ) + } +} -} \ No newline at end of file diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/assertions.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/assertions.kt index a72eae9720a..0e7f6bb5152 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/assertions.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/assertions.kt @@ -8,10 +8,16 @@ package org.jetbrains.kotlin.commonizer.utils import kotlinx.metadata.klib.KlibModuleMetadata import kotlinx.metadata.klib.annotations import org.jetbrains.kotlin.commonizer.CommonizerTarget +import org.jetbrains.kotlin.commonizer.cir.CirFunction +import org.jetbrains.kotlin.commonizer.cir.CirProperty import org.jetbrains.kotlin.commonizer.identityString import org.jetbrains.kotlin.commonizer.metadata.utils.MetadataDeclarationsComparator import org.jetbrains.kotlin.commonizer.metadata.utils.MetadataDeclarationsComparator.* import org.jetbrains.kotlin.commonizer.metadata.utils.SerializedMetadataLibraryProvider +import org.jetbrains.kotlin.commonizer.tree.CirTreeClass +import org.jetbrains.kotlin.commonizer.tree.CirTreeModule +import org.jetbrains.kotlin.commonizer.tree.CirTreePackage +import org.jetbrains.kotlin.commonizer.tree.CirTreeTypeAlias import org.jetbrains.kotlin.library.SerializedMetadata import java.io.File import kotlin.contracts.ExperimentalContracts