[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.*
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassFactory
|
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.CirTypeAliasFactory
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory
|
|
||||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers
|
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
@@ -70,70 +69,13 @@ private class TypeAliasShortCircuitingCommonizer(
|
|||||||
|
|
||||||
override fun doCommonizeWith(next: CirTypeAlias): Boolean {
|
override fun doCommonizeWith(next: CirTypeAlias): Boolean {
|
||||||
if (underlyingType == null) {
|
if (underlyingType == null) {
|
||||||
underlyingType = computeUnderlyingType(next.underlyingType) ?: return false
|
underlyingType = computeSuitableUnderlyingType(classifiers, next.underlyingType) ?: return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeParameters.commonizeWith(next.typeParameters)
|
return typeParameters.commonizeWith(next.typeParameters)
|
||||||
&& expandedType.commonizeWith(next.expandedType)
|
&& expandedType.commonizeWith(next.expandedType)
|
||||||
&& visibility.commonizeWith(next)
|
&& 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>() {
|
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) {
|
commonizedTypeBuilder = when (val commonClassifier = answer.commonClassifier) {
|
||||||
is CirClass -> CommonizedTypeAliasTypeBuilder.forClass(commonClassifier)
|
is CirClass -> CommonizedTypeAliasTypeBuilder.forClass(commonClassifier)
|
||||||
is CirTypeAlias -> CommonizedTypeAliasTypeBuilder.forTypeAlias(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")
|
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