Fix IR generation for string templates containing single entry.

This commit is contained in:
Dmitry Petrov
2016-09-20 15:24:14 +03:00
parent 1c2a676cd6
commit 291d535de7
4 changed files with 61 additions and 20 deletions
@@ -203,18 +203,20 @@ class StatementGenerator(
override fun visitStringTemplateExpression(expression: KtStringTemplateExpression, data: Nothing?): IrStatement {
val entries = expression.entries
when (entries.size) {
1 -> return entries[0].genExpr()
0 -> return IrConstImpl.string(expression.startOffset, expression.endOffset,
getInferredTypeWithImplicitCastsOrFail(expression), "")
val resultType = getInferredTypeWithImplicitCastsOrFail(expression)
return when (entries.size) {
1 -> {
val irArg = entries[0].genExpr()
if (irArg is IrConst<*> && irArg.kind == IrConstKind.String)
irArg
else
IrStringConcatenationImpl(expression.startOffset, expression.endOffset, resultType, listOf(irArg))
}
0 ->
IrConstImpl.string(expression.startOffset, expression.endOffset, resultType, "")
else ->
IrStringConcatenationImpl(expression.startOffset, expression.endOffset, resultType, entries.map { it.genExpr() })
}
val irStringTemplate = IrStringConcatenationImpl(expression.startOffset, expression.endOffset,
getInferredTypeWithImplicitCastsOrFail(expression))
entries.forEach {
irStringTemplate.addArgument(it.genExpr())
}
return irStringTemplate
}
override fun visitLiteralStringTemplateEntry(entry: KtLiteralStringTemplateEntry, data: Nothing?): IrStatement =
@@ -267,7 +269,7 @@ class StatementGenerator(
IrGetEnumValueImpl(expression.startOffset, expression.endOffset, classValueType, descriptor)
else -> {
IrGetObjectValueImpl(expression.startOffset, expression.endOffset, classValueType,
descriptor.companionObjectDescriptor ?: throw AssertionError("Class value without companion object: $descriptor"))
descriptor.companionObjectDescriptor ?: throw AssertionError("Class value without companion object: $descriptor"))
}
}
}
@@ -16,20 +16,19 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
class IrStringConcatenationImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType
) : IrExpressionBase(startOffset, endOffset, type), IrStringConcatenation {
class IrStringConcatenationImpl(startOffset: Int, endOffset: Int, type: KotlinType) :
IrExpressionBase(startOffset, endOffset, type), IrStringConcatenation {
constructor(startOffset: Int, endOffset: Int, type: KotlinType, arguments: Collection<IrExpression>) : this(startOffset, endOffset, type) {
this.arguments.addAll(arguments)
}
override val arguments: MutableList<IrExpression> = ArrayList()
override fun addArgument(argument: IrExpression) {
+6 -1
View File
@@ -1,4 +1,5 @@
fun foo(): String = ""
val x = 42
val test1 = ""
val test2 = "abc"
@@ -7,4 +8,8 @@ val test4 = """abc"""
val test5 = """
abc
"""
val test6 = "$test1 ${foo()}"
val test6 = "$test1 ${foo()}"
val test7 = "$test1"
val test8 = "${foo()}"
val test9 = "$x"
@@ -3,6 +3,14 @@ FILE /stringTemplates.kt
BLOCK_BODY
RETURN type=kotlin.Nothing from='foo(): String'
CONST String type=kotlin.String value=''
PROPERTY public val x: kotlin.Int = 42
FIELD PROPERTY_BACKING_FIELD public val x: kotlin.Int = 42
EXPRESSION_BODY
CONST Int type=kotlin.Int value='42'
FUN DEFAULT_PROPERTY_ACCESSOR public fun <get-x>(): kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-x>(): Int'
GET_FIELD 'x: Int' type=kotlin.Int origin=null
PROPERTY public val test1: kotlin.String = ""
FIELD PROPERTY_BACKING_FIELD public val test1: kotlin.String = ""
EXPRESSION_BODY
@@ -63,3 +71,30 @@ abc
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-test6>(): String'
GET_FIELD 'test6: String' type=kotlin.String origin=null
PROPERTY public val test7: kotlin.String = ""
FIELD PROPERTY_BACKING_FIELD public val test7: kotlin.String = ""
EXPRESSION_BODY
STRING_CONCATENATION type=kotlin.String
CALL '<get-test1>(): String' type=kotlin.String origin=GET_PROPERTY
FUN DEFAULT_PROPERTY_ACCESSOR public fun <get-test7>(): kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-test7>(): String'
GET_FIELD 'test7: String' type=kotlin.String origin=null
PROPERTY public val test8: kotlin.String
FIELD PROPERTY_BACKING_FIELD public val test8: kotlin.String
EXPRESSION_BODY
STRING_CONCATENATION type=kotlin.String
CALL 'foo(): String' type=kotlin.String origin=null
FUN DEFAULT_PROPERTY_ACCESSOR public fun <get-test8>(): kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-test8>(): String'
GET_FIELD 'test8: String' type=kotlin.String origin=null
PROPERTY public val test9: kotlin.String = "42"
FIELD PROPERTY_BACKING_FIELD public val test9: kotlin.String = "42"
EXPRESSION_BODY
STRING_CONCATENATION type=kotlin.String
CALL '<get-x>(): Int' type=kotlin.Int origin=GET_PROPERTY
FUN DEFAULT_PROPERTY_ACCESSOR public fun <get-test9>(): kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-test9>(): String'
GET_FIELD 'test9: String' type=kotlin.String origin=null