mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 08:31:29 +00:00
[Commonizer] Implement TypeCommonizer as AssociativeCommonizer
This commit is contained in:
committed by
Space
parent
b29fd17d26
commit
684e51b0be
@@ -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)
|
||||
|
||||
|
||||
@@ -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>() {
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,5 +39,5 @@ class TypeParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStanda
|
||||
}
|
||||
|
||||
private class TypeParameterUpperBoundsCommonizer(classifiers: CirKnownClassifiers) : AbstractListCommonizer<CirType, CirType>(
|
||||
singleElementCommonizerFactory = { TypeCommonizer(classifiers) }
|
||||
singleElementCommonizerFactory = { TypeCommonizer(classifiers).asCommonizer() }
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user