From 7113523e34ecbeb5631f2fd1067ed8d70fa28548 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Mon, 15 Nov 2021 14:47:49 +0300 Subject: [PATCH] Support interpretation of `trimMargin` and `trimIndent` --- .../intrinsics/IntrinsicEvaluator.kt | 2 +- .../intrinsics/IntrinsicImplementations.kt | 33 +++++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicEvaluator.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicEvaluator.kt index ae6aa8c1ef3..0e44f5f0d95 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicEvaluator.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicEvaluator.kt @@ -15,7 +15,7 @@ internal object IntrinsicEvaluator { private val fqNameToHandler: Map = buildMap { listOf( EmptyArray, ArrayOf, ArrayOfNulls, ArrayConstructor, EnumValues, EnumValueOf, - JsPrimitives, SourceLocation, AssertIntrinsic, DataClassArrayToString + JsPrimitives, SourceLocation, AssertIntrinsic, DataClassArrayToString, Indent ).forEach { intrinsic -> intrinsic.getListOfAcceptableFunctions().forEach { put(it, intrinsic) } } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt index bb575dc641b..8e18346f0a4 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.ir.interpreter.createGetValue import org.jetbrains.kotlin.ir.interpreter.toIrConst import org.jetbrains.kotlin.ir.interpreter.exceptions.handleUserException import org.jetbrains.kotlin.ir.interpreter.exceptions.stop +import org.jetbrains.kotlin.ir.interpreter.exceptions.withExceptionHandler import org.jetbrains.kotlin.ir.interpreter.state.* import org.jetbrains.kotlin.ir.interpreter.state.reflection.KFunctionState import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState @@ -31,8 +32,10 @@ internal sealed class IntrinsicBase { fun customEvaluateInstruction(irFunction: IrFunction, environment: IrInterpreterEnvironment): CustomInstruction { return CustomInstruction { - evaluate(irFunction, environment) - environment.callStack.dropFrameAndCopyResult() + withExceptionHandler(environment) { // Exception handling is used only for indent actions; TODO: drop later + evaluate(irFunction, environment) + environment.callStack.dropFrameAndCopyResult() + } } } } @@ -340,4 +343,28 @@ internal object DataClassArrayToString : IntrinsicBase() { val array = environment.callStack.loadState(irFunction.valueParameters.single().symbol) as Primitive<*> environment.callStack.pushState(environment.convertToState(arrayToString(array.value), irFunction.returnType)) } -} \ No newline at end of file +} + +internal object Indent : IntrinsicBase() { + override fun getListOfAcceptableFunctions(): List { + return listOf( + "kotlin.text.StringsKt.trimIndent", "kotlin.text.trimIndent", + "kotlin.text.StringsKt.trimMargin", "kotlin.text.trimMargin", + "kotlin.text.StringsKt.trimMargin\$default", "kotlin.text.trimMargin\$default", + ) + } + + override fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment) { + val str = environment.callStack.loadState(irFunction.getExtensionReceiver()!!).asString() + val trimmed = when (irFunction.fqName) { + "kotlin.text.StringsKt.trimIndent", "kotlin.text.trimIndent" -> str.trimIndent() + "kotlin.text.StringsKt.trimMargin", "kotlin.text.trimMargin" -> { + val marginPrefix = environment.callStack.loadState(irFunction.valueParameters.single().symbol).asString() + str.trimMargin(marginPrefix) + } + "kotlin.text.StringsKt.trimMargin\$default", "kotlin.text.trimMargin\$default" -> str.trimMargin() + else -> TODO("unknown trim function") + } + environment.callStack.pushState(environment.convertToState(trimmed, irFunction.returnType)) + } +}