[FIR] Combine type attributes in typealias expansion

^KT-48651 Fixed
This commit is contained in:
Dmitriy Novozhilov
2021-09-14 17:08:21 +03:00
committed by teamcityserver
parent 0f6b6dbca3
commit 37b427c656
4 changed files with 41 additions and 1 deletions
@@ -17,6 +17,8 @@ object CompilerConeAttributes {
override fun union(other: Exact?): Exact? = null
override fun intersect(other: Exact?): Exact? = null
override fun add(other: Exact?): Exact = this
override fun isSubtypeOf(other: Exact?): Boolean = true
override val key: KClass<out Exact> = Exact::class
@@ -29,6 +31,7 @@ object CompilerConeAttributes {
override fun union(other: NoInfer?): NoInfer? = null
override fun intersect(other: NoInfer?): NoInfer? = null
override fun add(other: NoInfer?): NoInfer = this
override fun isSubtypeOf(other: NoInfer?): Boolean = true
override val key: KClass<out NoInfer> = NoInfer::class
@@ -41,6 +44,8 @@ object CompilerConeAttributes {
override fun union(other: EnhancedNullability?): EnhancedNullability? = other
override fun intersect(other: EnhancedNullability?): EnhancedNullability = this
override fun add(other: EnhancedNullability?): EnhancedNullability = this
override fun isSubtypeOf(other: EnhancedNullability?): Boolean = true
override val key: KClass<out EnhancedNullability> = EnhancedNullability::class
@@ -53,6 +58,8 @@ object CompilerConeAttributes {
override fun union(other: ExtensionFunctionType?): ExtensionFunctionType? = other
override fun intersect(other: ExtensionFunctionType?): ExtensionFunctionType = this
override fun add(other: ExtensionFunctionType?): ExtensionFunctionType = this
override fun isSubtypeOf(other: ExtensionFunctionType?): Boolean = true
override val key: KClass<out ExtensionFunctionType> = ExtensionFunctionType::class
@@ -65,6 +72,8 @@ object CompilerConeAttributes {
override fun union(other: UnsafeVariance?): UnsafeVariance? = null
override fun intersect(other: UnsafeVariance?): UnsafeVariance? = null
override fun add(other: UnsafeVariance?): UnsafeVariance = this
override fun isSubtypeOf(other: UnsafeVariance?): Boolean = true
override val key: KClass<out UnsafeVariance> = UnsafeVariance::class
@@ -15,6 +15,17 @@ import kotlin.reflect.KClass
abstract class ConeAttribute<T : ConeAttribute<T>> : AnnotationMarker {
abstract fun union(other: @UnsafeVariance T?): T?
abstract fun intersect(other: @UnsafeVariance T?): T?
/*
* This function is used to decide how multiple attributes should be united in presence of typealiases:
* typealias B = @SomeAttribute(1) A
* typealias C = @SomeAttribute(2) B
*
* For determining attribute value of expanded type of C we should add @SomeAttribute(2) to @SomeAttribute(1)
*
* This function must be symmetrical: a.add(b) == b.add(a)
*/
abstract fun add(other: @UnsafeVariance T?): T
abstract fun isSubtypeOf(other: @UnsafeVariance T?): Boolean
abstract override fun toString(): String
@@ -65,6 +76,10 @@ class ConeAttributes private constructor(attributes: List<ConeAttribute<*>>) : A
return perform(other) { this.intersect(it) }
}
fun add(other: ConeAttributes): ConeAttributes {
return perform(other) { this.add(it) }
}
operator fun contains(attribute: ConeAttribute<*>): Boolean {
val index = getId(attribute.key)
return arrayMap[index] != null
@@ -68,7 +68,10 @@ fun ConeClassLikeType.directExpansionType(
val typeAliasSymbol = lookupTag.toSymbol(useSiteSession) as? FirTypeAliasSymbol ?: return null
val typeAlias = typeAliasSymbol.fir
val resultType = expandedConeType(typeAlias)?.applyNullabilityFrom(useSiteSession, this) ?: return null
val resultType = expandedConeType(typeAlias)
?.applyNullabilityFrom(useSiteSession, this)
?.applyAttributesFrom(useSiteSession, this)
?: return null
if (resultType.typeArguments.isEmpty()) return resultType
return mapTypeAliasArguments(typeAlias, this, resultType, useSiteSession) as? ConeClassLikeType
@@ -82,6 +85,14 @@ private fun ConeClassLikeType.applyNullabilityFrom(
return this
}
private fun ConeClassLikeType.applyAttributesFrom(
session: FirSession,
abbreviation: ConeClassLikeType
): ConeClassLikeType {
val combinedAttributes = attributes.add(abbreviation.attributes)
return withAttributes(combinedAttributes, session.typeContext)
}
private fun mapTypeAliasArguments(
typeAlias: FirTypeAlias,
abbreviatedType: ConeClassLikeType,
@@ -14,6 +14,11 @@ class CustomAnnotationTypeAttribute(val annotations: List<FirAnnotation>) : Cone
override fun intersect(other: CustomAnnotationTypeAttribute?): CustomAnnotationTypeAttribute? = null
override fun add(other: CustomAnnotationTypeAttribute?): CustomAnnotationTypeAttribute {
if (other == null) return this
return CustomAnnotationTypeAttribute(annotations + other.annotations)
}
override fun isSubtypeOf(other: CustomAnnotationTypeAttribute?): Boolean = true
override fun toString(): String = annotations.joinToString(separator = " ") { it.render() }