Use TypeSystemCommonBackendContext in computeExpandedTypeForInlineClass

This commit is contained in:
Alexander Udalov
2019-06-21 16:30:40 +02:00
parent c27d9c4546
commit 13bc5f0c47
4 changed files with 55 additions and 20 deletions
@@ -6,15 +6,15 @@
package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.resolve.substitutedUnderlyingType
import org.jetbrains.kotlin.resolve.unsubstitutedUnderlyingType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.isNullable
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
internal fun computeUnderlyingType(inlineClassType: KotlinType): KotlinType? {
@@ -27,39 +27,42 @@ internal fun computeUnderlyingType(inlineClassType: KotlinType): KotlinType? {
inlineClassType.substitutedUnderlyingType()
}
internal fun computeExpandedTypeForInlineClass(inlineClassType: KotlinType): KotlinType? =
fun TypeSystemCommonBackendContext.computeExpandedTypeForInlineClass(inlineClassType: KotlinTypeMarker): KotlinTypeMarker? =
computeExpandedTypeInner(inlineClassType, hashSetOf())
private fun computeExpandedTypeInner(kotlinType: KotlinType, visitedClassifiers: HashSet<ClassifierDescriptor>): KotlinType? {
val classifier = kotlinType.constructor.declarationDescriptor
?: throw AssertionError("Type with a declaration expected: $kotlinType")
private fun TypeSystemCommonBackendContext.computeExpandedTypeInner(
kotlinType: KotlinTypeMarker, visitedClassifiers: HashSet<TypeConstructorMarker>
): KotlinTypeMarker? {
val classifier = kotlinType.typeConstructor()
if (!visitedClassifiers.add(classifier)) return null
val typeParameter = classifier.getTypeParameterClassifier()
return when {
classifier is TypeParameterDescriptor ->
computeExpandedTypeInner(classifier.representativeUpperBound, visitedClassifiers)
typeParameter != null ->
computeExpandedTypeInner(typeParameter.getRepresentativeUpperBound(), visitedClassifiers)
?.let { expandedUpperBound ->
if (expandedUpperBound.isNullable() || !kotlinType.isMarkedNullable)
if (expandedUpperBound.isNullableType() || !kotlinType.isMarkedNullable())
expandedUpperBound
else
expandedUpperBound.makeNullable()
}
classifier is ClassDescriptor && classifier.isInline -> {
classifier.isInlineClass() -> {
// kotlinType is the boxed inline class type
val underlyingType = kotlinType.substitutedUnderlyingType() ?: return null
val underlyingType = kotlinType.getSubstitutedUnderlyingType() ?: return null
val expandedUnderlyingType = computeExpandedTypeInner(underlyingType, visitedClassifiers) ?: return null
when {
!kotlinType.isNullable() -> expandedUnderlyingType
!kotlinType.isNullableType() -> expandedUnderlyingType
// Here inline class type is nullable. Apply nullability to the expandedUnderlyingType.
// Nullable types become inline class boxes
expandedUnderlyingType.isNullable() -> kotlinType
expandedUnderlyingType.isNullableType() -> kotlinType
// Primitives become inline class boxes
KotlinBuiltIns.isPrimitiveType(expandedUnderlyingType) -> kotlinType
expandedUnderlyingType is SimpleTypeMarker && expandedUnderlyingType.isPrimitiveType() -> kotlinType
// Non-null reference types become nullable reference types
else -> expandedUnderlyingType.makeNullable()
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext
import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
import org.jetbrains.kotlin.utils.DO_NOTHING_3
@@ -136,7 +137,7 @@ fun <T : Any> mapType(
descriptor is ClassDescriptor -> {
// NB if inline class is recursive, it's ok to map it as wrapped
if (descriptor.isInline && !mode.needInlineClassWrapping) {
val expandedType = computeExpandedTypeForInlineClass(kotlinType)
val expandedType = SimpleClassicTypeSystemContext.computeExpandedTypeForInlineClass(kotlinType) as KotlinType?
if (expandedType != null) {
return mapType(
expandedType,