[IR] Refactor ir infrastructure
- Remove range-based uniq id indexes using to link built ins - Limit KotlinType usages, replace them with corresponding IrType
This commit is contained in:
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
@@ -1144,21 +1145,22 @@ class Fir2IrVisitor(
|
||||
}
|
||||
// TODO: it's temporary hack which should be refactored
|
||||
val simpleType = when (val classId = (firstType.type as? ConeClassLikeType)?.lookupTag?.classId) {
|
||||
ClassId(FqName("kotlin"), FqName("Long"), false) -> irBuiltIns.builtIns.longType
|
||||
ClassId(FqName("kotlin"), FqName("Int"), false) -> irBuiltIns.builtIns.intType
|
||||
ClassId(FqName("kotlin"), FqName("Float"), false) -> irBuiltIns.builtIns.floatType
|
||||
ClassId(FqName("kotlin"), FqName("Double"), false) -> irBuiltIns.builtIns.doubleType
|
||||
ClassId(FqName("kotlin"), FqName("Long"), false) -> irBuiltIns.longType
|
||||
ClassId(FqName("kotlin"), FqName("Int"), false) -> irBuiltIns.intType
|
||||
ClassId(FqName("kotlin"), FqName("Float"), false) -> irBuiltIns.floatType
|
||||
ClassId(FqName("kotlin"), FqName("Double"), false) -> irBuiltIns.doubleType
|
||||
else -> {
|
||||
return IrErrorCallExpressionImpl(
|
||||
startOffset, endOffset, booleanType, "Comparison of arguments with unsupported type: $classId"
|
||||
)
|
||||
}
|
||||
}
|
||||
val classifier = simpleType.classifierOrFail
|
||||
val (symbol, origin) = when (operation) {
|
||||
FirOperation.LT -> irBuiltIns.lessFunByOperandType[simpleType] to IrStatementOrigin.LT
|
||||
FirOperation.GT -> irBuiltIns.greaterFunByOperandType[simpleType] to IrStatementOrigin.GT
|
||||
FirOperation.LT_EQ -> irBuiltIns.lessOrEqualFunByOperandType[simpleType] to IrStatementOrigin.LTEQ
|
||||
FirOperation.GT_EQ -> irBuiltIns.greaterOrEqualFunByOperandType[simpleType] to IrStatementOrigin.GTEQ
|
||||
FirOperation.LT -> irBuiltIns.lessFunByOperandType[classifier] to IrStatementOrigin.LT
|
||||
FirOperation.GT -> irBuiltIns.greaterFunByOperandType[classifier] to IrStatementOrigin.GT
|
||||
FirOperation.LT_EQ -> irBuiltIns.lessOrEqualFunByOperandType[classifier] to IrStatementOrigin.LTEQ
|
||||
FirOperation.GT_EQ -> irBuiltIns.greaterOrEqualFunByOperandType[classifier] to IrStatementOrigin.GTEQ
|
||||
else -> throw AssertionError("Unexpected comparison operation: $operation")
|
||||
}
|
||||
return primitiveOp2(startOffset, endOffset, symbol!!, booleanType, origin, first.toIrExpression(), second.toIrExpression())
|
||||
|
||||
+2
-2
@@ -18,8 +18,8 @@ import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.getClass
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.constructedClass
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
@@ -78,7 +78,7 @@ class ArrayConstructorLowering(val context: CommonBackendContext) : IrElementTra
|
||||
val invoke = invokable.type.getClass()!!.functions.single { it.name == OperatorNameConventions.INVOKE }
|
||||
val invokableVar = if (lambda == null) irTemporary(invokable) else null
|
||||
+irWhile().apply {
|
||||
condition = irCall(context.irBuiltIns.lessFunByOperandType[index.type.toKotlinType()]!!).apply {
|
||||
condition = irCall(context.irBuiltIns.lessFunByOperandType[index.type.classifierOrFail]!!).apply {
|
||||
putValueArgument(0, irGet(index))
|
||||
putValueArgument(1, irGet(sizeVar))
|
||||
}
|
||||
|
||||
+6
-6
@@ -78,10 +78,10 @@ internal sealed class ForLoopHeader(
|
||||
with(builder) {
|
||||
val builtIns = context.irBuiltIns
|
||||
val progressionType = headerInfo.progressionType
|
||||
val progressionKotlinType = progressionType.elementType(builtIns).toKotlinType()
|
||||
val progressionElementType = progressionType.elementType(builtIns)
|
||||
val compFun =
|
||||
if (isLastInclusive) builtIns.lessOrEqualFunByOperandType[progressionKotlinType]!!
|
||||
else builtIns.lessFunByOperandType[progressionKotlinType]!!
|
||||
if (isLastInclusive) builtIns.lessOrEqualFunByOperandType[progressionElementType.classifierOrFail]!!
|
||||
else builtIns.lessFunByOperandType[progressionElementType.classifierOrFail]!!
|
||||
|
||||
// The default condition depends on the direction.
|
||||
when (headerInfo.direction) {
|
||||
@@ -101,11 +101,11 @@ internal sealed class ForLoopHeader(
|
||||
// If the direction is unknown, we check depending on the "step" value:
|
||||
// // (use `<` if last is exclusive)
|
||||
// (step > 0 && inductionVar <= last) || (step < 0 || last <= inductionVar)
|
||||
val stepKotlinType = progressionType.stepType(builtIns).toKotlinType()
|
||||
val stepType = progressionType.stepType(builtIns)
|
||||
val isLong = progressionType == ProgressionType.LONG_PROGRESSION
|
||||
context.oror(
|
||||
context.andand(
|
||||
irCall(builtIns.greaterFunByOperandType[stepKotlinType]!!).apply {
|
||||
irCall(builtIns.greaterFunByOperandType[stepType.classifierOrFail]!!).apply {
|
||||
putValueArgument(0, irGet(step))
|
||||
putValueArgument(1, if (isLong) irLong(0) else irInt(0))
|
||||
},
|
||||
@@ -114,7 +114,7 @@ internal sealed class ForLoopHeader(
|
||||
putValueArgument(1, lastExpression)
|
||||
}),
|
||||
context.andand(
|
||||
irCall(builtIns.lessFunByOperandType[stepKotlinType]!!).apply {
|
||||
irCall(builtIns.lessFunByOperandType[stepType.classifierOrFail]!!).apply {
|
||||
putValueArgument(0, irGet(step))
|
||||
putValueArgument(1, if (isLong) irLong(0) else irInt(0))
|
||||
},
|
||||
|
||||
+1
-1
@@ -257,7 +257,7 @@ internal class StepHandler(
|
||||
//
|
||||
// We insert this check in the lowered form only if necessary.
|
||||
val stepType = data.stepType(context.irBuiltIns)
|
||||
val stepGreaterFun = context.irBuiltIns.greaterFunByOperandType[stepType.toKotlinType()]!!
|
||||
val stepGreaterFun = context.irBuiltIns.greaterFunByOperandType[stepType.classifierOrFail]!!
|
||||
val zeroStep = if (data == ProgressionType.LONG_PROGRESSION) irLong(0) else irInt(0)
|
||||
val throwIllegalStepExceptionCall = {
|
||||
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.isLong
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
@@ -92,7 +93,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
// Type checks:
|
||||
|
||||
val jsInstanceOf = binOpBool("jsInstanceOf")
|
||||
val jsTypeOf = unOp("jsTypeOf", irBuiltIns.string)
|
||||
val jsTypeOf = unOp("jsTypeOf", irBuiltIns.stringType)
|
||||
|
||||
// Number conversions:
|
||||
|
||||
@@ -336,18 +337,18 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
}
|
||||
}
|
||||
|
||||
private fun unOp(name: String, returnType: KotlinType = irBuiltIns.anyN) =
|
||||
irBuiltIns.run { defineOperator(name, returnType, listOf(anyN)) }
|
||||
private fun unOp(name: String, returnType: IrType = irBuiltIns.anyNType) =
|
||||
irBuiltIns.run { defineOperator(name, returnType, listOf(anyNType)) }
|
||||
|
||||
private fun unOpBool(name: String) = unOp(name, irBuiltIns.bool)
|
||||
private fun unOpInt(name: String) = unOp(name, irBuiltIns.int)
|
||||
private fun unOpBool(name: String) = unOp(name, irBuiltIns.booleanType)
|
||||
private fun unOpInt(name: String) = unOp(name, irBuiltIns.intType)
|
||||
|
||||
private fun binOp(name: String, returnType: KotlinType = irBuiltIns.anyN) =
|
||||
irBuiltIns.run { defineOperator(name, returnType, listOf(anyN, anyN)) }
|
||||
private fun binOp(name: String, returnType: IrType = irBuiltIns.anyNType) =
|
||||
irBuiltIns.run { defineOperator(name, returnType, listOf(anyNType, anyNType)) }
|
||||
|
||||
private fun tripleOp(name: String, returnType: KotlinType = irBuiltIns.anyN) =
|
||||
irBuiltIns.run { defineOperator(name, returnType, listOf(anyN, anyN, anyN)) }
|
||||
private fun tripleOp(name: String, returnType: IrType = irBuiltIns.anyNType) =
|
||||
irBuiltIns.run { defineOperator(name, returnType, listOf(anyNType, anyNType, anyNType)) }
|
||||
|
||||
private fun binOpBool(name: String) = binOp(name, irBuiltIns.bool)
|
||||
private fun binOpInt(name: String) = binOp(name, irBuiltIns.int)
|
||||
private fun binOpBool(name: String) = binOp(name, irBuiltIns.booleanType)
|
||||
private fun binOpInt(name: String) = binOp(name, irBuiltIns.intType)
|
||||
}
|
||||
|
||||
+3
-2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower.calls
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.irCall
|
||||
@@ -16,13 +17,13 @@ import org.jetbrains.kotlin.types.SimpleType
|
||||
|
||||
typealias SymbolToTransformer = MutableMap<IrFunctionSymbol, (IrFunctionAccessExpression) -> IrExpression>
|
||||
|
||||
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrFunctionSymbol>, to: IrFunctionSymbol) {
|
||||
internal fun SymbolToTransformer.add(from: Map<IrClassifierSymbol, IrFunctionSymbol>, to: IrFunctionSymbol) {
|
||||
from.forEach { _, func ->
|
||||
add(func, to)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun SymbolToTransformer.add(from: Map<SimpleType, IrFunctionSymbol>, to: (IrFunctionAccessExpression) -> IrExpression) {
|
||||
internal fun SymbolToTransformer.add(from: Map<IrClassifierSymbol, IrFunctionSymbol>, to: (IrFunctionAccessExpression) -> IrExpression) {
|
||||
from.forEach { _, func ->
|
||||
add(func, to)
|
||||
}
|
||||
|
||||
+8
-8
@@ -34,15 +34,15 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
|
||||
|
||||
add(irBuiltIns.booleanNotSymbol, intrinsics.jsNot)
|
||||
|
||||
add(irBuiltIns.lessFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsLt)
|
||||
add(irBuiltIns.lessOrEqualFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsLtEq)
|
||||
add(irBuiltIns.greaterFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsGt)
|
||||
add(irBuiltIns.greaterOrEqualFunByOperandType.filterKeys { it != irBuiltIns.long }, intrinsics.jsGtEq)
|
||||
add(irBuiltIns.lessFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsLt)
|
||||
add(irBuiltIns.lessOrEqualFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsLtEq)
|
||||
add(irBuiltIns.greaterFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsGt)
|
||||
add(irBuiltIns.greaterOrEqualFunByOperandType.filterKeys { it != irBuiltIns.longClass }, intrinsics.jsGtEq)
|
||||
|
||||
add(irBuiltIns.lessFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsLt))
|
||||
add(irBuiltIns.lessOrEqualFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsLtEq))
|
||||
add(irBuiltIns.greaterFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsGt))
|
||||
add(irBuiltIns.greaterOrEqualFunByOperandType[irBuiltIns.long]!!, transformLongComparison(intrinsics.jsGtEq))
|
||||
add(irBuiltIns.lessFunByOperandType[irBuiltIns.longClass]!!, transformLongComparison(intrinsics.jsLt))
|
||||
add(irBuiltIns.lessOrEqualFunByOperandType[irBuiltIns.longClass]!!, transformLongComparison(intrinsics.jsLtEq))
|
||||
add(irBuiltIns.greaterFunByOperandType[irBuiltIns.longClass]!!, transformLongComparison(intrinsics.jsGt))
|
||||
add(irBuiltIns.greaterOrEqualFunByOperandType[irBuiltIns.longClass]!!, transformLongComparison(intrinsics.jsGtEq))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -81,8 +80,8 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
|
||||
) to Clone,
|
||||
irBuiltIns.eqeqSymbol.toKey()!! to Equals(KtTokens.EQEQ),
|
||||
irBuiltIns.eqeqeqSymbol.toKey()!! to Equals(KtTokens.EQEQEQ),
|
||||
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.float]!!.toKey()!! to Ieee754Equals(Type.FLOAT_TYPE),
|
||||
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.double]!!.toKey()!! to Ieee754Equals(Type.DOUBLE_TYPE),
|
||||
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.floatClass]!!.toKey()!! to Ieee754Equals(Type.FLOAT_TYPE),
|
||||
irBuiltIns.ieee754equalsFunByOperandType[irBuiltIns.doubleClass]!!.toKey()!! to Ieee754Equals(Type.DOUBLE_TYPE),
|
||||
irBuiltIns.booleanNotSymbol.toKey()!! to Not,
|
||||
irBuiltIns.enumValueOfSymbol.toKey()!! to IrEnumValueOf,
|
||||
irBuiltIns.noWhenBranchMatchedExceptionSymbol.toKey()!! to IrNoWhenBranchMatchedException,
|
||||
@@ -240,11 +239,11 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
|
||||
|
||||
|
||||
private fun primitiveComparisonIntrinsics(
|
||||
typeToIrFun: Map<SimpleType, IrSimpleFunctionSymbol>,
|
||||
typeToIrFun: Map<IrClassifierSymbol, IrSimpleFunctionSymbol>,
|
||||
operator: KtSingleValueToken
|
||||
): List<Pair<Key, PrimitiveComparison>> =
|
||||
typeToIrFun.map { (type, irFunSymbol) ->
|
||||
irFunSymbol.toKey()!! to PrimitiveComparison(type, operator)
|
||||
irFunSymbol.toKey()!! to PrimitiveComparison(type.descriptor.defaultType, operator)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -70,13 +72,13 @@ class WasmSymbols(
|
||||
context.irBuiltIns.doubleType to getInternalFunction("wasm_f64_eq")
|
||||
)
|
||||
|
||||
private fun wasmString(simpleType: SimpleType): String = with(context.irBuiltIns) {
|
||||
when (simpleType) {
|
||||
bool, byte, short, char, int -> "i32"
|
||||
float -> "f32"
|
||||
double -> "f64"
|
||||
long -> "i64"
|
||||
else -> error("Unkonow primitive type")
|
||||
private fun wasmString(classfier: IrClassifierSymbol): String = with(context.irBuiltIns) {
|
||||
when (classfier) {
|
||||
booleanClass, byteClass, shortClass, charClass, intClass -> "i32"
|
||||
floatClass -> "f32"
|
||||
doubleClass -> "f64"
|
||||
longClass -> "i64"
|
||||
else -> error("Unknown primitive type")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -204,7 +204,7 @@ class DataClassMembersGenerator(
|
||||
when (val typeConstructorDescriptor = type.constructor.declarationDescriptor) {
|
||||
is ClassDescriptor ->
|
||||
if (KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor))
|
||||
context.irBuiltIns.dataClassArrayMemberHashCodeSymbol.descriptor
|
||||
context.irBuiltIns.dataClassArrayMemberHashCode
|
||||
else
|
||||
type.memberScope.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }
|
||||
|
||||
|
||||
+13
-6
@@ -24,6 +24,9 @@ import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.ir.types.makeNotNull
|
||||
import org.jetbrains.kotlin.ir.util.referenceFunction
|
||||
@@ -316,7 +319,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
val comparisonInfo = getPrimitiveNumericComparisonInfo(expression)
|
||||
val comparisonType = comparisonInfo?.comparisonType
|
||||
|
||||
val eqeqSymbol = context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType] ?: context.irBuiltIns.eqeqSymbol
|
||||
val eqeqSymbol = context.irBuiltIns.ieee754equalsFunByOperandType[kotlinTypeToIrType(comparisonType)?.classifierOrNull] ?: context.irBuiltIns.eqeqSymbol
|
||||
|
||||
val irEquals = primitiveOp2(
|
||||
expression.startOffsetSkippingComments, expression.endOffset,
|
||||
@@ -354,7 +357,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
if (comparisonInfo != null) {
|
||||
val comparisonType = comparisonInfo.comparisonType
|
||||
val eqeqSymbol =
|
||||
context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType] ?: context.irBuiltIns.eqeqSymbol
|
||||
context.irBuiltIns.ieee754equalsFunByOperandType[kotlinTypeToIrType(comparisonType)?.classifierOrNull] ?: context.irBuiltIns.eqeqSymbol
|
||||
primitiveOp2(
|
||||
startOffset, endOffset,
|
||||
eqeqSymbol,
|
||||
@@ -432,6 +435,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
return memberScope.findSingleFunction(Name.identifier("to$targetTypeName"))
|
||||
}
|
||||
|
||||
private val primitiveTypeMapping = context.irBuiltIns.run { primitiveTypes.zip(primitiveIrTypes).toMap() }
|
||||
private fun kotlinTypeToIrType(kotlinType: KotlinType?) = kotlinType?.let { primitiveTypeMapping[it] }
|
||||
|
||||
private fun generateComparisonOperator(ktExpression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
|
||||
if (isDynamicBinaryOperator(ktExpression)) return generateDynamicBinaryExpression(ktExpression)
|
||||
|
||||
@@ -444,9 +450,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
val ktRight = ktExpression.right ?: throw AssertionError("No RHS in ${ktExpression.text}")
|
||||
|
||||
return if (comparisonInfo != null) {
|
||||
val comparisonType = comparisonInfo.comparisonType
|
||||
primitiveOp2(
|
||||
startOffset, endOffset,
|
||||
getComparisonOperatorSymbol(origin, comparisonInfo.comparisonType),
|
||||
getComparisonOperatorSymbol(origin, kotlinTypeToIrType(comparisonType) ?: error("$comparisonType expected to be primitive")),
|
||||
context.irBuiltIns.booleanType,
|
||||
origin,
|
||||
ktLeft.generateAsPrimitiveNumericComparisonOperand(comparisonInfo.leftType, comparisonInfo.comparisonType),
|
||||
@@ -458,7 +465,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
|
||||
primitiveOp2(
|
||||
startOffset, endOffset,
|
||||
getComparisonOperatorSymbol(origin, context.irBuiltIns.int),
|
||||
getComparisonOperatorSymbol(origin, context.irBuiltIns.intType),
|
||||
context.irBuiltIns.booleanType,
|
||||
origin,
|
||||
generateCall(resolvedCall, ktExpression, origin),
|
||||
@@ -474,14 +481,14 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
) =
|
||||
CallGenerator(statementGenerator).generateCall(ktExpression, statementGenerator.pregenerateCall(resolvedCall), origin)
|
||||
|
||||
private fun getComparisonOperatorSymbol(origin: IrStatementOrigin, primitiveNumericType: KotlinType): IrSimpleFunctionSymbol =
|
||||
private fun getComparisonOperatorSymbol(origin: IrStatementOrigin, primitiveNumericType: IrType): IrSimpleFunctionSymbol =
|
||||
when (origin) {
|
||||
IrStatementOrigin.LT -> context.irBuiltIns.lessFunByOperandType
|
||||
IrStatementOrigin.LTEQ -> context.irBuiltIns.lessOrEqualFunByOperandType
|
||||
IrStatementOrigin.GT -> context.irBuiltIns.greaterFunByOperandType
|
||||
IrStatementOrigin.GTEQ -> context.irBuiltIns.greaterOrEqualFunByOperandType
|
||||
else -> throw AssertionError("Unexpected comparison operator: $origin")
|
||||
}[primitiveNumericType]!!
|
||||
}[primitiveNumericType.classifierOrFail]!!
|
||||
|
||||
private fun generateExclExclOperator(expression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression {
|
||||
val ktArgument = expression.baseExpression!!
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -13,18 +15,25 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeBuilder
|
||||
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
import org.jetbrains.kotlin.ir.types.withHasQuestionMark
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
class IrBuiltIns(
|
||||
val builtIns: KotlinBuiltIns,
|
||||
@@ -35,34 +44,179 @@ class IrBuiltIns(
|
||||
|
||||
private val builtInsModule = builtIns.builtInsModule
|
||||
|
||||
private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtInsModule, KOTLIN_INTERNAL_IR_FQN)
|
||||
val irBuiltInsSymbols = mutableListOf<IrSimpleFunctionSymbol>()
|
||||
val irBuiltInsSymbols = mutableListOf<IrBuiltinWithMangle>()
|
||||
|
||||
private val symbolTable = outerSymbolTable ?: SymbolTable()
|
||||
|
||||
private val packageFragmentDescriptor = IrBuiltinsPackageFragmentDescriptorImpl(builtInsModule, KOTLIN_INTERNAL_IR_FQN)
|
||||
private val packageFragment =
|
||||
IrExternalPackageFragmentImpl(symbolTable.referenceExternalPackageFragment(packageFragmentDescriptor), KOTLIN_INTERNAL_IR_FQN)
|
||||
|
||||
private fun ClassDescriptor.toIrSymbol() = symbolTable.referenceClass(this)
|
||||
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
|
||||
|
||||
fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrSimpleFunctionSymbol {
|
||||
val operatorDescriptor = IrSimpleBuiltinOperatorDescriptorImpl(packageFragment, Name.identifier(name), returnType)
|
||||
for ((i, valueParameterType) in valueParameterTypes.withIndex()) {
|
||||
operatorDescriptor.addValueParameter(
|
||||
IrBuiltinValueParameterDescriptorImpl(operatorDescriptor, Name.identifier("arg$i"), i, valueParameterType)
|
||||
)
|
||||
fun defineOperator(name: String, returnType: IrType, valueParameterTypes: List<IrType>): IrSimpleFunctionSymbol {
|
||||
val descriptor = WrappedSimpleFunctionDescriptor()
|
||||
val symbol = symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, descriptor) {
|
||||
val suffix = valueParameterTypes.joinToString(":", "[", "]") { t -> t.originalKotlinType?.toString() ?: "T" }
|
||||
val operator = IrBuiltInOperator(it, Name.identifier(name), returnType, suffix)
|
||||
operator.parent = packageFragment
|
||||
packageFragment.declarations += operator
|
||||
descriptor.bind(operator)
|
||||
|
||||
valueParameterTypes.mapIndexedTo(operator.valueParameters) { i, t ->
|
||||
val valueParameterDescriptor = WrappedValueParameterDescriptor()
|
||||
val valueParameterSymbol = IrValueParameterSymbolImpl(valueParameterDescriptor)
|
||||
IrBuiltInOperatorValueParameter(valueParameterSymbol, i, t).apply {
|
||||
valueParameterDescriptor.bind(this)
|
||||
parent = operator
|
||||
}
|
||||
}
|
||||
|
||||
irBuiltInsSymbols += operator
|
||||
|
||||
operator
|
||||
}
|
||||
return operatorDescriptor.addStub()
|
||||
|
||||
return symbol.symbol
|
||||
}
|
||||
|
||||
private fun <T : SimpleFunctionDescriptor> T.addStub(): IrSimpleFunctionSymbol =
|
||||
symbolTable.referenceSimpleFunction(this).also {
|
||||
irBuiltInsSymbols += it
|
||||
private fun defineEnumValueOfOperator(): IrSimpleFunctionSymbol {
|
||||
val name = Name.identifier("enumValueOf")
|
||||
val typeParameterDescriptor: TypeParameterDescriptor
|
||||
val valueParameterDescriptor: ValueParameterDescriptor
|
||||
val descriptor = SimpleFunctionDescriptorImpl.create(
|
||||
packageFragmentDescriptor,
|
||||
Annotations.EMPTY,
|
||||
name,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE
|
||||
).apply {
|
||||
typeParameterDescriptor = TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||
this, Annotations.EMPTY, true, Variance.INVARIANT, Name.identifier("T0"), 0
|
||||
)
|
||||
|
||||
valueParameterDescriptor = ValueParameterDescriptorImpl(
|
||||
this, null, 0, Annotations.EMPTY, Name.identifier("arg0"), string,
|
||||
false, false, false, null, SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
val returnType = typeParameterDescriptor.typeConstructor.makeNonNullType()
|
||||
|
||||
initialize(null, null, listOf(typeParameterDescriptor), listOf(valueParameterDescriptor), returnType, Modality.FINAL, Visibilities.PUBLIC)
|
||||
}
|
||||
|
||||
private fun defineComparisonOperator(name: String, operandType: KotlinType) =
|
||||
defineOperator(name, bool, listOf(operandType, operandType))
|
||||
val returnKotlinType = descriptor.returnType
|
||||
val typeParameterSymbol = IrTypeParameterSymbolImpl(typeParameterDescriptor)
|
||||
val typeParameter = IrBuiltInOperatorTypeParameter(typeParameterSymbol, Variance.INVARIANT, 0, true).apply {
|
||||
superTypes += anyNType
|
||||
}
|
||||
|
||||
private fun List<SimpleType>.defineComparisonOperatorForEachType(name: String) =
|
||||
associate { it to defineComparisonOperator(name, it) }
|
||||
val returnIrType = IrSimpleTypeBuilder().run {
|
||||
classifier = typeParameterSymbol
|
||||
kotlinType = returnKotlinType
|
||||
buildSimpleType()
|
||||
}
|
||||
|
||||
return symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, descriptor) {
|
||||
val operator = IrBuiltInOperator(it, name, returnIrType, ":enum")
|
||||
operator.parent = packageFragment
|
||||
packageFragment.declarations += operator
|
||||
|
||||
val valueParameterSymbol = IrValueParameterSymbolImpl(valueParameterDescriptor)
|
||||
val valueParameter = IrBuiltInOperatorValueParameter(valueParameterSymbol, 0, stringType)
|
||||
|
||||
valueParameter.parent = operator
|
||||
typeParameter.parent = operator
|
||||
|
||||
operator.valueParameters += valueParameter
|
||||
operator.typeParameters += typeParameter
|
||||
|
||||
irBuiltInsSymbols += operator
|
||||
|
||||
operator
|
||||
}.symbol
|
||||
}
|
||||
|
||||
private fun defineCheckNotNullOperator(): IrSimpleFunctionSymbol {
|
||||
val name = Name.identifier("CHECK_NOT_NULL")
|
||||
val typeParameterDescriptor: TypeParameterDescriptor
|
||||
val valueParameterDescriptor: ValueParameterDescriptor
|
||||
|
||||
val returnKotlinType: SimpleType
|
||||
val valueKotlinType: SimpleType
|
||||
|
||||
// Note: We still need a complete function descriptor here because `CHECK_NOT_NULL` is being substituted by psi2ir
|
||||
val descriptor = SimpleFunctionDescriptorImpl.create(
|
||||
packageFragmentDescriptor,
|
||||
Annotations.EMPTY,
|
||||
name,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE
|
||||
).apply {
|
||||
typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||
this, Annotations.EMPTY, false, Variance.INVARIANT, Name.identifier("T0"), 0, SourceElement.NO_SOURCE
|
||||
).apply {
|
||||
addUpperBound(any)
|
||||
setInitialized()
|
||||
}
|
||||
|
||||
valueKotlinType = typeParameterDescriptor.typeConstructor.makeNullableType()
|
||||
|
||||
valueParameterDescriptor = ValueParameterDescriptorImpl(
|
||||
this, null, 0, Annotations.EMPTY, Name.identifier("arg0"), valueKotlinType,
|
||||
false, false, false, null, SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
returnKotlinType = typeParameterDescriptor.typeConstructor.makeNonNullType()
|
||||
|
||||
initialize(null, null, listOf(typeParameterDescriptor), listOf(valueParameterDescriptor), returnKotlinType, Modality.FINAL, Visibilities.PUBLIC)
|
||||
}
|
||||
|
||||
val typeParameterSymbol = IrTypeParameterSymbolImpl(typeParameterDescriptor)
|
||||
val typeParameter = IrBuiltInOperatorTypeParameter(typeParameterSymbol, Variance.INVARIANT, 0, true).apply {
|
||||
superTypes += anyType
|
||||
}
|
||||
|
||||
val returnIrType = IrSimpleTypeBuilder().run {
|
||||
classifier = typeParameterSymbol
|
||||
kotlinType = returnKotlinType
|
||||
hasQuestionMark = false
|
||||
buildSimpleType()
|
||||
}
|
||||
|
||||
val valueIrType = IrSimpleTypeBuilder().run {
|
||||
classifier = typeParameterSymbol
|
||||
kotlinType = valueKotlinType
|
||||
hasQuestionMark = true
|
||||
buildSimpleType()
|
||||
}
|
||||
|
||||
return symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, descriptor) {
|
||||
val operator = IrBuiltInOperator(it, name, returnIrType, ":!!")
|
||||
operator.parent = packageFragment
|
||||
packageFragment.declarations += operator
|
||||
|
||||
val valueParameterSymbol = IrValueParameterSymbolImpl(valueParameterDescriptor)
|
||||
val valueParameter = IrBuiltInOperatorValueParameter(valueParameterSymbol, 0, valueIrType)
|
||||
|
||||
valueParameter.parent = operator
|
||||
typeParameter.parent = operator
|
||||
|
||||
operator.valueParameters += valueParameter
|
||||
operator.typeParameters += typeParameter
|
||||
|
||||
irBuiltInsSymbols += operator
|
||||
|
||||
operator
|
||||
}.symbol
|
||||
}
|
||||
|
||||
private fun defineComparisonOperator(name: String, operandType: IrType) =
|
||||
defineOperator(name, booleanType, listOf(operandType, operandType))
|
||||
|
||||
private fun List<IrType>.defineComparisonOperatorForEachIrType(name: String) =
|
||||
associate { it.classifierOrFail to defineComparisonOperator(name, it) }
|
||||
|
||||
val any = builtIns.anyType
|
||||
val anyN = builtIns.nullableAnyType
|
||||
@@ -127,36 +281,6 @@ class IrBuiltIns(
|
||||
val throwableType = builtIns.throwable.defaultType.toIrType()
|
||||
val throwableClass = builtIns.throwable.toIrSymbol()
|
||||
|
||||
private class BuiltInIrTypePair(val type: IrType) {
|
||||
val nType: IrType = with(type as IrSimpleType) {
|
||||
IrSimpleTypeImpl(classifier, true, arguments, annotations)
|
||||
}
|
||||
}
|
||||
|
||||
private val primitiveTypesMapping = mapOf(
|
||||
builtIns.any to BuiltInIrTypePair(anyType),
|
||||
builtIns.boolean to BuiltInIrTypePair(booleanType),
|
||||
builtIns.char to BuiltInIrTypePair(charType),
|
||||
builtIns.number to BuiltInIrTypePair(numberType),
|
||||
builtIns.byte to BuiltInIrTypePair(byteType),
|
||||
builtIns.short to BuiltInIrTypePair(shortType),
|
||||
builtIns.int to BuiltInIrTypePair(intType),
|
||||
builtIns.long to BuiltInIrTypePair(longType),
|
||||
builtIns.float to BuiltInIrTypePair(floatType),
|
||||
builtIns.double to BuiltInIrTypePair(doubleType),
|
||||
builtIns.nothing to BuiltInIrTypePair(nothingType),
|
||||
builtIns.unit to BuiltInIrTypePair(unitType),
|
||||
builtIns.string to BuiltInIrTypePair(stringType),
|
||||
builtIns.throwable to BuiltInIrTypePair(throwableType)
|
||||
)
|
||||
|
||||
fun getPrimitiveTypeOrNullByDescriptor(descriptor: ClassifierDescriptor, isNullable: Boolean) =
|
||||
primitiveTypesMapping[descriptor]?.let {
|
||||
if (isNullable) it.nType else it.type
|
||||
} as IrSimpleType?
|
||||
|
||||
val primitiveIrTypes by lazy { listOf(booleanType, charType, byteType, shortType, intType, floatType, longType, doubleType) }
|
||||
|
||||
val kCallableClass = builtIns.kCallable.toIrSymbol()
|
||||
val kPropertyClass = builtIns.kProperty.toIrSymbol()
|
||||
val kDeclarationContainerClass = builtIns.kDeclarationContainer.toIrSymbol()
|
||||
@@ -177,9 +301,10 @@ class IrBuiltIns(
|
||||
}
|
||||
|
||||
// TODO switch to IrType
|
||||
val primitiveTypes = listOf(bool, char, byte, short, int, long, float, double)
|
||||
val primitiveTypesWithComparisons = listOf(char, byte, short, int, long, float, double)
|
||||
val primitiveFloatingPointTypes = listOf(float, double)
|
||||
val primitiveTypes = listOf(bool, char, byte, short, int, float, long, double)
|
||||
val primitiveIrTypes = listOf(booleanType, charType, byteType, shortType, intType, floatType, longType, doubleType)
|
||||
private val primitiveIrTypesWithComparisons = listOf(charType, byteType, shortType, intType, floatType, longType, doubleType)
|
||||
private val primitiveFloatingPointIrTypes = listOf(floatType, doubleType)
|
||||
val primitiveArrays = PrimitiveType.values().map { builtIns.getPrimitiveArrayClassDescriptor(it).toIrSymbol() }
|
||||
val primitiveArrayElementTypes = primitiveArrays.zip(primitiveIrTypes).toMap()
|
||||
val primitiveArrayForType = primitiveArrayElementTypes.asSequence().associate { it.value to it.key }
|
||||
@@ -195,96 +320,45 @@ class IrBuiltIns(
|
||||
PrimitiveType.DOUBLE to doubleType
|
||||
)
|
||||
|
||||
val lessFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.LESS)
|
||||
val lessOrEqualFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.LESS_OR_EQUAL)
|
||||
val greaterOrEqualFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.GREATER_OR_EQUAL)
|
||||
val greaterFunByOperandType = primitiveTypesWithComparisons.defineComparisonOperatorForEachType(OperatorNames.GREATER)
|
||||
val lessFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.LESS)
|
||||
val lessOrEqualFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.LESS_OR_EQUAL)
|
||||
val greaterOrEqualFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.GREATER_OR_EQUAL)
|
||||
val greaterFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(OperatorNames.GREATER)
|
||||
|
||||
val ieee754equalsFunByOperandType =
|
||||
primitiveFloatingPointTypes.associateWith {
|
||||
defineOperator(OperatorNames.IEEE754_EQUALS, bool, listOf(it.makeNullable(), it.makeNullable()))
|
||||
}
|
||||
primitiveFloatingPointIrTypes.map {
|
||||
it.classifierOrFail to defineOperator(OperatorNames.IEEE754_EQUALS, booleanType, listOf(it.makeNullable(), it.makeNullable()))
|
||||
}.toMap()
|
||||
|
||||
val booleanNot = builtIns.boolean.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("not"), NoLookupLocation.FROM_BACKEND).single()
|
||||
private val booleanNot = builtIns.boolean.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("not"), NoLookupLocation.FROM_BACKEND).single()
|
||||
val booleanNotSymbol = symbolTable.referenceSimpleFunction(booleanNot)
|
||||
|
||||
val eqeqeqSymbol = defineOperator(OperatorNames.EQEQEQ, bool, listOf(anyN, anyN))
|
||||
val eqeqSymbol = defineOperator(OperatorNames.EQEQ, bool, listOf(anyN, anyN))
|
||||
val throwCceSymbol = defineOperator(OperatorNames.THROW_CCE, nothing, listOf())
|
||||
val throwIseSymbol = defineOperator(OperatorNames.THROW_ISE, nothing, listOf())
|
||||
val andandSymbol = defineOperator(OperatorNames.ANDAND, bool, listOf(bool, bool))
|
||||
val ororSymbol = defineOperator(OperatorNames.OROR, bool, listOf(bool, bool))
|
||||
val noWhenBranchMatchedExceptionSymbol = defineOperator(OperatorNames.NO_WHEN_BRANCH_MATCHED_EXCEPTION, nothing, listOf())
|
||||
val illegalArgumentExceptionSymbol = defineOperator(OperatorNames.ILLEGAL_ARGUMENT_EXCEPTION, nothing, listOf(string))
|
||||
val eqeqeqSymbol = defineOperator(OperatorNames.EQEQEQ, booleanType, listOf(anyNType, anyNType))
|
||||
val eqeqSymbol = defineOperator(OperatorNames.EQEQ, booleanType, listOf(anyNType, anyNType))
|
||||
val throwCceSymbol = defineOperator(OperatorNames.THROW_CCE, nothingType, listOf())
|
||||
val throwIseSymbol = defineOperator(OperatorNames.THROW_ISE, nothingType, listOf())
|
||||
val andandSymbol = defineOperator(OperatorNames.ANDAND, booleanType, listOf(booleanType, booleanType))
|
||||
val ororSymbol = defineOperator(OperatorNames.OROR, booleanType, listOf(booleanType, booleanType))
|
||||
val noWhenBranchMatchedExceptionSymbol = defineOperator(OperatorNames.NO_WHEN_BRANCH_MATCHED_EXCEPTION, nothingType, listOf())
|
||||
val illegalArgumentExceptionSymbol = defineOperator(OperatorNames.ILLEGAL_ARGUMENT_EXCEPTION, nothingType, listOf(stringType))
|
||||
|
||||
val eqeqeq = eqeqeqSymbol.descriptor
|
||||
val eqeq = eqeqSymbol.descriptor
|
||||
val throwCce = throwCceSymbol.descriptor
|
||||
val noWhenBranchMatchedException = noWhenBranchMatchedExceptionSymbol.descriptor
|
||||
val illegalArgumentException = illegalArgumentExceptionSymbol.descriptor
|
||||
val enumValueOfSymbol = defineEnumValueOfOperator()
|
||||
val checkNotNullSymbol = defineCheckNotNullOperator()
|
||||
|
||||
val enumValueOfSymbol =
|
||||
SimpleFunctionDescriptorImpl.create(
|
||||
packageFragment,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier("enumValueOf"),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE
|
||||
).apply {
|
||||
val typeParameterT = TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||
this, Annotations.EMPTY, true, Variance.INVARIANT, Name.identifier("T"), 0
|
||||
)
|
||||
|
||||
val valueParameterName = ValueParameterDescriptorImpl(
|
||||
this, null, 0, Annotations.EMPTY, Name.identifier("name"), builtIns.stringType,
|
||||
false, false, false, null, SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
val returnType = typeParameterT.typeConstructor.makeNonNullType()
|
||||
|
||||
initialize(null, null, listOf(typeParameterT), listOf(valueParameterName), returnType, Modality.FINAL, Visibilities.PUBLIC)
|
||||
}.addStub()
|
||||
val enumValueOf = enumValueOfSymbol.descriptor
|
||||
|
||||
val checkNotNullSymbol =
|
||||
SimpleFunctionDescriptorImpl.create(
|
||||
packageFragment,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier("CHECK_NOT_NULL"),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE
|
||||
).apply {
|
||||
val typeParameterT = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||
this, Annotations.EMPTY, false, Variance.INVARIANT, Name.identifier("T"), 0, SourceElement.NO_SOURCE
|
||||
).apply {
|
||||
addUpperBound(builtIns.anyType)
|
||||
setInitialized()
|
||||
}
|
||||
|
||||
val valueParameterX = ValueParameterDescriptorImpl(
|
||||
this, null, 0, Annotations.EMPTY, Name.identifier("x"), typeParameterT.typeConstructor.makeNullableType(),
|
||||
false, false, false, null, SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
initialize(
|
||||
null, null,
|
||||
listOf(typeParameterT), listOf(valueParameterX), typeParameterT.typeConstructor.makeNonNullType(),
|
||||
Modality.FINAL, Visibilities.PUBLIC
|
||||
)
|
||||
}.addStub()
|
||||
val checkNotNull = checkNotNullSymbol.descriptor
|
||||
|
||||
private fun TypeConstructor.makeNonNullType() = KotlinTypeFactory.simpleType(Annotations.EMPTY, this, listOf(), false)
|
||||
private fun TypeConstructor.makeNullableType() = KotlinTypeFactory.simpleType(Annotations.EMPTY, this, listOf(), true)
|
||||
|
||||
val dataClassArrayMemberHashCodeSymbol = defineOperator("dataClassArrayMemberHashCode", int, listOf(any))
|
||||
val dataClassArrayMemberHashCodeSymbol = defineOperator("dataClassArrayMemberHashCode", intType, listOf(anyType))
|
||||
val dataClassArrayMemberHashCode = dataClassArrayMemberHashCodeSymbol.descriptor
|
||||
|
||||
val dataClassArrayMemberToStringSymbol = defineOperator("dataClassArrayMemberToString", string, listOf(anyN))
|
||||
val dataClassArrayMemberToStringSymbol = defineOperator("dataClassArrayMemberToString", stringType, listOf(anyNType))
|
||||
val dataClassArrayMemberToString = dataClassArrayMemberToStringSymbol.descriptor
|
||||
|
||||
companion object {
|
||||
val KOTLIN_INTERNAL_IR_FQN = FqName("kotlin.internal.ir")
|
||||
val BUILTIN_OPERATOR = object : IrDeclarationOriginImpl("OPERATOR") {}
|
||||
}
|
||||
|
||||
object OperatorNames {
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionBase
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
interface IrBuiltinWithMangle : IrDeclaration, IrSymbolOwner {
|
||||
val mangle: String
|
||||
}
|
||||
|
||||
class IrBuiltInOperator(
|
||||
override val symbol: IrSimpleFunctionSymbol,
|
||||
name: Name,
|
||||
returnType: IrType,
|
||||
val suffix: String
|
||||
) : IrSimpleFunction, IrBuiltinWithMangle, IrFunctionBase(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrBuiltIns.BUILTIN_OPERATOR, name, Visibilities.PUBLIC, false, false, false, returnType
|
||||
) {
|
||||
override val modality get() = Modality.FINAL
|
||||
override val isTailrec get() = false
|
||||
override val isSuspend get() = false
|
||||
override val isFakeOverride get() = false
|
||||
override var correspondingPropertySymbol: IrPropertySymbol?
|
||||
get() = null
|
||||
set(_) {}
|
||||
override val descriptor: FunctionDescriptor get() = symbol.descriptor
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitSimpleFunction(this, data)
|
||||
}
|
||||
|
||||
override val overriddenSymbols: MutableList<IrSimpleFunctionSymbol> = SmartList()
|
||||
override val mangle: String get() = "operator#$name@$suffix"
|
||||
|
||||
init {
|
||||
symbol.bind(this)
|
||||
}
|
||||
}
|
||||
|
||||
class IrBuiltInOperatorValueParameter(override val symbol: IrValueParameterSymbol, override val index: Int, override val type: IrType) :
|
||||
IrValueParameter, IrDeclarationBase(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrBuiltIns.BUILTIN_OPERATOR) {
|
||||
override val descriptor: ParameterDescriptor get() = symbol.descriptor
|
||||
override val varargElementType: IrType? get() = null
|
||||
override val isCrossinline: Boolean get() = false
|
||||
override val isNoinline: Boolean get() = false
|
||||
override var defaultValue: IrExpressionBody?
|
||||
get() = null
|
||||
set(_) {}
|
||||
override val name: Name = Name.identifier("arg$index")
|
||||
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D) =
|
||||
transformer.visitValueParameter(this, data) as IrValueParameter
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = visitor.visitValueParameter(this, data)
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {}
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {}
|
||||
|
||||
init {
|
||||
symbol.bind(this)
|
||||
}
|
||||
}
|
||||
|
||||
class IrBuiltInOperatorTypeParameter(
|
||||
override val symbol: IrTypeParameterSymbol,
|
||||
override val variance: Variance,
|
||||
override val index: Int,
|
||||
override val isReified: Boolean
|
||||
) : IrTypeParameter, IrDeclarationBase(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrBuiltIns.BUILTIN_OPERATOR) {
|
||||
override val descriptor: TypeParameterDescriptor get() = symbol.descriptor
|
||||
override val superTypes: MutableList<IrType> = SmartList()
|
||||
override val name: Name = Name.identifier("T$index")
|
||||
|
||||
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrTypeParameter =
|
||||
transformer.visitTypeParameter(this, data) as IrTypeParameter
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = visitor.visitTypeParameter(this, data)
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {}
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {}
|
||||
|
||||
init {
|
||||
symbol.bind(this)
|
||||
}
|
||||
}
|
||||
+3
-5
@@ -35,14 +35,12 @@ abstract class GlobalDeclarationTable(private val mangler: KotlinMangler, privat
|
||||
|
||||
constructor(mangler: KotlinMangler) : this(mangler, UniqIdClashTracker.DEFAULT_TRACKER)
|
||||
|
||||
protected open fun loadKnownBuiltins(builtIns: IrBuiltIns, startIndex: Long): Long {
|
||||
var index = startIndex
|
||||
protected fun loadKnownBuiltins(builtIns: IrBuiltIns) {
|
||||
val mask = 1L shl 63
|
||||
builtIns.knownBuiltins.forEach {
|
||||
table[it.owner] = UniqId(index or mask).also { id -> clashTracker.commit(it.owner, id) }
|
||||
index++
|
||||
val index = with(mangler) { it.mangle.hashMangle }
|
||||
table[it] = UniqId(index or mask).also { id -> clashTracker.commit(it, id) }
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
open fun computeUniqIdByDeclaration(declaration: IrDeclaration): UniqId {
|
||||
|
||||
+9
-9
@@ -51,7 +51,7 @@ abstract class KotlinIrLinker(
|
||||
val symbolTable: SymbolTable,
|
||||
private val exportedDependencies: List<ModuleDescriptor>,
|
||||
private val forwardModuleDescriptor: ModuleDescriptor?,
|
||||
private val firstKnownBuiltinsIndex: Long
|
||||
mangler: KotlinMangler
|
||||
) : DescriptorUniqIdAware, IrDeserializer {
|
||||
|
||||
|
||||
@@ -472,18 +472,18 @@ abstract class KotlinIrLinker(
|
||||
|
||||
protected abstract val descriptorReferenceDeserializer: DescriptorReferenceDeserializer
|
||||
|
||||
protected val indexAfterKnownBuiltins = loadKnownBuiltinSymbols()
|
||||
|
||||
private fun loadKnownBuiltinSymbols(): Long {
|
||||
var currentIndex = firstKnownBuiltinsIndex
|
||||
private fun loadKnownBuiltinSymbols(mangler: KotlinMangler) {
|
||||
val mask = 1L shl 63
|
||||
val globalDeserializedSymbols = globalDeserializationState.deserializedSymbols
|
||||
builtIns.knownBuiltins.forEach {
|
||||
globalDeserializedSymbols[UniqId(currentIndex or mask)] = it
|
||||
assert(symbolTable.referenceSimpleFunction(it.descriptor) == it)
|
||||
currentIndex++
|
||||
val currentIndex = with(mangler) { it.mangle.hashMangle }
|
||||
globalDeserializedSymbols[UniqId(currentIndex or mask)] = it.symbol
|
||||
assert(symbolTable.referenceSimpleFunction(it.symbol.descriptor as SimpleFunctionDescriptor).owner === it)
|
||||
}
|
||||
return currentIndex
|
||||
}
|
||||
|
||||
init {
|
||||
loadKnownBuiltinSymbols(mangler)
|
||||
}
|
||||
|
||||
private val ByteArray.codedInputStream: org.jetbrains.kotlin.protobuf.CodedInputStream
|
||||
|
||||
+1
-1
@@ -41,6 +41,6 @@ class JsUniqIdClashTracker : UniqIdClashTracker {
|
||||
|
||||
class JsGlobalDeclarationTable(builtIns: IrBuiltIns) : GlobalDeclarationTable(JsMangler, JsUniqIdClashTracker()) {
|
||||
init {
|
||||
loadKnownBuiltins(builtIns, PUBLIC_LOCAL_UNIQ_ID_EDGE)
|
||||
loadKnownBuiltins(builtIns)
|
||||
}
|
||||
}
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
||||
|
||||
internal const val PUBLIC_LOCAL_UNIQ_ID_EDGE = 0x7FFF_FFFF_FFFF_FFFFL + 1L
|
||||
+1
-1
@@ -22,7 +22,7 @@ class JsIrLinker(
|
||||
logger: LoggingContext,
|
||||
builtIns: IrBuiltIns,
|
||||
symbolTable: SymbolTable
|
||||
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, PUBLIC_LOCAL_UNIQ_ID_EDGE),
|
||||
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, mangler),
|
||||
DescriptorUniqIdAware by DeserializedDescriptorUniqIdAware {
|
||||
|
||||
override val descriptorReferenceDeserializer =
|
||||
|
||||
@@ -3,6 +3,6 @@ FILE fqName:<root> fileName:/dynamicExclExclOperator.kt
|
||||
VALUE_PARAMETER name:d index:0 type:dynamic
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test (d: dynamic): dynamic declared in <root>'
|
||||
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=dynamic origin=EXCLEXCL
|
||||
<T>: dynamic
|
||||
x: GET_VAR 'd: dynamic declared in <root>.test' type=dynamic origin=null
|
||||
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=dynamic origin=EXCLEXCL
|
||||
<T0>: dynamic
|
||||
arg0: GET_VAR 'd: dynamic declared in <root>.test' type=dynamic origin=null
|
||||
|
||||
+15
-15
@@ -3,16 +3,16 @@ FILE fqName:<root> fileName:/bangbang.kt
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Any?
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test1 (a: kotlin.Any?): kotlin.Any declared in <root>'
|
||||
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Any origin=EXCLEXCL
|
||||
<T>: kotlin.Any
|
||||
x: GET_VAR 'a: kotlin.Any? declared in <root>.test1' type=kotlin.Any? origin=null
|
||||
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Any origin=EXCLEXCL
|
||||
<T0>: kotlin.Any
|
||||
arg0: GET_VAR 'a: kotlin.Any? declared in <root>.test1' type=kotlin.Any? origin=null
|
||||
FUN name:test2 visibility:public modality:FINAL <> (a:kotlin.Any?) returnType:kotlin.Int
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Any?
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test2 (a: kotlin.Any?): kotlin.Int declared in <root>'
|
||||
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Int origin=EXCLEXCL
|
||||
<T>: kotlin.Int
|
||||
x: BLOCK type=kotlin.Int? origin=SAFE_CALL
|
||||
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Int origin=EXCLEXCL
|
||||
<T0>: kotlin.Int
|
||||
arg0: BLOCK type=kotlin.Int? origin=SAFE_CALL
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Any? [val]
|
||||
GET_VAR 'a: kotlin.Any? declared in <root>.test2' type=kotlin.Any? origin=null
|
||||
WHEN type=kotlin.Int? origin=null
|
||||
@@ -30,9 +30,9 @@ FILE fqName:<root> fileName:/bangbang.kt
|
||||
VALUE_PARAMETER name:a index:0 type:X of <root>.test3
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test3 <X> (a: X of <root>.test3): X of <root>.test3 declared in <root>'
|
||||
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test3 origin=EXCLEXCL
|
||||
<T>: X of <root>.test3
|
||||
x: GET_VAR 'a: X of <root>.test3 declared in <root>.test3' type=X of <root>.test3 origin=null
|
||||
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test3 origin=EXCLEXCL
|
||||
<T0>: X of <root>.test3
|
||||
arg0: GET_VAR 'a: X of <root>.test3 declared in <root>.test3' type=X of <root>.test3 origin=null
|
||||
FUN name:useString visibility:public modality:FINAL <> (s:kotlin.String) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:s index:0 type:kotlin.String
|
||||
BLOCK_BODY
|
||||
@@ -45,15 +45,15 @@ FILE fqName:<root> fileName:/bangbang.kt
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.String?
|
||||
GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
|
||||
then: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test4 origin=EXCLEXCL
|
||||
<T>: X of <root>.test4
|
||||
x: GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
|
||||
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test4 origin=EXCLEXCL
|
||||
<T0>: X of <root>.test4
|
||||
arg0: GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
|
||||
WHEN type=kotlin.Unit origin=IF
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.String?
|
||||
GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
|
||||
then: CALL 'public final fun useString (s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
s: TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String
|
||||
CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test4 origin=EXCLEXCL
|
||||
<T>: X of <root>.test4
|
||||
x: GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
|
||||
CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=X of <root>.test4 origin=EXCLEXCL
|
||||
<T0>: X of <root>.test4
|
||||
arg0: GET_VAR 'a: X of <root>.test4 declared in <root>.test4' type=X of <root>.test4 origin=null
|
||||
|
||||
+3
-3
@@ -9,9 +9,9 @@ FILE fqName:<root> fileName:/eqeqRhsConditionPossiblyAffectingLhs.kt
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=NOT_INSTANCEOF typeOperand=kotlin.Double
|
||||
GET_VAR 'x: kotlin.Any declared in <root>.test' type=kotlin.Any origin=null
|
||||
then: CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Nothing origin=EXCLEXCL
|
||||
<T>: kotlin.Nothing
|
||||
x: CONST Null type=kotlin.Nothing? value=null
|
||||
then: CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.Nothing origin=EXCLEXCL
|
||||
<T0>: kotlin.Nothing
|
||||
arg0: CONST Null type=kotlin.Nothing? value=null
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
|
||||
|
||||
+6
-6
@@ -51,9 +51,9 @@ FILE fqName:<root> fileName:/kt30020.kt
|
||||
element: CONST Int type=kotlin.Int value=4
|
||||
CALL 'public final fun plusAssign <T> (element: T of kotlin.collections.plusAssign): kotlin.Unit [inline] declared in kotlin.collections' type=kotlin.Unit origin=PLUSEQ
|
||||
<T>: kotlin.Int
|
||||
$receiver: CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.collections.MutableList<kotlin.Any> origin=EXCLEXCL
|
||||
<T>: kotlin.collections.MutableList<kotlin.Any>
|
||||
x: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL
|
||||
$receiver: CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.collections.MutableList<kotlin.Any> origin=EXCLEXCL
|
||||
<T0>: kotlin.collections.MutableList<kotlin.Any>
|
||||
arg0: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:<root>.X? [val]
|
||||
GET_VAR 'nx: <root>.X? declared in <root>.test' type=<root>.X? origin=null
|
||||
WHEN type=kotlin.collections.MutableList<kotlin.Any>? origin=null
|
||||
@@ -69,9 +69,9 @@ FILE fqName:<root> fileName:/kt30020.kt
|
||||
element: CONST Int type=kotlin.Int value=5
|
||||
CALL 'public final fun plusAssign <T> (element: T of kotlin.collections.plusAssign): kotlin.Unit [inline] declared in kotlin.collections' type=kotlin.Unit origin=PLUSEQ
|
||||
<T>: kotlin.Int
|
||||
$receiver: CALL 'public final fun CHECK_NOT_NULL <T> (x: T of kotlin.internal.ir.CHECK_NOT_NULL?): T of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.collections.MutableList<kotlin.Any> origin=EXCLEXCL
|
||||
<T>: kotlin.collections.MutableList<kotlin.Any>
|
||||
x: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL
|
||||
$receiver: CALL 'public final fun CHECK_NOT_NULL <T0> (arg0: T0 of kotlin.internal.ir.CHECK_NOT_NULL?): T0 of kotlin.internal.ir.CHECK_NOT_NULL declared in kotlin.internal.ir' type=kotlin.collections.MutableList<kotlin.Any> origin=EXCLEXCL
|
||||
<T0>: kotlin.collections.MutableList<kotlin.Any>
|
||||
arg0: BLOCK type=kotlin.collections.MutableList<kotlin.Any>? origin=SAFE_CALL
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:<root>.X? [val]
|
||||
GET_VAR 'nx: <root>.X? declared in <root>.test' type=<root>.X? origin=null
|
||||
WHEN type=kotlin.collections.MutableList<kotlin.Any>? origin=null
|
||||
|
||||
Reference in New Issue
Block a user