From 684e51b0be172ea2b3979a16fe3f84b348b1e9fe Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Thu, 1 Jul 2021 17:32:06 +0200 Subject: [PATCH] [Commonizer] Implement TypeCommonizer as AssociativeCommonizer --- .../AbstractFunctionOrPropertyCommonizer.kt | 2 +- .../commonizer/core/AssociativeCommonizer.kt | 6 +- .../core/ClassOrTypeAliasTypeCommonizer.kt | 5 +- .../commonizer/core/CommonizationVisitor.kt | 2 +- .../core/ExtensionReceiverCommonizer.kt | 2 +- .../commonizer/core/TypeAliasCommonizer.kt | 4 +- .../commonizer/core/TypeArgumentCommonizer.kt | 2 +- .../kotlin/commonizer/core/TypeCommonizer.kt | 68 ++++++++----------- .../core/TypeParameterCommonizer.kt | 2 +- .../core/ValueParameterCommonizer.kt | 2 +- .../commonizer/core/TypeCommonizerTest.kt | 4 +- 11 files changed, 42 insertions(+), 57 deletions(-) diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt index 1ea38339da2..ce7c307c592 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt @@ -19,7 +19,7 @@ abstract class AbstractFunctionOrPropertyCommonizer( protected val modality = ModalityCommonizer() protected val visibility = VisibilityCommonizer.lowering() protected val extensionReceiver = ExtensionReceiverCommonizer(classifiers) - protected val returnType = TypeCommonizer(classifiers) + protected val returnType = TypeCommonizer(classifiers).asCommonizer() protected lateinit var kind: CallableMemberDescriptor.Kind protected val typeParameters = TypeParameterListCommonizer(classifiers) diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/AssociativeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/AssociativeCommonizer.kt index 9bb4f4bda59..e7e42747f68 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/AssociativeCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/AssociativeCommonizer.kt @@ -5,11 +5,13 @@ package org.jetbrains.kotlin.commonizer.core -internal interface AssociativeCommonizer { +interface AssociativeCommonizer { fun commonize(first: T, second: T): T? } -internal open class AssociativeCommonizerAdapter( +fun AssociativeCommonizer.asCommonizer(): AssociativeCommonizerAdapter = AssociativeCommonizerAdapter(this) + +open class AssociativeCommonizerAdapter( private val commonizer: AssociativeCommonizer ) : AbstractStandardCommonizer() { diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt index 11c18a78e51..6c3787fe45e 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt @@ -10,7 +10,7 @@ import org.jetbrains.kotlin.commonizer.cir.CirClassType import org.jetbrains.kotlin.commonizer.cir.CirTypeAliasType import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers -internal class ClassOrTypeAliasTypeAssociativeCommonizer( +internal class ClassOrTypeAliasTypeCommonizer( private val classifiers: CirKnownClassifiers ) : AssociativeCommonizer { @@ -51,9 +51,6 @@ internal class ClassOrTypeAliasTypeAssociativeCommonizer( } } -internal class ClassOrTypeAliasTypeCommonizer(classifiers: CirKnownClassifiers) : - AssociativeCommonizerAdapter(ClassOrTypeAliasTypeAssociativeCommonizer(classifiers)) - internal tailrec fun CirClassOrTypeAliasType.expandedType(): CirClassType = when (this) { is CirClassType -> this is CirTypeAliasType -> this.underlyingType.expandedType() 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 ff7a77a1c7f..29f160cd0c8 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/CommonizationVisitor.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/CommonizationVisitor.kt @@ -143,7 +143,7 @@ internal class CommonizationVisitor( supertypesMap: Map>? ) { val commonSupertypes = supertypesMap?.values?.compactMapNotNull { supertypesGroup -> - commonize(supertypesGroup, TypeCommonizer(classifiers)) + commonize(supertypesGroup, TypeCommonizer(classifiers).asCommonizer()) }.orEmpty() supertypes = commonSupertypes diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ExtensionReceiverCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ExtensionReceiverCommonizer.kt index 61916c216e4..8fb08760769 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ExtensionReceiverCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ExtensionReceiverCommonizer.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers class ExtensionReceiverCommonizer(classifiers: CirKnownClassifiers) : AbstractNullableCommonizer( - wrappedCommonizerFactory = { TypeCommonizer(classifiers) }, + wrappedCommonizerFactory = { TypeCommonizer(classifiers).asCommonizer() }, extractor = { it.type }, builder = { receiverType -> CirExtensionReceiver.create( diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeAliasCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeAliasCommonizer.kt index 3c6fd0c58f2..98fee727946 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeAliasCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeAliasCommonizer.kt @@ -40,7 +40,7 @@ private class TypeAliasShortCircuitingCommonizer( private lateinit var name: CirName private val typeParameters = TypeParameterListCommonizer(classifiers) private var underlyingType: CirClassOrTypeAliasType? = null // null means not computed yet - private val expandedType = TypeCommonizer(classifiers) + private val expandedType = TypeCommonizer(classifiers).asCommonizer() private val visibility = VisibilityCommonizer.lowering() override fun commonizationResult() = CirTypeAlias.create( @@ -70,7 +70,7 @@ private class TypeAliasShortCircuitingCommonizer( private class TypeAliasLiftingUpCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer() { private lateinit var name: CirName private val typeParameters = TypeParameterListCommonizer(classifiers) - private val underlyingType = TypeCommonizer(classifiers) + private val underlyingType = TypeCommonizer(classifiers).asCommonizer() private val visibility = VisibilityCommonizer.lowering() override fun commonizationResult(): CirTypeAlias { diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeArgumentCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeArgumentCommonizer.kt index f6ccba77b3b..3dc1fc5f759 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeArgumentCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeArgumentCommonizer.kt @@ -16,7 +16,7 @@ class TypeArgumentCommonizer( ) : AbstractStandardCommonizer() { private var isStar = false private lateinit var projectionKind: Variance - private val type = TypeCommonizer(classifiers) + private val type = TypeCommonizer(classifiers).asCommonizer() override fun commonizationResult() = if (isStar) CirStarTypeProjection else CirRegularTypeProjection( projectionKind = projectionKind, diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeCommonizer.kt index 5161590d4dc..36465234958 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeCommonizer.kt @@ -8,56 +8,42 @@ package org.jetbrains.kotlin.commonizer.core import org.jetbrains.kotlin.commonizer.cir.* import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers -class TypeCommonizer(private val classifiers: CirKnownClassifiers) : AbstractStandardCommonizer() { - private lateinit var typeCommonizer: Commonizer<*, CirType> - - override fun commonizationResult() = typeCommonizer.result - - override fun initialize(first: CirType) { - @Suppress("UNCHECKED_CAST") - typeCommonizer = when (first) { - is CirClassOrTypeAliasType -> ClassOrTypeAliasTypeCommonizer(classifiers) - is CirTypeParameterType -> TypeParameterTypeCommonizer() - is CirFlexibleType -> FlexibleTypeCommonizer(classifiers) - } as Commonizer<*, CirType> - } - - override fun doCommonizeWith(next: CirType): Boolean { - return when (next) { - is CirClassOrTypeAliasType -> (typeCommonizer as? ClassOrTypeAliasTypeCommonizer)?.commonizeWith(next) == true - is CirTypeParameterType -> (typeCommonizer as? TypeParameterTypeCommonizer)?.commonizeWith(next) == true - is CirFlexibleType -> (typeCommonizer as? FlexibleTypeCommonizer)?.commonizeWith(next) == true +class TypeCommonizer(private val classifiers: CirKnownClassifiers) : AssociativeCommonizer { + override fun commonize(first: CirType, second: CirType): CirType? { + if (first is CirClassOrTypeAliasType && second is CirClassOrTypeAliasType) { + return ClassOrTypeAliasTypeCommonizer(classifiers).commonize(first, second) } + + if (first is CirTypeParameterType && second is CirTypeParameterType) { + return TypeParameterTypeCommonizer.commonize(first, second) + } + + if (first is CirFlexibleType && second is CirFlexibleType) { + return FlexibleTypeAssociativeCommonizer(classifiers).commonize(first, second) + } + + return null } } -private class TypeParameterTypeCommonizer : AbstractStandardCommonizer() { - private lateinit var temp: CirTypeParameterType - - override fun commonizationResult() = temp - - override fun initialize(first: CirTypeParameterType) { - temp = first - } - - override fun doCommonizeWith(next: CirTypeParameterType): Boolean { +private object TypeParameterTypeCommonizer : AssociativeCommonizer { + override fun commonize(first: CirTypeParameterType, second: CirTypeParameterType): CirTypeParameterType? { // Real type parameter commonization is performed in TypeParameterCommonizer. // Here it is enough to check that type parameter indices and nullability are equal. - return temp == next + if (first == second) return first + return null } } -private class FlexibleTypeCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer() { - private val lowerBound = TypeCommonizer(classifiers) - private val upperBound = TypeCommonizer(classifiers) +private class FlexibleTypeAssociativeCommonizer(private val classifiers: CirKnownClassifiers) : AssociativeCommonizer { + override fun commonize(first: CirFlexibleType, second: CirFlexibleType): CirFlexibleType? { - override fun commonizationResult() = CirFlexibleType( - lowerBound = lowerBound.result as CirSimpleType, - upperBound = upperBound.result as CirSimpleType - ) + val lowerBound = TypeCommonizer(classifiers).commonize(first.lowerBound, second.lowerBound) ?: return null + val upperBound = TypeCommonizer(classifiers).commonize(first.upperBound, second.upperBound) ?: return null - override fun initialize(first: CirFlexibleType) = Unit - - override fun doCommonizeWith(next: CirFlexibleType) = - lowerBound.commonizeWith(next.lowerBound) && upperBound.commonizeWith(next.upperBound) + return CirFlexibleType( + lowerBound = lowerBound as CirSimpleType, + upperBound = upperBound as CirSimpleType + ) + } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeParameterCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeParameterCommonizer.kt index bc44f5a0949..56fe1440499 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeParameterCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeParameterCommonizer.kt @@ -39,5 +39,5 @@ class TypeParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStanda } private class TypeParameterUpperBoundsCommonizer(classifiers: CirKnownClassifiers) : AbstractListCommonizer( - singleElementCommonizerFactory = { TypeCommonizer(classifiers) } + singleElementCommonizerFactory = { TypeCommonizer(classifiers).asCommonizer() } ) diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ValueParameterCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ValueParameterCommonizer.kt index b0e0104cca0..5904fdfa420 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ValueParameterCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ValueParameterCommonizer.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.commonizer.utils.isNull class ValueParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer() { private lateinit var name: CirName - private val returnType = TypeCommonizer(classifiers) + private val returnType = TypeCommonizer(classifiers).asCommonizer() private var varargElementType: CirType? = null private var isCrossinline = true private var isNoinline = true 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 72c710d636a..d757a420442 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/core/TypeCommonizerTest.kt @@ -480,13 +480,13 @@ class TypeCommonizerTest : AbstractCommonizerTest() { super.doTestFailure(*variants, shouldFailOnFirstVariant = shouldFailOnFirstVariant) } - override fun createCommonizer() = TypeCommonizer(classifiers) + override fun createCommonizer() = TypeCommonizer(classifiers).asCommonizer() override fun areEqual(a: CirType?, b: CirType?) = (a === b) || (a != null && b != null && areEqual(classifiers, a, b)) companion object { fun areEqual(classifiers: CirKnownClassifiers, a: CirType, b: CirType): Boolean = - TypeCommonizer(classifiers).run { commonizeWith(a) && commonizeWith(b) } + TypeCommonizer(classifiers).asCommonizer().run { commonizeWith(a) && commonizeWith(b) } private fun CirKnownClassifiers.classNode(classId: CirEntityId, computation: () -> CirClassNode) = commonizedNodes.classNode(classId) ?: computation()