[Commonizer] Implement TypeCommonizer as AssociativeCommonizer
This commit is contained in:
committed by
Space
parent
b29fd17d26
commit
684e51b0be
+1
-1
@@ -19,7 +19,7 @@ abstract class AbstractFunctionOrPropertyCommonizer<T : CirFunctionOrProperty>(
|
|||||||
protected val modality = ModalityCommonizer()
|
protected val modality = ModalityCommonizer()
|
||||||
protected val visibility = VisibilityCommonizer.lowering()
|
protected val visibility = VisibilityCommonizer.lowering()
|
||||||
protected val extensionReceiver = ExtensionReceiverCommonizer(classifiers)
|
protected val extensionReceiver = ExtensionReceiverCommonizer(classifiers)
|
||||||
protected val returnType = TypeCommonizer(classifiers)
|
protected val returnType = TypeCommonizer(classifiers).asCommonizer()
|
||||||
protected lateinit var kind: CallableMemberDescriptor.Kind
|
protected lateinit var kind: CallableMemberDescriptor.Kind
|
||||||
protected val typeParameters = TypeParameterListCommonizer(classifiers)
|
protected val typeParameters = TypeParameterListCommonizer(classifiers)
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.commonizer.core
|
package org.jetbrains.kotlin.commonizer.core
|
||||||
|
|
||||||
internal interface AssociativeCommonizer<T> {
|
interface AssociativeCommonizer<T> {
|
||||||
fun commonize(first: T, second: T): 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>
|
private val commonizer: AssociativeCommonizer<T>
|
||||||
) : AbstractStandardCommonizer<T, T>() {
|
) : AbstractStandardCommonizer<T, T>() {
|
||||||
|
|
||||||
|
|||||||
+1
-4
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.commonizer.cir.CirClassType
|
|||||||
import org.jetbrains.kotlin.commonizer.cir.CirTypeAliasType
|
import org.jetbrains.kotlin.commonizer.cir.CirTypeAliasType
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
||||||
|
|
||||||
internal class ClassOrTypeAliasTypeAssociativeCommonizer(
|
internal class ClassOrTypeAliasTypeCommonizer(
|
||||||
private val classifiers: CirKnownClassifiers
|
private val classifiers: CirKnownClassifiers
|
||||||
) : AssociativeCommonizer<CirClassOrTypeAliasType> {
|
) : 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) {
|
internal tailrec fun CirClassOrTypeAliasType.expandedType(): CirClassType = when (this) {
|
||||||
is CirClassType -> this
|
is CirClassType -> this
|
||||||
is CirTypeAliasType -> this.underlyingType.expandedType()
|
is CirTypeAliasType -> this.underlyingType.expandedType()
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ internal class CommonizationVisitor(
|
|||||||
supertypesMap: Map<CirType, CommonizedGroup<CirType>>?
|
supertypesMap: Map<CirType, CommonizedGroup<CirType>>?
|
||||||
) {
|
) {
|
||||||
val commonSupertypes = supertypesMap?.values?.compactMapNotNull { supertypesGroup ->
|
val commonSupertypes = supertypesMap?.values?.compactMapNotNull { supertypesGroup ->
|
||||||
commonize(supertypesGroup, TypeCommonizer(classifiers))
|
commonize(supertypesGroup, TypeCommonizer(classifiers).asCommonizer())
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
|
|
||||||
supertypes = commonSupertypes
|
supertypes = commonSupertypes
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
|||||||
|
|
||||||
class ExtensionReceiverCommonizer(classifiers: CirKnownClassifiers) :
|
class ExtensionReceiverCommonizer(classifiers: CirKnownClassifiers) :
|
||||||
AbstractNullableCommonizer<CirExtensionReceiver, CirExtensionReceiver, CirType, CirType>(
|
AbstractNullableCommonizer<CirExtensionReceiver, CirExtensionReceiver, CirType, CirType>(
|
||||||
wrappedCommonizerFactory = { TypeCommonizer(classifiers) },
|
wrappedCommonizerFactory = { TypeCommonizer(classifiers).asCommonizer() },
|
||||||
extractor = { it.type },
|
extractor = { it.type },
|
||||||
builder = { receiverType ->
|
builder = { receiverType ->
|
||||||
CirExtensionReceiver.create(
|
CirExtensionReceiver.create(
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ private class TypeAliasShortCircuitingCommonizer(
|
|||||||
private lateinit var name: CirName
|
private lateinit var name: CirName
|
||||||
private val typeParameters = TypeParameterListCommonizer(classifiers)
|
private val typeParameters = TypeParameterListCommonizer(classifiers)
|
||||||
private var underlyingType: CirClassOrTypeAliasType? = null // null means not computed yet
|
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()
|
private val visibility = VisibilityCommonizer.lowering()
|
||||||
|
|
||||||
override fun commonizationResult() = CirTypeAlias.create(
|
override fun commonizationResult() = CirTypeAlias.create(
|
||||||
@@ -70,7 +70,7 @@ private class TypeAliasShortCircuitingCommonizer(
|
|||||||
private class TypeAliasLiftingUpCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirTypeAlias, CirTypeAlias>() {
|
private class TypeAliasLiftingUpCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirTypeAlias, CirTypeAlias>() {
|
||||||
private lateinit var name: CirName
|
private lateinit var name: CirName
|
||||||
private val typeParameters = TypeParameterListCommonizer(classifiers)
|
private val typeParameters = TypeParameterListCommonizer(classifiers)
|
||||||
private val underlyingType = TypeCommonizer(classifiers)
|
private val underlyingType = TypeCommonizer(classifiers).asCommonizer()
|
||||||
private val visibility = VisibilityCommonizer.lowering()
|
private val visibility = VisibilityCommonizer.lowering()
|
||||||
|
|
||||||
override fun commonizationResult(): CirTypeAlias {
|
override fun commonizationResult(): CirTypeAlias {
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ class TypeArgumentCommonizer(
|
|||||||
) : AbstractStandardCommonizer<CirTypeProjection, CirTypeProjection>() {
|
) : AbstractStandardCommonizer<CirTypeProjection, CirTypeProjection>() {
|
||||||
private var isStar = false
|
private var isStar = false
|
||||||
private lateinit var projectionKind: Variance
|
private lateinit var projectionKind: Variance
|
||||||
private val type = TypeCommonizer(classifiers)
|
private val type = TypeCommonizer(classifiers).asCommonizer()
|
||||||
|
|
||||||
override fun commonizationResult() = if (isStar) CirStarTypeProjection else CirRegularTypeProjection(
|
override fun commonizationResult() = if (isStar) CirStarTypeProjection else CirRegularTypeProjection(
|
||||||
projectionKind = projectionKind,
|
projectionKind = projectionKind,
|
||||||
|
|||||||
@@ -8,56 +8,42 @@ package org.jetbrains.kotlin.commonizer.core
|
|||||||
import org.jetbrains.kotlin.commonizer.cir.*
|
import org.jetbrains.kotlin.commonizer.cir.*
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
||||||
|
|
||||||
class TypeCommonizer(private val classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirType, CirType>() {
|
class TypeCommonizer(private val classifiers: CirKnownClassifiers) : AssociativeCommonizer<CirType> {
|
||||||
private lateinit var typeCommonizer: Commonizer<*, CirType>
|
override fun commonize(first: CirType, second: CirType): CirType? {
|
||||||
|
if (first is CirClassOrTypeAliasType && second is CirClassOrTypeAliasType) {
|
||||||
override fun commonizationResult() = typeCommonizer.result
|
return ClassOrTypeAliasTypeCommonizer(classifiers).commonize(first, second)
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 object TypeParameterTypeCommonizer : AssociativeCommonizer<CirTypeParameterType> {
|
||||||
private lateinit var temp: CirTypeParameterType
|
override fun commonize(first: CirTypeParameterType, second: CirTypeParameterType): CirTypeParameterType? {
|
||||||
|
|
||||||
override fun commonizationResult() = temp
|
|
||||||
|
|
||||||
override fun initialize(first: CirTypeParameterType) {
|
|
||||||
temp = first
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun doCommonizeWith(next: CirTypeParameterType): Boolean {
|
|
||||||
// Real type parameter commonization is performed in TypeParameterCommonizer.
|
// Real type parameter commonization is performed in TypeParameterCommonizer.
|
||||||
// Here it is enough to check that type parameter indices and nullability are equal.
|
// 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 class FlexibleTypeAssociativeCommonizer(private val classifiers: CirKnownClassifiers) : AssociativeCommonizer<CirFlexibleType> {
|
||||||
private val lowerBound = TypeCommonizer(classifiers)
|
override fun commonize(first: CirFlexibleType, second: CirFlexibleType): CirFlexibleType? {
|
||||||
private val upperBound = TypeCommonizer(classifiers)
|
|
||||||
|
|
||||||
override fun commonizationResult() = CirFlexibleType(
|
val lowerBound = TypeCommonizer(classifiers).commonize(first.lowerBound, second.lowerBound) ?: return null
|
||||||
lowerBound = lowerBound.result as CirSimpleType,
|
val upperBound = TypeCommonizer(classifiers).commonize(first.upperBound, second.upperBound) ?: return null
|
||||||
upperBound = upperBound.result as CirSimpleType
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun initialize(first: CirFlexibleType) = Unit
|
return CirFlexibleType(
|
||||||
|
lowerBound = lowerBound as CirSimpleType,
|
||||||
override fun doCommonizeWith(next: CirFlexibleType) =
|
upperBound = upperBound as CirSimpleType
|
||||||
lowerBound.commonizeWith(next.lowerBound) && upperBound.commonizeWith(next.upperBound)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -39,5 +39,5 @@ class TypeParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStanda
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class TypeParameterUpperBoundsCommonizer(classifiers: CirKnownClassifiers) : AbstractListCommonizer<CirType, CirType>(
|
private class TypeParameterUpperBoundsCommonizer(classifiers: CirKnownClassifiers) : AbstractListCommonizer<CirType, CirType>(
|
||||||
singleElementCommonizerFactory = { TypeCommonizer(classifiers) }
|
singleElementCommonizerFactory = { TypeCommonizer(classifiers).asCommonizer() }
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.commonizer.utils.isNull
|
|||||||
|
|
||||||
class ValueParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirValueParameter, CirValueParameter>() {
|
class ValueParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirValueParameter, CirValueParameter>() {
|
||||||
private lateinit var name: CirName
|
private lateinit var name: CirName
|
||||||
private val returnType = TypeCommonizer(classifiers)
|
private val returnType = TypeCommonizer(classifiers).asCommonizer()
|
||||||
private var varargElementType: CirType? = null
|
private var varargElementType: CirType? = null
|
||||||
private var isCrossinline = true
|
private var isCrossinline = true
|
||||||
private var isNoinline = true
|
private var isNoinline = true
|
||||||
|
|||||||
@@ -480,13 +480,13 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
|
|||||||
super.doTestFailure(*variants, shouldFailOnFirstVariant = shouldFailOnFirstVariant)
|
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))
|
override fun areEqual(a: CirType?, b: CirType?) = (a === b) || (a != null && b != null && areEqual(classifiers, a, b))
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun areEqual(classifiers: CirKnownClassifiers, a: CirType, b: CirType): Boolean =
|
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) =
|
private fun CirKnownClassifiers.classNode(classId: CirEntityId, computation: () -> CirClassNode) =
|
||||||
commonizedNodes.classNode(classId) ?: computation()
|
commonizedNodes.classNode(classId) ?: computation()
|
||||||
|
|||||||
Reference in New Issue
Block a user