mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 08:31:29 +00:00
[Commonizer] Implement ClassSuperTypeCommonizer
This implementation runs as regular part of the commonization. Previous implementation inside the CommonizationVisitor was fully replaced by it. As a side effect: CirClass.supertypes was now marked immutable. ^KT-47430 In Progress
This commit is contained in:
committed by
Space
parent
50a343f91e
commit
1857096071
@@ -15,7 +15,7 @@ interface CirClass : CirClassifier, CirContainingClass {
|
||||
val isValue: Boolean
|
||||
val isInner: Boolean
|
||||
val isExternal: Boolean
|
||||
var supertypes: List<CirType>
|
||||
val supertypes: List<CirType>
|
||||
|
||||
companion object {
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
@@ -23,6 +23,7 @@ interface CirClass : CirClassifier, CirContainingClass {
|
||||
annotations: List<CirAnnotation>,
|
||||
name: CirName,
|
||||
typeParameters: List<CirTypeParameter>,
|
||||
supertypes: List<CirType>,
|
||||
visibility: Visibility,
|
||||
modality: Modality,
|
||||
kind: ClassKind,
|
||||
@@ -31,11 +32,12 @@ interface CirClass : CirClassifier, CirContainingClass {
|
||||
isData: Boolean,
|
||||
isValue: Boolean,
|
||||
isInner: Boolean,
|
||||
isExternal: Boolean
|
||||
isExternal: Boolean,
|
||||
): CirClass = CirClassImpl(
|
||||
annotations = annotations,
|
||||
name = name,
|
||||
typeParameters = typeParameters,
|
||||
supertypes = supertypes,
|
||||
visibility = visibility,
|
||||
modality = modality,
|
||||
kind = kind,
|
||||
@@ -53,6 +55,7 @@ data class CirClassImpl(
|
||||
override val annotations: List<CirAnnotation>,
|
||||
override val name: CirName,
|
||||
override val typeParameters: List<CirTypeParameter>,
|
||||
override val supertypes: List<CirType>,
|
||||
override val visibility: Visibility,
|
||||
override val modality: Modality,
|
||||
override val kind: ClassKind,
|
||||
@@ -62,13 +65,4 @@ data class CirClassImpl(
|
||||
override val isValue: Boolean,
|
||||
override val isInner: Boolean,
|
||||
override val isExternal: Boolean,
|
||||
) : CirClass {
|
||||
private var _supertypes: List<CirType>? = null
|
||||
|
||||
override var supertypes: List<CirType>
|
||||
get() = _supertypes ?: error("${::supertypes.name} has not been initialized yet")
|
||||
set(value) {
|
||||
check(_supertypes == null) { "Re-initialization of ${::supertypes.name}" }
|
||||
_supertypes = value
|
||||
}
|
||||
}
|
||||
) : CirClass
|
||||
|
||||
@@ -19,11 +19,13 @@ class ClassCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommon
|
||||
private var isInner = false
|
||||
private var isValue = false
|
||||
private var isCompanion = false
|
||||
private val supertypes = ClassSuperTypeCommonizer(classifiers).asCommonizer()
|
||||
|
||||
override fun commonizationResult() = CirClass.create(
|
||||
annotations = emptyList(),
|
||||
name = name,
|
||||
typeParameters = typeParameters.result,
|
||||
supertypes = supertypes.result,
|
||||
visibility = visibility.result,
|
||||
modality = modality.result,
|
||||
kind = kind,
|
||||
@@ -51,4 +53,5 @@ class ClassCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommon
|
||||
&& modality.commonizeWith(next.modality)
|
||||
&& visibility.commonizeWith(next)
|
||||
&& typeParameters.commonizeWith(next.typeParameters)
|
||||
&& supertypes.commonizeWith(next.supertypes)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.core
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirClassOrTypeAliasType
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirType
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
||||
|
||||
class ClassSuperTypeCommonizer(
|
||||
private val classifiers: CirKnownClassifiers
|
||||
) : AssociativeCommonizer<List<CirType>> {
|
||||
|
||||
private val typeCommonizer = TypeCommonizer(classifiers)
|
||||
|
||||
override fun commonize(first: List<CirType>, second: List<CirType>): List<CirType> {
|
||||
if (first.isEmpty() || second.isEmpty()) return emptyList()
|
||||
|
||||
val firstGroup = first.filterIsInstance<CirClassOrTypeAliasType>().associateBy { it.classifierId }
|
||||
val secondGroup = second.filterIsInstance<CirClassOrTypeAliasType>().associateBy { it.classifierId }
|
||||
|
||||
val commonClassifiers = firstGroup.keys intersect secondGroup.keys
|
||||
|
||||
return commonClassifiers.mapNotNull { classifier ->
|
||||
typeCommonizer.commonize(firstGroup.getValue(classifier), secondGroup.getValue(classifier))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,11 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.commonizer.core
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirClass
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirType
|
||||
import org.jetbrains.kotlin.commonizer.mergedtree.*
|
||||
import org.jetbrains.kotlin.commonizer.utils.CommonizedGroup
|
||||
import org.jetbrains.kotlin.commonizer.utils.compactMapNotNull
|
||||
|
||||
internal class CommonizationVisitor(
|
||||
private val classifiers: CirKnownClassifiers,
|
||||
@@ -93,9 +89,6 @@ internal class CommonizationVisitor(
|
||||
commonClass.companion = companionObjectName
|
||||
}
|
||||
}
|
||||
|
||||
// find out common (and commonized) supertypes
|
||||
commonClass.commonizeSupertypes(node.collectCommonSupertypes())
|
||||
}
|
||||
|
||||
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: Unit) {
|
||||
@@ -103,49 +96,6 @@ internal class CommonizationVisitor(
|
||||
}
|
||||
|
||||
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: Unit) {
|
||||
val commonClassifier = node.commonDeclaration() // commonize type alias
|
||||
|
||||
if (commonClassifier is CirClass) {
|
||||
// find out common (and commonized) supertypes
|
||||
commonClassifier.commonizeSupertypes(node.collectCommonSupertypes())
|
||||
}
|
||||
}
|
||||
|
||||
private fun CirClassNode.collectCommonSupertypes(): Map<CirType, CommonizedGroup<CirType>> {
|
||||
val supertypesMap: MutableMap<CirType, CommonizedGroup<CirType>> = linkedMapOf() // preserve supertype order
|
||||
for ((index, clazz) in targetDeclarations.withIndex()) {
|
||||
for (supertype in clazz!!.supertypes) {
|
||||
supertypesMap.getOrPut(supertype) { CommonizedGroup(targetDeclarations.size) }[index] = supertype
|
||||
}
|
||||
}
|
||||
return supertypesMap
|
||||
}
|
||||
|
||||
private fun CirTypeAliasNode.collectCommonSupertypes(): Map<CirType, CommonizedGroup<CirType>>? {
|
||||
val supertypesMap: MutableMap<CirType, CommonizedGroup<CirType>> = linkedMapOf() // preserve supertype order
|
||||
for ((index, typeAlias) in targetDeclarations.withIndex()) {
|
||||
val expandedClassId = typeAlias!!.expandedType.classifierId
|
||||
if (classifiers.commonDependencies.hasClassifier(expandedClassId))
|
||||
return null // this case is not supported yet
|
||||
|
||||
val expandedClassNode = classifiers.commonizedNodes.classNode(expandedClassId) ?: return null
|
||||
val expandedClass = expandedClassNode.targetDeclarations[index]
|
||||
?: error("Can't find expanded class with class ID $expandedClassId and index $index for type alias $classifierName")
|
||||
|
||||
for (supertype in expandedClass.supertypes) {
|
||||
supertypesMap.getOrPut(supertype) { CommonizedGroup(targetDeclarations.size) }[index] = supertype
|
||||
}
|
||||
}
|
||||
return supertypesMap
|
||||
}
|
||||
|
||||
private fun CirClass.commonizeSupertypes(
|
||||
supertypesMap: Map<CirType, CommonizedGroup<CirType>>?
|
||||
) {
|
||||
val commonSupertypes = supertypesMap?.values?.compactMapNotNull { supertypesGroup ->
|
||||
commonize(supertypesGroup, TypeCommonizer(classifiers).asCommonizer())
|
||||
}.orEmpty()
|
||||
|
||||
supertypes = commonSupertypes
|
||||
node.commonDeclaration() // commonize type alias
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ object CirFictitiousFunctionClassifiers : CirProvidedClassifiers {
|
||||
}
|
||||
|
||||
val classId = CirEntityId.create(PACKAGE_NAME, CirName.create("$prefix$arity"))
|
||||
val clazz = CirProvided.RegularClass(typeParameters, Visibilities.Public)
|
||||
val clazz = CirProvided.RegularClass(typeParameters, emptyList(), Visibilities.Public)
|
||||
|
||||
consumer(classId, clazz)
|
||||
}
|
||||
|
||||
@@ -258,6 +258,7 @@ object CirDeserializers {
|
||||
annotations = annotations(source.flags, typeResolver, source::annotations),
|
||||
name = name,
|
||||
typeParameters = source.typeParameters.compactMap { typeParameter(it, typeResolver) },
|
||||
supertypes = source.filteredSupertypes.compactMap { type(it, typeResolver) },
|
||||
visibility = visibility(source.flags),
|
||||
modality = modality(source.flags),
|
||||
kind = classKind(source.flags),
|
||||
@@ -267,9 +268,7 @@ object CirDeserializers {
|
||||
isValue = Flag.Class.IS_VALUE(source.flags),
|
||||
isInner = Flag.Class.IS_INNER(source.flags),
|
||||
isExternal = Flag.Class.IS_EXTERNAL(source.flags)
|
||||
).apply {
|
||||
supertypes = source.filteredSupertypes.compactMap { type(it, typeResolver) }
|
||||
}
|
||||
)
|
||||
|
||||
fun defaultEnumEntry(
|
||||
name: CirName,
|
||||
@@ -281,6 +280,15 @@ object CirDeserializers {
|
||||
annotations = annotations.compactMap { annotation(it, typeResolver) },
|
||||
name = name,
|
||||
typeParameters = emptyList(),
|
||||
supertypes = listOf(
|
||||
CirClassType.createInterned(
|
||||
classId = enumClassId,
|
||||
outerType = null,
|
||||
visibility = visibility(enumClass.flags),
|
||||
arguments = emptyList(),
|
||||
isMarkedNullable = false
|
||||
)
|
||||
),
|
||||
visibility = Visibilities.Public,
|
||||
modality = Modality.FINAL,
|
||||
kind = ClassKind.ENUM_ENTRY,
|
||||
@@ -290,16 +298,7 @@ object CirDeserializers {
|
||||
isValue = false,
|
||||
isInner = false,
|
||||
isExternal = false
|
||||
).apply {
|
||||
val enumClassType = CirClassType.createInterned(
|
||||
classId = enumClassId,
|
||||
outerType = null,
|
||||
visibility = visibility(enumClass.flags),
|
||||
arguments = emptyList(),
|
||||
isMarkedNullable = false
|
||||
)
|
||||
supertypes = listOf(enumClassType)
|
||||
}
|
||||
)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
private inline fun classKind(flags: Flags): ClassKind =
|
||||
|
||||
@@ -144,11 +144,10 @@ private data class ArtificialAliasedCirClass(
|
||||
}
|
||||
|
||||
private fun CirTypeAlias.toArtificialCirClass(): CirClass = CirClass.create(
|
||||
annotations = emptyList(), name = name, typeParameters = typeParameters,
|
||||
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
|
||||
).also { it.supertypes = artificialSupertypes() }
|
||||
|
||||
)
|
||||
|
||||
/**
|
||||
* Analog to "KlibResolvedModuleDescriptorsFactoryImpl.createForwardDeclarationsModule" which also
|
||||
|
||||
@@ -431,6 +431,7 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
|
||||
annotations = emptyList(),
|
||||
name = type.classifierId.relativeNameSegments.last(),
|
||||
typeParameters = emptyList(),
|
||||
supertypes = emptyList(),
|
||||
visibility = Visibilities.Public,
|
||||
modality = Modality.FINAL,
|
||||
kind = ClassKind.CLASS,
|
||||
|
||||
@@ -96,7 +96,8 @@ class InlineTypeAliasCirNodeTransformerTest {
|
||||
storageManager, 2, classifiers, null, CirEntityId.create("under/test/X")
|
||||
).apply {
|
||||
targetDeclarations[1] = CirClass.create(
|
||||
name = CirName.create("X"), typeParameters = emptyList(), visibility = Visibilities.Public,
|
||||
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(),
|
||||
|
||||
@@ -61,6 +61,7 @@ internal val MOCK_CLASSIFIERS = CirKnownClassifiers(
|
||||
annotations = emptyList(),
|
||||
name = CirName.create("Any"),
|
||||
typeParameters = emptyList(),
|
||||
supertypes = emptyList(),
|
||||
visibility = Visibilities.Public,
|
||||
modality = Modality.OPEN,
|
||||
kind = ClassKind.CLASS,
|
||||
|
||||
Reference in New Issue
Block a user