[Commonizer] Change CIR type calculation procedure

- By default, all CIR types are created as abbreviated types
  (if such information is available in descriptors).
- When necessary, CIR type can be "unabbreviated" to remove any
  abbreviations from it. This can be done via a separate function
  in CirTypeFactory: unabbreviate().
This commit is contained in:
Dmitriy Dolovov
2021-02-26 23:08:32 +03:00
parent 3f16f84d0d
commit 7ad35b2f49
3 changed files with 63 additions and 21 deletions
@@ -22,7 +22,7 @@ object CirAnnotationFactory {
private val interner = Interner<CirAnnotation>() private val interner = Interner<CirAnnotation>()
fun create(source: AnnotationDescriptor): CirAnnotation { fun create(source: AnnotationDescriptor): CirAnnotation {
val type = CirTypeFactory.create(source.type, useAbbreviation = false) as CirClassType val type = CirTypeFactory.create(source.type) as CirClassType
val allValueArguments: Map<Name, ConstantValue<*>> = source.allValueArguments val allValueArguments: Map<Name, ConstantValue<*>> = source.allValueArguments
if (allValueArguments.isEmpty()) if (allValueArguments.isEmpty())
@@ -12,14 +12,19 @@ import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeAliasImpl
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap
object CirTypeAliasFactory { object CirTypeAliasFactory {
fun create(source: TypeAliasDescriptor): CirTypeAlias = create( fun create(source: TypeAliasDescriptor): CirTypeAlias {
annotations = source.annotations.compactMap(CirAnnotationFactory::create), val underlyingType = CirTypeFactory.create(source.underlyingType) as CirClassOrTypeAliasType
name = CirName.create(source.name), val expandedType = CirTypeFactory.unabbreviate(underlyingType)
typeParameters = source.declaredTypeParameters.compactMap(CirTypeParameterFactory::create),
visibility = source.visibility, return create(
underlyingType = CirTypeFactory.create(source.underlyingType, useAbbreviation = true) as CirClassOrTypeAliasType, annotations = source.annotations.compactMap(CirAnnotationFactory::create),
expandedType = CirTypeFactory.create(source.expandedType, useAbbreviation = false) as CirClassType name = CirName.create(source.name),
) typeParameters = source.declaredTypeParameters.compactMap(CirTypeParameterFactory::create),
visibility = source.visibility,
underlyingType = underlyingType,
expandedType = expandedType
)
}
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")
inline fun create( inline fun create(
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.cir.* import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassTypeImpl import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassTypeImpl
import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeAliasTypeImpl import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeAliasTypeImpl
import org.jetbrains.kotlin.descriptors.commonizer.core.computeExpandedType
import org.jetbrains.kotlin.descriptors.commonizer.utils.* import org.jetbrains.kotlin.descriptors.commonizer.utils.*
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
@@ -28,22 +29,22 @@ object CirTypeFactory {
private val typeAliasTypeInterner = Interner<CirTypeAliasType>() private val typeAliasTypeInterner = Interner<CirTypeAliasType>()
private val typeParameterTypeInterner = Interner<CirTypeParameterType>() private val typeParameterTypeInterner = Interner<CirTypeParameterType>()
fun create(source: KotlinType, useAbbreviation: Boolean = true): CirType = source.unwrap().run { fun create(source: KotlinType): CirType = source.unwrap().run {
when (this) { when (this) {
is SimpleType -> create(this, useAbbreviation) is SimpleType -> create(this)
is FlexibleType -> CirFlexibleType(create(lowerBound, useAbbreviation), create(upperBound, useAbbreviation)) is FlexibleType -> CirFlexibleType(create(lowerBound), create(upperBound))
} }
} }
fun create(source: SimpleType, useAbbreviation: Boolean): CirSimpleType { fun create(source: SimpleType): CirSimpleType {
if (useAbbreviation && source is AbbreviatedType) { if (source is AbbreviatedType) {
val abbreviation = source.abbreviation val abbreviation = source.abbreviation
when (val classifierDescriptor = abbreviation.declarationDescriptor) { when (val classifierDescriptor = abbreviation.declarationDescriptor) {
is TypeAliasDescriptor -> { is TypeAliasDescriptor -> {
return createTypeAliasType( return createTypeAliasType(
typeAliasId = classifierDescriptor.classifierId, typeAliasId = classifierDescriptor.classifierId,
underlyingType = create(extractExpandedType(source), useAbbreviation = true) as CirClassOrTypeAliasType, underlyingType = create(extractExpandedType(source)) as CirClassOrTypeAliasType,
arguments = createArguments(abbreviation.arguments, useAbbreviation = true), arguments = createArguments(abbreviation.arguments),
isMarkedNullable = abbreviation.isMarkedNullable isMarkedNullable = abbreviation.isMarkedNullable
) )
} }
@@ -54,7 +55,7 @@ object CirTypeFactory {
return when (val classifierDescriptor = source.declarationDescriptor) { return when (val classifierDescriptor = source.declarationDescriptor) {
is ClassDescriptor -> createClassTypeWithAllOuterTypes( is ClassDescriptor -> createClassTypeWithAllOuterTypes(
classDescriptor = classifierDescriptor, classDescriptor = classifierDescriptor,
arguments = createArguments(source.arguments, useAbbreviation), arguments = createArguments(source.arguments),
isMarkedNullable = source.isMarkedNullable isMarkedNullable = source.isMarkedNullable
) )
is TypeAliasDescriptor -> { is TypeAliasDescriptor -> {
@@ -65,13 +66,13 @@ object CirTypeFactory {
val expandedType = extractExpandedType(abbreviatedType) val expandedType = extractExpandedType(abbreviatedType)
val cirExpandedType = create(expandedType, useAbbreviation = true) as CirClassOrTypeAliasType val cirExpandedType = create(expandedType) as CirClassOrTypeAliasType
val cirExpandedTypeWithProperNullability = if (source.isMarkedNullable) makeNullable(cirExpandedType) else cirExpandedType val cirExpandedTypeWithProperNullability = if (source.isMarkedNullable) makeNullable(cirExpandedType) else cirExpandedType
createTypeAliasType( createTypeAliasType(
typeAliasId = classifierDescriptor.classifierId, typeAliasId = classifierDescriptor.classifierId,
underlyingType = cirExpandedTypeWithProperNullability, underlyingType = cirExpandedTypeWithProperNullability,
arguments = createArguments(source.arguments, useAbbreviation = true), arguments = createArguments(source.arguments),
isMarkedNullable = source.isMarkedNullable isMarkedNullable = source.isMarkedNullable
) )
} }
@@ -147,6 +148,42 @@ object CirTypeFactory {
) )
} }
fun unabbreviate(type: CirClassOrTypeAliasType): CirClassType = when (type) {
is CirClassType -> {
var hasAbbreviationsInArguments = false
val unabreviatedArguments = type.arguments.compactMap { argument ->
val argumentType =
(argument as? CirTypeProjectionImpl)?.type as? CirClassOrTypeAliasType ?: return@compactMap argument
val unabbreviatedArgumentType = unabbreviate(argumentType)
if (argumentType == unabbreviatedArgumentType)
argument
else {
hasAbbreviationsInArguments = true
CirTypeProjectionImpl(
projectionKind = argument.projectionKind,
type = unabbreviatedArgumentType
)
}
}
val outerType = type.outerType
val unabbreviatedOuterType = outerType?.let(::unabbreviate)
if (!hasAbbreviationsInArguments && outerType == unabbreviatedOuterType)
type
else
createClassType(
classId = type.classifierId,
outerType = unabbreviatedOuterType,
visibility = type.visibility,
arguments = unabreviatedArguments,
isMarkedNullable = type.isMarkedNullable
)
}
is CirTypeAliasType -> unabbreviate(computeExpandedType(type))
}
private fun createClassTypeWithAllOuterTypes( private fun createClassTypeWithAllOuterTypes(
classDescriptor: ClassDescriptor, classDescriptor: ClassDescriptor,
arguments: List<CirTypeProjection>, arguments: List<CirTypeProjection>,
@@ -178,14 +215,14 @@ object CirTypeFactory {
} }
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")
private inline fun createArguments(arguments: List<TypeProjection>, useAbbreviation: Boolean): List<CirTypeProjection> = private inline fun createArguments(arguments: List<TypeProjection>): List<CirTypeProjection> =
arguments.compactMap { projection -> arguments.compactMap { projection ->
if (projection.isStarProjection) if (projection.isStarProjection)
CirStarTypeProjection CirStarTypeProjection
else else
CirTypeProjectionImpl( CirTypeProjectionImpl(
projectionKind = projection.projectionKind, projectionKind = projection.projectionKind,
type = create(projection.type, useAbbreviation) type = create(projection.type)
) )
} }