From 1857096071166923e6cc39adbeb4209c65abf0a0 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Wed, 11 Aug 2021 09:52:14 +0200 Subject: [PATCH] [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 --- .../kotlin/commonizer/cir/CirClass.kt | 18 +++---- .../kotlin/commonizer/core/ClassCommonizer.kt | 3 ++ .../core/ClassSuperTypeCommonizer.kt | 31 +++++++++++ .../commonizer/core/CommonizationVisitor.kt | 52 +------------------ .../CirFictitiousFunctionClassifiers.kt | 2 +- .../commonizer/metadata/CirDeserializers.kt | 25 +++++---- .../InlineTypeAliasCirNodeTransformer.kt | 5 +- .../commonizer/core/TypeCommonizerTest.kt | 1 + .../InlineTypeAliasCirNodeTransformerTest.kt | 3 +- .../kotlin/commonizer/utils/mocks.kt | 1 + 10 files changed, 60 insertions(+), 81 deletions(-) create mode 100644 native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassSuperTypeCommonizer.kt diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirClass.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirClass.kt index 15eb568c0f3..d3832c42fbc 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirClass.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/cir/CirClass.kt @@ -15,7 +15,7 @@ interface CirClass : CirClassifier, CirContainingClass { val isValue: Boolean val isInner: Boolean val isExternal: Boolean - var supertypes: List + val supertypes: List companion object { @Suppress("NOTHING_TO_INLINE") @@ -23,6 +23,7 @@ interface CirClass : CirClassifier, CirContainingClass { annotations: List, name: CirName, typeParameters: List, + supertypes: List, 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, override val name: CirName, override val typeParameters: List, + override val supertypes: List, 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? = null - - override var supertypes: List - get() = _supertypes ?: error("${::supertypes.name} has not been initialized yet") - set(value) { - check(_supertypes == null) { "Re-initialization of ${::supertypes.name}" } - _supertypes = value - } -} +) : CirClass diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassCommonizer.kt index 94daab0fb65..6ffe68bd64f 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassCommonizer.kt @@ -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) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassSuperTypeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassSuperTypeCommonizer.kt new file mode 100644 index 00000000000..c021415dc48 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassSuperTypeCommonizer.kt @@ -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> { + + private val typeCommonizer = TypeCommonizer(classifiers) + + override fun commonize(first: List, second: List): List { + if (first.isEmpty() || second.isEmpty()) return emptyList() + + val firstGroup = first.filterIsInstance().associateBy { it.classifierId } + val secondGroup = second.filterIsInstance().associateBy { it.classifierId } + + val commonClassifiers = firstGroup.keys intersect secondGroup.keys + + return commonClassifiers.mapNotNull { classifier -> + typeCommonizer.commonize(firstGroup.getValue(classifier), secondGroup.getValue(classifier)) + } + } + +} \ No newline at end of file diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/CommonizationVisitor.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/CommonizationVisitor.kt index 29f160cd0c8..affa215f207 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/CommonizationVisitor.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/CommonizationVisitor.kt @@ -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> { - val supertypesMap: MutableMap> = 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>? { - val supertypesMap: MutableMap> = 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>? - ) { - val commonSupertypes = supertypesMap?.values?.compactMapNotNull { supertypesGroup -> - commonize(supertypesGroup, TypeCommonizer(classifiers).asCommonizer()) - }.orEmpty() - - supertypes = commonSupertypes + node.commonDeclaration() // commonize type alias } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt index 5b1f0faceba..32aa42dcf77 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirFictitiousFunctionClassifiers.kt @@ -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) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirDeserializers.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirDeserializers.kt index d21d8c59c37..0aa05e3723e 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirDeserializers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirDeserializers.kt @@ -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 = 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 5cee3345143..af787e54f56 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformer.kt @@ -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 diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt index d757a420442..0e724d22f4e 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt @@ -431,6 +431,7 @@ class TypeCommonizerTest : AbstractCommonizerTest() { annotations = emptyList(), name = type.classifierId.relativeNameSegments.last(), typeParameters = emptyList(), + supertypes = emptyList(), visibility = Visibilities.Public, modality = Modality.FINAL, kind = ClassKind.CLASS, 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 96462b830d8..8264b859c25 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformerTest.kt @@ -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(), diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/mocks.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/mocks.kt index 167494a7998..913a3fcc39c 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/mocks.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/mocks.kt @@ -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,