From 7ad35b2f49bc7dd41edc29abe56f8c903d9c3135 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Fri, 26 Feb 2021 23:08:32 +0300 Subject: [PATCH] [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(). --- .../cir/factory/CirAnnotationFactory.kt | 2 +- .../cir/factory/CirTypeAliasFactory.kt | 21 ++++--- .../commonizer/cir/factory/CirTypeFactory.kt | 61 +++++++++++++++---- 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirAnnotationFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirAnnotationFactory.kt index 250fe79d212..37f047d945e 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirAnnotationFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirAnnotationFactory.kt @@ -22,7 +22,7 @@ object CirAnnotationFactory { private val interner = Interner() 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> = source.allValueArguments if (allValueArguments.isEmpty()) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeAliasFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeAliasFactory.kt index 7923348e8ec..f2039d3d414 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeAliasFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeAliasFactory.kt @@ -12,14 +12,19 @@ import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeAliasImpl import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap object CirTypeAliasFactory { - fun create(source: TypeAliasDescriptor): CirTypeAlias = create( - annotations = source.annotations.compactMap(CirAnnotationFactory::create), - name = CirName.create(source.name), - typeParameters = source.declaredTypeParameters.compactMap(CirTypeParameterFactory::create), - visibility = source.visibility, - underlyingType = CirTypeFactory.create(source.underlyingType, useAbbreviation = true) as CirClassOrTypeAliasType, - expandedType = CirTypeFactory.create(source.expandedType, useAbbreviation = false) as CirClassType - ) + fun create(source: TypeAliasDescriptor): CirTypeAlias { + val underlyingType = CirTypeFactory.create(source.underlyingType) as CirClassOrTypeAliasType + val expandedType = CirTypeFactory.unabbreviate(underlyingType) + + return create( + annotations = source.annotations.compactMap(CirAnnotationFactory::create), + name = CirName.create(source.name), + typeParameters = source.declaredTypeParameters.compactMap(CirTypeParameterFactory::create), + visibility = source.visibility, + underlyingType = underlyingType, + expandedType = expandedType + ) + } @Suppress("NOTHING_TO_INLINE") inline fun create( diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeFactory.kt index cda5e6b83db..32903d02543 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeFactory.kt @@ -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.impl.CirClassTypeImpl 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.types.* @@ -28,22 +29,22 @@ object CirTypeFactory { private val typeAliasTypeInterner = Interner() private val typeParameterTypeInterner = Interner() - fun create(source: KotlinType, useAbbreviation: Boolean = true): CirType = source.unwrap().run { + fun create(source: KotlinType): CirType = source.unwrap().run { when (this) { - is SimpleType -> create(this, useAbbreviation) - is FlexibleType -> CirFlexibleType(create(lowerBound, useAbbreviation), create(upperBound, useAbbreviation)) + is SimpleType -> create(this) + is FlexibleType -> CirFlexibleType(create(lowerBound), create(upperBound)) } } - fun create(source: SimpleType, useAbbreviation: Boolean): CirSimpleType { - if (useAbbreviation && source is AbbreviatedType) { + fun create(source: SimpleType): CirSimpleType { + if (source is AbbreviatedType) { val abbreviation = source.abbreviation when (val classifierDescriptor = abbreviation.declarationDescriptor) { is TypeAliasDescriptor -> { return createTypeAliasType( typeAliasId = classifierDescriptor.classifierId, - underlyingType = create(extractExpandedType(source), useAbbreviation = true) as CirClassOrTypeAliasType, - arguments = createArguments(abbreviation.arguments, useAbbreviation = true), + underlyingType = create(extractExpandedType(source)) as CirClassOrTypeAliasType, + arguments = createArguments(abbreviation.arguments), isMarkedNullable = abbreviation.isMarkedNullable ) } @@ -54,7 +55,7 @@ object CirTypeFactory { return when (val classifierDescriptor = source.declarationDescriptor) { is ClassDescriptor -> createClassTypeWithAllOuterTypes( classDescriptor = classifierDescriptor, - arguments = createArguments(source.arguments, useAbbreviation), + arguments = createArguments(source.arguments), isMarkedNullable = source.isMarkedNullable ) is TypeAliasDescriptor -> { @@ -65,13 +66,13 @@ object CirTypeFactory { 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 createTypeAliasType( typeAliasId = classifierDescriptor.classifierId, underlyingType = cirExpandedTypeWithProperNullability, - arguments = createArguments(source.arguments, useAbbreviation = true), + arguments = createArguments(source.arguments), 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( classDescriptor: ClassDescriptor, arguments: List, @@ -178,14 +215,14 @@ object CirTypeFactory { } @Suppress("NOTHING_TO_INLINE") - private inline fun createArguments(arguments: List, useAbbreviation: Boolean): List = + private inline fun createArguments(arguments: List): List = arguments.compactMap { projection -> if (projection.isStarProjection) CirStarTypeProjection else CirTypeProjectionImpl( projectionKind = projection.projectionKind, - type = create(projection.type, useAbbreviation) + type = create(projection.type) ) }