Support interpretation of trimMargin and trimIndent

This commit is contained in:
Ivan Kylchik
2021-11-15 14:47:49 +03:00
parent 3bf678a011
commit 7113523e34
2 changed files with 31 additions and 4 deletions
@@ -15,7 +15,7 @@ internal object IntrinsicEvaluator {
private val fqNameToHandler: Map<String, IntrinsicBase> = 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) } }
}
@@ -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))
}
}
}
internal object Indent : IntrinsicBase() {
override fun getListOfAcceptableFunctions(): List<String> {
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))
}
}