From 0cf161896087a3f085f1bf4eb44d475d591709ff Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Tue, 1 Jun 2021 18:28:05 +0200 Subject: [PATCH] [Commonizer] Implement `CirNodeRelationship` over `CommonizerCondition` --- .../mergedtree/CirNodeRelationship.kt | 35 ++++++++++++++++ .../mergedtree/CommonizerCondition.kt | 37 ----------------- .../commonizer/mergedtree/nodeBuilders.kt | 41 +++++++++++-------- .../InlineTypeAliasCirNodeTransformer.kt | 11 +++-- .../kotlin/commonizer/tree/mergeCirTree.kt | 8 ++-- .../commonizer/core/TypeCommonizerTest.kt | 2 +- 6 files changed, 72 insertions(+), 62 deletions(-) create mode 100644 native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirNodeRelationship.kt delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CommonizerCondition.kt diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirNodeRelationship.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirNodeRelationship.kt new file mode 100644 index 00000000000..9cee86845f6 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CirNodeRelationship.kt @@ -0,0 +1,35 @@ +/* + * 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. + */ + +@file:Suppress("FunctionName") + +package org.jetbrains.kotlin.commonizer.mergedtree + +internal sealed class CirNodeRelationship { + + class PreferredNode(val node: CirNode<*, *>) : CirNodeRelationship() + + class ParentNode(val node: CirNode<*, *>) : CirNodeRelationship() + + class Composite private constructor(val relationships: List) : CirNodeRelationship() { + companion object { + operator fun CirNodeRelationship.plus(other: CirNodeRelationship): Composite { + if (this is Composite) { + return if (other is Composite) { + Composite(this.relationships + other.relationships) + } else Composite(this.relationships + other) + } else if (other is Composite) { + return Composite(listOf(this) + other.relationships) + } + return Composite(listOf(this, other)) + } + } + } + + companion object { + fun ParentNode(node: CirNode<*, *>?): ParentNode? = if (node != null) CirNodeRelationship.ParentNode(node) else null + } +} + diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CommonizerCondition.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CommonizerCondition.kt deleted file mode 100644 index 36a4dd64ed7..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/CommonizerCondition.kt +++ /dev/null @@ -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 - -import org.jetbrains.kotlin.commonizer.cir.CirDeclaration -import org.jetbrains.kotlin.storage.NullableLazyValue - - -internal fun interface CommonizerCondition { - - fun allowCommonization(): Boolean - - infix fun and(other: CommonizerCondition) = CommonizerCondition { allowCommonization() && other.allowCommonization() } - - companion object Factory { - fun none(): CommonizerCondition = NoneCommonizerCondition - - fun nodeIsNotCommonized(node: CirNode<*, *>) = CommonizerCondition { node.commonDeclaration() == null } - - fun parent(parent: CirNode<*, *>): ParentNodeCommonizerCondition = ParentNodeCommonizerCondition(parent.commonDeclaration) - - fun parent(parent: CirNode<*, *>?): CommonizerCondition = if (parent == null) none() else parent(parent) - } -} - -private object NoneCommonizerCondition : CommonizerCondition { - override fun allowCommonization(): Boolean = true -} - -internal class ParentNodeCommonizerCondition( - private val parentNodeCommonDeclaration: NullableLazyValue -) : CommonizerCondition { - override fun allowCommonization(): Boolean = parentNodeCommonDeclaration() != null -} diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/nodeBuilders.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/nodeBuilders.kt index 330e5719e1f..7e60847736c 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/nodeBuilders.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/mergedtree/nodeBuilders.kt @@ -20,7 +20,7 @@ internal fun buildRootNode( ): CirRootNode = buildNode( storageManager = storageManager, size = size, - commonizerCondition = CommonizerCondition.none(), + nodeRelationship = null, commonizerProducer = ::RootCommonizer, nodeProducer = ::CirRootNode ) @@ -31,7 +31,7 @@ internal fun buildModuleNode( ): CirModuleNode = buildNode( storageManager = storageManager, size = size, - commonizerCondition = CommonizerCondition.none(), + nodeRelationship = null, commonizerProducer = ::ModuleCommonizer, nodeProducer = ::CirModuleNode ) @@ -42,7 +42,7 @@ internal fun buildPackageNode( ): CirPackageNode = buildNode( storageManager = storageManager, size = size, - commonizerCondition = CommonizerCondition.none(), + nodeRelationship = null, commonizerProducer = ::PackageCommonizer, nodeProducer = ::CirPackageNode ) @@ -51,11 +51,11 @@ internal fun buildPropertyNode( storageManager: StorageManager, size: Int, classifiers: CirKnownClassifiers, - condition: CommonizerCondition = CommonizerCondition.none(), + nodeRelationship: CirNodeRelationship? = null, ): CirPropertyNode = buildNode( storageManager = storageManager, size = size, - commonizerCondition = condition, + nodeRelationship = nodeRelationship, commonizerProducer = { PropertyCommonizer(classifiers) }, nodeProducer = ::CirPropertyNode ) @@ -64,11 +64,11 @@ internal fun buildFunctionNode( storageManager: StorageManager, size: Int, classifiers: CirKnownClassifiers, - condition: CommonizerCondition = CommonizerCondition.none(), + nodeRelationship: CirNodeRelationship?, ): CirFunctionNode = buildNode( storageManager = storageManager, size = size, - commonizerCondition = condition, + nodeRelationship = nodeRelationship, commonizerProducer = { FunctionCommonizer(classifiers) }, nodeProducer = ::CirFunctionNode ) @@ -77,12 +77,12 @@ internal fun buildClassNode( storageManager: StorageManager, size: Int, classifiers: CirKnownClassifiers, - condition: CommonizerCondition = CommonizerCondition.none(), + nodeRelationship: CirNodeRelationship?, classId: CirEntityId ): CirClassNode = buildNode( storageManager = storageManager, size = size, - commonizerCondition = condition, + nodeRelationship = nodeRelationship, commonizerProducer = { ClassCommonizer(classifiers) }, recursionMarker = CirClassRecursionMarker, nodeProducer = { targetDeclarations, commonDeclaration -> @@ -97,11 +97,11 @@ internal fun buildClassConstructorNode( storageManager: StorageManager, size: Int, classifiers: CirKnownClassifiers, - condition: ParentNodeCommonizerCondition, + nodeRelationship: CirNodeRelationship?, ): CirClassConstructorNode = buildNode( storageManager = storageManager, size = size, - commonizerCondition = condition, + nodeRelationship = nodeRelationship, commonizerProducer = { ClassConstructorCommonizer(classifiers) }, nodeProducer = ::CirClassConstructorNode ) @@ -114,7 +114,7 @@ internal fun buildTypeAliasNode( ): CirTypeAliasNode = buildNode( storageManager = storageManager, size = size, - commonizerCondition = CommonizerCondition.none(), + nodeRelationship = null, commonizerProducer = { TypeAliasCommonizer(classifiers) }, recursionMarker = CirClassifierRecursionMarker, nodeProducer = { targetDeclarations, commonDeclaration -> @@ -127,14 +127,14 @@ internal fun buildTypeAliasNode( private fun > buildNode( storageManager: StorageManager, size: Int, - commonizerCondition: CommonizerCondition, + nodeRelationship: CirNodeRelationship?, commonizerProducer: () -> Commonizer, recursionMarker: R? = null, nodeProducer: (CommonizedGroup, NullableLazyValue) -> N ): N { val targetDeclarations = CommonizedGroup(size) - val commonComputable = { commonize(commonizerCondition, targetDeclarations, commonizerProducer()) } + val commonComputable = { commonize(nodeRelationship, targetDeclarations, commonizerProducer()) } val commonLazyValue = if (recursionMarker != null) storageManager.createRecursionTolerantNullableLazyValue(commonComputable, recursionMarker) @@ -158,13 +158,22 @@ internal fun commonize( @Suppress("NOTHING_TO_INLINE") private inline fun commonize( - commonizerCondition: CommonizerCondition, + nodeRelationship: CirNodeRelationship?, targetDeclarations: CommonizedGroup, commonizer: Commonizer ): R? { - if (commonizerCondition.allowCommonization()) { + if (nodeRelationship.shouldCommonize()) { return commonize(targetDeclarations, commonizer) } return null } + +private fun CirNodeRelationship?.shouldCommonize(): Boolean { + return when (this) { + null -> true + is CirNodeRelationship.ParentNode -> node.commonDeclaration() != null + is CirNodeRelationship.PreferredNode -> node.commonDeclaration() == null + is CirNodeRelationship.Composite -> relationships.all { it.shouldCommonize() } + } +} \ No newline at end of file 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 e9d3ce69ee1..0405ce45365 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/InlineTypeAliasCirNodeTransformer.kt @@ -7,6 +7,9 @@ package org.jetbrains.kotlin.commonizer.transformer import org.jetbrains.kotlin.commonizer.cir.* 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.CirNodeTransformer.Context import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality @@ -84,21 +87,21 @@ internal class InlineTypeAliasCirNodeTransformer( fromAliasedClassNode.constructors.forEach { (key, aliasedConstructorNode) -> val aliasedConstructor = aliasedConstructorNode.targetDeclarations[targetIndex] ?: return@forEach intoClassNode.constructors.getOrPut(key) { - buildClassConstructorNode(storageManager, targetSize, classifiers, CommonizerCondition.parent(intoClassNode)) + buildClassConstructorNode(storageManager, targetSize, classifiers, ParentNode(intoClassNode)) }.targetDeclarations[targetIndex] = aliasedConstructor.withContainingClass(intoClass).markedArtificial() } fromAliasedClassNode.functions.forEach { (key, aliasedFunctionNode) -> val aliasedFunction = aliasedFunctionNode.targetDeclarations[targetIndex] ?: return@forEach intoClassNode.functions.getOrPut(key) { - buildFunctionNode(storageManager, targetSize, classifiers, CommonizerCondition.parent(intoClassNode)) + buildFunctionNode(storageManager, targetSize, classifiers, ParentNode(intoClassNode)) }.targetDeclarations[targetIndex] = aliasedFunction.withContainingClass(intoClass).markedArtificial() } fromAliasedClassNode.properties.forEach { (key, aliasedPropertyNode) -> val aliasedProperty = aliasedPropertyNode.targetDeclarations[targetIndex] ?: return@forEach intoClassNode.properties.getOrPut(key) { - buildPropertyNode(storageManager, targetSize, classifiers, CommonizerCondition.parent(intoClassNode)) + buildPropertyNode(storageManager, targetSize, classifiers, ParentNode(intoClassNode)) }.targetDeclarations[targetIndex] = aliasedProperty.withContainingClass(intoClass).markedArtificial() } } @@ -112,7 +115,7 @@ internal class InlineTypeAliasCirNodeTransformer( // and if the original typeAliasNode cannot be commonized. // Therefore, this artificial class node acts as a fallback with the original type-alias being still the preferred // option for commonization - condition = CommonizerCondition.parent(this) and CommonizerCondition.nodeIsNotCommonized(typeAliasNode), + nodeRelationship = ParentNode(this) + PreferredNode(typeAliasNode), classId = typeAliasNode.id ) this.classes[typeAliasNode.classifierName] = classNode diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/mergeCirTree.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/mergeCirTree.kt index 535929f924b..dd6a592e204 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/mergeCirTree.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/tree/mergeCirTree.kt @@ -52,7 +52,7 @@ internal fun CirNodeWithMembers<*, *>.buildClass( context: TargetBuildingContext, treeClass: CirTreeClass, parent: CirNode<*, *>? = null ) { val classNode = classes.getOrPut(treeClass.clazz.name) { - buildClassNode(context.storageManager, context.targets, context.classifiers, CommonizerCondition.parent(parent), treeClass.id) + buildClassNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent), treeClass.id) } classNode.targetDeclarations[context.targetIndex] = treeClass.clazz treeClass.functions.forEach { function -> classNode.buildFunction(context, function, classNode) } @@ -65,7 +65,7 @@ internal fun CirNodeWithMembers<*, *>.buildFunction( context: TargetBuildingContext, treeFunction: CirTreeFunction, parent: CirNode<*, *>? = null ) { val functionNode = functions.getOrPut(treeFunction.approximationKey) { - buildFunctionNode(context.storageManager, context.targets, context.classifiers, CommonizerCondition.parent(parent)) + buildFunctionNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent)) } functionNode.targetDeclarations[context.targetIndex] = treeFunction.function } @@ -74,7 +74,7 @@ internal fun CirNodeWithMembers<*, *>.buildProperty( context: TargetBuildingContext, treeProperty: CirTreeProperty, parent: CirNode<*, *>? = null ) { val propertyNode = properties.getOrPut(treeProperty.approximationKey) { - buildPropertyNode(context.storageManager, context.targets, context.classifiers, CommonizerCondition.parent(parent)) + buildPropertyNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent)) } propertyNode.targetDeclarations[context.targetIndex] = treeProperty.property } @@ -83,7 +83,7 @@ internal fun CirClassNode.buildConstructor( context: TargetBuildingContext, treeConstructor: CirTreeClassConstructor, parent: CirNode<*, *> ) { val constructorNode = constructors.getOrPut(treeConstructor.approximationKey) { - buildClassConstructorNode(context.storageManager, context.targets, context.classifiers, CommonizerCondition.parent(parent)) + buildClassConstructorNode(context.storageManager, context.targets, context.classifiers, CirNodeRelationship.ParentNode(parent)) } constructorNode.targetDeclarations[context.targetIndex] = treeConstructor.constructor } 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 8d5a79b9da2..f85ad7cbdbc 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt @@ -425,7 +425,7 @@ class TypeCommonizerTest : AbstractCommonizerTest() { storageManager = LockBasedStorageManager.NO_LOCKS, size = variants.size, classifiers = classifiers, - condition = CommonizerCondition.none(), + nodeRelationship = null, classId = type.classifierId ) }