FIR: Minor. Refactor calculation of erased upper bound

This commit is contained in:
Denis Zharkov
2020-02-11 14:51:35 +03:00
parent bc34bc3f96
commit 42e8017bde
@@ -179,25 +179,29 @@ private fun FirTypeParameter.getErasedUpperBound(
val firstUpperBound = this.bounds.first().coneTypeUnsafe<ConeKotlinType>() val firstUpperBound = this.bounds.first().coneTypeUnsafe<ConeKotlinType>()
if (firstUpperBound is ConeClassLikeType) { return getErasedVersionOfFirstUpperBound(firstUpperBound, mutableSetOf(this, potentiallyRecursiveTypeParameter), defaultValue)
return firstUpperBound.withArguments(firstUpperBound.typeArguments.map { ConeStarProjection }.toTypedArray())
} }
val alreadyVisited = mutableSetOf(potentiallyRecursiveTypeParameter, this) private tailrec fun getErasedVersionOfFirstUpperBound(
var current = (firstUpperBound as ConeTypeParameterType).lookupTag.typeParameterSymbol.fir firstUpperBound: ConeKotlinType,
alreadyVisitedParameters: MutableSet<FirTypeParameter?>,
defaultValue: () -> ConeKotlinType
): ConeKotlinType =
when (firstUpperBound) {
is ConeClassLikeType ->
firstUpperBound.withArguments(firstUpperBound.typeArguments.map { ConeStarProjection }.toTypedArray())
while (current !in alreadyVisited) { is ConeTypeParameterType -> {
alreadyVisited += current val current = firstUpperBound.lookupTag.typeParameterSymbol.fir
if (alreadyVisitedParameters.add(current)) {
val nextUpperBound = current.bounds.first().coneTypeUnsafe<ConeKotlinType>() val nextUpperBound = current.bounds.first().coneTypeUnsafe<ConeKotlinType>()
if (nextUpperBound is ConeClassLikeType) { getErasedVersionOfFirstUpperBound(nextUpperBound, alreadyVisitedParameters, defaultValue)
return nextUpperBound.withArguments(nextUpperBound.typeArguments.map { ConeStarProjection }.toTypedArray()) } else {
defaultValue()
} }
current = (nextUpperBound as ConeTypeParameterType).lookupTag.typeParameterSymbol.fir
} }
else -> error("Unexpected kind of firstUpperBound: $firstUpperBound [${firstUpperBound::class}]")
return defaultValue()
} }