mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 08:31:29 +00:00
[Commonizer] Implement CirNodeRelationship over CommonizerCondition
This commit is contained in:
committed by
Space
parent
8272564ca0
commit
0cf1618960
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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() }
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user