diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/AssociativeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/AssociativeCommonizer.kt new file mode 100644 index 00000000000..9bb4f4bda59 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/AssociativeCommonizer.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. + */ + +package org.jetbrains.kotlin.commonizer.core + +internal interface AssociativeCommonizer { + fun commonize(first: T, second: T): T? +} + +internal open class AssociativeCommonizerAdapter( + private val commonizer: AssociativeCommonizer +) : AbstractStandardCommonizer() { + + private var _result: T? = null + + override fun commonizationResult(): T { + return _result ?: failInEmptyState() + } + + override fun initialize(first: T) = Unit + + override fun doCommonizeWith(next: T): Boolean { + val currentResult = _result + + if (currentResult == null) { + _result = next + return true + } + + _result = commonizer.commonize(currentResult, next) + return _result != null + } +} \ No newline at end of file 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 2329cd376ca..11c18a78e51 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassOrTypeAliasTypeCommonizer.kt @@ -10,52 +10,49 @@ import org.jetbrains.kotlin.commonizer.cir.CirClassType import org.jetbrains.kotlin.commonizer.cir.CirTypeAliasType import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers -internal class ClassOrTypeAliasTypeStatelessCommonizer( +internal class ClassOrTypeAliasTypeAssociativeCommonizer( private val classifiers: CirKnownClassifiers -) : StatelessCommonizer { +) : AssociativeCommonizer { - override fun commonize(values: List): CirClassOrTypeAliasType? { - if (values.isEmpty()) return null - values.singleOrNull()?.let { return it } - - val classTypes = values.filterIsInstance() - val typeAliasTypes = values.filterIsInstance() - val expandedTypeAliasTypes = typeAliasTypes.map { it.expandedType() } - - if (values.all { it is CirClassType }) { - return ClassTypeCommonizer(classifiers).commonize(classTypes) + override fun commonize(first: CirClassOrTypeAliasType, second: CirClassOrTypeAliasType): CirClassOrTypeAliasType? { + if (first is CirClassType && second is CirClassType) { + return ClassTypeCommonizer(classifiers).commonize(listOf(first, second)) } - if (values.all { it is CirTypeAliasType }) { + if (first is CirTypeAliasType && second is CirTypeAliasType) { /* In case regular type-alias-type commonization fails, we try to expand all type-aliases and try our luck with commonizing those class types */ - return TypeAliasTypeCommonizer(classifiers).commonize(typeAliasTypes) - ?: ClassTypeCommonizer(classifiers).commonize(expandedTypeAliasTypes) + return TypeAliasTypeCommonizer(classifiers).commonize(listOf(first, second)) + ?: ClassTypeCommonizer(classifiers).commonize(listOf(first.expandedType(), second.expandedType())) + } + + val classType = when { + first is CirClassType -> first + second is CirClassType -> second + else -> return null + } + + val typeAliasType = when { + first is CirTypeAliasType -> first + second is CirTypeAliasType -> second + else -> return null } /* - There are type-alias types & class types enqueued for commonization. - We reduce all classes to a common representation and all type aliases to a common representation. + TypeAliasCommonizer will be able to figure out if the typealias will be represented as expect class in common. + If so, re-use this class type, otherwise: try to expand the typeAlias */ - val commonizedClass = ClassTypeCommonizer(classifiers).commonize(classTypes) ?: return null - val commonizedTypeAlias = TypeAliasTypeCommonizer(classifiers).commonize(typeAliasTypes) + val typeAliasClassType = TypeAliasTypeCommonizer(classifiers).commonize(listOf(typeAliasType))?.expandedType() + ?: typeAliasType.expandedType() - if (commonizedTypeAlias != null) { - return ClassTypeCommonizer(classifiers).commonize(listOf(commonizedClass, commonizedTypeAlias.expandedType())) - } - - /* - If type-alias type commonization failed: - Last attempt: Try to commonize all type-alias expansions with the commonized class - */ - return ClassTypeCommonizer(classifiers).commonize(expandedTypeAliasTypes + commonizedClass) + return ClassTypeCommonizer(classifiers).commonize(listOf(classType, typeAliasClassType)) } } internal class ClassOrTypeAliasTypeCommonizer(classifiers: CirKnownClassifiers) : - StatelessCommonizerAdapter(ClassOrTypeAliasTypeStatelessCommonizer(classifiers)) + AssociativeCommonizerAdapter(ClassOrTypeAliasTypeAssociativeCommonizer(classifiers)) internal tailrec fun CirClassOrTypeAliasType.expandedType(): CirClassType = when (this) { is CirClassType -> this diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/Commonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/Commonizer.kt index 4cac2958606..656cdf3ce02 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/Commonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/Commonizer.kt @@ -11,11 +11,6 @@ interface Commonizer { } fun Commonizer.commonize(values: List): R? { - /* Fast path: If commonizer supports StatelessCommonizer interface */ - if (this is StatelessCommonizerAdapter) { - return commonize(values) - } - values.forEach { value -> if (!commonizeWith(value)) return null } return result } diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/StatelessCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/StatelessCommonizer.kt deleted file mode 100644 index 2d2530ecda5..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/StatelessCommonizer.kt +++ /dev/null @@ -1,31 +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.core - -interface StatelessCommonizer { - fun commonize(values: List): R? -} - -open class StatelessCommonizerAdapter( - private val commonizer: StatelessCommonizer -) : AbstractStandardCommonizer(), StatelessCommonizer by commonizer { - private val values = mutableListOf() - - override fun commonizationResult(): R { - try { - return checkNotNull(commonize(values.toList())) - } finally { - values.clear() - } - } - - override fun initialize(first: T) = Unit - - override fun doCommonizeWith(next: T): Boolean { - values.add(next) - return commonize(values.toList()) != null - } -}