[Commonizer] ClassOrTypeAliasTypeCommonizer: Implement proper type argument substitution

^KT-47574 Verification Pending
This commit is contained in:
sebastian.sellmair
2021-09-10 11:00:24 +02:00
committed by Space
parent c1f118e502
commit 595cab2aaf
3 changed files with 38 additions and 16 deletions
@@ -100,6 +100,7 @@ abstract class CirClassType : CirClassOrTypeAliasType(), CirHasVisibility {
} }
override fun withArguments(arguments: List<CirTypeProjection>): CirClassOrTypeAliasType { override fun withArguments(arguments: List<CirTypeProjection>): CirClassOrTypeAliasType {
if (arguments == this.arguments) return this
return createInterned( return createInterned(
classId = classifierId, classId = classifierId,
outerType = outerType, outerType = outerType,
@@ -162,12 +163,13 @@ abstract class CirTypeAliasType : CirClassOrTypeAliasType() {
} }
override fun withArguments(arguments: List<CirTypeProjection>): CirClassOrTypeAliasType { override fun withArguments(arguments: List<CirTypeProjection>): CirClassOrTypeAliasType {
return createInterned( if (this.arguments == arguments) return this
typeAliasId = classifierId, return copyInterned(arguments = arguments)
underlyingType = underlyingType, }
arguments = arguments,
isMarkedNullable = isMarkedNullable fun withUnderlyingType(underlyingType: CirClassOrTypeAliasType): CirClassOrTypeAliasType {
) if (this.underlyingType == underlyingType) return this
return copyInterned(underlyingType = underlyingType)
} }
companion object { companion object {
@@ -68,8 +68,8 @@ internal class ClassOrTypeAliasTypeCommonizer(
val commonizedClassifier = classifiers.commonizedNodes.classNode(classifierId)?.commonDeclaration?.invoke() val commonizedClassifier = classifiers.commonizedNodes.classNode(classifierId)?.commonDeclaration?.invoke()
?: classifiers.commonizedNodes.typeAliasNode(classifierId)?.commonDeclaration?.invoke() ?: classifiers.commonizedNodes.typeAliasNode(classifierId)?.commonDeclaration?.invoke()
when (commonizedClassifier) { return when (commonizedClassifier) {
is CirClass -> return CirClassType.createInterned( is CirClass -> CirClassType.createInterned(
classId = classifierId, classId = classifierId,
outerType = outerType, outerType = outerType,
arguments = arguments, arguments = arguments,
@@ -77,19 +77,15 @@ internal class ClassOrTypeAliasTypeCommonizer(
isMarkedNullable = isMarkedNullable isMarkedNullable = isMarkedNullable
) )
is CirTypeAlias -> return CirTypeAliasType.createInterned( is CirTypeAlias -> CirTypeAliasType.createInterned(
typeAliasId = classifierId, typeAliasId = classifierId,
arguments = arguments, arguments = arguments,
isMarkedNullable = isMarkedNullable, isMarkedNullable = isMarkedNullable,
underlyingType = computeSuitableUnderlyingType( underlyingType = commonizedClassifier.underlyingType.withParentArguments(arguments, isMarkedNullable)
classifiers, typeCommonizer, commonizedClassifier.underlyingType
)?.makeNullableIfNecessary(isMarkedNullable) ?: return null
) )
else -> Unit else -> null
} }
return null
} }
private fun selectClassifierId(types: List<CirClassOrTypeAliasType>): CirEntityId? { private fun selectClassifierId(types: List<CirClassOrTypeAliasType>): CirEntityId? {
@@ -105,6 +101,30 @@ internal class ClassOrTypeAliasTypeCommonizer(
} }
} }
private fun CirClassOrTypeAliasType.withParentArguments(
parentArguments: List<CirTypeProjection>, parentIsMarkedNullable: Boolean
): CirClassOrTypeAliasType {
val newIsMarkedNullable = isMarkedNullable || parentIsMarkedNullable
val newArguments = arguments.map { oldArgument ->
if (oldArgument is CirRegularTypeProjection) {
val oldArgumentType = oldArgument.type
if (oldArgumentType is CirTypeParameterType) {
return@map parentArguments[oldArgumentType.index]
}
}
oldArgument
}
return when (val newUnderlyingType = makeNullableIfNecessary(newIsMarkedNullable).withArguments(newArguments)) {
this -> this
is CirClassType -> newUnderlyingType
is CirTypeAliasType -> newUnderlyingType.withUnderlyingType(
newUnderlyingType.underlyingType.withParentArguments(newArguments, newIsMarkedNullable)
)
}
}
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()
@@ -130,7 +130,7 @@ class HierarchicalTypeAliasCommonizationTest : AbstractInlineSourcesCommonizatio
) )
} }
fun `KT-47574 - test long typealias chain`() { fun `test long typealias chain`() {
val result = commonize { val result = commonize {
outputTarget("(a, b)") outputTarget("(a, b)")