diff --git a/compiler/fir/analysis-tests/testData/builtIns/kotlin.txt b/compiler/fir/analysis-tests/testData/builtIns/kotlin.txt index cd8ac1f710b..66ebfe74410 100644 --- a/compiler/fir/analysis-tests/testData/builtIns/kotlin.txt +++ b/compiler/fir/analysis-tests/testData/builtIns/kotlin.txt @@ -263,6 +263,8 @@ public final class Char : R|kotlin/Comparable|, R|java/io/Serializa @R|kotlin/internal/IntrinsicConstEvaluation|() public open operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| + public open fun hashCode(): R|kotlin/Int| + public final operator fun inc(): R|kotlin/Char| @R|kotlin/internal/IntrinsicConstEvaluation|() public final operator fun minus(other: R|kotlin/Char|): R|kotlin/Int| diff --git a/core/builtins/native/kotlin/Char.kt b/core/builtins/native/kotlin/Char.kt index 15061b08e2c..177b267a548 100644 --- a/core/builtins/native/kotlin/Char.kt +++ b/core/builtins/native/kotlin/Char.kt @@ -1,13 +1,14 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +// Auto-generated file. DO NOT EDIT! + package kotlin /** * Represents a 16-bit Unicode character. - * * On the JVM, non-nullable values of this type are represented as values of the primitive type `char`. */ public class Char private constructor() : Comparable { @@ -27,6 +28,7 @@ public class Char private constructor() : Comparable { /** Subtracts the other Char value from this value resulting an Int. */ @kotlin.internal.IntrinsicConstEvaluation public operator fun minus(other: Char): Int + /** Subtracts the other Int value from this value resulting a Char. */ @kotlin.internal.IntrinsicConstEvaluation public operator fun minus(other: Int): Char @@ -62,29 +64,35 @@ public class Char private constructor() : Comparable { @DeprecatedSinceKotlin(warningSince = "1.5") @kotlin.internal.IntrinsicConstEvaluation public fun toByte(): Byte + /** Returns the value of this character as a `Char`. */ @kotlin.internal.IntrinsicConstEvaluation public fun toChar(): Char + /** Returns the value of this character as a `Short`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toShort()")) @DeprecatedSinceKotlin(warningSince = "1.5") @kotlin.internal.IntrinsicConstEvaluation public fun toShort(): Short + /** Returns the value of this character as a `Int`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code")) @DeprecatedSinceKotlin(warningSince = "1.5") @kotlin.internal.IntrinsicConstEvaluation public fun toInt(): Int + /** Returns the value of this character as a `Long`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toLong()")) @DeprecatedSinceKotlin(warningSince = "1.5") @kotlin.internal.IntrinsicConstEvaluation public fun toLong(): Long + /** Returns the value of this character as a `Float`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toFloat()")) @DeprecatedSinceKotlin(warningSince = "1.5") @kotlin.internal.IntrinsicConstEvaluation public fun toFloat(): Float + /** Returns the value of this character as a `Double`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toDouble()")) @DeprecatedSinceKotlin(warningSince = "1.5") @@ -92,10 +100,12 @@ public class Char private constructor() : Comparable { public fun toDouble(): Double @kotlin.internal.IntrinsicConstEvaluation - public override fun equals(other: Any?): Boolean + public override fun toString(): String @kotlin.internal.IntrinsicConstEvaluation - public override fun toString(): String + public override fun equals(other: Any?): Boolean + + public override fun hashCode(): Int companion object { /** @@ -152,6 +162,4 @@ public class Char private constructor() : Comparable { @SinceKotlin("1.3") public const val SIZE_BITS: Int = 16 } - } - diff --git a/generators/builtins/generateBuiltIns.kt b/generators/builtins/generateBuiltIns.kt index 77fb89afbc1..b748a61fff6 100644 --- a/generators/builtins/generateBuiltIns.kt +++ b/generators/builtins/generateBuiltIns.kt @@ -18,10 +18,7 @@ import org.jetbrains.kotlin.generators.builtins.progressionIterators.GeneratePro import org.jetbrains.kotlin.generators.builtins.progressions.GenerateProgressions import org.jetbrains.kotlin.generators.builtins.ranges.GenerateRanges import org.jetbrains.kotlin.generators.builtins.unsigned.generateUnsignedTypes -import primitives.JsBooleanGenerator -import primitives.JvmBooleanGenerator -import primitives.NativeBooleanGenerator -import primitives.WasmBooleanGenerator +import primitives.* import java.io.File import java.io.PrintWriter @@ -87,6 +84,11 @@ fun generateBuiltIns(generate: (File, (PrintWriter) -> BuiltInsGenerator) -> Uni generate(File(BUILT_INS_NATIVE_DIR_WASM, "kotlin/Boolean.kt")) { WasmBooleanGenerator(it) } generate(File(BUILT_INS_NATIVE_DIR_NATIVE, "kotlin/Boolean.kt")) { NativeBooleanGenerator(it) } + generate(File(BUILT_INS_NATIVE_DIR_JVM, "kotlin/Char.kt")) { JvmCharGenerator(it) } + generate(File(BUILT_INS_NATIVE_DIR_JS, "Char.kt")) { JsCharGenerator(it) } + generate(File(BUILT_INS_NATIVE_DIR_WASM, "kotlin/Char.kt")) { WasmCharGenerator(it) } + generate(File(BUILT_INS_NATIVE_DIR_NATIVE, "kotlin/Char.kt")) { NativeCharGenerator(it) } + generate(File(RUNTIME_JVM_DIR, "kotlin/jvm/functions/Functions.kt")) { GenerateFunctions(it) } generate(File(BUILT_INS_NATIVE_DIR_JVM, "kotlin/Arrays.kt")) { GenerateArrays(it) } generate(File(STDLIB_DIR, "kotlin/collections/PrimitiveIterators.kt")) { GenerateIterators(it) } diff --git a/generators/builtins/primitives/BooleanGenerator.kt b/generators/builtins/primitives/BooleanGenerator.kt index 5a89b84c712..1b6b21d04d8 100644 --- a/generators/builtins/primitives/BooleanGenerator.kt +++ b/generators/builtins/primitives/BooleanGenerator.kt @@ -183,9 +183,11 @@ class WasmBooleanGenerator(writer: PrintWriter) : BooleanGenerator(writer) { override fun ClassBuilder.modifyGeneratedClass() { annotations += "WasmAutoboxed" - constructorParam { - name = "private val value" - type = PrimitiveType.BOOLEAN.capitalized + primaryConstructor { + parameter { + name = "private val value" + type = PrimitiveType.BOOLEAN.capitalized + } } } @@ -254,24 +256,23 @@ class NativeBooleanGenerator(writer: PrintWriter) : BooleanGenerator(writer) { } override fun MethodBuilder.modifyGeneratedNot() { - setAsExternal() + setAsExternal(PrimitiveType.BOOLEAN) } override fun MethodBuilder.modifyGeneratedAnd() { - setAsExternal() + setAsExternal(PrimitiveType.BOOLEAN) } override fun MethodBuilder.modifyGeneratedOr() { - setAsExternal() + setAsExternal(PrimitiveType.BOOLEAN) } override fun MethodBuilder.modifyGeneratedXor() { - setAsExternal() + setAsExternal(PrimitiveType.BOOLEAN) } override fun MethodBuilder.modifyGeneratedCompareTo() { - annotations += "TypedIntrinsic(IntrinsicType.UNSIGNED_COMPARE_TO)" - modifySignature { isExternal = true } + setAsExternal(PrimitiveType.BOOLEAN) } override fun MethodBuilder.modifyGeneratedToString() { diff --git a/generators/builtins/primitives/CharGenerator.kt b/generators/builtins/primitives/CharGenerator.kt new file mode 100644 index 00000000000..3d6572d8531 --- /dev/null +++ b/generators/builtins/primitives/CharGenerator.kt @@ -0,0 +1,721 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package primitives + +import org.jetbrains.kotlin.generators.builtins.PrimitiveType +import org.jetbrains.kotlin.generators.builtins.generateBuiltIns.BuiltInsGenerator +import org.jetbrains.kotlin.generators.builtins.numbers.primitives.* +import org.jetbrains.kotlin.generators.builtins.numbers.primitives.NativePrimitivesGenerator.Companion.setAsExternal +import java.io.PrintWriter + +abstract class CharGenerator(private val writer: PrintWriter) : BuiltInsGenerator { + override fun generate() { + writer.print(generateFile().build()) + } + + private fun generateFile(): FileBuilder { + return file { generateClass() }.apply { this.modifyGeneratedFile() } + } + + private fun FileBuilder.generateClass() { + klass { + appendDoc("Represents a 16-bit Unicode character.") + name = PrimitiveType.CHAR.capitalized + superType("Comparable<$name>") + + generateCompareTo() + generatePlus() + generateMinusChar() + generateMinusInt() + generateInc() + generateDec() + generateRangeTo() + generateRangeUntil() + generateConversions() + + generateToString() + generateEquals() + generateHashCode() + generateAdditionalMethods() + + generateCompanionObject() + }.modifyGeneratedClass() + } + + private fun ClassBuilder.generateCompanionObject() { + companionObject { + property { + appendDoc("The minimum value of a character code unit.") + annotations += "SinceKotlin(\"1.3\")" + name = "MIN_VALUE" + type = PrimitiveType.CHAR.capitalized + value = "'\\u0000'" + } + + property { + appendDoc("The maximum value of a character code unit.") + annotations += "SinceKotlin(\"1.3\")" + name = "MAX_VALUE" + type = PrimitiveType.CHAR.capitalized + value = "'\\uFFFF'" + } + + property { + appendDoc("The minimum value of a Unicode high-surrogate code unit.") + name = "MIN_HIGH_SURROGATE" + type = PrimitiveType.CHAR.capitalized + value = "'\\uD800'" + } + + property { + appendDoc("The maximum value of a Unicode high-surrogate code unit.") + name = "MAX_HIGH_SURROGATE" + type = PrimitiveType.CHAR.capitalized + value = "'\\uDBFF'" + } + + property { + appendDoc("The minimum value of a Unicode low-surrogate code unit.") + name = "MIN_LOW_SURROGATE" + type = PrimitiveType.CHAR.capitalized + value = "'\\uDC00'" + } + + property { + appendDoc("The maximum value of a Unicode low-surrogate code unit.") + name = "MAX_LOW_SURROGATE" + type = PrimitiveType.CHAR.capitalized + value = "'\\uDFFF'" + } + + property { + appendDoc("The minimum value of a Unicode surrogate code unit.") + name = "MIN_SURROGATE" + type = PrimitiveType.CHAR.capitalized + value = "MIN_HIGH_SURROGATE" + } + + property { + appendDoc("The maximum value of a Unicode surrogate code unit.") + name = "MAX_SURROGATE" + type = PrimitiveType.CHAR.capitalized + value = "MAX_LOW_SURROGATE" + } + + property { + appendDoc("The number of bytes used to represent a Char in a binary form.") + annotations += "SinceKotlin(\"1.3\")" + name = "SIZE_BYTES" + type = PrimitiveType.INT.capitalized + value = "2" + } + + property { + appendDoc("The number of bits used to represent a Char in a binary form.") + annotations += "SinceKotlin(\"1.3\")" + name = "SIZE_BITS" + type = PrimitiveType.INT.capitalized + value = "16" + } + }.modifyGeneratedCompanionObject() + } + + private fun ClassBuilder.generateCompareTo() { + val doc = """ + Compares this value with the specified value for order. + + Returns zero if this value is equal to the specified other value, a negative number if it's less than other, + or a positive number if it's greater than other. + """.trimIndent() + method { + appendDoc(doc) + annotations += intrinsicConstEvaluationAnnotation + signature { + isOverride = true + methodName = "compareTo" + parameter { + name = "other" + type = PrimitiveType.CHAR.capitalized + } + returnType = PrimitiveType.INT.capitalized + } + }.modifyGeneratedCompareTo() + } + + private fun ClassBuilder.generatePlus() { + method { + appendDoc("Adds the other Int value to this value resulting a Char.") + annotations += intrinsicConstEvaluationAnnotation + signature { + isOperator = true + methodName = "plus" + parameter { + name = "other" + type = PrimitiveType.INT.capitalized + } + returnType = PrimitiveType.CHAR.capitalized + } + }.modifyGeneratedPlus() + } + + private fun ClassBuilder.generateMinusChar() { + method { + appendDoc("Subtracts the other Char value from this value resulting an Int.") + annotations += intrinsicConstEvaluationAnnotation + signature { + isOperator = true + methodName = "minus" + parameter { + name = "other" + type = PrimitiveType.CHAR.capitalized + } + returnType = PrimitiveType.INT.capitalized + } + }.modifyGeneratedMinusChar() + } + + private fun ClassBuilder.generateMinusInt() { + method { + appendDoc("Subtracts the other Int value from this value resulting a Char.") + annotations += intrinsicConstEvaluationAnnotation + signature { + isOperator = true + methodName = "minus" + parameter { + name = "other" + type = PrimitiveType.INT.capitalized + } + returnType = PrimitiveType.CHAR.capitalized + } + }.modifyGeneratedMinusInt() + } + + private fun ClassBuilder.generateInc() { + val doc = """ + Returns this value incremented by one. + + @sample samples.misc.Builtins.inc + """.trimIndent() + method { + appendDoc(doc) + signature { + isOperator = true + methodName = "inc" + returnType = PrimitiveType.CHAR.capitalized + } + }.modifyGeneratedInc() + } + + private fun ClassBuilder.generateDec() { + val doc = """ + Returns this value decremented by one. + + @sample samples.misc.Builtins.dec + """.trimIndent() + method { + appendDoc(doc) + signature { + isOperator = true + methodName = "dec" + returnType = PrimitiveType.CHAR.capitalized + } + }.modifyGeneratedDec() + } + + private fun ClassBuilder.generateRangeTo() { + method { + appendDoc("Creates a range from this value to the specified [other] value.") + signature { + isOperator = true + methodName = "rangeTo" + parameter { + name = "other" + type = PrimitiveType.CHAR.capitalized + } + returnType = "CharRange" + } + }.modifyGeneratedRangeTo() + } + + private fun ClassBuilder.generateRangeUntil() { + val doc = """ + Creates a range from this value up to but excluding the specified [other] value. + + If the [other] value is less than or equal to `this` value, then the returned range is empty. + """.trimIndent() + method { + appendDoc(doc) + annotations += "SinceKotlin(\"1.9\")" + annotations += "WasExperimental(ExperimentalStdlibApi::class)" + signature { + isOperator = true + methodName = "rangeUntil" + parameter { + name = "other" + type = PrimitiveType.CHAR.capitalized + } + returnType = "CharRange" + } + }.modifyGeneratedRangeUntil() + } + + private fun ClassBuilder.generateConversions() { + for (otherKind in PrimitiveType.exceptBoolean) { + val otherName = otherKind.capitalized + method { + appendDoc("Returns the value of this character as a `$otherName`.") + if (otherKind != PrimitiveType.CHAR) { + val replaceWith = if (otherKind == PrimitiveType.INT) "this.code" else "this.code.to$otherName()" + annotations += "Deprecated(\"Conversion of Char to Number is deprecated. Use Char.code property instead.\", ReplaceWith(\"$replaceWith\"))" + annotations += "DeprecatedSinceKotlin(warningSince = \"1.5\")" + } + annotations += intrinsicConstEvaluationAnnotation + signature { + methodName = "to$otherName" + returnType = otherKind.capitalized + } + }.modifyGeneratedConversions() + } + } + + private fun ClassBuilder.generateToString() { + method { + annotations += intrinsicConstEvaluationAnnotation + signature { + methodName = "toString" + isOverride = true + returnType = "String" + } + }.modifyGeneratedToString() + } + + private fun ClassBuilder.generateEquals() { + method { + annotations += intrinsicConstEvaluationAnnotation + signature { + isOverride = true + methodName = "equals" + parameter { + name = "other" + type = "Any?" + } + returnType = PrimitiveType.BOOLEAN.capitalized + } + }.modifyGeneratedEquals() + } + + private fun ClassBuilder.generateHashCode() { + method { + signature { + isOverride = true + methodName = "hashCode" + returnType = PrimitiveType.INT.capitalized + } + }.modifyGeneratedHashCode() + } + + internal open fun FileBuilder.modifyGeneratedFile() {} + internal open fun ClassBuilder.modifyGeneratedClass() {} + internal open fun CompanionObjectBuilder.modifyGeneratedCompanionObject() {} + internal open fun MethodBuilder.modifyGeneratedCompareTo() {} + internal open fun MethodBuilder.modifyGeneratedPlus() {} + internal open fun MethodBuilder.modifyGeneratedMinusChar() {} + internal open fun MethodBuilder.modifyGeneratedMinusInt() {} + internal open fun MethodBuilder.modifyGeneratedInc() {} + internal open fun MethodBuilder.modifyGeneratedDec() {} + internal open fun MethodBuilder.modifyGeneratedRangeTo() {} + internal open fun MethodBuilder.modifyGeneratedRangeUntil() {} + internal open fun MethodBuilder.modifyGeneratedConversions() {} + internal open fun MethodBuilder.modifyGeneratedToString() {} + internal open fun MethodBuilder.modifyGeneratedEquals() {} + internal open fun MethodBuilder.modifyGeneratedHashCode() {} + internal open fun ClassBuilder.generateAdditionalMethods() {} +} + +class JvmCharGenerator(writer: PrintWriter) : CharGenerator(writer) { + override fun ClassBuilder.modifyGeneratedClass() { + appendDoc("On the JVM, non-nullable values of this type are represented as values of the primitive type `char`.") + } +} + +class JsCharGenerator(writer: PrintWriter) : CharGenerator(writer) { + override fun FileBuilder.modifyGeneratedFile() { + appendFileComment("Char is a magic class.") + appendFileComment("Char is defined as a regular class, but we lower it as a value class.") + appendFileComment("See [org.jetbrains.kotlin.ir.backend.js.utils.JsInlineClassesUtils.isClassInlineLike] for explanation.") + } + + override fun ClassBuilder.modifyGeneratedClass() { + primaryConstructor { + annotations += "kotlin.internal.LowPriorityInOverloadResolution" + visibility = MethodVisibility.INTERNAL + parameter { + name = "private val value" + type = PrimitiveType.INT.capitalized + } + } + + secondaryConstructor { + annotations += "SinceKotlin(\"1.5\")" + annotations += "WasExperimental(ExperimentalStdlibApi::class)" + visibility = MethodVisibility.PUBLIC + parameter { + name = "code" + type = "UShort" + } + argument("code.toInt()") + } + } + + override fun MethodBuilder.modifyGeneratedCompareTo() { + "value - other.value".addAsSingleLineBody(bodyOnNewLine = false) + } + + override fun MethodBuilder.modifyGeneratedPlus() { + "(value + other).toChar()".addAsSingleLineBody(bodyOnNewLine = false) + } + + override fun MethodBuilder.modifyGeneratedMinusChar() { + "value - other.value".addAsSingleLineBody(bodyOnNewLine = false) + } + + override fun MethodBuilder.modifyGeneratedMinusInt() { + "(value - other).toChar()".addAsSingleLineBody(bodyOnNewLine = false) + } + + override fun MethodBuilder.modifyGeneratedInc() { + "(value + 1).toChar()".addAsSingleLineBody(bodyOnNewLine = false) + } + + override fun MethodBuilder.modifyGeneratedDec() { + "(value - 1).toChar()".addAsSingleLineBody(bodyOnNewLine = false) + } + + override fun MethodBuilder.modifyGeneratedRangeTo() { + "CharRange(this, other)".addAsSingleLineBody(bodyOnNewLine = false) + } + + override fun MethodBuilder.modifyGeneratedRangeUntil() { + "this until other".addAsSingleLineBody(bodyOnNewLine = false) + } + + override fun MethodBuilder.modifyGeneratedConversions() { + val body = when (methodName) { + "toChar" -> "this" + "toInt" -> "value" + else -> "value.$methodName()" + } + body.addAsSingleLineBody(bodyOnNewLine = false) + } + + override fun MethodBuilder.modifyGeneratedEquals() { + """ + if (other !is Char) return false + return this.value == other.value + """.trimIndent().addAsMultiLineBody() + } + + override fun MethodBuilder.modifyGeneratedToString() { + additionalDoc = "TODO implicit usages of toString and valueOf must be covered in DCE" + annotations += "Suppress(\"JS_NAME_PROHIBITED_FOR_OVERRIDE\")" + annotations += "JsName(\"toString\")" + "return js(\"String\").fromCharCode(value).unsafeCast()".addAsMultiLineBody() + } + + override fun MethodBuilder.modifyGeneratedHashCode() { + "value".addAsSingleLineBody(bodyOnNewLine = false) + } +} + +class WasmCharGenerator(writer: PrintWriter) : CharGenerator(writer) { + override fun FileBuilder.modifyGeneratedFile() { + import("kotlin.wasm.internal.*") + } + + override fun ClassBuilder.modifyGeneratedClass() { + annotations += "WasmAutoboxed" + annotations += "Suppress(\"NOTHING_TO_INLINE\")" + primaryConstructor { + parameter { + name = "private val value" + type = PrimitiveType.CHAR.capitalized + } + } + } + + override fun CompanionObjectBuilder.modifyGeneratedCompanionObject() { + isPublic = true + property { + appendDoc("The minimum value of a supplementary code point, `\\u0x10000`.") + visibility = MethodVisibility.INTERNAL + name = "MIN_SUPPLEMENTARY_CODE_POINT" + type = PrimitiveType.INT.capitalized + value = "0x10000" + } + + property { + appendDoc("The minimum value of a Unicode code point.") + visibility = MethodVisibility.INTERNAL + name = "MIN_CODE_POINT" + type = PrimitiveType.INT.capitalized + value = "0x000000" + } + + property { + appendDoc("The maximum value of a Unicode code point.") + visibility = MethodVisibility.INTERNAL + name = "MAX_CODE_POINT" + type = PrimitiveType.INT.capitalized + value = "0X10FFFF" + } + + property { + appendDoc("The minimum radix available for conversion to and from strings.") + visibility = MethodVisibility.INTERNAL + name = "MIN_RADIX" + type = PrimitiveType.INT.capitalized + value = "2" + } + + property { + appendDoc("The maximum radix available for conversion to and from strings.") + visibility = MethodVisibility.INTERNAL + name = "MAX_RADIX" + type = PrimitiveType.INT.capitalized + value = "36" + } + } + + override fun MethodBuilder.modifyGeneratedCompareTo() { + "wasm_i32_compareTo(this.toInt(), other.toInt())".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedPlus() { + modifySignature { isInline = true } + "(this.toInt() + other).toChar()".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedMinusChar() { + modifySignature { isInline = true } + "(this.toInt() - other.toInt())".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedMinusInt() { + modifySignature { isInline = true } + "(this.toInt() - other).toChar()".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedInc() { + modifySignature { isInline = true } + "(this.toInt() + 1).toChar()".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedDec() { + modifySignature { isInline = true } + "(this.toInt() - 1).toChar()".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedRangeTo() { + "CharRange(this, other)".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedRangeUntil() { + "this until other".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedConversions() { + modifySignature { isInline = methodName != "toInt" } + val body = when (methodName) { + "toChar" -> "this" + "toInt" -> { + annotations += "WasmNoOpCast" + "implementedAsIntrinsic" + } + else -> "this.toInt().$methodName()" + } + body.addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedEquals() { + """ + if (other is Char) + return wasm_i32_eq(this.toInt(), other.toInt()) + return false + """.trimIndent().addAsMultiLineBody() + } + + override fun MethodBuilder.modifyGeneratedToString() { + modifySignature { visibility = null } + """ + val array = WasmCharArray(1) + array.set(0, this) + return array.createString() + """.trimIndent().addAsMultiLineBody() + } + + override fun MethodBuilder.modifyGeneratedHashCode() { + modifySignature { visibility = null } + "this.toInt().hashCode()".addAsSingleLineBody(bodyOnNewLine = true) + } +} + +class NativeCharGenerator(writer: PrintWriter) : CharGenerator(writer) { + override fun FileBuilder.modifyGeneratedFile() { + suppress("NOTHING_TO_INLINE") + import("kotlin.experimental.ExperimentalNativeApi") + import("kotlin.native.internal.GCUnsafeCall") + import("kotlin.native.internal.TypedIntrinsic") + import("kotlin.native.internal.IntrinsicType") + } + + override fun CompanionObjectBuilder.modifyGeneratedCompanionObject() { + annotations += "kotlin.native.internal.CanBePrecreated" + property { + appendDoc( + """ + The minimum value of a supplementary code point, `\u0x10000`. + + Note that this constant is experimental. + In the future it could be deprecated in favour of another constant of a `CodePoint` type. + """.trimIndent() + ) + annotations += "ExperimentalNativeApi" + name = "MIN_SUPPLEMENTARY_CODE_POINT" + type = PrimitiveType.INT.capitalized + value = "0x10000" + } + + property { + appendDoc( + """ + The minimum value of a Unicode code point. + + Note that this constant is experimental. + In the future it could be deprecated in favour of another constant of a `CodePoint` type. + """.trimIndent() + ) + annotations += "ExperimentalNativeApi" + name = "MIN_CODE_POINT" + type = PrimitiveType.INT.capitalized + value = "0x000000" + } + + property { + appendDoc( + """ + The maximum value of a Unicode code point. + + Note that this constant is experimental. + In the future it could be deprecated in favour of another constant of a `CodePoint` type. + """.trimIndent() + ) + annotations += "ExperimentalNativeApi" + name = "MAX_CODE_POINT" + type = PrimitiveType.INT.capitalized + value = "0X10FFFF" + } + + property { + appendDoc("The minimum radix available for conversion to and from strings.") + annotations += "Deprecated(\"Introduce your own constant with the value of `2`\", ReplaceWith(\"2\"))" + annotations += "DeprecatedSinceKotlin(warningSince = \"1.9\")" + name = "MIN_RADIX" + type = PrimitiveType.INT.capitalized + value = "2" + } + + property { + appendDoc("The maximum radix available for conversion to and from strings.") + annotations += "Deprecated(\"Introduce your own constant with the value of `36\", ReplaceWith(\"36\"))" + annotations += "DeprecatedSinceKotlin(warningSince = \"1.9\")" + name = "MAX_RADIX" + type = PrimitiveType.INT.capitalized + value = "36" + } + } + + override fun MethodBuilder.modifyGeneratedCompareTo() { + setAsExternal(PrimitiveType.CHAR) + } + + override fun MethodBuilder.modifyGeneratedPlus() { + modifySignature { isInline = true } + "(this.code + other).toChar()".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedMinusChar() { + modifySignature { isInline = true } + "this.code - other.code".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedMinusInt() { + modifySignature { isInline = true } + "(this.code - other).toChar()".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedInc() { + setAsExternal(PrimitiveType.CHAR) + } + + override fun MethodBuilder.modifyGeneratedDec() { + setAsExternal(PrimitiveType.CHAR) + } + + override fun MethodBuilder.modifyGeneratedRangeTo() { + "CharRange(this, other)".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedRangeUntil() { + "this until other".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedConversions() { + modifySignature { isExternal = methodName != "toChar" } + when (methodName) { + "toByte" -> annotations += "TypedIntrinsic(IntrinsicType.INT_TRUNCATE)" + "toChar" -> { + modifySignature { isInline = true } + "this".addAsSingleLineBody(bodyOnNewLine = true) + } + "toShort", "toInt", "toLong" -> annotations += "TypedIntrinsic(IntrinsicType.ZERO_EXTEND)" + "toFloat", "toDouble" -> annotations += "TypedIntrinsic(IntrinsicType.UNSIGNED_TO_FLOAT)" + } + } + + override fun MethodBuilder.modifyGeneratedEquals() { + "other is Char && this.code == other.code".addAsSingleLineBody(bodyOnNewLine = true) + } + + override fun MethodBuilder.modifyGeneratedToString() { + annotations += "GCUnsafeCall(\"Kotlin_Char_toString\")" + modifySignature { isExternal = true } + } + + private fun ClassBuilder.generateCustomEquals() { + method { + annotations += "Deprecated(\"Provided for binary compatibility\", level = DeprecationLevel.HIDDEN)" + annotations += intrinsicConstEvaluationAnnotation + signature { + methodName = "equals" + parameter { + name = "other" + type = PrimitiveType.CHAR.capitalized + } + returnType = PrimitiveType.BOOLEAN.capitalized + } + + "this == other".addAsSingleLineBody(bodyOnNewLine = false) + } + } + + override fun MethodBuilder.modifyGeneratedHashCode() { + "return this.code".addAsMultiLineBody() + } + + override fun ClassBuilder.generateAdditionalMethods() { + generateCustomEquals() + } +} diff --git a/generators/builtins/primitives/NativePrimitivesGenerator.kt b/generators/builtins/primitives/NativePrimitivesGenerator.kt index 9f041649493..cb0d213bb7b 100644 --- a/generators/builtins/primitives/NativePrimitivesGenerator.kt +++ b/generators/builtins/primitives/NativePrimitivesGenerator.kt @@ -58,7 +58,7 @@ class NativePrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(w return thisBits.compareTo(otherBits) """.trimIndent().addAsMultiLineBody() } else { - setAsExternal() + setAsExternal(thisKind) } return } @@ -77,7 +77,7 @@ class NativePrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(w val sign = operatorSign(this.methodName) if (thisKind != PrimitiveType.BYTE && thisKind != PrimitiveType.SHORT && thisKind == otherKind) { - return setAsExternal() + return setAsExternal(thisKind) } modifySignature { isInline = true } @@ -91,7 +91,7 @@ class NativePrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(w if (methodName in setOf("inc", "dec") || thisKind == PrimitiveType.INT || thisKind in PrimitiveType.floatingPoint || (methodName == "unaryMinus" && thisKind == PrimitiveType.LONG) ) { - return setAsExternal() + return setAsExternal(thisKind) } modifySignature { isInline = true } @@ -102,11 +102,11 @@ class NativePrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(w } override fun MethodBuilder.modifyGeneratedBitShiftOperators(thisKind: PrimitiveType) { - setAsExternal() + setAsExternal(thisKind) } override fun MethodBuilder.modifyGeneratedBitwiseOperators(thisKind: PrimitiveType) { - setAsExternal() + setAsExternal(thisKind) } override fun MethodBuilder.modifyGeneratedConversions(thisKind: PrimitiveType) { @@ -234,15 +234,23 @@ class NativePrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(w } companion object { - private fun String.toNativeOperator(): String { - if (this == "div" || this == "rem") return "SIGNED_${this.uppercase(Locale.getDefault())}" - if (this == "compareTo") return "SIGNED_COMPARE_TO" - if (this.startsWith("unary")) return "UNARY_${this.replace("unary", "").uppercase(Locale.getDefault())}" - return this.uppercase(Locale.getDefault()) + private fun String.toNativeOperator(thisKind: PrimitiveType): String { + return when { + this == "div" || this == "rem" -> { + val prefix = if (thisKind == PrimitiveType.BOOLEAN || thisKind == PrimitiveType.CHAR) "UNSIGNED" else "SIGNED" + "${prefix}_${this.uppercase()}" + } + this == "compareTo" -> { + val prefix = if (thisKind == PrimitiveType.BOOLEAN || thisKind == PrimitiveType.CHAR) "UNSIGNED" else "SIGNED" + "${prefix}_COMPARE_TO" + } + this.startsWith("unary") -> "UNARY_${this.replace("unary", "").uppercase()}" + else -> this.uppercase() + } } - internal fun MethodBuilder.setAsExternal() { - annotations += "TypedIntrinsic(IntrinsicType.${methodName.toNativeOperator()})" + internal fun MethodBuilder.setAsExternal(thisKind: PrimitiveType) { + annotations += "TypedIntrinsic(IntrinsicType.${methodName.toNativeOperator(thisKind)})" modifySignature { isExternal = true } } } diff --git a/generators/builtins/primitives/WasmPrimitivesGenerator.kt b/generators/builtins/primitives/WasmPrimitivesGenerator.kt index 7aa0e37fd89..e392f1d7d5b 100644 --- a/generators/builtins/primitives/WasmPrimitivesGenerator.kt +++ b/generators/builtins/primitives/WasmPrimitivesGenerator.kt @@ -21,9 +21,11 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri override fun ClassBuilder.modifyGeneratedClass(thisKind: PrimitiveType) { annotations += "WasmAutoboxed" // used here little hack with name extension just to avoid creation of specialized "ConstructorParameterDescription" - constructorParam { - name = "private val value" - type = thisKind.capitalized + primaryConstructor { + parameter { + name = "private val value" + type = thisKind.capitalized + } } } diff --git a/generators/builtins/primitives/builders.kt b/generators/builtins/primitives/builders.kt index 7564b242264..1b32cda02d5 100644 --- a/generators/builtins/primitives/builders.kt +++ b/generators/builtins/primitives/builders.kt @@ -77,6 +77,7 @@ internal abstract class AnnotatedAndDocumented { internal class FileBuilder : PrimitiveBuilder { private val suppresses: MutableList = mutableListOf() private val imports: MutableList = mutableListOf() + private val fileComments: MutableList = mutableListOf() private val classes: MutableList = mutableListOf() fun suppress(suppress: String) { @@ -87,6 +88,10 @@ internal class FileBuilder : PrimitiveBuilder { imports += newImport } + fun appendFileComment(doc: String) { + fileComments += doc + } + fun klass(init: ClassBuilder.() -> Unit): ClassBuilder { val classBuilder = ClassBuilder() classes += classBuilder.apply(init) @@ -113,6 +118,11 @@ internal class FileBuilder : PrimitiveBuilder { appendLine() } + if (fileComments.isNotEmpty()) { + appendLine(fileComments.joinToString(separator = END_LINE) { "// $it" }) + appendLine() + } + append(classes.joinToString(separator = END_LINE) { it.build() }) } } @@ -121,14 +131,21 @@ internal class FileBuilder : PrimitiveBuilder { internal class ClassBuilder : AnnotatedAndDocumented(), PrimitiveBuilder { var isFinal: Boolean = false var name: String = "" - private var constructorParam: MethodParameterBuilder? = null + private var primaryConstructor: PrimaryConstructorBuilder = PrimaryConstructorBuilder() + private var secondaryConstructor: SecondaryConstructorBuilder? = null private var superTypes: List = emptyList() private var companionObject: CompanionObjectBuilder? = null - private val methods: MutableList = mutableListOf() - fun constructorParam(init: MethodParameterBuilder.() -> Unit) { - throwIfAlreadyInitialized(constructorParam, "constructorParam", "ClassBuilder") - constructorParam = MethodParameterBuilder().apply(init) + private var builders: MutableList = mutableListOf() + + fun primaryConstructor(init: PrimaryConstructorBuilder.() -> Unit) { + primaryConstructor = PrimaryConstructorBuilder().apply(init) + } + + fun secondaryConstructor(init: SecondaryConstructorBuilder.() -> Unit): SecondaryConstructorBuilder { + val secondaryConstructorBuilder = SecondaryConstructorBuilder() + secondaryConstructor = secondaryConstructorBuilder.apply(init) + return secondaryConstructorBuilder } fun superType(type: String) { @@ -139,12 +156,13 @@ internal class ClassBuilder : AnnotatedAndDocumented(), PrimitiveBuilder { throwIfAlreadyInitialized(companionObject, "companionObject", "ClassBuilder") val companionObjectBuilder = CompanionObjectBuilder() companionObject = companionObjectBuilder.apply(init) + builders.add(companionObjectBuilder) return companionObjectBuilder } fun method(init: MethodBuilder.() -> Unit): MethodBuilder { val methodBuilder = MethodBuilder() - methods += methodBuilder.apply(init) + builders.add(methodBuilder.apply(init)) return methodBuilder } @@ -154,10 +172,14 @@ internal class ClassBuilder : AnnotatedAndDocumented(), PrimitiveBuilder { append("public ") if (isFinal) append("final ") - appendLine("class $name private constructor(${constructorParam?.build() ?: ""}) : ${superTypes.joinToString()} {") + appendLine("class $name ${primaryConstructor.build()}: ${superTypes.joinToString()} {") - companionObject?.let { appendLine(it.build().shift()) } - appendLine(methods.joinToString(separator = END_LINE + END_LINE) { it.build().shift() }) + secondaryConstructor?.let { + appendLine(it.build().shift()) + appendLine() + } + + appendLine(builders.joinToString(separator = END_LINE + END_LINE) { it.build().shift() }) appendLine("}") } } @@ -178,16 +200,65 @@ internal class CompanionObjectBuilder : AnnotatedAndDocumented(), PrimitiveBuild printDocumentationAndAnnotations() if (isPublic) append("public ") if (properties.isEmpty()) { - appendLine("companion object {}") + append("companion object {}") } else { appendLine("companion object {") appendLine(properties.joinToString(separator = END_LINE + END_LINE) { it.build().shift() }) - appendLine("}") + append("}") } } } } +internal class PrimaryConstructorBuilder : AnnotatedAndDocumented(), PrimitiveBuilder { + var visibility: MethodVisibility? = MethodVisibility.PRIVATE + private var parameters: MutableList = mutableListOf() + + fun parameter(init: MethodParameterBuilder.() -> Unit): MethodParameterBuilder { + val argBuilder = MethodParameterBuilder() + parameters.add(argBuilder.apply(init)) + return argBuilder + } + + override fun build(): String { + return buildString { + if (annotations.isNotEmpty()) appendLine() + printDocumentationAndAnnotations() + + visibility?.let { append("${it.name.lowercase()} ") } + append("constructor") + append(parameters.joinToString(prefix = "(", postfix = ") ") { it.build() }) + } + } +} + +internal class SecondaryConstructorBuilder : AnnotatedAndDocumented(), PrimitiveBuilder { + var visibility: MethodVisibility? = MethodVisibility.PRIVATE + private var parameters: MutableList = mutableListOf() + private var argumentsToPrimaryContructor: MutableList = mutableListOf() + + fun parameter(init: MethodParameterBuilder.() -> Unit): MethodParameterBuilder { + val argBuilder = MethodParameterBuilder() + parameters.add(argBuilder.apply(init)) + return argBuilder + } + + fun argument(arg: String) { + argumentsToPrimaryContructor += arg + } + + override fun build(): String { + return buildString { + printDocumentationAndAnnotations() + + visibility?.let { append("${it.name.lowercase()} ") } + append("constructor") + append(parameters.joinToString(prefix = "(", postfix = ") : ") { it.build() }) + append(argumentsToPrimaryContructor.joinToString(prefix = "this(", postfix = ")")) + } + } +} + internal class MethodSignatureBuilder : PrimitiveBuilder { var isExternal: Boolean = false var visibility: MethodVisibility? = MethodVisibility.PUBLIC @@ -295,6 +366,7 @@ internal class MethodBuilder : AnnotatedAndDocumented(), PrimitiveBuilder { } internal class PropertyBuilder : AnnotatedAndDocumented(), PrimitiveBuilder { + var visibility: MethodVisibility? = MethodVisibility.PUBLIC var name: String? = null var type: String? = null var value: String? = null @@ -306,7 +378,8 @@ internal class PropertyBuilder : AnnotatedAndDocumented(), PrimitiveBuilder { return buildString { printDocumentationAndAnnotations(forceMultiLineDoc = true) - append("public const val $name: $type = $value") + visibility?.let { append("${it.name.lowercase()} ") } + append("const val $name: $type = $value") } } } diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/Char.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/Char.kt index 67ca194fd70..dd58fd52b71 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/Char.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/Char.kt @@ -1,7 +1,10 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ + +// Auto-generated file. DO NOT EDIT! + @file:Suppress("NOTHING_TO_INLINE") package kotlin @@ -11,9 +14,7 @@ import kotlin.native.internal.GCUnsafeCall import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.IntrinsicType -/** - * Represents a 16-bit Unicode character. - */ +/** Represents a 16-bit Unicode character. */ public class Char private constructor() : Comparable { /** * Compares this value with the specified value for order. @@ -21,22 +22,24 @@ public class Char private constructor() : Comparable { * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - @TypedIntrinsic(IntrinsicType.UNSIGNED_COMPARE_TO) @kotlin.internal.IntrinsicConstEvaluation + @TypedIntrinsic(IntrinsicType.UNSIGNED_COMPARE_TO) external public override fun compareTo(other: Char): Int /** Adds the other Int value to this value resulting a Char. */ @kotlin.internal.IntrinsicConstEvaluation public inline operator fun plus(other: Int): Char = - (this.code + other).toChar() + (this.code + other).toChar() + /** Subtracts the other Char value from this value resulting an Int. */ @kotlin.internal.IntrinsicConstEvaluation public inline operator fun minus(other: Char): Int = - this.code - other.code + this.code - other.code + /** Subtracts the other Int value from this value resulting a Char. */ @kotlin.internal.IntrinsicConstEvaluation public inline operator fun minus(other: Int): Char = - (this.code - other).toChar() + (this.code - other).toChar() /** * Returns this value incremented by one. @@ -45,6 +48,7 @@ public class Char private constructor() : Comparable { */ @TypedIntrinsic(IntrinsicType.INC) external public operator fun inc(): Char + /** * Returns this value decremented by one. * @@ -54,9 +58,8 @@ public class Char private constructor() : Comparable { external public operator fun dec(): Char /** Creates a range from this value to the specified [other] value. */ - public operator fun rangeTo(other: Char): CharRange { - return CharRange(this, other) - } + public operator fun rangeTo(other: Char): CharRange = + CharRange(this, other) /** * Creates a range from this value up to but excluding the specified [other] value. @@ -65,48 +68,72 @@ public class Char private constructor() : Comparable { */ @SinceKotlin("1.9") @WasExperimental(ExperimentalStdlibApi::class) - public operator fun rangeUntil(other: Char): CharRange = this until other + public operator fun rangeUntil(other: Char): CharRange = + this until other /** Returns the value of this character as a `Byte`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toByte()")) @DeprecatedSinceKotlin(warningSince = "1.5") - @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) @kotlin.internal.IntrinsicConstEvaluation + @TypedIntrinsic(IntrinsicType.INT_TRUNCATE) external public fun toByte(): Byte + /** Returns the value of this character as a `Char`. */ @kotlin.internal.IntrinsicConstEvaluation - public inline fun toChar(): Char = this + public inline fun toChar(): Char = + this + /** Returns the value of this character as a `Short`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toShort()")) @DeprecatedSinceKotlin(warningSince = "1.5") - @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) @kotlin.internal.IntrinsicConstEvaluation + @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) external public fun toShort(): Short + /** Returns the value of this character as a `Int`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code")) @DeprecatedSinceKotlin(warningSince = "1.5") - @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) @kotlin.internal.IntrinsicConstEvaluation + @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) external public fun toInt(): Int + /** Returns the value of this character as a `Long`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toLong()")) @DeprecatedSinceKotlin(warningSince = "1.5") - @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) @kotlin.internal.IntrinsicConstEvaluation + @TypedIntrinsic(IntrinsicType.ZERO_EXTEND) external public fun toLong(): Long + /** Returns the value of this character as a `Float`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toFloat()")) @DeprecatedSinceKotlin(warningSince = "1.5") - @TypedIntrinsic(IntrinsicType.UNSIGNED_TO_FLOAT) @kotlin.internal.IntrinsicConstEvaluation + @TypedIntrinsic(IntrinsicType.UNSIGNED_TO_FLOAT) external public fun toFloat(): Float + /** Returns the value of this character as a `Double`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toDouble()")) @DeprecatedSinceKotlin(warningSince = "1.5") - @TypedIntrinsic(IntrinsicType.UNSIGNED_TO_FLOAT) @kotlin.internal.IntrinsicConstEvaluation + @TypedIntrinsic(IntrinsicType.UNSIGNED_TO_FLOAT) external public fun toDouble(): Double + @kotlin.internal.IntrinsicConstEvaluation + @GCUnsafeCall("Kotlin_Char_toString") + external public override fun toString(): String + + @kotlin.internal.IntrinsicConstEvaluation + public override fun equals(other: Any?): Boolean = + other is Char && this.code == other.code + + public override fun hashCode(): Int { + return this.code + } + + @Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) + @kotlin.internal.IntrinsicConstEvaluation + public fun equals(other: Char): Boolean = this == other + @kotlin.native.internal.CanBePrecreated companion object { /** @@ -121,17 +148,6 @@ public class Char private constructor() : Comparable { @SinceKotlin("1.3") public const val MAX_VALUE: Char = '\uFFFF' - /** - * The number of bytes used to represent a Char in a binary form. - */ - @SinceKotlin("1.3") - public const val SIZE_BYTES: Int = 2 - /** - * The number of bits used to represent a Char in a binary form. - */ - @SinceKotlin("1.3") - public const val SIZE_BITS: Int = 16 - /** * The minimum value of a Unicode high-surrogate code unit. */ @@ -162,6 +178,18 @@ public class Char private constructor() : Comparable { */ public const val MAX_SURROGATE: Char = MAX_LOW_SURROGATE + /** + * The number of bytes used to represent a Char in a binary form. + */ + @SinceKotlin("1.3") + public const val SIZE_BYTES: Int = 2 + + /** + * The number of bits used to represent a Char in a binary form. + */ + @SinceKotlin("1.3") + public const val SIZE_BITS: Int = 16 + /** * The minimum value of a supplementary code point, `\u0x10000`. * @@ -178,7 +206,7 @@ public class Char private constructor() : Comparable { * In the future it could be deprecated in favour of another constant of a `CodePoint` type. */ @ExperimentalNativeApi - public const val MIN_CODE_POINT = 0x000000 + public const val MIN_CODE_POINT: Int = 0x000000 /** * The maximum value of a Unicode code point. @@ -187,7 +215,7 @@ public class Char private constructor() : Comparable { * In the future it could be deprecated in favour of another constant of a `CodePoint` type. */ @ExperimentalNativeApi - public const val MAX_CODE_POINT = 0X10FFFF + public const val MAX_CODE_POINT: Int = 0X10FFFF /** * The minimum radix available for conversion to and from strings. @@ -203,21 +231,4 @@ public class Char private constructor() : Comparable { @DeprecatedSinceKotlin(warningSince = "1.9") public const val MAX_RADIX: Int = 36 } - - @Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) - @kotlin.internal.IntrinsicConstEvaluation - public fun equals(other: Char): Boolean = this == other - - @kotlin.internal.IntrinsicConstEvaluation - public override fun equals(other: Any?): Boolean = - other is Char && this.code == other.code - - @GCUnsafeCall("Kotlin_Char_toString") - @kotlin.internal.IntrinsicConstEvaluation - external public override fun toString(): String - - public override fun hashCode(): Int { - return this.code - } } - diff --git a/libraries/stdlib/api/js/kotlin.kt b/libraries/stdlib/api/js/kotlin.kt index 9d293e14757..9be8720126b 100644 --- a/libraries/stdlib/api/js/kotlin.kt +++ b/libraries/stdlib/api/js/kotlin.kt @@ -1227,8 +1227,8 @@ public final class Char : kotlin.Comparable { @kotlin.internal.IntrinsicConstEvaluation public final fun toShort(): kotlin.Short - @kotlin.js.JsName(name = "toString") @kotlin.internal.IntrinsicConstEvaluation + @kotlin.js.JsName(name = "toString") public open override fun toString(): kotlin.String public companion object of Char { diff --git a/libraries/stdlib/js-ir/builtins/Char.kt b/libraries/stdlib/js-ir/builtins/Char.kt index 2f305bd485c..c7253e403e6 100644 --- a/libraries/stdlib/js-ir/builtins/Char.kt +++ b/libraries/stdlib/js-ir/builtins/Char.kt @@ -1,28 +1,27 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +// Auto-generated file. DO NOT EDIT! + package kotlin // Char is a magic class. // Char is defined as a regular class, but we lower it as a value class. // See [org.jetbrains.kotlin.ir.backend.js.utils.JsInlineClassesUtils.isClassInlineLike] for explanation. -/** - * Represents a 16-bit Unicode character. - * On the JVM, non-nullable values of this type are represented as values of the primitive type `char`. - */ -public /*value*/ class Char +/** Represents a 16-bit Unicode character. */ +public class Char @kotlin.internal.LowPriorityInOverloadResolution internal constructor(private val value: Int) : Comparable { - @SinceKotlin("1.5") @WasExperimental(ExperimentalStdlibApi::class) public constructor(code: UShort) : this(code.toInt()) /** * Compares this value with the specified value for order. + * * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ @@ -36,6 +35,7 @@ internal constructor(private val value: Int) : Comparable { /** Subtracts the other Char value from this value resulting an Int. */ @kotlin.internal.IntrinsicConstEvaluation public operator fun minus(other: Char): Int = value - other.value + /** Subtracts the other Int value from this value resulting a Char. */ @kotlin.internal.IntrinsicConstEvaluation public operator fun minus(other: Int): Char = (value - other).toChar() @@ -66,35 +66,40 @@ internal constructor(private val value: Int) : Comparable { @WasExperimental(ExperimentalStdlibApi::class) public operator fun rangeUntil(other: Char): CharRange = this until other - /** Returns the value of this character as a `Byte`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toByte()")) @DeprecatedSinceKotlin(warningSince = "1.5") @kotlin.internal.IntrinsicConstEvaluation public fun toByte(): Byte = value.toByte() + /** Returns the value of this character as a `Char`. */ @kotlin.internal.IntrinsicConstEvaluation public fun toChar(): Char = this + /** Returns the value of this character as a `Short`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toShort()")) @DeprecatedSinceKotlin(warningSince = "1.5") @kotlin.internal.IntrinsicConstEvaluation public fun toShort(): Short = value.toShort() + /** Returns the value of this character as a `Int`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code")) @DeprecatedSinceKotlin(warningSince = "1.5") @kotlin.internal.IntrinsicConstEvaluation public fun toInt(): Int = value + /** Returns the value of this character as a `Long`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toLong()")) @DeprecatedSinceKotlin(warningSince = "1.5") @kotlin.internal.IntrinsicConstEvaluation public fun toLong(): Long = value.toLong() + /** Returns the value of this character as a `Float`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toFloat()")) @DeprecatedSinceKotlin(warningSince = "1.5") @kotlin.internal.IntrinsicConstEvaluation public fun toFloat(): Float = value.toFloat() + /** Returns the value of this character as a `Double`. */ @Deprecated("Conversion of Char to Number is deprecated. Use Char.code property instead.", ReplaceWith("this.code.toDouble()")) @DeprecatedSinceKotlin(warningSince = "1.5") @@ -102,20 +107,20 @@ internal constructor(private val value: Int) : Comparable { public fun toDouble(): Double = value.toDouble() @kotlin.internal.IntrinsicConstEvaluation - override fun equals(other: Any?): Boolean { + @Suppress("JS_NAME_PROHIBITED_FOR_OVERRIDE") + @JsName("toString") + // TODO implicit usages of toString and valueOf must be covered in DCE + public override fun toString(): String { + return js("String").fromCharCode(value).unsafeCast() + } + + @kotlin.internal.IntrinsicConstEvaluation + public override fun equals(other: Any?): Boolean { if (other !is Char) return false return this.value == other.value } - override fun hashCode(): Int = value - - // TODO implicit usages of toString and valueOf must be covered in DCE - @Suppress("JS_NAME_PROHIBITED_FOR_OVERRIDE") - @JsName("toString") - @kotlin.internal.IntrinsicConstEvaluation - public override fun toString(): String { - return js("String").fromCharCode(value).unsafeCast() - } + public override fun hashCode(): Int = value companion object { /** @@ -172,5 +177,4 @@ internal constructor(private val value: Int) : Comparable { @SinceKotlin("1.3") public const val SIZE_BITS: Int = 16 } - } diff --git a/libraries/stdlib/wasm/builtins/kotlin/Char.kt b/libraries/stdlib/wasm/builtins/kotlin/Char.kt index f5409868079..a1961ade3f1 100644 --- a/libraries/stdlib/wasm/builtins/kotlin/Char.kt +++ b/libraries/stdlib/wasm/builtins/kotlin/Char.kt @@ -1,18 +1,15 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +// Auto-generated file. DO NOT EDIT! package kotlin import kotlin.wasm.internal.* -/** - * Represents a 16-bit Unicode character. - * - * On the JVM, non-nullable values of this type are represented as values of the primitive type `char`. - */ +/** Represents a 16-bit Unicode character. */ @WasmAutoboxed @Suppress("NOTHING_TO_INLINE") public class Char private constructor(private val value: Char) : Comparable { @@ -26,13 +23,6 @@ public class Char private constructor(private val value: Char) : Comparable