[Commonizer] Implement TypeCommonizer as AssociativeCommonizer

This commit is contained in:
sebastian.sellmair
2021-07-01 17:32:06 +02:00
committed by Space
parent b29fd17d26
commit 684e51b0be
11 changed files with 42 additions and 57 deletions

View File

@@ -19,7 +19,7 @@ abstract class AbstractFunctionOrPropertyCommonizer<T : CirFunctionOrProperty>(
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)

View File

@@ -5,11 +5,13 @@
package org.jetbrains.kotlin.commonizer.core
internal interface AssociativeCommonizer<T> {
interface AssociativeCommonizer<T> {
fun commonize(first: T, second: T): T?
}
internal open class AssociativeCommonizerAdapter<T : Any>(
fun <T : Any> AssociativeCommonizer<T>.asCommonizer(): AssociativeCommonizerAdapter<T> = AssociativeCommonizerAdapter(this)
open class AssociativeCommonizerAdapter<T : Any>(
private val commonizer: AssociativeCommonizer<T>
) : AbstractStandardCommonizer<T, T>() {

View File

@@ -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<CirClassOrTypeAliasType> {
@@ -51,9 +51,6 @@ internal class ClassOrTypeAliasTypeAssociativeCommonizer(
}
}
internal class ClassOrTypeAliasTypeCommonizer(classifiers: CirKnownClassifiers) :
AssociativeCommonizerAdapter<CirClassOrTypeAliasType>(ClassOrTypeAliasTypeAssociativeCommonizer(classifiers))
internal tailrec fun CirClassOrTypeAliasType.expandedType(): CirClassType = when (this) {
is CirClassType -> this
is CirTypeAliasType -> this.underlyingType.expandedType()

View File

@@ -143,7 +143,7 @@ internal class CommonizationVisitor(
supertypesMap: Map<CirType, CommonizedGroup<CirType>>?
) {
val commonSupertypes = supertypesMap?.values?.compactMapNotNull { supertypesGroup ->
commonize(supertypesGroup, TypeCommonizer(classifiers))
commonize(supertypesGroup, TypeCommonizer(classifiers).asCommonizer())
}.orEmpty()
supertypes = commonSupertypes

View File

@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
class ExtensionReceiverCommonizer(classifiers: CirKnownClassifiers) :
AbstractNullableCommonizer<CirExtensionReceiver, CirExtensionReceiver, CirType, CirType>(
wrappedCommonizerFactory = { TypeCommonizer(classifiers) },
wrappedCommonizerFactory = { TypeCommonizer(classifiers).asCommonizer() },
extractor = { it.type },
builder = { receiverType ->
CirExtensionReceiver.create(

View File

@@ -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<CirTypeAlias, CirTypeAlias>() {
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 {

View File

@@ -16,7 +16,7 @@ class TypeArgumentCommonizer(
) : AbstractStandardCommonizer<CirTypeProjection, CirTypeProjection>() {
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,

View File

@@ -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<CirType, CirType>() {
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<CirType> {
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<CirTypeParameterType, CirTypeParameterType>() {
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<CirTypeParameterType> {
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<CirFlexibleType, CirFlexibleType>() {
private val lowerBound = TypeCommonizer(classifiers)
private val upperBound = TypeCommonizer(classifiers)
private class FlexibleTypeAssociativeCommonizer(private val classifiers: CirKnownClassifiers) : AssociativeCommonizer<CirFlexibleType> {
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
)
}
}

View File

@@ -39,5 +39,5 @@ class TypeParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStanda
}
private class TypeParameterUpperBoundsCommonizer(classifiers: CirKnownClassifiers) : AbstractListCommonizer<CirType, CirType>(
singleElementCommonizerFactory = { TypeCommonizer(classifiers) }
singleElementCommonizerFactory = { TypeCommonizer(classifiers).asCommonizer() }
)

View File

@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.commonizer.utils.isNull
class ValueParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirValueParameter, CirValueParameter>() {
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

View File

@@ -480,13 +480,13 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
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()