Use TypeSystemCommonBackendContext in mapBuiltInType

This commit is contained in:
Alexander Udalov
2019-06-27 16:48:09 +02:00
parent 13bc5f0c47
commit d399144b80
4 changed files with 53 additions and 14 deletions
@@ -33,6 +33,8 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.typeUtil.createProjection import org.jetbrains.kotlin.types.typeUtil.createProjection
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
@@ -42,7 +44,11 @@ import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
// For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`. // For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`.
fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = unwrap().enhancePossiblyFlexible(qualifiers, 0).typeIfChanged fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = unwrap().enhancePossiblyFlexible(qualifiers, 0).typeIfChanged
fun KotlinType.hasEnhancedNullability() = annotations.findAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION) != null fun KotlinType.hasEnhancedNullability(): Boolean =
SimpleClassicTypeSystemContext.hasEnhancedNullability(this)
fun TypeSystemCommonBackendContext.hasEnhancedNullability(type: KotlinTypeMarker): Boolean =
type.hasAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION)
enum class TypeComponentPosition { enum class TypeComponentPosition {
FLEXIBLE_LOWER, FLEXIBLE_LOWER,
@@ -13,11 +13,11 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
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.checker.SimpleClassicTypeSystemContext
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
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
@@ -69,7 +69,9 @@ fun <T : Any> mapType(
) )
} }
mapBuiltInType(kotlinType, factory, mode)?.let { builtInType -> with(SimpleClassicTypeSystemContext) {
mapBuiltInType(kotlinType, factory, mode)
}?.let { builtInType ->
val jvmType = factory.boxTypeIfNeeded(builtInType, mode.needPrimitiveBoxing) val jvmType = factory.boxTypeIfNeeded(builtInType, mode.needPrimitiveBoxing)
writeGenericType(kotlinType, jvmType, mode) writeGenericType(kotlinType, jvmType, mode)
return jvmType return jvmType
@@ -203,31 +205,31 @@ fun hasVoidReturnType(descriptor: CallableDescriptor): Boolean {
&& descriptor !is PropertyGetterDescriptor && descriptor !is PropertyGetterDescriptor
} }
private fun <T : Any> mapBuiltInType( fun <T : Any> TypeSystemCommonBackendContext.mapBuiltInType(
type: KotlinType, type: KotlinTypeMarker,
typeFactory: JvmTypeFactory<T>, typeFactory: JvmTypeFactory<T>,
mode: TypeMappingMode mode: TypeMappingMode
): T? { ): T? {
val descriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return null val constructor = type.typeConstructor()
if (!constructor.isClassTypeConstructor()) return null
val primitiveType = KotlinBuiltIns.getPrimitiveType(descriptor) val primitiveType = constructor.getPrimitiveType()
if (primitiveType != null) { if (primitiveType != null) {
val jvmType = typeFactory.createFromString(JvmPrimitiveType.get(primitiveType).desc) val jvmType = typeFactory.createFromString(JvmPrimitiveType.get(primitiveType).desc)
val isNullableInJava = TypeUtils.isNullableType(type) || type.hasEnhancedNullability() val isNullableInJava = type.isNullableType() || hasEnhancedNullability(type)
return typeFactory.boxTypeIfNeeded(jvmType, isNullableInJava) return typeFactory.boxTypeIfNeeded(jvmType, isNullableInJava)
} }
val arrayElementType = KotlinBuiltIns.getPrimitiveArrayType(descriptor) val arrayElementType = constructor.getPrimitiveArrayType()
if (arrayElementType != null) { if (arrayElementType != null) {
return typeFactory.createFromString("[" + JvmPrimitiveType.get(arrayElementType).desc) return typeFactory.createFromString("[" + JvmPrimitiveType.get(arrayElementType).desc)
} }
if (KotlinBuiltIns.isUnderKotlinPackage(descriptor)) { if (constructor.isUnderKotlinPackage()) {
val classId = JavaToKotlinClassMap.mapKotlinToJava(descriptor.fqNameUnsafe) val classId = constructor.getClassFqNameUnsafe()?.let(JavaToKotlinClassMap::mapKotlinToJava)
if (classId != null) { if (classId != null) {
if (!mode.kotlinCollectionsToJavaCollections && if (!mode.kotlinCollectionsToJavaCollections && JavaToKotlinClassMap.mutabilityMappings.any { it.javaClass == classId })
JavaToKotlinClassMap.mutabilityMappings.any { it.javaClass == classId } return null
) return null
return typeFactory.createObjectType(JvmClassName.byClassId(classId).internalName) return typeFactory.createObjectType(JvmClassName.byClassId(classId).internalName)
} }
@@ -5,7 +5,9 @@
package org.jetbrains.kotlin.types package org.jetbrains.kotlin.types
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
interface TypeSystemCommonBackendContext : TypeSystemContext { interface TypeSystemCommonBackendContext : TypeSystemContext {
@@ -33,4 +35,10 @@ interface TypeSystemCommonBackendContext : TypeSystemContext {
fun KotlinTypeMarker.makeNullable(): KotlinTypeMarker = fun KotlinTypeMarker.makeNullable(): KotlinTypeMarker =
asSimpleType()?.withNullability(true) ?: this asSimpleType()?.withNullability(true) ?: this
fun TypeConstructorMarker.getPrimitiveType(): PrimitiveType?
fun TypeConstructorMarker.getPrimitiveArrayType(): PrimitiveType?
fun TypeConstructorMarker.isUnderKotlinPackage(): Boolean
fun TypeConstructorMarker.getClassFqNameUnsafe(): FqNameUnsafe?
} }
@@ -7,12 +7,15 @@ package org.jetbrains.kotlin.types.checker
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
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
@@ -517,6 +520,26 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
require(this is KotlinType, this::errorMessage) require(this is KotlinType, this::errorMessage)
return substitutedUnderlyingType() return substitutedUnderlyingType()
} }
override fun TypeConstructorMarker.getPrimitiveType(): PrimitiveType? {
require(this is TypeConstructor, this::errorMessage)
return KotlinBuiltIns.getPrimitiveType(declarationDescriptor as ClassDescriptor)
}
override fun TypeConstructorMarker.getPrimitiveArrayType(): PrimitiveType? {
require(this is TypeConstructor, this::errorMessage)
return KotlinBuiltIns.getPrimitiveArrayType(declarationDescriptor as ClassDescriptor)
}
override fun TypeConstructorMarker.isUnderKotlinPackage(): Boolean {
require(this is TypeConstructor, this::errorMessage)
return declarationDescriptor?.let(KotlinBuiltIns::isUnderKotlinPackage) == true
}
override fun TypeConstructorMarker.getClassFqNameUnsafe(): FqNameUnsafe {
require(this is TypeConstructor, this::errorMessage)
return (declarationDescriptor as ClassDescriptor).fqNameUnsafe
}
} }
fun TypeVariance.convertVariance(): Variance { fun TypeVariance.convertVariance(): Variance {