[Commonizer] Respect artificial supertypes when loading dependencies
CirProvided.ExportedForwardDeclarationClass will now correctly report artificial superclasses. The InlineTypeAliasCirNodeTransformer does not need to know anything about artificial supertypes anymore. When inlining any type alias, it is enough to resolve the type-alias's expansions supertypes. ^KT-47430
This commit is contained in:
committed by
Space
parent
26ede5d885
commit
f64a0efa8b
@@ -82,6 +82,8 @@ internal fun <T> TargetDependent(keys: Iterable<CommonizerTarget>, factory: (tar
|
|||||||
return FactoryBasedTargetDependent(keys.toList(), factory)
|
return FactoryBasedTargetDependent(keys.toList(), factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun <T> TargetDependent(vararg pairs: Pair<CommonizerTarget, T>) = pairs.toMap().toTargetDependent()
|
||||||
|
|
||||||
internal fun <T> EagerTargetDependent(keys: Iterable<CommonizerTarget>, factory: (target: CommonizerTarget) -> T): TargetDependent<T> {
|
internal fun <T> EagerTargetDependent(keys: Iterable<CommonizerTarget>, factory: (target: CommonizerTarget) -> T): TargetDependent<T> {
|
||||||
return keys.associateWith(factory).toTargetDependent()
|
return keys.associateWith(factory).toTargetDependent()
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-2
@@ -7,6 +7,10 @@ package org.jetbrains.kotlin.commonizer.mergedtree
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.commonizer.ModulesProvider
|
import org.jetbrains.kotlin.commonizer.ModulesProvider
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
|
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.commonizer.utils.isUnderKotlinNativeSyntheticPackages
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
@@ -88,8 +92,7 @@ object CirProvided {
|
|||||||
|
|
||||||
override val typeParameters: List<TypeParameter> get() = emptyList()
|
override val typeParameters: List<TypeParameter> get() = emptyList()
|
||||||
override val visibility: Visibility get() = Visibilities.Public
|
override val visibility: Visibility get() = Visibilities.Public
|
||||||
override val supertypes: List<Type>
|
override val supertypes: List<Type> = syntheticClassId.artificialSupertypes()
|
||||||
get() = emptyList() // TODO!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class TypeAlias(
|
data class TypeAlias(
|
||||||
@@ -129,3 +132,28 @@ object CirProvided {
|
|||||||
data class RegularTypeProjection(val variance: Variance, val type: Type) : TypeProjection
|
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<CirProvided.Type> {
|
||||||
|
return when (packageName) {
|
||||||
|
CNAMES_STRUCTS_PACKAGE -> cOpaqueType
|
||||||
|
OBJCNAMES_CLASSES_PACKAGE -> objcObjectBase
|
||||||
|
OBJCNAMES_PROTOCOLS_PACKAGE -> objcCObject
|
||||||
|
else -> emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+3
-6
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.metadata.deserialization.*
|
|||||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
|
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
internal class CirProvidedClassifiersByModules private constructor(
|
internal class CirProvidedClassifiersByModules internal constructor(
|
||||||
private val hasForwardDeclarations: Boolean,
|
private val hasForwardDeclarations: Boolean,
|
||||||
private val classifiers: Map<CirEntityId, CirProvided.Classifier>,
|
private val classifiers: Map<CirEntityId, CirProvided.Classifier>,
|
||||||
) : CirProvidedClassifiers {
|
) : CirProvidedClassifiers {
|
||||||
@@ -33,11 +33,8 @@ internal class CirProvidedClassifiersByModules private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun classifier(classifierId: CirEntityId) =
|
override fun classifier(classifierId: CirEntityId) =
|
||||||
if (classifierId.packageName.isUnderKotlinNativeSyntheticPackages) {
|
classifiers[classifierId] ?: if (hasForwardDeclarations && classifierId.packageName.isUnderKotlinNativeSyntheticPackages)
|
||||||
if (hasForwardDeclarations) FALLBACK_FORWARD_DECLARATION_CLASS else null
|
FALLBACK_FORWARD_DECLARATION_CLASS else null
|
||||||
} else {
|
|
||||||
classifiers[classifierId]
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun load(modulesProvider: ModulesProvider): CirProvidedClassifiers {
|
fun load(modulesProvider: ModulesProvider): CirProvidedClassifiers {
|
||||||
|
|||||||
+19
-40
@@ -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.Composite.Companion.plus
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirNodeRelationship.ParentNode
|
import org.jetbrains.kotlin.commonizer.mergedtree.CirNodeRelationship.ParentNode
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirNodeRelationship.PreferredNode
|
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.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
internal class InlineTypeAliasCirNodeTransformer(
|
internal class InlineTypeAliasCirNodeTransformer(
|
||||||
private val storageManager: StorageManager,
|
private val storageManager: StorageManager,
|
||||||
private val classifiers: CirKnownClassifiers
|
private val classifiers: CirKnownClassifiers,
|
||||||
) : CirNodeTransformer {
|
) : CirNodeTransformer {
|
||||||
override fun invoke(root: CirRootNode) {
|
override fun invoke(root: CirRootNode) {
|
||||||
root.modules.values.forEach(::invoke)
|
root.modules.values.forEach(::invoke)
|
||||||
@@ -70,7 +65,7 @@ internal class InlineTypeAliasCirNodeTransformer(
|
|||||||
|
|
||||||
val intoArtificialClass = ArtificialAliasedCirClass(
|
val intoArtificialClass = ArtificialAliasedCirClass(
|
||||||
pointingTypeAlias = fromTypeAlias,
|
pointingTypeAlias = fromTypeAlias,
|
||||||
pointedClass = fromAliasedClassNode?.targetDeclarations?.get(targetIndex) ?: fromTypeAlias.toArtificialCirClass()
|
pointedClass = fromAliasedClassNode?.targetDeclarations?.get(targetIndex) ?: fromTypeAlias.toArtificialCirClass(targetIndex)
|
||||||
)
|
)
|
||||||
|
|
||||||
intoClassNode.targetDeclarations[targetIndex] = intoArtificialClass
|
intoClassNode.targetDeclarations[targetIndex] = intoArtificialClass
|
||||||
@@ -125,6 +120,23 @@ internal class InlineTypeAliasCirNodeTransformer(
|
|||||||
this.classes[typeAliasNode.classifierName] = classNode
|
this.classes[typeAliasNode.classifierName] = classNode
|
||||||
return 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<CirType> {
|
||||||
|
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<CirEntityId, CirClassNode>
|
private typealias ClassNodeIndex = Map<CirEntityId, CirClassNode>
|
||||||
@@ -143,38 +155,5 @@ private data class ArtificialAliasedCirClass(
|
|||||||
set(_) = throw UnsupportedOperationException("Can't set companion on artificial class (pointed by $pointingTypeAlias)")
|
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<CirType> {
|
|
||||||
/* 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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -39,7 +39,7 @@ class HierarchicalClassAndTypeAliasCommonizationTest : AbstractInlineSourcesComm
|
|||||||
simpleSingleSourceTarget("d", "typealias X = Short")
|
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("(c, d)", "expect class X")
|
||||||
result.assertCommonized("((a, b), (c, d))", "expect class X")
|
result.assertCommonized("((a, b), (c, d))", "expect class X")
|
||||||
}
|
}
|
||||||
@@ -558,7 +558,7 @@ class HierarchicalClassAndTypeAliasCommonizationTest : AbstractInlineSourcesComm
|
|||||||
|
|
||||||
result.assertCommonized(
|
result.assertCommonized(
|
||||||
"(c, d)", """
|
"(c, d)", """
|
||||||
expect class Proxy
|
expect class Proxy: Number
|
||||||
typealias X = Proxy
|
typealias X = Proxy
|
||||||
expect val x: X
|
expect val x: X
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
@@ -566,7 +566,7 @@ class HierarchicalClassAndTypeAliasCommonizationTest : AbstractInlineSourcesComm
|
|||||||
|
|
||||||
result.assertCommonized(
|
result.assertCommonized(
|
||||||
"(a, b, c, d)", """
|
"(a, b, c, d)", """
|
||||||
expect class Proxy
|
expect class Proxy: Number
|
||||||
typealias X = Proxy
|
typealias X = Proxy
|
||||||
expect val x: X
|
expect val x: X
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|||||||
+186
-107
@@ -1,123 +1,202 @@
|
|||||||
package org.jetbrains.kotlin.commonizer.transformer
|
package org.jetbrains.kotlin.commonizer.transformer
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.commonizer.LeafCommonizerTarget
|
||||||
import org.jetbrains.kotlin.commonizer.TargetDependent
|
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.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.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
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(
|
fun InlineSourceBuilder.ModuleBuilder.withDependencies() = dependency {
|
||||||
classifierIndices = TargetDependent.empty(),
|
source(
|
||||||
targetDependencies = TargetDependent.empty(),
|
"""
|
||||||
commonizedNodes = CirCommonizedClassifierNodes.default(),
|
package dep
|
||||||
commonDependencies = CirProvidedClassifiers.EMPTY
|
class ClassA
|
||||||
)
|
class ClassB: ClassA()
|
||||||
|
""".trimIndent()
|
||||||
@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(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
fun `test inlining typealias to target dependencies`() {
|
||||||
get() = assertNotNull(xClassNode.targetDeclarations[0], "Missing inlined class 'X' at index 0")
|
|
||||||
|
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()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
@@ -8,10 +8,16 @@ package org.jetbrains.kotlin.commonizer.utils
|
|||||||
import kotlinx.metadata.klib.KlibModuleMetadata
|
import kotlinx.metadata.klib.KlibModuleMetadata
|
||||||
import kotlinx.metadata.klib.annotations
|
import kotlinx.metadata.klib.annotations
|
||||||
import org.jetbrains.kotlin.commonizer.CommonizerTarget
|
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.identityString
|
||||||
import org.jetbrains.kotlin.commonizer.metadata.utils.MetadataDeclarationsComparator
|
import org.jetbrains.kotlin.commonizer.metadata.utils.MetadataDeclarationsComparator
|
||||||
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.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 org.jetbrains.kotlin.library.SerializedMetadata
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
|||||||
Reference in New Issue
Block a user