IR: add getPrimitiveType, optimize some usages of isInt/isByte/...

This commit is contained in:
Alexander Udalov
2021-02-21 12:12:57 +01:00
parent 17ee10a0d8
commit 0ebdf7c3c4
6 changed files with 114 additions and 119 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.common.lower.optimizations
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.*
@@ -52,18 +53,18 @@ class FoldConstantLowering(
)
@Suppress("unused")
private data class PrimitiveType<T>(val name: String)
private data class PrimitiveTypeName<T>(val name: String)
companion object {
private val INT = PrimitiveType<Int>("Int")
private val LONG = PrimitiveType<Long>("Long")
private val DOUBLE = PrimitiveType<Double>("Double")
private val FLOAT = PrimitiveType<Float>("Float")
private val INT = PrimitiveTypeName<Int>("Int")
private val LONG = PrimitiveTypeName<Long>("Long")
private val DOUBLE = PrimitiveTypeName<Double>("Double")
private val FLOAT = PrimitiveTypeName<Float>("Float")
private val BINARY_OP_TO_EVALUATOR = HashMap<BinaryOp, Function2<Any?, Any?, Any>>()
@Suppress("UNCHECKED_CAST")
private fun <T> registerBuiltinBinaryOp(operandType: PrimitiveType<T>, operatorName: String, f: (T, T) -> Any) {
private fun <T> registerBuiltinBinaryOp(operandType: PrimitiveTypeName<T>, operatorName: String, f: (T, T) -> Any) {
BINARY_OP_TO_EVALUATOR[BinaryOp(operandType.name, operandType.name, operatorName)] = f as Function2<Any?, Any?, Any>
}
@@ -105,17 +106,19 @@ class FoldConstantLowering(
private fun buildIrConstant(startOffset: Int, endOffset: Int, type: IrType, v: Any?): IrConst<*> {
val constType = type.makeNotNull()
return when {
constType.isInt() -> IrConstImpl.int(startOffset, endOffset, constType, (v as Number).toInt())
constType.isChar() -> IrConstImpl.char(startOffset, endOffset, constType, v as Char)
constType.isBoolean() -> IrConstImpl.boolean(startOffset, endOffset, constType, v as Boolean)
constType.isByte() -> IrConstImpl.byte(startOffset, endOffset, constType, (v as Number).toByte())
constType.isShort() -> IrConstImpl.short(startOffset, endOffset, constType, (v as Number).toShort())
constType.isLong() -> IrConstImpl.long(startOffset, endOffset, constType, (v as Number).toLong())
constType.isDouble() -> IrConstImpl.double(startOffset, endOffset, constType, (v as Number).toDouble())
constType.isFloat() -> fromFloatConstSafe(startOffset, endOffset, type, v)
constType.isString() -> IrConstImpl.string(startOffset, endOffset, constType, v as String)
else -> throw IllegalArgumentException("Unexpected IrCall return type")
return when (type.getPrimitiveType()) {
PrimitiveType.BOOLEAN -> IrConstImpl.boolean(startOffset, endOffset, constType, v as Boolean)
PrimitiveType.CHAR -> IrConstImpl.char(startOffset, endOffset, constType, v as Char)
PrimitiveType.BYTE -> IrConstImpl.byte(startOffset, endOffset, constType, (v as Number).toByte())
PrimitiveType.SHORT -> IrConstImpl.short(startOffset, endOffset, constType, (v as Number).toShort())
PrimitiveType.INT -> IrConstImpl.int(startOffset, endOffset, constType, (v as Number).toInt())
PrimitiveType.FLOAT -> fromFloatConstSafe(startOffset, endOffset, type, v)
PrimitiveType.LONG -> IrConstImpl.long(startOffset, endOffset, constType, (v as Number).toLong())
PrimitiveType.DOUBLE -> IrConstImpl.double(startOffset, endOffset, constType, (v as Number).toDouble())
else -> when {
constType.isString() -> IrConstImpl.string(startOffset, endOffset, constType, v as String)
else -> throw IllegalArgumentException("Unexpected IrCall return type")
}
}
}
@@ -251,7 +251,7 @@ internal class LambdaMetafactoryArgumentsBuilder(
null -> true
TypeAdaptationConstraint.FORCE_BOXING -> irType.isNullable()
TypeAdaptationConstraint.KEEP_UNBOXED -> !irType.isNullable()
TypeAdaptationConstraint.BOX_PRIMITIVE -> irType.isJvmPrimitiveOrNullable()
TypeAdaptationConstraint.BOX_PRIMITIVE -> irType.getPrimitiveType() != null
TypeAdaptationConstraint.CONFLICT -> false
}
@@ -414,9 +414,9 @@ internal class LambdaMetafactoryArgumentsBuilder(
// ** JVM primitives **
// All Kotlin types mapped to JVM primitive are final,
// and their supertypes are trivially mapped reference types.
if (adapteeType.isJvmPrimitiveType()) {
if (adapteeType.isPrimitiveType()) {
return if (
expectedType.isJvmPrimitiveType() &&
expectedType.isPrimitiveType() &&
!expectedType.hasAnnotation(context.ir.symbols.enhancedNullabilityAnnotationFqName)
)
TypeAdaptationConstraint.KEEP_UNBOXED
@@ -433,7 +433,7 @@ internal class LambdaMetafactoryArgumentsBuilder(
// TODO consider adding a special type annotation to force boxing on an inline class type regardless of its underlying type.
val underlyingAdapteeType = getInlineClassUnderlyingType(erasedAdapteeClass) as? IrSimpleType
?: throw AssertionError("Underlying type for inline class should be a simple type: ${erasedAdapteeClass.render()}")
if (!underlyingAdapteeType.hasQuestionMark && !underlyingAdapteeType.isJvmPrimitiveType()) {
if (!underlyingAdapteeType.hasQuestionMark && !underlyingAdapteeType.isPrimitiveType()) {
return TypeAdaptationConstraint.CONFLICT
}
@@ -522,14 +522,6 @@ internal class LambdaMetafactoryArgumentsBuilder(
private fun IrDeclarationParent.isCrossinlineLambda(): Boolean =
this is IrSimpleFunction && this in crossinlineLambdas
private fun IrType.isJvmPrimitiveType() =
isBoolean() || isChar() || isByte() || isShort() || isInt() || isLong() || isFloat() || isDouble()
private fun IrType.isJvmPrimitiveOrNullable() =
isBooleanOrNullable() || isCharOrNullable() ||
isByteOrNullable() || isShortOrNullable() || isIntOrNullable() || isLongOrNullable() ||
isFloatOrNullable() || isDoubleOrNullable()
fun collectValueParameters(
irFun: IrFunction,
withDispatchReceiver: Boolean = false,
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.interpreter
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -66,23 +67,26 @@ internal fun Any?.toState(irType: IrType): State {
}
fun Any?.toIrConst(irType: IrType, startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET): IrConst<*> {
if (this == null) return IrConstImpl.constNull(startOffset, endOffset, irType)
val constType = irType.makeNotNull()
return when {
this == null -> IrConstImpl.constNull(startOffset, endOffset, irType)
constType.isBoolean() -> IrConstImpl.boolean(startOffset, endOffset, constType, this as Boolean)
constType.isChar() -> IrConstImpl.char(startOffset, endOffset, constType, this as Char)
constType.isByte() -> IrConstImpl.byte(startOffset, endOffset, constType, (this as Number).toByte())
constType.isShort() -> IrConstImpl.short(startOffset, endOffset, constType, (this as Number).toShort())
constType.isInt() -> IrConstImpl.int(startOffset, endOffset, constType, (this as Number).toInt())
constType.isLong() -> IrConstImpl.long(startOffset, endOffset, constType, (this as Number).toLong())
constType.isString() -> IrConstImpl.string(startOffset, endOffset, constType, this as String)
constType.isFloat() -> IrConstImpl.float(startOffset, endOffset, constType, (this as Number).toFloat())
constType.isDouble() -> IrConstImpl.double(startOffset, endOffset, constType, (this as Number).toDouble())
constType.isUByte() -> IrConstImpl.byte(startOffset, endOffset, constType, (this as Number).toByte())
constType.isUShort() -> IrConstImpl.short(startOffset, endOffset, constType, (this as Number).toShort())
constType.isUInt() -> IrConstImpl.int(startOffset, endOffset, constType, (this as Number).toInt())
constType.isULong() -> IrConstImpl.long(startOffset, endOffset, constType, (this as Number).toLong())
else -> throw UnsupportedOperationException("Unsupported const element type ${constType.render()}")
return when (irType.getPrimitiveType()) {
PrimitiveType.BOOLEAN -> IrConstImpl.boolean(startOffset, endOffset, constType, this as Boolean)
PrimitiveType.CHAR -> IrConstImpl.char(startOffset, endOffset, constType, this as Char)
PrimitiveType.BYTE -> IrConstImpl.byte(startOffset, endOffset, constType, (this as Number).toByte())
PrimitiveType.SHORT -> IrConstImpl.short(startOffset, endOffset, constType, (this as Number).toShort())
PrimitiveType.INT -> IrConstImpl.int(startOffset, endOffset, constType, (this as Number).toInt())
PrimitiveType.FLOAT -> IrConstImpl.float(startOffset, endOffset, constType, (this as Number).toFloat())
PrimitiveType.LONG -> IrConstImpl.long(startOffset, endOffset, constType, (this as Number).toLong())
PrimitiveType.DOUBLE -> IrConstImpl.double(startOffset, endOffset, constType, (this as Number).toDouble())
else -> when {
constType.isString() -> IrConstImpl.string(startOffset, endOffset, constType, this as String)
constType.isUByte() -> IrConstImpl.byte(startOffset, endOffset, constType, (this as Number).toByte())
constType.isUShort() -> IrConstImpl.short(startOffset, endOffset, constType, (this as Number).toShort())
constType.isUInt() -> IrConstImpl.int(startOffset, endOffset, constType, (this as Number).toInt())
constType.isULong() -> IrConstImpl.long(startOffset, endOffset, constType, (this as Number).toLong())
else -> throw UnsupportedOperationException("Unsupported const element type ${constType.render()}")
}
}
}
@@ -109,20 +113,21 @@ internal fun IrAnnotationContainer.getEvaluateIntrinsicValue(): String? {
return (this.getAnnotation(evaluateIntrinsicAnnotation).getValueArgument(0) as IrConst<*>).value.toString()
}
internal fun getPrimitiveClass(irType: IrType, asObject: Boolean = false): Class<*>? {
return when {
irType.isBoolean() -> if (asObject) Boolean::class.javaObjectType else Boolean::class.java
irType.isChar() -> if (asObject) Char::class.javaObjectType else Char::class.java
irType.isByte() -> if (asObject) Byte::class.javaObjectType else Byte::class.java
irType.isShort() -> if (asObject) Short::class.javaObjectType else Short::class.java
irType.isInt() -> if (asObject) Int::class.javaObjectType else Int::class.java
irType.isLong() -> if (asObject) Long::class.javaObjectType else Long::class.java
irType.isString() -> if (asObject) String::class.javaObjectType else String::class.java
irType.isFloat() -> if (asObject) Float::class.javaObjectType else Float::class.java
irType.isDouble() -> if (asObject) Double::class.javaObjectType else Double::class.java
else -> null
internal fun getPrimitiveClass(irType: IrType, asObject: Boolean = false): Class<*>? =
when (irType.getPrimitiveType()) {
PrimitiveType.BOOLEAN -> if (asObject) Boolean::class.javaObjectType else Boolean::class.java
PrimitiveType.CHAR -> if (asObject) Char::class.javaObjectType else Char::class.java
PrimitiveType.BYTE -> if (asObject) Byte::class.javaObjectType else Byte::class.java
PrimitiveType.SHORT -> if (asObject) Short::class.javaObjectType else Short::class.java
PrimitiveType.INT -> if (asObject) Int::class.javaObjectType else Int::class.java
PrimitiveType.FLOAT -> if (asObject) Float::class.javaObjectType else Float::class.java
PrimitiveType.LONG -> if (asObject) Long::class.javaObjectType else Long::class.java
PrimitiveType.DOUBLE -> if (asObject) Double::class.javaObjectType else Double::class.java
else -> when {
irType.isString() -> String::class.java
else -> null
}
}
}
internal fun IrFunction.getArgsForMethodInvocation(args: List<Variable>): List<Any?> {
val argsValues = args.map {
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.ir.types.*
@@ -74,16 +75,19 @@ class IrConstImpl<T>(
fun short(startOffset: Int, endOffset: Int, type: IrType, value: Short): IrConstImpl<Short> =
IrConstImpl(startOffset, endOffset, type, IrConstKind.Short, value)
fun defaultValueForType(startOffset: Int, endOffset: Int, type: IrType) = when {
type.isFloat() -> float(startOffset, endOffset, type, 0.0F)
type.isDouble() -> double(startOffset, endOffset, type, 0.0)
type.isBoolean() -> boolean(startOffset, endOffset, type, false)
type.isByte() -> byte(startOffset, endOffset, type, 0)
type.isChar() -> char(startOffset, endOffset, type, 0.toChar())
type.isShort() -> short(startOffset, endOffset, type, 0)
type.isInt() -> int(startOffset, endOffset, type, 0)
type.isLong() -> long(startOffset, endOffset, type, 0)
else -> constNull(startOffset, endOffset, type)
fun defaultValueForType(startOffset: Int, endOffset: Int, type: IrType): IrConstImpl<*> {
if (type.isMarkedNullable()) return constNull(startOffset, endOffset, type)
return when (type.getPrimitiveType()) {
PrimitiveType.BOOLEAN -> boolean(startOffset, endOffset, type, false)
PrimitiveType.CHAR -> char(startOffset, endOffset, type, 0.toChar())
PrimitiveType.BYTE -> byte(startOffset, endOffset, type, 0)
PrimitiveType.SHORT -> short(startOffset, endOffset, type, 0)
PrimitiveType.INT -> int(startOffset, endOffset, type, 0)
PrimitiveType.FLOAT -> float(startOffset, endOffset, type, 0.0F)
PrimitiveType.LONG -> long(startOffset, endOffset, type, 0)
PrimitiveType.DOUBLE -> double(startOffset, endOffset, type, 0.0)
else -> constNull(startOffset, endOffset, type)
}
}
}
}
@@ -11,39 +11,36 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.hasEqualFqName
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize
@Suppress("ObjectPropertyName")
object IdSignatureValues {
@JvmField val any = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Any")
@JvmField val nothing = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"Nothing")
@JvmField val unit = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"Unit")
@JvmField val nothing = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Nothing")
@JvmField val unit = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Unit")
@JvmField val _boolean = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Boolean")
@JvmField val _char = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Char")
@JvmField val _byte = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"Byte")
@JvmField val _short = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"Short")
@JvmField val _int = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"Int")
@JvmField val _long = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"Long")
@JvmField val _float = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"Float")
@JvmField val _double = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"Double")
@JvmField val number = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"Number")
@JvmField val uByte = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"UByte")
@JvmField val uShort = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"UShort")
@JvmField val uInt = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"UInt")
@JvmField val uLong = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"ULong")
@JvmField val string = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"String")
@JvmField val array = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"Array")
@JvmField val _byte = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Byte")
@JvmField val _short = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Short")
@JvmField val _int = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Int")
@JvmField val _long = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Long")
@JvmField val _float = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Float")
@JvmField val _double = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Double")
@JvmField val number = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Number")
@JvmField val uByte = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "UByte")
@JvmField val uShort = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "UShort")
@JvmField val uInt = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "UInt")
@JvmField val uLong = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "ULong")
@JvmField val string = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "String")
@JvmField val array = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Array")
@JvmField val collection = getPublicSignature(StandardNames.COLLECTIONS_PACKAGE_FQ_NAME, "Collection")
@JvmField val kClass = getPublicSignature(StandardNames.KOTLIN_REFLECT_FQ_NAME, "KClass")
@JvmField val comparable = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"Comparable")
@JvmField val charSequence = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME,"CharSequence")
@JvmField val comparable = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Comparable")
@JvmField val charSequence = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "CharSequence")
@JvmField val iterable = getPublicSignature(StandardNames.COLLECTIONS_PACKAGE_FQ_NAME, "Iterable")
@JvmField val continuation = getPublicSignature(StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE,"Continuation")
@JvmField val continuation = getPublicSignature(StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE, "Continuation")
@JvmField val result = getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Result")
@JvmField val sequence = IdSignature.PublicSignature("kotlin.sequences", "Sequence", null, 0)
}
@@ -69,18 +66,13 @@ private fun classFqNameEquals(symbol: IrClassSymbol, fqName: FqNameUnsafe): Bool
}
private val idSignatureToPrimitiveType: Map<IdSignature.PublicSignature, PrimitiveType> =
newHashMapWithExpectedSize<IdSignature.PublicSignature, PrimitiveType>(PrimitiveType.values().size).apply {
for (primitiveType in PrimitiveType.values()) {
this[getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, primitiveType.typeName.asString())] = primitiveType
}
PrimitiveType.values().associateBy {
getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, it.typeName.asString())
}
val primitiveArrayTypesSignatures: Map<PrimitiveType, IdSignature.PublicSignature> =
newHashMapWithExpectedSize<PrimitiveType, IdSignature.PublicSignature>(PrimitiveType.values().size).apply {
for (primitiveType in PrimitiveType.values()) {
this[primitiveType] =
getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "${primitiveType.typeName.asString()}Array")
}
PrimitiveType.values().associateWith {
getPublicSignature(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "${it.typeName.asString()}Array")
}
private fun classFqNameEquals(declaration: IrClass, fqName: FqNameUnsafe): Boolean =
@@ -99,35 +91,31 @@ fun IrType.isNothing(): Boolean = isNotNullClassType(IdSignatureValues.nothing)
fun IrType.isNullableNothing(): Boolean = isNullableClassType(IdSignatureValues.nothing)
fun IrType.isPrimitiveType(hasQuestionMark: Boolean = false): Boolean =
(this is IrSimpleType && hasQuestionMark == this.hasQuestionMark) &&
classOrNull?.signature in idSignatureToPrimitiveType
this is IrSimpleType && hasQuestionMark == this.hasQuestionMark && getPrimitiveType() != null
fun IrType.isNullablePrimitiveType(): Boolean = isPrimitiveType(true)
fun IrType.getPrimitiveType(): PrimitiveType? =
if (this is IrSimpleType && classifier is IrClassSymbol)
idSignatureToPrimitiveType[classifier.signature]
else null
fun IrType.isMarkedNullable() = (this as? IrSimpleType)?.hasQuestionMark ?: false
fun IrType.isUnit() = isNotNullClassType(IdSignatureValues.unit)
fun IrType.isBoolean(): Boolean = isNotNullClassType(IdSignatureValues._boolean)
fun IrType.isBooleanOrNullable(): Boolean = isClassType(IdSignatureValues._boolean)
fun IrType.isChar(): Boolean = isNotNullClassType(IdSignatureValues._char)
fun IrType.isCharOrNullable(): Boolean = isClassType(IdSignatureValues._char)
fun IrType.isByte(): Boolean = isNotNullClassType(IdSignatureValues._byte)
fun IrType.isByteOrNullable(): Boolean = isClassType(IdSignatureValues._byte)
fun IrType.isShort(): Boolean = isNotNullClassType(IdSignatureValues._short)
fun IrType.isShortOrNullable(): Boolean = isClassType(IdSignatureValues._short)
fun IrType.isInt(): Boolean = isNotNullClassType(IdSignatureValues._int)
fun IrType.isIntOrNullable(): Boolean = isClassType(IdSignatureValues._int)
fun IrType.isLong(): Boolean = isNotNullClassType(IdSignatureValues._long)
fun IrType.isLongOrNullable(): Boolean = isClassType(IdSignatureValues._long)
fun IrType.isUByte(): Boolean = isNotNullClassType(IdSignatureValues.uByte)
fun IrType.isUShort(): Boolean = isNotNullClassType(IdSignatureValues.uShort)
fun IrType.isUInt(): Boolean = isNotNullClassType(IdSignatureValues.uInt)
fun IrType.isULong(): Boolean = isNotNullClassType(IdSignatureValues.uLong)
fun IrType.isFloat(): Boolean = isNotNullClassType(IdSignatureValues._float)
fun IrType.isFloatOrNullable(): Boolean = isClassType(IdSignatureValues._float)
fun IrType.isDouble(): Boolean = isNotNullClassType(IdSignatureValues._double)
fun IrType.isDoubleOrNullable(): Boolean = isClassType(IdSignatureValues._double)
fun IrType.isNumber(): Boolean = isNotNullClassType(IdSignatureValues.number)
fun IrType.isComparable(): Boolean = isNotNullClassType(IdSignatureValues.comparable)
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irIfThen
import org.jetbrains.kotlin.backend.common.lower.irThrow
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
@@ -358,17 +359,19 @@ open class SerializerIrGenerator(
private fun IrBuilderWithScope.defaultValueAndType(descriptor: PropertyDescriptor): Pair<IrExpression, IrType> {
val kType = descriptor.returnType!!
val T = kType.toIrType()
val defaultPrimitive: IrExpression? = when {
T.isInt() -> IrConstImpl.int(startOffset, endOffset, T, 0)
T.isBoolean() -> IrConstImpl.boolean(startOffset, endOffset, T, false)
T.isLong() -> IrConstImpl.long(startOffset, endOffset, T, 0)
T.isDouble() -> IrConstImpl.double(startOffset, endOffset, T, 0.0)
T.isFloat() -> IrConstImpl.float(startOffset, endOffset, T, 0.0f)
T.isChar() -> IrConstImpl.char(startOffset, endOffset, T, 0.toChar())
T.isByte() -> IrConstImpl.byte(startOffset, endOffset, T, 0)
T.isShort() -> IrConstImpl.short(startOffset, endOffset, T, 0)
else -> null
}
val defaultPrimitive: IrExpression? =
if (T.isMarkedNullable()) null
else when (T.getPrimitiveType()) {
PrimitiveType.BOOLEAN -> IrConstImpl.boolean(startOffset, endOffset, T, false)
PrimitiveType.CHAR -> IrConstImpl.char(startOffset, endOffset, T, 0.toChar())
PrimitiveType.BYTE -> IrConstImpl.byte(startOffset, endOffset, T, 0)
PrimitiveType.SHORT -> IrConstImpl.short(startOffset, endOffset, T, 0)
PrimitiveType.INT -> IrConstImpl.int(startOffset, endOffset, T, 0)
PrimitiveType.FLOAT -> IrConstImpl.float(startOffset, endOffset, T, 0.0f)
PrimitiveType.LONG -> IrConstImpl.long(startOffset, endOffset, T, 0)
PrimitiveType.DOUBLE -> IrConstImpl.double(startOffset, endOffset, T, 0.0)
else -> null
}
return if (defaultPrimitive == null)
irNull(compilerContext.irBuiltIns.anyNType) to (compilerContext.irBuiltIns.anyNType)
else