From 86a52e6426e11667004889297c85ed87f9b73436 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 30 Aug 2016 13:35:02 +0300 Subject: [PATCH] Character literals and string templates. --- .../psi2ir/generators/StatementGenerator.kt | 27 ++++++++------- .../kotlin/ir/expressions/IrConst.kt | 12 ++++--- .../ir/irText/expressions/literals.kt | 3 +- .../ir/irText/expressions/literals.txt | 3 ++ .../ir/irText/expressions/stringTemplates.kt | 10 ++++++ .../ir/irText/expressions/stringTemplates.txt | 33 +++++++++++++++++++ .../kotlin/ir/IrTextTestCaseGenerated.java | 6 ++++ 7 files changed, 76 insertions(+), 18 deletions(-) create mode 100644 compiler/testData/ir/irText/expressions/stringTemplates.kt create mode 100644 compiler/testData/ir/irText/expressions/stringTemplates.txt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt index de24ae299c2..2b15573fa89 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt @@ -172,6 +172,8 @@ class StatementGenerator( IrConstImpl.double(expression.startOffset, expression.endOffset, constantType, constantValue.value) is FloatValue -> IrConstImpl.float(expression.startOffset, expression.endOffset, constantType, constantValue.value) + is CharValue -> + IrConstImpl.char(expression.startOffset, expression.endOffset, constantType, constantValue.value) else -> TODO("handle other literal types: ${constantValue.type}") } @@ -179,28 +181,29 @@ class StatementGenerator( override fun visitStringTemplateExpression(expression: KtStringTemplateExpression, data: Nothing?): IrStatement { val entries = expression.entries - when { - entries.size == 1 -> { - val entry0 = entries[0] - if (entry0 is KtLiteralStringTemplateEntry) { - return entry0.genExpr() - } - } - entries.size == 0 -> { - return IrConstImpl.string(expression.startOffset, expression.endOffset, - getInferredTypeWithImplicitCastsOrFail(expression), "") - } + when (entries.size) { + 1 -> return entries[0].genExpr() + 0 -> return IrConstImpl.string(expression.startOffset, expression.endOffset, + getInferredTypeWithImplicitCastsOrFail(expression), "") } val irStringTemplate = IrStringConcatenationImpl(expression.startOffset, expression.endOffset, getInferredTypeWithImplicitCastsOrFail(expression)) - entries.forEach { it.expression!!.let { irStringTemplate.addArgument(it.genExpr()) } } + entries.forEach { + irStringTemplate.addArgument(it.genExpr()) + } return irStringTemplate } override fun visitLiteralStringTemplateEntry(entry: KtLiteralStringTemplateEntry, data: Nothing?): IrStatement = IrConstImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.text) + override fun visitEscapeStringTemplateEntry(entry: KtEscapeStringTemplateEntry, data: Nothing?): IrStatement = + IrConstImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.unescapedValue) + + override fun visitStringTemplateEntryWithExpression(entry: KtStringTemplateEntryWithExpression, data: Nothing?): IrStatement = + entry.expression!!.genExpr() + override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, data: Nothing?): IrExpression { val resolvedCall = getResolvedCall(expression) ?: throw AssertionError("No resolved call for ${expression.text}") diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrConst.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrConst.kt index d51ab6eba40..4f87998d69e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrConst.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrConst.kt @@ -19,22 +19,21 @@ package org.jetbrains.kotlin.ir.expressions import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType -interface IrConst : IrExpression, IrExpressionWithCopy { +interface IrConst : IrExpression, IrExpressionWithCopy { val kind: IrConstKind val value: T override fun copy(): IrConst } -sealed class IrConstKind(val asString: kotlin.String) { +sealed class IrConstKind(val asString: kotlin.String) { @Suppress("UNCHECKED_CAST") fun valueOf(aConst: IrConst<*>) = (aConst as IrConst).value object Null : IrConstKind("Null") object Boolean : IrConstKind("Boolean") - object Byte : IrConstKind("Byte") - object Short : IrConstKind("Short") + object Char : IrConstKind("Char") object Int : IrConstKind("Int") object Long : IrConstKind("Long") object String : IrConstKind("String") @@ -44,7 +43,7 @@ sealed class IrConstKind(val asString: kotlin.String) { override fun toString() = asString } -class IrConstImpl ( +class IrConstImpl ( startOffset: Int, endOffset: Int, type: KotlinType, @@ -84,6 +83,9 @@ class IrConstImpl ( fun double(startOffset: Int, endOffset: Int, type: KotlinType, value: Double): IrExpression = IrConstImpl(startOffset, endOffset, type, IrConstKind.Double, value) + + fun char(startOffset: Int, endOffset: Int, type: KotlinType, value: Char): IrExpression = + IrConstImpl(startOffset, endOffset, type, IrConstKind.Char, value) } } diff --git a/compiler/testData/ir/irText/expressions/literals.kt b/compiler/testData/ir/irText/expressions/literals.kt index 1b80a5cb441..2d660548150 100644 --- a/compiler/testData/ir/irText/expressions/literals.kt +++ b/compiler/testData/ir/irText/expressions/literals.kt @@ -9,4 +9,5 @@ val test8 = -1L val test9 = 1.0 val test10 = -1.0 val test11 = 1.0f -val test12 = -1.0f \ No newline at end of file +val test12 = -1.0f +val test13 = 'a' \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/literals.txt b/compiler/testData/ir/irText/expressions/literals.txt index ebf22f44f89..e72b0ddf8b8 100644 --- a/compiler/testData/ir/irText/expressions/literals.txt +++ b/compiler/testData/ir/irText/expressions/literals.txt @@ -35,3 +35,6 @@ FILE /literals.kt PROPERTY public val test12: kotlin.Float = -1.0.toFloat() getter=null setter=null EXPRESSION_BODY CONST Float type=kotlin.Float value='-1.0' + PROPERTY public val test13: kotlin.Char = \u0061 ('a') getter=null setter=null + EXPRESSION_BODY + CONST Char type=kotlin.Char value='a' diff --git a/compiler/testData/ir/irText/expressions/stringTemplates.kt b/compiler/testData/ir/irText/expressions/stringTemplates.kt new file mode 100644 index 00000000000..c8a65990d65 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/stringTemplates.kt @@ -0,0 +1,10 @@ +fun foo(): String = "" + +val test1 = "" +val test2 = "abc" +val test3 = """""" +val test4 = """abc""" +val test5 = """ +abc +""" +val test6 = "$test1 ${foo()}" \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/stringTemplates.txt b/compiler/testData/ir/irText/expressions/stringTemplates.txt new file mode 100644 index 00000000000..d1ed1bf8907 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/stringTemplates.txt @@ -0,0 +1,33 @@ +FILE /stringTemplates.kt + FUN public fun foo(): kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from=foo + CONST String type=kotlin.String value='' + PROPERTY public val test1: kotlin.String = "" getter=null setter=null + EXPRESSION_BODY + CONST String type=kotlin.String value='' + PROPERTY public val test2: kotlin.String = "abc" getter=null setter=null + EXPRESSION_BODY + CONST String type=kotlin.String value='abc' + PROPERTY public val test3: kotlin.String = "" getter=null setter=null + EXPRESSION_BODY + CONST String type=kotlin.String value='' + PROPERTY public val test4: kotlin.String = "abc" getter=null setter=null + EXPRESSION_BODY + CONST String type=kotlin.String value='abc' + PROPERTY public val test5: kotlin.String = " +abc +" getter=null setter=null + EXPRESSION_BODY + STRING_CONCATENATION type=kotlin.String + CONST String type=kotlin.String value=' +' + CONST String type=kotlin.String value='abc' + CONST String type=kotlin.String value=' +' + PROPERTY public val test6: kotlin.String getter=null setter=null + EXPRESSION_BODY + STRING_CONCATENATION type=kotlin.String + CALL . type=kotlin.String operator=GET_PROPERTY + CONST String type=kotlin.String value=' ' + CALL .foo type=kotlin.String operator=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 2c5eff60a0c..ca36396a494 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -382,6 +382,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } + @TestMetadata("stringTemplates.kt") + public void testStringTemplates() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/stringTemplates.kt"); + doTest(fileName); + } + @TestMetadata("throw.kt") public void testThrow() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/throw.kt");