From 2663d9751a0acc326a68da1f60c9de8db07860dc Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Fri, 17 Aug 2018 14:25:23 +0300 Subject: [PATCH] JS: support unsigned constants inside string templates --- .../evaluate/ConstantExpressionEvaluator.kt | 2 +- .../unsignedTypeValuesInsideStringTemplates.kt | 7 ++++++- .../kotlin/resolve/constants/constantValues.kt | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt index 4be229843e9..eb1435045cc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt @@ -365,7 +365,7 @@ private class ConstantExpressionEvaluatorVisitor( return when (constantValue) { is ErrorValue, is EnumValue -> return null is NullValue -> StringValue("null") - else -> StringValue(constantValue.value.toString()) + else -> StringValue(constantValue.stringTemplateValue()) }.wrap(compileTimeConstant.parameters) } diff --git a/compiler/testData/codegen/box/unsignedTypes/unsignedTypeValuesInsideStringTemplates.kt b/compiler/testData/codegen/box/unsignedTypes/unsignedTypeValuesInsideStringTemplates.kt index a9fe317f0d2..b930ca88b04 100644 --- a/compiler/testData/codegen/box/unsignedTypes/unsignedTypeValuesInsideStringTemplates.kt +++ b/compiler/testData/codegen/box/unsignedTypes/unsignedTypeValuesInsideStringTemplates.kt @@ -1,13 +1,18 @@ // WITH_UNSIGNED -// IGNORE_BACKEND: JVM_IR, JS_IR, JS +// IGNORE_BACKEND: JVM_IR, JS_IR const val MAX_BYTE: UByte = 0xFFu const val HUNDRED: UByte = 100u +const val MAX_LONG: ULong = ULong.MAX_VALUE + fun box(): String { val maxByteStringSingle = "$MAX_BYTE" if (maxByteStringSingle != MAX_BYTE.toString() || maxByteStringSingle != "255") return "Fail 1: $maxByteStringSingle" + val maxLongStringSingle = "$MAX_LONG" + if (maxLongStringSingle != MAX_LONG.toString() || maxLongStringSingle != "18446744073709551615") return "Fail 1.5: $maxLongStringSingle" + val twoHundredUByte = "${(HUNDRED * 2u).toUByte()}" if (twoHundredUByte != "200") return "Fail 2: $twoHundredUByte" diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt index d1f3cbbffb3..8e7637f0de7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/constants/constantValues.kt @@ -37,6 +37,8 @@ abstract class ConstantValue(open val value: T) { override fun hashCode(): Int = value?.hashCode() ?: 0 override fun toString(): String = value.toString() + + open fun stringTemplateValue(): String = value.toString() } abstract class IntegerValueConstant protected constructor(value: T) : ConstantValue(value) @@ -200,6 +202,8 @@ class UByteValue(byteValue: Byte) : UnsignedValueConstant(byteValue) { override fun accept(visitor: AnnotationArgumentVisitor, data: D): R = visitor.visitUByteValue(this, data) override fun toString() = "$value.toUByte()" + + override fun stringTemplateValue(): String = (value.toInt() and 0xFF).toString() } class UShortValue(shortValue: Short) : UnsignedValueConstant(shortValue) { @@ -211,6 +215,8 @@ class UShortValue(shortValue: Short) : UnsignedValueConstant(shortValue) override fun accept(visitor: AnnotationArgumentVisitor, data: D): R = visitor.visitUShortValue(this, data) override fun toString() = "$value.toUShort()" + + override fun stringTemplateValue(): String = (value.toInt() and 0xFFFF).toString() } class UIntValue(intValue: Int) : UnsignedValueConstant(intValue) { @@ -222,6 +228,8 @@ class UIntValue(intValue: Int) : UnsignedValueConstant(intValue) { override fun accept(visitor: AnnotationArgumentVisitor, data: D) = visitor.visitUIntValue(this, data) override fun toString() = "$value.toUInt()" + + override fun stringTemplateValue(): String = (value.toLong() and 0xFFFFFFFFL).toString() } class ULongValue(longValue: Long) : UnsignedValueConstant(longValue) { @@ -233,4 +241,13 @@ class ULongValue(longValue: Long) : UnsignedValueConstant(longValue) { override fun accept(visitor: AnnotationArgumentVisitor, data: D): R = visitor.visitULongValue(this, data) override fun toString() = "$value.toULong()" + + override fun stringTemplateValue(): String { + if (value >= 0) return value.toString() + + val div10 = (value ushr 1) / 5 + val mod10 = value - 10 * div10 + + return "$div10$mod10" + } }