JS: fix char to string convertion in string templates (#KT-17966 fixed)

This commit is contained in:
Anton Bannykh
2017-05-21 14:13:44 +03:00
parent 6a8bb8b33d
commit 419f12f1b7
3 changed files with 45 additions and 11 deletions
@@ -422,6 +422,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
doTest(fileName);
}
@TestMetadata("charInStringTemplate.kt")
public void testCharInStringTemplate() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/char/charInStringTemplate.kt");
doTest(fileName);
}
@TestMetadata("charIsCheck.kt")
public void testCharIsCheck() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/char/charIsCheck.kt");
@@ -16,16 +16,14 @@
package org.jetbrains.kotlin.js.translate.expression;
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
import org.jetbrains.kotlin.js.backend.ast.JsInvocation;
import org.jetbrains.kotlin.js.backend.ast.JsNameRef;
import org.jetbrains.kotlin.js.backend.ast.JsNumberLiteral;
import org.jetbrains.kotlin.js.backend.ast.*;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.js.descriptorUtils.DescriptorUtilsKt;
import org.jetbrains.kotlin.js.patterns.NamePredicate;
import org.jetbrains.kotlin.js.translate.context.TemporaryVariable;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.js.translate.general.Translation;
@@ -87,17 +85,23 @@ public final class StringTemplateTranslator extends AbstractTranslator {
KotlinType type = context().bindingContext().getType(entryExpression);
if (translatedExpression instanceof JsNumberLiteral) {
if (type != null && KotlinBuiltIns.isCharOrNullableChar(type)) {
if (type.isMarkedNullable()) {
TemporaryVariable tmp = context().declareTemporary(translatedExpression);
append(new JsConditional(JsAstUtils.equality(tmp.assignmentExpression(), JsLiteral.NULL),
JsLiteral.NULL,
JsAstUtils.charToString(tmp.reference())));
}
else {
append(JsAstUtils.charToString(translatedExpression));
}
}
else if (translatedExpression instanceof JsNumberLiteral) {
append(context().program().getStringLiteral(translatedExpression.toString()));
return;
}
if (type == null || type.isMarkedNullable()) {
else if (type == null || type.isMarkedNullable()) {
append(TopLevelFIF.TO_STRING.apply((JsExpression) null, new SmartList<>(translatedExpression), context()));
}
else if (KotlinBuiltIns.isChar(type)) {
append(JsAstUtils.charToString(translatedExpression));
}
else if (mustCallToString(type)) {
append(new JsInvocation(new JsNameRef("toString", translatedExpression)));
}
@@ -0,0 +1,24 @@
package foo
var log = ""
fun sideEffects(c: Char?, msg: String): Char? {
log += msg
return c
}
fun box(): String {
val name = run { "John" } // Force compiler to actually do some concatenation
assertEquals("${'$'}name = $name", "\$name = John")
val ch1: Char? = null
assertEquals("${ch1}name = $name", "nullname = John")
val ch2: Char? = '$'
assertEquals("${ch2}name = $name", "\$name = John")
assertEquals("${sideEffects('$', "1")!!}${sideEffects('n', "2")}ame = $name", "\$name = John")
assertEquals(log, "12")
return "OK"
}