Implement instance of check in compile time

This commit is contained in:
Ivan Kylchik
2020-02-11 16:40:57 +03:00
parent 0a70277240
commit d6a45dfe75
@@ -552,13 +552,12 @@ class IrInterpreter(irModule: IrModuleFragment) {
} }
private suspend fun interpretTypeOperatorCall(expression: IrTypeOperatorCall, data: Frame): Code { private suspend fun interpretTypeOperatorCall(expression: IrTypeOperatorCall, data: Frame): Code {
val code = expression.argument.interpret(data).also { if (it != Code.NEXT) return it }
return when (expression.operator) { return when (expression.operator) {
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> { // coercion to unit means that return value isn't used
// coercion to unit means that return value isn't used IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> code
expression.argument.interpret(data).apply { if (this == Code.NEXT) data.popReturnValue() }
}
IrTypeOperator.CAST, IrTypeOperator.IMPLICIT_CAST -> { IrTypeOperator.CAST, IrTypeOperator.IMPLICIT_CAST -> {
val code = expression.argument.interpret(data)
if (!data.peekReturnValue().irClass.defaultType.isSubtypeOf(expression.type, irBuiltIns)) { if (!data.peekReturnValue().irClass.defaultType.isSubtypeOf(expression.type, irBuiltIns)) {
val convertibleClassName = data.popReturnValue().irClass.fqNameForIrSerialization val convertibleClassName = data.popReturnValue().irClass.fqNameForIrSerialization
val castClassName = expression.type.classOrNull?.owner?.fqNameForIrSerialization val castClassName = expression.type.classOrNull?.owner?.fqNameForIrSerialization
@@ -570,13 +569,22 @@ class IrInterpreter(irModule: IrModuleFragment) {
} }
} }
IrTypeOperator.SAFE_CAST -> { IrTypeOperator.SAFE_CAST -> {
val code = expression.argument.interpret(data)
if (!data.peekReturnValue().irClass.defaultType.isSubtypeOf(expression.type, irBuiltIns)) { if (!data.peekReturnValue().irClass.defaultType.isSubtypeOf(expression.type, irBuiltIns)) {
data.popReturnValue() data.popReturnValue()
data.pushReturnValue(null.toState(irBuiltIns.nothingType)) data.pushReturnValue(null.toState(irBuiltIns.nothingType))
} }
code code
} }
IrTypeOperator.INSTANCEOF -> {
val isInstance = data.popReturnValue().irClass.defaultType.isSubtypeOf(expression.typeOperand, irBuiltIns)
data.pushReturnValue(isInstance.toState(irBuiltIns.nothingType))
code
}
IrTypeOperator.NOT_INSTANCEOF -> {
val isInstance = data.popReturnValue().irClass.defaultType.isSubtypeOf(expression.typeOperand, irBuiltIns)
data.pushReturnValue((!isInstance).toState(irBuiltIns.nothingType))
code
}
else -> TODO("${expression.operator} not implemented") else -> TODO("${expression.operator} not implemented")
} }
} }