[Commonizer] Avoid leaking non-commonized underlying types in TAs
This commit is contained in:
+1
-59
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassFactory
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeAliasFactory
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -70,70 +69,13 @@ private class TypeAliasShortCircuitingCommonizer(
|
||||
|
||||
override fun doCommonizeWith(next: CirTypeAlias): Boolean {
|
||||
if (underlyingType == null) {
|
||||
underlyingType = computeUnderlyingType(next.underlyingType) ?: return false
|
||||
underlyingType = computeSuitableUnderlyingType(classifiers, next.underlyingType) ?: return false
|
||||
}
|
||||
|
||||
return typeParameters.commonizeWith(next.typeParameters)
|
||||
&& expandedType.commonizeWith(next.expandedType)
|
||||
&& visibility.commonizeWith(next)
|
||||
}
|
||||
|
||||
private tailrec fun computeUnderlyingType(underlyingType: CirClassOrTypeAliasType): CirClassOrTypeAliasType? {
|
||||
return when (underlyingType) {
|
||||
is CirClassType -> underlyingType.withCommonizedArguments()
|
||||
is CirTypeAliasType -> if (classifiers.commonDependeeLibraries.hasClassifier(underlyingType.classifierId))
|
||||
underlyingType.withCommonizedArguments()
|
||||
else
|
||||
computeUnderlyingType(underlyingType.underlyingType)
|
||||
}
|
||||
}
|
||||
|
||||
private fun CirClassType.withCommonizedArguments(): CirClassType? {
|
||||
val existingArguments = arguments
|
||||
val newArguments = existingArguments.toCommonizedArguments() ?: return null
|
||||
|
||||
val existingOuterType = outerType
|
||||
val newOuterType = existingOuterType?.let { it.withCommonizedArguments() ?: return null }
|
||||
|
||||
return if (newArguments !== existingArguments || newOuterType !== existingOuterType)
|
||||
CirTypeFactory.createClassType(
|
||||
classId = classifierId,
|
||||
outerType = newOuterType,
|
||||
visibility = visibility,
|
||||
arguments = newArguments,
|
||||
isMarkedNullable = isMarkedNullable
|
||||
)
|
||||
else
|
||||
this
|
||||
}
|
||||
|
||||
private fun CirTypeAliasType.withCommonizedArguments(): CirTypeAliasType? {
|
||||
val existingArguments = arguments
|
||||
val newArguments = existingArguments.toCommonizedArguments() ?: return null
|
||||
|
||||
val existingUnderlyingType = underlyingType
|
||||
val newUnderlyingType = when (existingUnderlyingType) {
|
||||
is CirClassType -> existingUnderlyingType.withCommonizedArguments()
|
||||
is CirTypeAliasType -> existingUnderlyingType.withCommonizedArguments()
|
||||
} ?: return null
|
||||
|
||||
return if (newArguments !== existingArguments || newUnderlyingType !== existingUnderlyingType)
|
||||
CirTypeFactory.createTypeAliasType(
|
||||
typeAliasId = classifierId,
|
||||
underlyingType = newUnderlyingType,
|
||||
arguments = newArguments,
|
||||
isMarkedNullable = isMarkedNullable
|
||||
)
|
||||
else
|
||||
this
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
private inline fun List<CirTypeProjection>.toCommonizedArguments(): List<CirTypeProjection>? =
|
||||
if (isEmpty())
|
||||
this
|
||||
else
|
||||
TypeArgumentListCommonizer(classifiers).let { if (it.commonizeWith(this)) it.result else null }
|
||||
}
|
||||
|
||||
private class TypeAliasLiftingUpCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer<CirTypeAlias, CirTypeAlias>() {
|
||||
|
||||
+4
-1
@@ -109,7 +109,10 @@ private class TypeAliasTypeCommonizer(private val classifiers: CirKnownClassifie
|
||||
commonizedTypeBuilder = when (val commonClassifier = answer.commonClassifier) {
|
||||
is CirClass -> CommonizedTypeAliasTypeBuilder.forClass(commonClassifier)
|
||||
is CirTypeAlias -> CommonizedTypeAliasTypeBuilder.forTypeAlias(commonClassifier)
|
||||
null -> CommonizedTypeAliasTypeBuilder.forKnownUnderlyingType(next.underlyingType)
|
||||
null -> {
|
||||
val underlyingType = computeSuitableUnderlyingType(classifiers, next.underlyingType) ?: return false
|
||||
CommonizedTypeAliasTypeBuilder.forKnownUnderlyingType(underlyingType)
|
||||
}
|
||||
else -> error("Unexpected common classifier type: ${commonClassifier::class.java}, $commonClassifier")
|
||||
}
|
||||
}
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.descriptors.commonizer.core
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassOrTypeAliasType
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeAliasType
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeProjection
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers
|
||||
|
||||
internal tailrec fun computeSuitableUnderlyingType(
|
||||
classifiers: CirKnownClassifiers,
|
||||
underlyingType: CirClassOrTypeAliasType
|
||||
): CirClassOrTypeAliasType? {
|
||||
return when (underlyingType) {
|
||||
is CirClassType -> underlyingType.withCommonizedArguments(classifiers)
|
||||
is CirTypeAliasType -> if (classifiers.commonDependeeLibraries.hasClassifier(underlyingType.classifierId))
|
||||
underlyingType.withCommonizedArguments(classifiers)
|
||||
else
|
||||
computeSuitableUnderlyingType(classifiers, underlyingType.underlyingType)
|
||||
}
|
||||
}
|
||||
|
||||
private fun CirClassType.withCommonizedArguments(classifiers: CirKnownClassifiers): CirClassType? {
|
||||
val existingArguments = arguments
|
||||
val newArguments = existingArguments.toCommonizedArguments(classifiers) ?: return null
|
||||
|
||||
val existingOuterType = outerType
|
||||
val newOuterType = existingOuterType?.let { it.withCommonizedArguments(classifiers) ?: return null }
|
||||
|
||||
return if (newArguments !== existingArguments || newOuterType !== existingOuterType)
|
||||
CirTypeFactory.createClassType(
|
||||
classId = classifierId,
|
||||
outerType = newOuterType,
|
||||
visibility = visibility,
|
||||
arguments = newArguments,
|
||||
isMarkedNullable = isMarkedNullable
|
||||
)
|
||||
else
|
||||
this
|
||||
}
|
||||
|
||||
private fun CirTypeAliasType.withCommonizedArguments(classifiers: CirKnownClassifiers): CirTypeAliasType? {
|
||||
val existingArguments = arguments
|
||||
val newArguments = existingArguments.toCommonizedArguments(classifiers) ?: return null
|
||||
|
||||
val existingUnderlyingType = underlyingType
|
||||
val newUnderlyingType = when (existingUnderlyingType) {
|
||||
is CirClassType -> existingUnderlyingType.withCommonizedArguments(classifiers)
|
||||
is CirTypeAliasType -> existingUnderlyingType.withCommonizedArguments(classifiers)
|
||||
} ?: return null
|
||||
|
||||
return if (newArguments !== existingArguments || newUnderlyingType !== existingUnderlyingType)
|
||||
CirTypeFactory.createTypeAliasType(
|
||||
typeAliasId = classifierId,
|
||||
underlyingType = newUnderlyingType,
|
||||
arguments = newArguments,
|
||||
isMarkedNullable = isMarkedNullable
|
||||
)
|
||||
else
|
||||
this
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
private inline fun List<CirTypeProjection>.toCommonizedArguments(classifiers: CirKnownClassifiers): List<CirTypeProjection>? =
|
||||
if (isEmpty())
|
||||
this
|
||||
else
|
||||
TypeArgumentListCommonizer(classifiers).let { if (it.commonizeWith(this)) it.result else null }
|
||||
Reference in New Issue
Block a user