Use TypeSystemCommonBackendContext in computeExpandedTypeForInlineClass
This commit is contained in:
@@ -6,15 +6,15 @@
|
|||||||
package org.jetbrains.kotlin.load.kotlin
|
package org.jetbrains.kotlin.load.kotlin
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
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.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.substitutedUnderlyingType
|
import org.jetbrains.kotlin.resolve.substitutedUnderlyingType
|
||||||
import org.jetbrains.kotlin.resolve.unsubstitutedUnderlyingType
|
import org.jetbrains.kotlin.resolve.unsubstitutedUnderlyingType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.isNullable
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
|
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
|
||||||
|
|
||||||
internal fun computeUnderlyingType(inlineClassType: KotlinType): KotlinType? {
|
internal fun computeUnderlyingType(inlineClassType: KotlinType): KotlinType? {
|
||||||
@@ -27,39 +27,42 @@ internal fun computeUnderlyingType(inlineClassType: KotlinType): KotlinType? {
|
|||||||
inlineClassType.substitutedUnderlyingType()
|
inlineClassType.substitutedUnderlyingType()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun computeExpandedTypeForInlineClass(inlineClassType: KotlinType): KotlinType? =
|
fun TypeSystemCommonBackendContext.computeExpandedTypeForInlineClass(inlineClassType: KotlinTypeMarker): KotlinTypeMarker? =
|
||||||
computeExpandedTypeInner(inlineClassType, hashSetOf())
|
computeExpandedTypeInner(inlineClassType, hashSetOf())
|
||||||
|
|
||||||
private fun computeExpandedTypeInner(kotlinType: KotlinType, visitedClassifiers: HashSet<ClassifierDescriptor>): KotlinType? {
|
private fun TypeSystemCommonBackendContext.computeExpandedTypeInner(
|
||||||
val classifier = kotlinType.constructor.declarationDescriptor
|
kotlinType: KotlinTypeMarker, visitedClassifiers: HashSet<TypeConstructorMarker>
|
||||||
?: throw AssertionError("Type with a declaration expected: $kotlinType")
|
): KotlinTypeMarker? {
|
||||||
|
val classifier = kotlinType.typeConstructor()
|
||||||
if (!visitedClassifiers.add(classifier)) return null
|
if (!visitedClassifiers.add(classifier)) return null
|
||||||
|
|
||||||
|
val typeParameter = classifier.getTypeParameterClassifier()
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
classifier is TypeParameterDescriptor ->
|
typeParameter != null ->
|
||||||
computeExpandedTypeInner(classifier.representativeUpperBound, visitedClassifiers)
|
computeExpandedTypeInner(typeParameter.getRepresentativeUpperBound(), visitedClassifiers)
|
||||||
?.let { expandedUpperBound ->
|
?.let { expandedUpperBound ->
|
||||||
if (expandedUpperBound.isNullable() || !kotlinType.isMarkedNullable)
|
if (expandedUpperBound.isNullableType() || !kotlinType.isMarkedNullable())
|
||||||
expandedUpperBound
|
expandedUpperBound
|
||||||
else
|
else
|
||||||
expandedUpperBound.makeNullable()
|
expandedUpperBound.makeNullable()
|
||||||
}
|
}
|
||||||
|
|
||||||
classifier is ClassDescriptor && classifier.isInline -> {
|
classifier.isInlineClass() -> {
|
||||||
// kotlinType is the boxed inline class type
|
// 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
|
val expandedUnderlyingType = computeExpandedTypeInner(underlyingType, visitedClassifiers) ?: return null
|
||||||
when {
|
when {
|
||||||
!kotlinType.isNullable() -> expandedUnderlyingType
|
!kotlinType.isNullableType() -> expandedUnderlyingType
|
||||||
|
|
||||||
// Here inline class type is nullable. Apply nullability to the expandedUnderlyingType.
|
// Here inline class type is nullable. Apply nullability to the expandedUnderlyingType.
|
||||||
|
|
||||||
// Nullable types become inline class boxes
|
// Nullable types become inline class boxes
|
||||||
expandedUnderlyingType.isNullable() -> kotlinType
|
expandedUnderlyingType.isNullableType() -> kotlinType
|
||||||
|
|
||||||
// Primitives become inline class boxes
|
// Primitives become inline class boxes
|
||||||
KotlinBuiltIns.isPrimitiveType(expandedUnderlyingType) -> kotlinType
|
expandedUnderlyingType is SimpleTypeMarker && expandedUnderlyingType.isPrimitiveType() -> kotlinType
|
||||||
|
|
||||||
// Non-null reference types become nullable reference types
|
// Non-null reference types become nullable reference types
|
||||||
else -> expandedUnderlyingType.makeNullable()
|
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.JvmClassName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||||
import org.jetbrains.kotlin.types.*
|
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.replaceArgumentsWithStarProjections
|
||||||
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
|
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
|
||||||
import org.jetbrains.kotlin.utils.DO_NOTHING_3
|
import org.jetbrains.kotlin.utils.DO_NOTHING_3
|
||||||
@@ -136,7 +137,7 @@ fun <T : Any> mapType(
|
|||||||
descriptor is ClassDescriptor -> {
|
descriptor is ClassDescriptor -> {
|
||||||
// NB if inline class is recursive, it's ok to map it as wrapped
|
// NB if inline class is recursive, it's ok to map it as wrapped
|
||||||
if (descriptor.isInline && !mode.needInlineClassWrapping) {
|
if (descriptor.isInline && !mode.needInlineClassWrapping) {
|
||||||
val expandedType = computeExpandedTypeForInlineClass(kotlinType)
|
val expandedType = SimpleClassicTypeSystemContext.computeExpandedTypeForInlineClass(kotlinType) as KotlinType?
|
||||||
if (expandedType != null) {
|
if (expandedType != null) {
|
||||||
return mapType(
|
return mapType(
|
||||||
expandedType,
|
expandedType,
|
||||||
|
|||||||
@@ -6,9 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.types
|
package org.jetbrains.kotlin.types
|
||||||
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.*
|
||||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
|
||||||
import org.jetbrains.kotlin.types.model.TypeSystemContext
|
|
||||||
|
|
||||||
interface TypeSystemCommonBackendContext : TypeSystemContext {
|
interface TypeSystemCommonBackendContext : TypeSystemContext {
|
||||||
fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean
|
fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean
|
||||||
@@ -24,4 +22,15 @@ interface TypeSystemCommonBackendContext : TypeSystemContext {
|
|||||||
* TODO: provide a more granular & elaborate API here to reduce confusion
|
* TODO: provide a more granular & elaborate API here to reduce confusion
|
||||||
*/
|
*/
|
||||||
fun KotlinTypeMarker.getAnnotationFirstArgumentValue(fqName: FqName): Any?
|
fun KotlinTypeMarker.getAnnotationFirstArgumentValue(fqName: FqName): Any?
|
||||||
|
|
||||||
|
fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker?
|
||||||
|
fun TypeConstructorMarker.isInlineClass(): Boolean
|
||||||
|
fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker
|
||||||
|
fun KotlinTypeMarker.getSubstitutedUnderlyingType(): KotlinTypeMarker?
|
||||||
|
|
||||||
|
fun KotlinTypeMarker.isMarkedNullable(): Boolean =
|
||||||
|
this is SimpleTypeMarker && isMarkedNullable()
|
||||||
|
|
||||||
|
fun KotlinTypeMarker.makeNullable(): KotlinTypeMarker =
|
||||||
|
asSimpleType()?.withNullability(true) ?: this
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasExactAnnotation
|
import org.jetbrains.kotlin.resolve.descriptorUtil.hasExactAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasNoInferAnnotation
|
import org.jetbrains.kotlin.resolve.descriptorUtil.hasNoInferAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExactAnnotation
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isExactAnnotation
|
||||||
|
import org.jetbrains.kotlin.resolve.substitutedUnderlyingType
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.model.*
|
import org.jetbrains.kotlin.types.model.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
@@ -495,6 +497,26 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
require(this is KotlinType, this::errorMessage)
|
require(this is KotlinType, this::errorMessage)
|
||||||
return annotations.findAnnotation(fqName)?.allValueArguments?.values?.firstOrNull()?.value
|
return annotations.findAnnotation(fqName)?.allValueArguments?.values?.firstOrNull()?.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker? {
|
||||||
|
require(this is TypeConstructor, this::errorMessage)
|
||||||
|
return declarationDescriptor as? TypeParameterDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun TypeConstructorMarker.isInlineClass(): Boolean {
|
||||||
|
require(this is TypeConstructor, this::errorMessage)
|
||||||
|
return (declarationDescriptor as? ClassDescriptor)?.isInline == true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker {
|
||||||
|
require(this is TypeParameterDescriptor, this::errorMessage)
|
||||||
|
return representativeUpperBound
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.getSubstitutedUnderlyingType(): KotlinTypeMarker? {
|
||||||
|
require(this is KotlinType, this::errorMessage)
|
||||||
|
return substitutedUnderlyingType()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TypeVariance.convertVariance(): Variance {
|
fun TypeVariance.convertVariance(): Variance {
|
||||||
|
|||||||
Reference in New Issue
Block a user