[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 {
if (arguments == this.arguments) return this
return createInterned(
classId = classifierId,
outerType = outerType,
@@ -162,12 +163,13 @@ abstract class CirTypeAliasType : CirClassOrTypeAliasType() {
}
override fun withArguments(arguments: List<CirTypeProjection>): CirClassOrTypeAliasType {
return createInterned(
typeAliasId = classifierId,
underlyingType = underlyingType,
arguments = arguments,
isMarkedNullable = isMarkedNullable
)
if (this.arguments == arguments) return this
return copyInterned(arguments = arguments)
}
fun withUnderlyingType(underlyingType: CirClassOrTypeAliasType): CirClassOrTypeAliasType {
if (this.underlyingType == underlyingType) return this
return copyInterned(underlyingType = underlyingType)
}
companion object {
@@ -68,8 +68,8 @@ internal class ClassOrTypeAliasTypeCommonizer(
val commonizedClassifier = classifiers.commonizedNodes.classNode(classifierId)?.commonDeclaration?.invoke()
?: classifiers.commonizedNodes.typeAliasNode(classifierId)?.commonDeclaration?.invoke()
when (commonizedClassifier) {
is CirClass -> return CirClassType.createInterned(
return when (commonizedClassifier) {
is CirClass -> CirClassType.createInterned(
classId = classifierId,
outerType = outerType,
arguments = arguments,
@@ -77,19 +77,15 @@ internal class ClassOrTypeAliasTypeCommonizer(
isMarkedNullable = isMarkedNullable
)
is CirTypeAlias -> return CirTypeAliasType.createInterned(
is CirTypeAlias -> CirTypeAliasType.createInterned(
typeAliasId = classifierId,
arguments = arguments,
isMarkedNullable = isMarkedNullable,
underlyingType = computeSuitableUnderlyingType(
classifiers, typeCommonizer, commonizedClassifier.underlyingType
)?.makeNullableIfNecessary(isMarkedNullable) ?: return null
underlyingType = commonizedClassifier.underlyingType.withParentArguments(arguments, isMarkedNullable)
)
else -> Unit
else -> null
}
return null
}
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) {
is CirClassType -> this
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 {
outputTarget("(a, b)")