[Commonizer] Implement CirNodeRelationship over CommonizerCondition

This commit is contained in:
sebastian.sellmair
2021-06-01 18:28:05 +02:00
committed by Space
parent 8272564ca0
commit 0cf1618960
6 changed files with 72 additions and 62 deletions

View File

@@ -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>) : 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
}
}

View File

@@ -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<CirDeclaration>
) : CommonizerCondition {
override fun allowCommonization(): Boolean = parentNodeCommonDeclaration() != null
}

View File

@@ -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 <T : CirDeclaration, R : CirDeclaration, N : CirNode<T, R>> buildNode(
storageManager: StorageManager,
size: Int,
commonizerCondition: CommonizerCondition,
nodeRelationship: CirNodeRelationship?,
commonizerProducer: () -> Commonizer<T, R>,
recursionMarker: R? = null,
nodeProducer: (CommonizedGroup<T>, NullableLazyValue<R>) -> N
): N {
val targetDeclarations = CommonizedGroup<T>(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 <T : Any, R> commonize(
@Suppress("NOTHING_TO_INLINE")
private inline fun <T : Any, R> commonize(
commonizerCondition: CommonizerCondition,
nodeRelationship: CirNodeRelationship?,
targetDeclarations: CommonizedGroup<T>,
commonizer: Commonizer<T, R>
): 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() }
}
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -425,7 +425,7 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
storageManager = LockBasedStorageManager.NO_LOCKS,
size = variants.size,
classifiers = classifiers,
condition = CommonizerCondition.none(),
nodeRelationship = null,
classId = type.classifierId
)
}