[Commonizer] Re-introduce node builders 'parentCommonDeclaration' context
This commit is contained in:
+1
-1
@@ -19,7 +19,7 @@ internal object ClassConstructorMerger {
|
|||||||
) = with(context) {
|
) = with(context) {
|
||||||
val approximationKey = ConstructorApproximationKey(constructor, context.typeResolver)
|
val approximationKey = ConstructorApproximationKey(constructor, context.typeResolver)
|
||||||
val constructorNode: CirClassConstructorNode = classNode.constructors.getOrPut(approximationKey) {
|
val constructorNode: CirClassConstructorNode = classNode.constructors.getOrPut(approximationKey) {
|
||||||
buildClassConstructorNode(storageManager, targets, classifiers)
|
buildClassConstructorNode(storageManager, targets, classifiers, classNode.commonDeclaration)
|
||||||
}
|
}
|
||||||
constructorNode.targetDeclarations[context.targetIndex] = CirDeserializers.constructor(
|
constructorNode.targetDeclarations[context.targetIndex] = CirDeserializers.constructor(
|
||||||
source = constructor,
|
source = constructor,
|
||||||
|
|||||||
+2
-1
@@ -26,8 +26,9 @@ internal class ClassMerger(
|
|||||||
val classId = classEntry.classId
|
val classId = classEntry.classId
|
||||||
val className = classId.relativeNameSegments.last()
|
val className = classId.relativeNameSegments.last()
|
||||||
|
|
||||||
|
val maybeClassOwnerNode: CirClassNode? = ownerNode as? CirClassNode
|
||||||
val classNode: CirClassNode = ownerNode.classes.getOrPut(className) {
|
val classNode: CirClassNode = ownerNode.classes.getOrPut(className) {
|
||||||
buildClassNode(storageManager, targets, classifiers, classId)
|
buildClassNode(storageManager, targets, classifiers, maybeClassOwnerNode?.commonDeclaration, classId)
|
||||||
}
|
}
|
||||||
|
|
||||||
val clazz: KmClass?
|
val clazz: KmClass?
|
||||||
|
|||||||
+4
-2
@@ -27,14 +27,16 @@ internal object FunctionMerger {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val maybeClassOwnerNode: CirClassNode? = ownerNode as? CirClassNode
|
||||||
|
|
||||||
val approximationKey = FunctionApproximationKey(function, context.typeResolver)
|
val approximationKey = FunctionApproximationKey(function, context.typeResolver)
|
||||||
val functionNode: CirFunctionNode = ownerNode.functions.getOrPut(approximationKey) {
|
val functionNode: CirFunctionNode = ownerNode.functions.getOrPut(approximationKey) {
|
||||||
buildFunctionNode(storageManager, targets, classifiers)
|
buildFunctionNode(storageManager, targets, classifiers, maybeClassOwnerNode?.commonDeclaration)
|
||||||
}
|
}
|
||||||
functionNode.targetDeclarations[context.targetIndex] = CirDeserializers.function(
|
functionNode.targetDeclarations[context.targetIndex] = CirDeserializers.function(
|
||||||
name = approximationKey.name,
|
name = approximationKey.name,
|
||||||
source = function,
|
source = function,
|
||||||
containingClass = ownerNode.run { this as? CirClassNode }?.targetDeclarations?.get(context.targetIndex),
|
containingClass = maybeClassOwnerNode?.targetDeclarations?.get(context.targetIndex),
|
||||||
typeResolver = context.typeResolver
|
typeResolver = context.typeResolver
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -21,14 +21,16 @@ internal object PropertyMerger {
|
|||||||
if (property.isFakeOverride())
|
if (property.isFakeOverride())
|
||||||
return
|
return
|
||||||
|
|
||||||
|
val maybeClassOwnerNode: CirClassNode? = ownerNode as? CirClassNode
|
||||||
|
|
||||||
val approximationKey = PropertyApproximationKey(property, context.typeResolver)
|
val approximationKey = PropertyApproximationKey(property, context.typeResolver)
|
||||||
val propertyNode: CirPropertyNode = ownerNode.properties.getOrPut(approximationKey) {
|
val propertyNode: CirPropertyNode = ownerNode.properties.getOrPut(approximationKey) {
|
||||||
buildPropertyNode(storageManager, targets, classifiers)
|
buildPropertyNode(storageManager, targets, classifiers, maybeClassOwnerNode?.commonDeclaration)
|
||||||
}
|
}
|
||||||
propertyNode.targetDeclarations[context.targetIndex] = CirDeserializers.property(
|
propertyNode.targetDeclarations[context.targetIndex] = CirDeserializers.property(
|
||||||
name = approximationKey.name,
|
name = approximationKey.name,
|
||||||
source = property,
|
source = property,
|
||||||
containingClass = ownerNode.run { this as? CirClassNode }?.targetDeclarations?.get(context.targetIndex),
|
containingClass = maybeClassOwnerNode?.targetDeclarations?.get(context.targetIndex),
|
||||||
typeResolver = context.typeResolver
|
typeResolver = context.typeResolver
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,9 +48,11 @@ internal fun buildPropertyNode(
|
|||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
size: Int,
|
size: Int,
|
||||||
classifiers: CirKnownClassifiers,
|
classifiers: CirKnownClassifiers,
|
||||||
|
parentCommonDeclaration: NullableLazyValue<*>?
|
||||||
): CirPropertyNode = buildNode(
|
): CirPropertyNode = buildNode(
|
||||||
storageManager = storageManager,
|
storageManager = storageManager,
|
||||||
size = size,
|
size = size,
|
||||||
|
parentCommonDeclaration = parentCommonDeclaration,
|
||||||
commonizerProducer = { PropertyCommonizer(classifiers) },
|
commonizerProducer = { PropertyCommonizer(classifiers) },
|
||||||
nodeProducer = ::CirPropertyNode
|
nodeProducer = ::CirPropertyNode
|
||||||
)
|
)
|
||||||
@@ -59,9 +61,11 @@ internal fun buildFunctionNode(
|
|||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
size: Int,
|
size: Int,
|
||||||
classifiers: CirKnownClassifiers,
|
classifiers: CirKnownClassifiers,
|
||||||
|
parentCommonDeclaration: NullableLazyValue<*>?
|
||||||
): CirFunctionNode = buildNode(
|
): CirFunctionNode = buildNode(
|
||||||
storageManager = storageManager,
|
storageManager = storageManager,
|
||||||
size = size,
|
size = size,
|
||||||
|
parentCommonDeclaration = parentCommonDeclaration,
|
||||||
commonizerProducer = { FunctionCommonizer(classifiers) },
|
commonizerProducer = { FunctionCommonizer(classifiers) },
|
||||||
nodeProducer = ::CirFunctionNode
|
nodeProducer = ::CirFunctionNode
|
||||||
)
|
)
|
||||||
@@ -70,10 +74,12 @@ internal fun buildClassNode(
|
|||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
size: Int,
|
size: Int,
|
||||||
classifiers: CirKnownClassifiers,
|
classifiers: CirKnownClassifiers,
|
||||||
|
parentCommonDeclaration: NullableLazyValue<*>?,
|
||||||
classId: CirEntityId
|
classId: CirEntityId
|
||||||
): CirClassNode = buildNode(
|
): CirClassNode = buildNode(
|
||||||
storageManager = storageManager,
|
storageManager = storageManager,
|
||||||
size = size,
|
size = size,
|
||||||
|
parentCommonDeclaration = parentCommonDeclaration,
|
||||||
commonizerProducer = { ClassCommonizer(classifiers) },
|
commonizerProducer = { ClassCommonizer(classifiers) },
|
||||||
recursionMarker = CirClassRecursionMarker,
|
recursionMarker = CirClassRecursionMarker,
|
||||||
nodeProducer = { targetDeclarations, commonDeclaration ->
|
nodeProducer = { targetDeclarations, commonDeclaration ->
|
||||||
@@ -87,9 +93,11 @@ internal fun buildClassConstructorNode(
|
|||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
size: Int,
|
size: Int,
|
||||||
classifiers: CirKnownClassifiers,
|
classifiers: CirKnownClassifiers,
|
||||||
|
parentCommonDeclaration: NullableLazyValue<*>?
|
||||||
): CirClassConstructorNode = buildNode(
|
): CirClassConstructorNode = buildNode(
|
||||||
storageManager = storageManager,
|
storageManager = storageManager,
|
||||||
size = size,
|
size = size,
|
||||||
|
parentCommonDeclaration = parentCommonDeclaration,
|
||||||
commonizerProducer = { ClassConstructorCommonizer(classifiers) },
|
commonizerProducer = { ClassConstructorCommonizer(classifiers) },
|
||||||
nodeProducer = ::CirClassConstructorNode
|
nodeProducer = ::CirClassConstructorNode
|
||||||
)
|
)
|
||||||
@@ -114,13 +122,14 @@ internal fun buildTypeAliasNode(
|
|||||||
private fun <T : CirDeclaration, R : CirDeclaration, N : CirNode<T, R>> buildNode(
|
private fun <T : CirDeclaration, R : CirDeclaration, N : CirNode<T, R>> buildNode(
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
size: Int,
|
size: Int,
|
||||||
|
parentCommonDeclaration: NullableLazyValue<*>? = null,
|
||||||
commonizerProducer: () -> Commonizer<T, R>,
|
commonizerProducer: () -> Commonizer<T, R>,
|
||||||
recursionMarker: R? = null,
|
recursionMarker: R? = null,
|
||||||
nodeProducer: (CommonizedGroup<T>, NullableLazyValue<R>) -> N
|
nodeProducer: (CommonizedGroup<T>, NullableLazyValue<R>) -> N
|
||||||
): N {
|
): N {
|
||||||
val targetDeclarations = CommonizedGroup<T>(size)
|
val targetDeclarations = CommonizedGroup<T>(size)
|
||||||
|
|
||||||
val commonComputable = { commonize(targetDeclarations, commonizerProducer()) }
|
val commonComputable = { commonize(parentCommonDeclaration, targetDeclarations, commonizerProducer()) }
|
||||||
|
|
||||||
val commonLazyValue = if (recursionMarker != null)
|
val commonLazyValue = if (recursionMarker != null)
|
||||||
storageManager.createRecursionTolerantNullableLazyValue(commonComputable, recursionMarker)
|
storageManager.createRecursionTolerantNullableLazyValue(commonComputable, recursionMarker)
|
||||||
@@ -141,3 +150,17 @@ internal fun <T : Any, R> commonize(
|
|||||||
|
|
||||||
return commonizer.result
|
return commonizer.result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
private inline fun <T : Any, R> commonize(
|
||||||
|
parentCommonDeclaration: NullableLazyValue<*>?,
|
||||||
|
targetDeclarations: CommonizedGroup<T>,
|
||||||
|
commonizer: Commonizer<T, R>
|
||||||
|
): R? {
|
||||||
|
if (parentCommonDeclaration != null && parentCommonDeclaration.invoke() == null) {
|
||||||
|
// don't commonize declaration if it's parent failed to commonize
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return commonize(targetDeclarations, commonizer)
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.commonizer.tree
|
|||||||
import org.jetbrains.kotlin.commonizer.TargetDependent
|
import org.jetbrains.kotlin.commonizer.TargetDependent
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirRoot
|
import org.jetbrains.kotlin.commonizer.cir.CirRoot
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.*
|
import org.jetbrains.kotlin.commonizer.mergedtree.*
|
||||||
import org.jetbrains.kotlin.commonizer.tree.*
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
internal data class TargetBuildingContext(
|
internal data class TargetBuildingContext(
|
||||||
@@ -49,34 +48,41 @@ internal fun CirModuleNode.buildPackage(context: TargetBuildingContext, treePack
|
|||||||
treePackage.classes.forEach { clazz -> packageNode.buildClass(context, clazz) }
|
treePackage.classes.forEach { clazz -> packageNode.buildClass(context, clazz) }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun CirNodeWithMembers<*, *>.buildClass(context: TargetBuildingContext, treeClass: CirTreeClass) {
|
internal fun CirNodeWithMembers<*, *>.buildClass(
|
||||||
|
context: TargetBuildingContext, treeClass: CirTreeClass, parent: CirNode<*, *>? = null
|
||||||
|
) {
|
||||||
val classNode = classes.getOrPut(treeClass.clazz.name) {
|
val classNode = classes.getOrPut(treeClass.clazz.name) {
|
||||||
buildClassNode(context.storageManager, context.targets, context.classifiers, treeClass.id)
|
buildClassNode(context.storageManager, context.targets, context.classifiers, parent?.commonDeclaration, treeClass.id)
|
||||||
}
|
}
|
||||||
classNode.targetDeclarations[context.targetIndex] = treeClass.clazz
|
classNode.targetDeclarations[context.targetIndex] = treeClass.clazz
|
||||||
treeClass.functions.forEach { function -> classNode.buildFunction(context, function) }
|
treeClass.functions.forEach { function -> classNode.buildFunction(context, function, classNode) }
|
||||||
treeClass.properties.forEach { property -> classNode.buildProperty(context, property) }
|
treeClass.properties.forEach { property -> classNode.buildProperty(context, property, classNode) }
|
||||||
treeClass.constructors.forEach { constructor -> classNode.buildConstructor(context, constructor) }
|
treeClass.constructors.forEach { constructor -> classNode.buildConstructor(context, constructor, classNode) }
|
||||||
treeClass.classes.forEach { clazz -> classNode.buildClass(context, clazz) }
|
treeClass.classes.forEach { clazz -> classNode.buildClass(context, clazz, classNode) }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun CirNodeWithMembers<*, *>.buildFunction(context: TargetBuildingContext, treeFunction: CirTreeFunction) {
|
internal fun CirNodeWithMembers<*, *>.buildFunction(
|
||||||
|
context: TargetBuildingContext, treeFunction: CirTreeFunction, parent: CirNode<*, *>? = null
|
||||||
|
) {
|
||||||
val functionNode = functions.getOrPut(treeFunction.approximationKey) {
|
val functionNode = functions.getOrPut(treeFunction.approximationKey) {
|
||||||
buildFunctionNode(context.storageManager, context.targets, context.classifiers)
|
buildFunctionNode(context.storageManager, context.targets, context.classifiers, parent?.commonDeclaration)
|
||||||
}
|
}
|
||||||
functionNode.targetDeclarations[context.targetIndex] = treeFunction.function
|
functionNode.targetDeclarations[context.targetIndex] = treeFunction.function
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun CirNodeWithMembers<*, *>.buildProperty(context: TargetBuildingContext, treeProperty: CirTreeProperty) {
|
internal fun CirNodeWithMembers<*, *>.buildProperty(
|
||||||
|
context: TargetBuildingContext, treeProperty: CirTreeProperty, parent: CirNode<*, *>? = null) {
|
||||||
val propertyNode = properties.getOrPut(treeProperty.approximationKey) {
|
val propertyNode = properties.getOrPut(treeProperty.approximationKey) {
|
||||||
buildPropertyNode(context.storageManager, context.targets, context.classifiers)
|
buildPropertyNode(context.storageManager, context.targets, context.classifiers, parent?.commonDeclaration)
|
||||||
}
|
}
|
||||||
propertyNode.targetDeclarations[context.targetIndex] = treeProperty.property
|
propertyNode.targetDeclarations[context.targetIndex] = treeProperty.property
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun CirClassNode.buildConstructor(context: TargetBuildingContext, treeConstructor: CirTreeClassConstructor) {
|
internal fun CirClassNode.buildConstructor(
|
||||||
|
context: TargetBuildingContext, treeConstructor: CirTreeClassConstructor, parent: CirNode<*, *>?
|
||||||
|
) {
|
||||||
val constructorNode = constructors.getOrPut(treeConstructor.approximationKey) {
|
val constructorNode = constructors.getOrPut(treeConstructor.approximationKey) {
|
||||||
buildClassConstructorNode(context.storageManager, context.targets, context.classifiers)
|
buildClassConstructorNode(context.storageManager, context.targets, context.classifiers, parent?.commonDeclaration)
|
||||||
}
|
}
|
||||||
constructorNode.targetDeclarations[context.targetIndex] = treeConstructor.constructor
|
constructorNode.targetDeclarations[context.targetIndex] = treeConstructor.constructor
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -469,6 +469,7 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
|
|||||||
storageManager = LockBasedStorageManager.NO_LOCKS,
|
storageManager = LockBasedStorageManager.NO_LOCKS,
|
||||||
size = variants.size,
|
size = variants.size,
|
||||||
classifiers = classifiers,
|
classifiers = classifiers,
|
||||||
|
parentCommonDeclaration = null,
|
||||||
classId = type.classifierId
|
classId = type.classifierId
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+120
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* 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.hierarchical
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.commonizer.AbstractInlineSourcesCommonizationTest
|
||||||
|
import org.jetbrains.kotlin.commonizer.assertCommonized
|
||||||
|
|
||||||
|
class FunctionReturnTypeCommonizationTest : AbstractInlineSourcesCommonizationTest() {
|
||||||
|
|
||||||
|
fun `test non-commonized return type of top level function`() {
|
||||||
|
val result = commonize {
|
||||||
|
outputTarget("(a,b)")
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"a", """
|
||||||
|
class A { // NOTE: Class
|
||||||
|
class B
|
||||||
|
}
|
||||||
|
fun x(): A.B = TODO()
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"b", """
|
||||||
|
interface A { // NOTE: Interface
|
||||||
|
class B
|
||||||
|
}
|
||||||
|
fun x(): A.B = TODO()
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -> A is not commonized (interface vs class)
|
||||||
|
* -> B is not commonized
|
||||||
|
* -> fun x can't be commonized
|
||||||
|
* -> Empty commonization
|
||||||
|
*/
|
||||||
|
result.assertCommonized(
|
||||||
|
"(a,b)", ""
|
||||||
|
)
|
||||||
|
|
||||||
|
result.assertCommonized(
|
||||||
|
"a", """
|
||||||
|
class A {
|
||||||
|
class B
|
||||||
|
}
|
||||||
|
fun x(): A.B = TODO()
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
result.assertCommonized(
|
||||||
|
"b", """
|
||||||
|
interface A {
|
||||||
|
class B
|
||||||
|
}
|
||||||
|
fun x(): A.B = TODO()
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun `test commonized return type of top level function`() {
|
||||||
|
val result = commonize {
|
||||||
|
outputTarget("(a,b)")
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"a", """
|
||||||
|
interface A {
|
||||||
|
class B
|
||||||
|
}
|
||||||
|
fun x(): A.B = TODO()
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"b", """
|
||||||
|
interface A {
|
||||||
|
class B
|
||||||
|
}
|
||||||
|
fun x(): A.B = TODO()
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -> A is not commonized (interface vs class)
|
||||||
|
* -> B is not commonized
|
||||||
|
* -> fun x can't be commonized
|
||||||
|
* -> Empty commonization
|
||||||
|
*/
|
||||||
|
result.assertCommonized(
|
||||||
|
"(a,b)", """
|
||||||
|
expect interface A {
|
||||||
|
expect class B expect constructor()
|
||||||
|
}
|
||||||
|
expect fun x(): A.B
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
result.assertCommonized(
|
||||||
|
"a", """
|
||||||
|
interface A {
|
||||||
|
class B
|
||||||
|
}
|
||||||
|
fun x(): A.B = TODO()
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
result.assertCommonized(
|
||||||
|
"b", """
|
||||||
|
interface A {
|
||||||
|
class B
|
||||||
|
}
|
||||||
|
fun x(): A.B = TODO()
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user