Rewrite primitives' generation using simple DSL

This commit is contained in:
Ivan Kylchik
2023-03-02 16:27:27 +01:00
committed by Space Team
parent dd0267f4ad
commit 2e836494f5
12 changed files with 1455 additions and 1359 deletions
+12 -12
View File
@@ -371,10 +371,10 @@ public class Byte private constructor() : Number(), Comparable<Byte> {
public override fun toDouble(): Double public override fun toDouble(): Double
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean public override fun toString(): String
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String public override fun equals(other: Any?): Boolean
} }
/** /**
@@ -739,10 +739,10 @@ public class Short private constructor() : Number(), Comparable<Short> {
public override fun toDouble(): Double public override fun toDouble(): Double
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean public override fun toString(): String
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String public override fun equals(other: Any?): Boolean
} }
/** /**
@@ -1153,10 +1153,10 @@ public class Int private constructor() : Number(), Comparable<Int> {
public override fun toDouble(): Double public override fun toDouble(): Double
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean public override fun toString(): String
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String public override fun equals(other: Any?): Boolean
} }
/** /**
@@ -1570,10 +1570,10 @@ public class Long private constructor() : Number(), Comparable<Long> {
public override fun toDouble(): Double public override fun toDouble(): Double
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean public override fun toString(): String
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String public override fun equals(other: Any?): Boolean
} }
/** /**
@@ -1903,10 +1903,10 @@ public class Float private constructor() : Number(), Comparable<Float> {
public override fun toDouble(): Double public override fun toDouble(): Double
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean public override fun toString(): String
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String public override fun equals(other: Any?): Boolean
} }
/** /**
@@ -2238,8 +2238,8 @@ public class Double private constructor() : Number(), Comparable<Double> {
public override fun toDouble(): Double public override fun toDouble(): Double
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean public override fun toString(): String
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String public override fun equals(other: Any?): Boolean
} }
@@ -18,18 +18,23 @@ abstract class BasePrimitivesGenerator(private val writer: PrintWriter) : BuiltI
"div", "div",
"rem", "rem",
) )
internal val unaryPlusMinusOperators: Map<String, String> = mapOf( internal val unaryPlusMinusOperators: Map<String, String> = mapOf(
"unaryPlus" to "Returns this value.", "unaryPlus" to "Returns this value.",
"unaryMinus" to "Returns the negative of this value." "unaryMinus" to "Returns the negative of this value."
) )
internal val shiftOperators: Map<String, String> = mapOf( internal val shiftOperators: Map<String, String> = mapOf(
"shl" to "Shifts this value left by the [bitCount] number of bits.", "shl" to "Shifts this value left by the [bitCount] number of bits.",
"shr" to "Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit.", "shr" to "Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with copies of the sign bit.",
"ushr" to "Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros.") "ushr" to "Shifts this value right by the [bitCount] number of bits, filling the leftmost bits with zeros."
)
internal val bitwiseOperators: Map<String, String> = mapOf( internal val bitwiseOperators: Map<String, String> = mapOf(
"and" to "Performs a bitwise AND operation between the two values.", "and" to "Performs a bitwise AND operation between the two values.",
"or" to "Performs a bitwise OR operation between the two values.", "or" to "Performs a bitwise OR operation between the two values.",
"xor" to "Performs a bitwise XOR operation between the two values.") "xor" to "Performs a bitwise XOR operation between the two values."
)
internal fun shiftOperatorsDocDetail(kind: PrimitiveType): String { internal fun shiftOperatorsDocDetail(kind: PrimitiveType): String {
val bitsUsed = when (kind) { val bitsUsed = when (kind) {
@@ -136,25 +141,23 @@ abstract class BasePrimitivesGenerator(private val writer: PrintWriter) : BuiltI
val otherName = toIntegral.capitalized val otherName = toIntegral.capitalized
return if (toIntegral == PrimitiveType.CHAR) { return if (toIntegral == PrimitiveType.CHAR) {
if (fromIntegral == PrimitiveType.SHORT) { when (fromIntegral) {
""" PrimitiveType.SHORT -> """
The resulting `Char` code is equal to this value reinterpreted as an unsigned number, The resulting `Char` code is equal to this value reinterpreted as an unsigned number,
i.e. it has the same binary representation as this `Short`. i.e. it has the same binary representation as this `Short`.
""".trimIndent() """.trimIndent()
} else if (fromIntegral == PrimitiveType.BYTE) { PrimitiveType.BYTE -> """
""" If this value is non-negative, the resulting `Char` code is equal to this value.
If this value is non-negative, the resulting `Char` code is equal to this value.
The least significant 8 bits of the resulting `Char` code are the same as the bits of this `Byte` value,
The least significant 8 bits of the resulting `Char` code are the same as the bits of this `Byte` value, whereas the most significant 8 bits are filled with the sign bit of this value.
whereas the most significant 8 bits are filled with the sign bit of this value. """.trimIndent()
""".trimIndent() else -> """
} else { If this value is in the range of `Char` codes `Char.MIN_VALUE..Char.MAX_VALUE`,
""" the resulting `Char` code is equal to this value.
If this value is in the range of `Char` codes `Char.MIN_VALUE..Char.MAX_VALUE`,
the resulting `Char` code is equal to this value. The resulting `Char` code is represented by the least significant 16 bits of this `$thisName` value.
""".trimIndent()
The resulting `Char` code is represented by the least significant 16 bits of this `$thisName` value.
""".trimIndent()
} }
} else if (compareByDomainCapacity(toIntegral, fromIntegral) < 0) { } else if (compareByDomainCapacity(toIntegral, fromIntegral) < 0) {
""" """
@@ -227,301 +230,306 @@ abstract class BasePrimitivesGenerator(private val writer: PrintWriter) : BuiltI
open fun PrimitiveType.shouldGenerate(): Boolean = true open fun PrimitiveType.shouldGenerate(): Boolean = true
override fun generate() { override fun generate() {
writer.print(FileDescription(classes = generateClasses()).apply { this.modifyGeneratedFile() }.toString()) writer.print(generateFile().build())
} }
private fun generateClasses(): List<ClassDescription> { private fun generateFile(): FileBuilder {
return buildList { return file { generateClasses() }.apply { this.modifyGeneratedFile() }
for (thisKind in PrimitiveType.onlyNumeric.filter { it.shouldGenerate() }) { }
val className = thisKind.capitalized
val doc = "Represents a ${typeDescriptions[thisKind]}."
val methods = buildList { private fun FileBuilder.generateClasses() {
this.addAll(generateCompareTo(thisKind)) for (thisKind in PrimitiveType.onlyNumeric.filter { it.shouldGenerate() }) {
this.addAll(generateBinaryOperators(thisKind)) val className = thisKind.capitalized
this.addAll(generateUnaryOperators(thisKind))
this.addAll(generateRangeTo(thisKind))
this.addAll(generateRangeUntil(thisKind))
if (thisKind == PrimitiveType.INT || thisKind == PrimitiveType.LONG) { klass {
this.addAll(generateBitShiftOperators(thisKind)) appendDoc("Represents a ${typeDescriptions[thisKind]}.")
this.addAll(generateBitwiseOperators(thisKind)) name = className
} generateCompanionObject(thisKind)
this.addAll(generateConversions(thisKind)) generateCompareTo(thisKind)
this += generateEquals(thisKind) generateBinaryOperators(thisKind)
this += generateToString(thisKind) generateUnaryOperators(thisKind)
this.addAll(generateAdditionalMethods(thisKind)) generateRangeTo(thisKind)
generateRangeUntil(thisKind)
if (thisKind == PrimitiveType.INT || thisKind == PrimitiveType.LONG) {
generateBitShiftOperators(thisKind)
generateBitwiseOperators(thisKind)
} }
this += ClassDescription( generateConversions(thisKind)
doc, generateToString(thisKind)
annotations = mutableListOf(), generateEquals(thisKind)
name = className, generateAdditionalMethods(thisKind)
companionObject = generateCompanionObject(thisKind), }.modifyGeneratedClass(thisKind)
methods = methods
).apply { this.modifyGeneratedClass(thisKind) }
}
} }
} }
private fun generateCompanionObject(thisKind: PrimitiveType): CompanionObjectDescription { private fun ClassBuilder.generateCompanionObject(thisKind: PrimitiveType) {
val properties = buildList { companionObject {
val className = thisKind.capitalized val className = thisKind.capitalized
if (thisKind == PrimitiveType.FLOAT || thisKind == PrimitiveType.DOUBLE) { if (thisKind == PrimitiveType.FLOAT || thisKind == PrimitiveType.DOUBLE) {
val (minValue, maxValue, posInf, negInf, nan) = primitiveConstants(thisKind) val (minValue, maxValue, posInf, negInf, nan) = primitiveConstants(thisKind)
this += PropertyDescription( property {
doc = "A constant holding the smallest *positive* nonzero value of $className.", appendDoc("A constant holding the smallest *positive* nonzero value of $className.")
name = "MIN_VALUE", name = "MIN_VALUE"
type = className, type = className
value = minValue.toString() value = minValue.toString()
) }.modifyGeneratedCompanionObjectProperty(thisKind)
this += PropertyDescription( property {
doc = "A constant holding the largest positive finite value of $className.", appendDoc("A constant holding the largest positive finite value of $className.")
name = "MAX_VALUE", name = "MAX_VALUE"
type = className, type = className
value = maxValue.toString() value = maxValue.toString()
) }.modifyGeneratedCompanionObjectProperty(thisKind)
this += PropertyDescription( property {
doc = "A constant holding the positive infinity value of $className.", appendDoc("A constant holding the positive infinity value of $className.")
name = "POSITIVE_INFINITY", name = "POSITIVE_INFINITY"
type = className, type = className
value = posInf.toString() value = posInf.toString()
) }.modifyGeneratedCompanionObjectProperty(thisKind)
this += PropertyDescription( property {
doc = "A constant holding the negative infinity value of $className.", appendDoc("A constant holding the negative infinity value of $className.")
name = "NEGATIVE_INFINITY", name = "NEGATIVE_INFINITY"
type = className, type = className
value = negInf.toString() value = negInf.toString()
) }.modifyGeneratedCompanionObjectProperty(thisKind)
this += PropertyDescription( property {
doc = "A constant holding the \"not a number\" value of $className.", appendDoc("A constant holding the \"not a number\" value of $className.")
name = "NaN", name = "NaN"
type = className, type = className
value = nan.toString() value = nan.toString()
) }.modifyGeneratedCompanionObjectProperty(thisKind)
} }
if (thisKind == PrimitiveType.INT || thisKind == PrimitiveType.LONG || thisKind == PrimitiveType.SHORT || thisKind == PrimitiveType.BYTE) { if (thisKind == PrimitiveType.INT || thisKind == PrimitiveType.LONG || thisKind == PrimitiveType.SHORT || thisKind == PrimitiveType.BYTE) {
val (minValue, maxValue) = primitiveConstants(thisKind) val (minValue, maxValue) = primitiveConstants(thisKind)
this += PropertyDescription( property {
doc = "A constant holding the minimum value an instance of $className can have.", appendDoc("A constant holding the minimum value an instance of $className can have.")
name = "MIN_VALUE", name = "MIN_VALUE"
type = className, type = className
value = minValue.toString() value = minValue.toString()
) }.modifyGeneratedCompanionObjectProperty(thisKind)
this += PropertyDescription( property {
doc = "A constant holding the maximum value an instance of $className can have.", appendDoc("A constant holding the maximum value an instance of $className can have.")
name = "MAX_VALUE", name = "MAX_VALUE"
type = className, type = className
value = maxValue.toString() value = maxValue.toString()
) }.modifyGeneratedCompanionObjectProperty(thisKind)
} }
val sizeSince = if (thisKind.isFloatingPoint) "1.4" else "1.3" val sizeSince = if (thisKind.isFloatingPoint) "1.4" else "1.3"
this += PropertyDescription( property {
doc = "The number of bytes used to represent an instance of $className in a binary form.", appendDoc("The number of bytes used to represent an instance of $className in a binary form.")
annotations = mutableListOf("SinceKotlin(\"$sizeSince\")"), annotations += mutableListOf("SinceKotlin(\"$sizeSince\")")
name = "SIZE_BYTES", name = "SIZE_BYTES"
type = "Int", type = "Int"
value = thisKind.byteSize.toString() value = thisKind.byteSize.toString()
) }.modifyGeneratedCompanionObjectProperty(thisKind)
this += PropertyDescription( property {
doc = "The number of bits used to represent an instance of $className in a binary form.", appendDoc("The number of bits used to represent an instance of $className in a binary form.")
annotations = mutableListOf("SinceKotlin(\"$sizeSince\")"), annotations += mutableListOf("SinceKotlin(\"$sizeSince\")")
name = "SIZE_BITS", name = "SIZE_BITS"
type = "Int", type = "Int"
value = thisKind.bitSize.toString() value = thisKind.bitSize.toString()
) }.modifyGeneratedCompanionObjectProperty(thisKind)
} }.modifyGeneratedCompanionObject(thisKind)
properties.forEach { it.modifyGeneratedCompanionObjectProperty(thisKind) }
return CompanionObjectDescription(properties = properties).apply { this.modifyGeneratedCompanionObject(thisKind) }
} }
private fun generateCompareTo(thisKind: PrimitiveType): List<MethodDescription> { private fun ClassBuilder.generateCompareTo(thisKind: PrimitiveType) {
return buildList { for (otherKind in PrimitiveType.onlyNumeric) {
for (otherKind in PrimitiveType.onlyNumeric) { val doc = """
val doc = """
Compares this value with the specified value for order. 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, 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. or a positive number if it's greater than other.
""".trimIndent() """.trimIndent()
val signature = MethodSignature( method {
isOverride = otherKind == thisKind, appendDoc(doc)
isOperator = true, annotations += "kotlin.internal.IntrinsicConstEvaluation"
name = "compareTo", signature {
arg = MethodParameter("other", otherKind.capitalized), isOverride = otherKind == thisKind
isOperator = true
methodName = "compareTo"
parameter {
name = "other"
type = otherKind.capitalized
}
returnType = PrimitiveType.INT.capitalized returnType = PrimitiveType.INT.capitalized
)
this += MethodDescription(
doc = doc,
annotations = mutableListOf("kotlin.internal.IntrinsicConstEvaluation"),
signature = signature
).apply { this.modifyGeneratedCompareTo(thisKind, otherKind) }
}
}
}
private fun generateBinaryOperators(thisKind: PrimitiveType): List<MethodDescription> {
return buildList {
for (name in binaryOperators) {
this += generateOperator(name, thisKind)
}
}
}
private fun generateOperator(name: String, thisKind: PrimitiveType): List<MethodDescription> {
return buildList {
for (otherKind in PrimitiveType.onlyNumeric) {
val returnType = getOperatorReturnType(thisKind, otherKind)
val annotations = buildList {
if (name == "rem") add("SinceKotlin(\"1.1\")")
add("kotlin.internal.IntrinsicConstEvaluation")
} }
}.modifyGeneratedCompareTo(thisKind, otherKind)
this += MethodDescription(
doc = binaryOperatorDoc(name, thisKind, otherKind),
annotations = annotations.toMutableList(),
signature = MethodSignature(
isOperator = true,
name = name,
arg = MethodParameter("other", otherKind.capitalized),
returnType = returnType.capitalized
)
).apply { this.modifyGeneratedBinaryOperation(thisKind, otherKind) }
}
} }
} }
private fun generateUnaryOperators(thisKind: PrimitiveType): List<MethodDescription> { private fun ClassBuilder.generateBinaryOperators(thisKind: PrimitiveType) {
return buildList { for (name in binaryOperators) {
for (name in listOf("inc", "dec")) { generateOperator(name, thisKind)
this += MethodDescription(
doc = incDecOperatorsDoc(name),
signature = MethodSignature(isOperator = true, name = name, arg = null, returnType = thisKind.capitalized)
).apply { this.modifyGeneratedUnaryOperation(thisKind) }
}
for ((name, doc) in unaryPlusMinusOperators) {
val returnType = when (thisKind) {
in listOf(PrimitiveType.SHORT, PrimitiveType.BYTE, PrimitiveType.CHAR) -> PrimitiveType.INT.capitalized
else -> thisKind.capitalized
}
this += MethodDescription(
doc = doc,
annotations = mutableListOf("kotlin.internal.IntrinsicConstEvaluation"),
signature = MethodSignature(isOperator = true, name = name, arg = null, returnType = returnType)
).apply { this.modifyGeneratedUnaryOperation(thisKind) }
}
} }
} }
private fun generateRangeTo(thisKind: PrimitiveType): List<MethodDescription> { private fun ClassBuilder.generateOperator(operatorName: String, thisKind: PrimitiveType) {
return buildList { for (otherKind in PrimitiveType.onlyNumeric) {
for (otherKind in PrimitiveType.onlyNumeric) { val opReturnType = getOperatorReturnType(thisKind, otherKind)
val returnType = maxByDomainCapacity(maxByDomainCapacity(thisKind, otherKind), PrimitiveType.INT)
if (returnType == PrimitiveType.DOUBLE || returnType == PrimitiveType.FLOAT) { val annotationsToAdd = buildList {
continue if (operatorName == "rem") add("SinceKotlin(\"1.1\")")
} add("kotlin.internal.IntrinsicConstEvaluation")
this += MethodDescription(
doc = "Creates a range from this value to the specified [other] value.",
signature = MethodSignature(
isOperator = true,
name = "rangeTo",
arg = MethodParameter("other", otherKind.capitalized),
returnType = "${returnType.capitalized}Range"
)
).apply { this.modifyGeneratedRangeTo(thisKind) }
} }
method {
appendDoc(binaryOperatorDoc(operatorName, thisKind, otherKind))
annotations += annotationsToAdd
signature {
isOperator = true
methodName = operatorName
parameter {
name = "other"
type = otherKind.capitalized
}
returnType = opReturnType.capitalized
}
}.modifyGeneratedBinaryOperation(thisKind, otherKind)
} }
} }
private fun generateRangeUntil(thisKind: PrimitiveType): List<MethodDescription> { private fun ClassBuilder.generateUnaryOperators(thisKind: PrimitiveType) {
return buildList { for (operatorName in listOf("inc", "dec")) {
for (otherKind in PrimitiveType.onlyNumeric) { method {
val returnType = maxByDomainCapacity(maxByDomainCapacity(thisKind, otherKind), PrimitiveType.INT) appendDoc(incDecOperatorsDoc(operatorName))
signature {
if (returnType == PrimitiveType.DOUBLE || returnType == PrimitiveType.FLOAT) { isOperator = true
continue methodName = operatorName
returnType = thisKind.capitalized
} }
}.modifyGeneratedUnaryOperation(thisKind)
}
this += MethodDescription( for ((operatorName, doc) in unaryPlusMinusOperators) {
doc = """ val opReturnType = when (thisKind) {
in listOf(PrimitiveType.SHORT, PrimitiveType.BYTE, PrimitiveType.CHAR) -> PrimitiveType.INT.capitalized
else -> thisKind.capitalized
}
method {
appendDoc(doc)
annotations += "kotlin.internal.IntrinsicConstEvaluation"
signature {
isOperator = true
methodName = operatorName
returnType = opReturnType
}
}.modifyGeneratedUnaryOperation(thisKind)
}
}
private fun ClassBuilder.generateRangeTo(thisKind: PrimitiveType) {
for (otherKind in PrimitiveType.onlyNumeric) {
val opReturnType = maxByDomainCapacity(maxByDomainCapacity(thisKind, otherKind), PrimitiveType.INT)
if (opReturnType == PrimitiveType.DOUBLE || opReturnType == PrimitiveType.FLOAT) {
continue
}
method {
appendDoc("Creates a range from this value to the specified [other] value.")
signature {
isOperator = true
methodName = "rangeTo"
parameter {
name = "other"
type = otherKind.capitalized
}
returnType = "${opReturnType.capitalized}Range"
}
}.modifyGeneratedRangeTo(thisKind)
}
}
private fun ClassBuilder.generateRangeUntil(thisKind: PrimitiveType) {
for (otherKind in PrimitiveType.onlyNumeric) {
val opReturnType = maxByDomainCapacity(maxByDomainCapacity(thisKind, otherKind), PrimitiveType.INT)
if (opReturnType == PrimitiveType.DOUBLE || opReturnType == PrimitiveType.FLOAT) {
continue
}
method {
appendDoc(
"""
Creates a range from this value up to but excluding the specified [other] value. 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. If the [other] value is less than or equal to `this` value, then the returned range is empty.
""".trimIndent(), """.trimIndent()
annotations = mutableListOf("SinceKotlin(\"1.7\")", "ExperimentalStdlibApi"),
signature = MethodSignature(
isOperator = true,
name = "rangeUntil",
arg = MethodParameter("other", otherKind.capitalized),
returnType = "${returnType.capitalized}Range"
)
).apply { this.modifyGeneratedRangeUntil(thisKind) }
}
}
}
private fun generateBitShiftOperators(thisKind: PrimitiveType): List<MethodDescription> {
return buildList {
val className = thisKind.capitalized
val detail = shiftOperatorsDocDetail(thisKind)
for ((name, doc) in shiftOperators) {
this += MethodDescription(
doc = doc + END_LINE + END_LINE + detail,
annotations = mutableListOf("kotlin.internal.IntrinsicConstEvaluation"),
signature = MethodSignature(
isInfix = true,
name = name,
arg = MethodParameter("bitCount", PrimitiveType.INT.capitalized),
returnType = className
)
).apply { this.modifyGeneratedBitShiftOperators(thisKind) }
}
}
}
private fun generateBitwiseOperators(thisKind: PrimitiveType): List<MethodDescription> {
return buildList {
for ((name, doc) in bitwiseOperators) {
this += MethodDescription(
doc = doc,
annotations = mutableListOf("kotlin.internal.IntrinsicConstEvaluation"),
signature = MethodSignature(
isInfix = true,
name = name,
arg = MethodParameter("other", thisKind.capitalized),
returnType = thisKind.capitalized
)
).apply { this.modifyGeneratedBitwiseOperators(thisKind) }
}
this += MethodDescription(
doc = "Inverts the bits in this value.",
annotations = mutableListOf("kotlin.internal.IntrinsicConstEvaluation"),
signature = MethodSignature(
name = "inv",
arg = null,
returnType = thisKind.capitalized
) )
).apply { this.modifyGeneratedBitwiseOperators(thisKind) } annotations += mutableListOf("SinceKotlin(\"1.7\")", "ExperimentalStdlibApi")
signature {
isOperator = true
methodName = "rangeUntil"
parameter {
name = "other"
type = otherKind.capitalized
}
returnType = "${opReturnType.capitalized}Range"
}
}.modifyGeneratedRangeUntil(thisKind)
} }
} }
private fun generateConversions(thisKind: PrimitiveType): List<MethodDescription> { private fun ClassBuilder.generateBitShiftOperators(thisKind: PrimitiveType) {
val className = thisKind.capitalized
val detail = shiftOperatorsDocDetail(thisKind)
for ((operatorName, doc) in shiftOperators) {
method {
appendDoc(doc + END_LINE + END_LINE + detail)
annotations += "kotlin.internal.IntrinsicConstEvaluation"
signature {
isInfix = true
methodName = operatorName
parameter {
name = "bitCount"
type = PrimitiveType.INT.capitalized
}
returnType = className
}
}.modifyGeneratedBitShiftOperators(thisKind)
}
}
private fun ClassBuilder.generateBitwiseOperators(thisKind: PrimitiveType) {
for ((operatorName, doc) in bitwiseOperators) {
method {
appendDoc(doc)
annotations += "kotlin.internal.IntrinsicConstEvaluation"
signature {
isInfix = true
methodName = operatorName
parameter {
name = "other"
type = thisKind.capitalized
}
returnType = thisKind.capitalized
}
}.modifyGeneratedBitwiseOperators(thisKind)
}
method {
appendDoc("Inverts the bits in this value.")
annotations += "kotlin.internal.IntrinsicConstEvaluation"
signature {
methodName = "inv"
returnType = thisKind.capitalized
}
}.modifyGeneratedBitwiseOperators(thisKind)
}
private fun ClassBuilder.generateConversions(thisKind: PrimitiveType) {
fun isFpToIntConversionDeprecated(otherKind: PrimitiveType): Boolean { fun isFpToIntConversionDeprecated(otherKind: PrimitiveType): Boolean {
return thisKind in PrimitiveType.floatingPoint && otherKind in listOf(PrimitiveType.BYTE, PrimitiveType.SHORT) return thisKind in PrimitiveType.floatingPoint && otherKind in listOf(PrimitiveType.BYTE, PrimitiveType.SHORT)
} }
@@ -530,94 +538,94 @@ abstract class BasePrimitivesGenerator(private val writer: PrintWriter) : BuiltI
return thisKind != PrimitiveType.INT && otherKind == PrimitiveType.CHAR return thisKind != PrimitiveType.INT && otherKind == PrimitiveType.CHAR
} }
return buildList { val thisName = thisKind.capitalized
val thisName = thisKind.capitalized for (otherKind in PrimitiveType.exceptBoolean) {
for (otherKind in PrimitiveType.exceptBoolean) { val otherName = otherKind.capitalized
val otherName = otherKind.capitalized val doc = if (thisKind == otherKind) {
val doc = if (thisKind == otherKind) { "Returns this value."
"Returns this value." } else {
} else { val detail = if (thisKind in PrimitiveType.integral) {
val detail = if (thisKind in PrimitiveType.integral) { if (otherKind.isIntegral) {
if (otherKind.isIntegral) { docForConversionFromIntegralToIntegral(thisKind, otherKind)
docForConversionFromIntegralToIntegral(thisKind, otherKind)
} else {
docForConversionFromIntegralToFloating(thisKind, otherKind)
}
} else { } else {
if (otherKind.isIntegral) { docForConversionFromIntegralToFloating(thisKind, otherKind)
docForConversionFromFloatingToIntegral(thisKind, otherKind) }
} else { } else {
docForConversionFromFloatingToFloating(thisKind, otherKind) if (otherKind.isIntegral) {
} docForConversionFromFloatingToIntegral(thisKind, otherKind)
} else {
docForConversionFromFloatingToFloating(thisKind, otherKind)
} }
"Converts this [$thisName] value to [$otherName].$END_LINE$END_LINE" + detail
} }
val annotations = mutableListOf<String>() "Converts this [$thisName] value to [$otherName].$END_LINE$END_LINE$detail"
if (isFpToIntConversionDeprecated(otherKind)) {
annotations += "Deprecated(\"Unclear conversion. To achieve the same result convert to Int explicitly and then to $otherName.\", ReplaceWith(\"toInt().to$otherName()\"))"
annotations += "DeprecatedSinceKotlin(warningSince = \"1.3\", errorSince = \"1.5\")"
}
if (isCharConversionDeprecated(otherKind)) {
annotations += "Deprecated(\"Direct conversion to Char is deprecated. Use toInt().toChar() or Char constructor instead.\", ReplaceWith(\"this.toInt().toChar()\"))"
annotations += "DeprecatedSinceKotlin(warningSince = \"1.5\")"
}
annotations += "kotlin.internal.IntrinsicConstEvaluation"
this += MethodDescription(
doc = doc,
annotations = annotations,
signature = MethodSignature(
isOverride = true,
name = "to$otherName",
arg = null,
returnType = otherName
)
).apply { this.modifyGeneratedConversions(thisKind) }
} }
val annotationsToAdd = mutableListOf<String>()
if (isFpToIntConversionDeprecated(otherKind)) {
annotationsToAdd += "Deprecated(\"Unclear conversion. To achieve the same result convert to Int explicitly and then to $otherName.\", ReplaceWith(\"toInt().to$otherName()\"))"
annotationsToAdd += "DeprecatedSinceKotlin(warningSince = \"1.3\", errorSince = \"1.5\")"
}
if (isCharConversionDeprecated(otherKind)) {
annotationsToAdd += "Deprecated(\"Direct conversion to Char is deprecated. Use toInt().toChar() or Char constructor instead.\", ReplaceWith(\"this.toInt().toChar()\"))"
annotationsToAdd += "DeprecatedSinceKotlin(warningSince = \"1.5\", errorSince = \"2.3\")"
}
if (thisKind == PrimitiveType.INT && otherKind == PrimitiveType.CHAR) {
annotationsToAdd += "Suppress(\"OVERRIDE_DEPRECATION\")"
}
annotationsToAdd += "kotlin.internal.IntrinsicConstEvaluation"
method {
appendDoc(doc)
annotations += annotationsToAdd
signature {
isOverride = true
methodName = "to$otherName"
returnType = otherName
}
}.modifyGeneratedConversions(thisKind)
} }
} }
private fun generateEquals(thisKind: PrimitiveType): MethodDescription { private fun ClassBuilder.generateEquals(thisKind: PrimitiveType) {
return MethodDescription( method {
doc = null, annotations += "kotlin.internal.IntrinsicConstEvaluation"
annotations = mutableListOf("kotlin.internal.IntrinsicConstEvaluation"), signature {
signature = MethodSignature( isOverride = true
isOverride = true, methodName = "equals"
name = "equals", parameter {
arg = MethodParameter("other", "Any?"), name = "other"
type = "Any?"
}
returnType = "Boolean" returnType = "Boolean"
) }
).apply { this.modifyGeneratedEquals(thisKind) } }.modifyGeneratedEquals(thisKind)
} }
private fun generateToString(thisKind: PrimitiveType): MethodDescription { private fun ClassBuilder.generateToString(thisKind: PrimitiveType) {
return MethodDescription( method {
doc = null, annotations += "kotlin.internal.IntrinsicConstEvaluation"
annotations = mutableListOf("kotlin.internal.IntrinsicConstEvaluation"), signature {
signature = MethodSignature( isOverride = true
isOverride = true, methodName = "toString"
name = "toString",
arg = null,
returnType = "String" returnType = "String"
) }
).apply { modifyGeneratedToString(thisKind) } }.modifyGeneratedToString(thisKind)
} }
internal open fun FileDescription.modifyGeneratedFile() {} internal open fun FileBuilder.modifyGeneratedFile() {}
internal open fun ClassDescription.modifyGeneratedClass(thisKind: PrimitiveType) {} internal open fun ClassBuilder.modifyGeneratedClass(thisKind: PrimitiveType) {}
internal open fun CompanionObjectDescription.modifyGeneratedCompanionObject(thisKind: PrimitiveType) {} internal open fun CompanionObjectBuilder.modifyGeneratedCompanionObject(thisKind: PrimitiveType) {}
internal open fun PropertyDescription.modifyGeneratedCompanionObjectProperty(thisKind: PrimitiveType) {} internal open fun PropertyBuilder.modifyGeneratedCompanionObjectProperty(thisKind: PrimitiveType) {}
internal open fun MethodDescription.modifyGeneratedCompareTo(thisKind: PrimitiveType, otherKind: PrimitiveType) {} internal open fun MethodBuilder.modifyGeneratedCompareTo(thisKind: PrimitiveType, otherKind: PrimitiveType) {}
internal open fun MethodDescription.modifyGeneratedBinaryOperation(thisKind: PrimitiveType, otherKind: PrimitiveType) {} internal open fun MethodBuilder.modifyGeneratedBinaryOperation(thisKind: PrimitiveType, otherKind: PrimitiveType) {}
internal open fun MethodDescription.modifyGeneratedUnaryOperation(thisKind: PrimitiveType) {} internal open fun MethodBuilder.modifyGeneratedUnaryOperation(thisKind: PrimitiveType) {}
internal open fun MethodDescription.modifyGeneratedRangeTo(thisKind: PrimitiveType) {} internal open fun MethodBuilder.modifyGeneratedRangeTo(thisKind: PrimitiveType) {}
internal open fun MethodDescription.modifyGeneratedRangeUntil(thisKind: PrimitiveType) {} internal open fun MethodBuilder.modifyGeneratedRangeUntil(thisKind: PrimitiveType) {}
internal open fun MethodDescription.modifyGeneratedBitShiftOperators(thisKind: PrimitiveType) {} internal open fun MethodBuilder.modifyGeneratedBitShiftOperators(thisKind: PrimitiveType) {}
internal open fun MethodDescription.modifyGeneratedBitwiseOperators(thisKind: PrimitiveType) {} internal open fun MethodBuilder.modifyGeneratedBitwiseOperators(thisKind: PrimitiveType) {}
internal open fun MethodDescription.modifyGeneratedConversions(thisKind: PrimitiveType) {} internal open fun MethodBuilder.modifyGeneratedConversions(thisKind: PrimitiveType) {}
internal open fun MethodDescription.modifyGeneratedEquals(thisKind: PrimitiveType) {} internal open fun MethodBuilder.modifyGeneratedEquals(thisKind: PrimitiveType) {}
internal open fun MethodDescription.modifyGeneratedToString(thisKind: PrimitiveType) {} internal open fun MethodBuilder.modifyGeneratedToString(thisKind: PrimitiveType) {}
internal open fun generateAdditionalMethods(thisKind: PrimitiveType): List<MethodDescription> = emptyList() internal open fun ClassBuilder.generateAdditionalMethods(thisKind: PrimitiveType) {}
} }
@@ -13,27 +13,28 @@ class JsPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(write
return this != PrimitiveType.LONG return this != PrimitiveType.LONG
} }
override fun FileDescription.modifyGeneratedFile() { override fun FileBuilder.modifyGeneratedFile() {
addSuppress("NON_ABSTRACT_FUNCTION_WITH_NO_BODY") suppress("NON_ABSTRACT_FUNCTION_WITH_NO_BODY")
addSuppress("UNUSED_PARAMETER") suppress("UNUSED_PARAMETER")
} }
override fun PropertyDescription.modifyGeneratedCompanionObjectProperty(thisKind: PrimitiveType) { override fun PropertyBuilder.modifyGeneratedCompanionObjectProperty(thisKind: PrimitiveType) {
if (this.name in setOf("POSITIVE_INFINITY", "NEGATIVE_INFINITY", "NaN")) { if (this.name in setOf("POSITIVE_INFINITY", "NEGATIVE_INFINITY", "NaN")) {
this.addAnnotation("Suppress(\"DIVISION_BY_ZERO\")") annotations += "Suppress(\"DIVISION_BY_ZERO\")"
} }
} }
override fun generateAdditionalMethods(thisKind: PrimitiveType): List<MethodDescription> { override fun ClassBuilder.generateAdditionalMethods(thisKind: PrimitiveType) {
val hashCode = MethodDescription( method {
doc = null, signature {
signature = MethodSignature( isOverride = true
isOverride = true, methodName = "hashCode"
name = "hashCode",
arg = null,
returnType = PrimitiveType.INT.capitalized returnType = PrimitiveType.INT.capitalized
) }
) }
return listOf(hashCode) }
override fun MethodBuilder.modifyGeneratedRangeUntil(thisKind: PrimitiveType) {
"this until $parameterName".addAsSingleLineBody(bodyOnNewLine = false)
} }
} }
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.generators.builtins.PrimitiveType
import java.io.PrintWriter import java.io.PrintWriter
class JvmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(writer) { class JvmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(writer) {
override fun ClassDescription.modifyGeneratedClass(thisKind: PrimitiveType) { override fun ClassBuilder.modifyGeneratedClass(thisKind: PrimitiveType) {
this.addDoc("On the JVM, non-nullable values of this type are represented as values of the primitive type `${thisKind.name.lowercase()}`.") appendDoc("On the JVM, non-nullable values of this type are represented as values of the primitive type `${thisKind.name.lowercase()}`.")
} }
} }
@@ -10,19 +10,19 @@ import java.io.PrintWriter
import java.util.* import java.util.*
class NativePrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(writer) { class NativePrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(writer) {
override fun FileDescription.modifyGeneratedFile() { override fun FileBuilder.modifyGeneratedFile() {
this.addSuppress("OVERRIDE_BY_INLINE") suppress("OVERRIDE_BY_INLINE")
this.addSuppress("NOTHING_TO_INLINE") suppress("NOTHING_TO_INLINE")
this.addImport("kotlin.native.internal.*") import("kotlin.native.internal.*")
} }
override fun ClassDescription.modifyGeneratedClass(thisKind: PrimitiveType) { override fun ClassBuilder.modifyGeneratedClass(thisKind: PrimitiveType) {
this.isFinal = true this.isFinal = true
} }
override fun CompanionObjectDescription.modifyGeneratedCompanionObject(thisKind: PrimitiveType) { override fun CompanionObjectBuilder.modifyGeneratedCompanionObject(thisKind: PrimitiveType) {
if (thisKind !in PrimitiveType.floatingPoint) { if (thisKind !in PrimitiveType.floatingPoint) {
this.addAnnotation("CanBePrecreated") annotations += "CanBePrecreated"
} }
} }
@@ -37,25 +37,24 @@ class NativePrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(w
} }
} }
override fun PropertyDescription.modifyGeneratedCompanionObjectProperty(thisKind: PrimitiveType) { override fun PropertyBuilder.modifyGeneratedCompanionObjectProperty(thisKind: PrimitiveType) {
if (this.name in setOf("POSITIVE_INFINITY", "NEGATIVE_INFINITY", "NaN")) { if (this.name in setOf("POSITIVE_INFINITY", "NEGATIVE_INFINITY", "NaN")) {
this.addAnnotation("Suppress(\"DIVISION_BY_ZERO\")") annotations += "Suppress(\"DIVISION_BY_ZERO\")"
} }
} }
override fun MethodDescription.modifyGeneratedCompareTo(thisKind: PrimitiveType, otherKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedCompareTo(thisKind: PrimitiveType, otherKind: PrimitiveType) {
if (otherKind == thisKind) { if (otherKind == thisKind) {
if (thisKind in PrimitiveType.floatingPoint) { if (thisKind in PrimitiveType.floatingPoint) {
val argName = this.signature.arg!!.name
""" """
// if any of values in NaN both comparisons return false // if any of values in NaN both comparisons return false
if (this > $argName) return 1 if (this > $parameterName) return 1
if (this < $argName) return -1 if (this < $parameterName) return -1
val thisBits = this.toBits() val thisBits = this.toBits()
val otherBits = $argName.toBits() val otherBits = $parameterName.toBits()
// Canonical NaN bits representation higher than any other bit represent value // Canonical NaN bit representation is higher than any other value's bit representation
return thisBits.compareTo(otherBits) return thisBits.compareTo(otherBits)
""".trimIndent().addAsMultiLineBody() """.trimIndent().addAsMultiLineBody()
} else { } else {
@@ -64,172 +63,183 @@ class NativePrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(w
return return
} }
this.signature.isInline = thisKind !in PrimitiveType.floatingPoint modifySignature { isInline = thisKind !in PrimitiveType.floatingPoint }
val thisCasted = "this" + thisKind.castToIfNecessary(otherKind) val thisCasted = "this" + thisKind.castToIfNecessary(otherKind)
val otherCasted = this.signature.arg!!.name + otherKind.castToIfNecessary(thisKind) val otherCasted = parameterName + otherKind.castToIfNecessary(thisKind)
if (thisKind == PrimitiveType.FLOAT && otherKind == PrimitiveType.DOUBLE) { if (thisKind == PrimitiveType.FLOAT && otherKind == PrimitiveType.DOUBLE) {
"- ${otherCasted}.compareTo(this)" "-${otherCasted}.compareTo(this)"
} else { } else {
"$thisCasted.compareTo($otherCasted)" "$thisCasted.compareTo($otherCasted)"
}.addAsSingleLineBody(bodyOnNewLine = true) }.addAsSingleLineBody(bodyOnNewLine = true)
} }
override fun MethodDescription.modifyGeneratedBinaryOperation(thisKind: PrimitiveType, otherKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedBinaryOperation(thisKind: PrimitiveType, otherKind: PrimitiveType) {
val sign = this.signature.name.asSign() val sign = operatorSign(this.methodName)
if (thisKind != PrimitiveType.BYTE && thisKind != PrimitiveType.SHORT && thisKind == otherKind) { if (thisKind != PrimitiveType.BYTE && thisKind != PrimitiveType.SHORT && thisKind == otherKind) {
return setAsExternal() return setAsExternal()
} }
this.signature.isInline = true modifySignature { isInline = true }
val returnTypeAsPrimitive = PrimitiveType.valueOf(this.signature.returnType.uppercase()) val returnTypeAsPrimitive = PrimitiveType.valueOf(returnType.uppercase())
val thisCasted = "this" + thisKind.castToIfNecessary(returnTypeAsPrimitive) val thisCasted = "this" + thisKind.castToIfNecessary(returnTypeAsPrimitive)
val otherCasted = this.signature.arg!!.name + this.signature.arg.getTypeAsPrimitive().castToIfNecessary(returnTypeAsPrimitive) val otherCasted = parameterName + parameterType.toPrimitiveType().castToIfNecessary(returnTypeAsPrimitive)
"$thisCasted $sign $otherCasted".addAsSingleLineBody(bodyOnNewLine = true) "$thisCasted $sign $otherCasted".addAsSingleLineBody(bodyOnNewLine = true)
} }
override fun MethodDescription.modifyGeneratedUnaryOperation(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedUnaryOperation(thisKind: PrimitiveType) {
if (this.signature.name in setOf("inc", "dec") || thisKind == PrimitiveType.INT || if (methodName in setOf("inc", "dec") || thisKind == PrimitiveType.INT ||
thisKind in PrimitiveType.floatingPoint || (this.signature.name == "unaryMinus" && thisKind == PrimitiveType.LONG) thisKind in PrimitiveType.floatingPoint || (methodName == "unaryMinus" && thisKind == PrimitiveType.LONG)
) { ) {
return setAsExternal() return setAsExternal()
} }
this.signature.isInline = true modifySignature { isInline = true }
val returnTypeAsPrimitive = PrimitiveType.valueOf(this.signature.returnType.uppercase()) val returnTypeAsPrimitive = PrimitiveType.valueOf(returnType.uppercase())
val thisCasted = "this" + thisKind.castToIfNecessary(returnTypeAsPrimitive) val thisCasted = "this" + thisKind.castToIfNecessary(returnTypeAsPrimitive)
val sign = if (this.signature.name == "unaryMinus") "-" else "" val sign = if (methodName == "unaryMinus") "-" else ""
"$sign$thisCasted".addAsSingleLineBody(bodyOnNewLine = true) "$sign$thisCasted".addAsSingleLineBody(bodyOnNewLine = true)
} }
override fun MethodDescription.modifyGeneratedRangeTo(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedRangeTo(thisKind: PrimitiveType) {
val rangeType = PrimitiveType.valueOf(this.signature.returnType.replace("Range", "").uppercase()) val rangeType = PrimitiveType.valueOf(returnType.replace("Range", "").uppercase())
val thisCasted = "this" + thisKind.castToIfNecessary(rangeType) val thisCasted = "this" + thisKind.castToIfNecessary(rangeType)
val otherCasted = this.signature.arg!!.name + this.signature.arg.getTypeAsPrimitive().castToIfNecessary(rangeType) val otherCasted = parameterName + parameterType.toPrimitiveType().castToIfNecessary(rangeType)
"return ${this.signature.returnType}($thisCasted, $otherCasted)".addAsMultiLineBody() "return ${returnType}($thisCasted, $otherCasted)".addAsMultiLineBody()
} }
override fun MethodDescription.modifyGeneratedRangeUntil(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedRangeUntil(thisKind: PrimitiveType) {
"this until ${this.signature.arg!!.name}".addAsSingleLineBody(bodyOnNewLine = false) "this until $parameterName".addAsSingleLineBody(bodyOnNewLine = false)
} }
override fun MethodDescription.modifyGeneratedBitShiftOperators(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedBitShiftOperators(thisKind: PrimitiveType) {
setAsExternal() setAsExternal()
} }
override fun MethodDescription.modifyGeneratedBitwiseOperators(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedBitwiseOperators(thisKind: PrimitiveType) {
setAsExternal() setAsExternal()
} }
override fun MethodDescription.modifyGeneratedConversions(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedConversions(thisKind: PrimitiveType) {
val returnTypeAsPrimitive = PrimitiveType.valueOf(this.signature.returnType.uppercase()) val returnTypeAsPrimitive = PrimitiveType.valueOf(returnType.uppercase())
when { when {
returnTypeAsPrimitive == thisKind -> { returnTypeAsPrimitive == thisKind -> {
this.signature.isInline = true modifySignature { isInline = true }
"this".addAsSingleLineBody(bodyOnNewLine = true) "this".addAsSingleLineBody(bodyOnNewLine = true)
} }
thisKind !in PrimitiveType.floatingPoint -> { thisKind !in PrimitiveType.floatingPoint -> {
this.signature.isExternal = true modifySignature { isExternal = true }
val intrinsicType = when { val intrinsicType = when {
returnTypeAsPrimitive in PrimitiveType.floatingPoint -> "SIGNED_TO_FLOAT" returnTypeAsPrimitive in PrimitiveType.floatingPoint -> "SIGNED_TO_FLOAT"
returnTypeAsPrimitive.byteSize < thisKind.byteSize -> "INT_TRUNCATE" returnTypeAsPrimitive.byteSize < thisKind.byteSize -> "INT_TRUNCATE"
returnTypeAsPrimitive.byteSize > thisKind.byteSize -> "SIGN_EXTEND" returnTypeAsPrimitive.byteSize > thisKind.byteSize -> "SIGN_EXTEND"
else -> "ZERO_EXTEND" else -> "ZERO_EXTEND"
} }
this.addAnnotation("TypedIntrinsic(IntrinsicType.$intrinsicType)") annotations += "TypedIntrinsic(IntrinsicType.$intrinsicType)"
} }
else -> { else -> {
if (returnTypeAsPrimitive in setOf(PrimitiveType.BYTE, PrimitiveType.SHORT, PrimitiveType.CHAR)) { if (returnTypeAsPrimitive in setOf(PrimitiveType.BYTE, PrimitiveType.SHORT, PrimitiveType.CHAR)) {
"this.toInt().to${this.signature.returnType}()".addAsSingleLineBody(bodyOnNewLine = false) "this.toInt().to${returnType}()".addAsSingleLineBody(bodyOnNewLine = false)
return return
} }
this.signature.isExternal = true modifySignature { isExternal = true }
when { when {
returnTypeAsPrimitive in setOf(PrimitiveType.INT, PrimitiveType.LONG) -> { returnTypeAsPrimitive in setOf(PrimitiveType.INT, PrimitiveType.LONG) -> {
this.addAnnotation("GCUnsafeCall(\"Kotlin_${thisKind.capitalized}_to${this.signature.returnType}\")") annotations += "GCUnsafeCall(\"Kotlin_${thisKind.capitalized}_to${returnType}\")"
} }
thisKind.byteSize > returnTypeAsPrimitive.byteSize -> { thisKind.byteSize > returnTypeAsPrimitive.byteSize -> {
this.addAnnotation("TypedIntrinsic(IntrinsicType.FLOAT_TRUNCATE)") annotations += "TypedIntrinsic(IntrinsicType.FLOAT_TRUNCATE)"
} }
thisKind.byteSize < returnTypeAsPrimitive.byteSize -> { thisKind.byteSize < returnTypeAsPrimitive.byteSize -> {
this.addAnnotation("TypedIntrinsic(IntrinsicType.FLOAT_EXTEND)") annotations += "TypedIntrinsic(IntrinsicType.FLOAT_EXTEND)"
} }
} }
} }
} }
} }
override fun MethodDescription.modifyGeneratedEquals(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedEquals(thisKind: PrimitiveType) {
val argName = this.signature.arg!!.name
val additionalCheck = if (thisKind in PrimitiveType.floatingPoint) { val additionalCheck = if (thisKind in PrimitiveType.floatingPoint) {
"this.equals(other)" "this.equals(other)"
} else { } else {
"kotlin.native.internal.areEqualByValue(this, $argName)" "kotlin.native.internal.areEqualByValue(this, $parameterName)"
} }
" $argName is ${thisKind.capitalized} && $additionalCheck".addAsSingleLineBody(bodyOnNewLine = true) "$parameterName is ${thisKind.capitalized} && $additionalCheck".addAsSingleLineBody(bodyOnNewLine = true)
} }
override fun MethodDescription.modifyGeneratedToString(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedToString(thisKind: PrimitiveType) {
if (thisKind in PrimitiveType.floatingPoint) { if (thisKind in PrimitiveType.floatingPoint) {
appendDoc("Returns the string representation of this [${thisKind.capitalized}] value.\n")
"""
Note that the representation format is unstable and may change in a future release.
However, it is guaranteed that the returned string is valid for converting back to [${thisKind.capitalized}]
using [String.to${thisKind.capitalized}], and will result in the same numeric value.
The exact bit pattern of a `NaN` ${thisKind.name.lowercase()} is not guaranteed to be preserved though.
""".trimIndent().let { appendDoc(it) }
"NumberConverter.convert(this)".addAsSingleLineBody(bodyOnNewLine = false) "NumberConverter.convert(this)".addAsSingleLineBody(bodyOnNewLine = false)
} else { } else {
this.signature.isExternal = true modifySignature { isExternal = true }
this.addAnnotation("GCUnsafeCall(\"Kotlin_${thisKind.capitalized}_toString\")") annotations += "GCUnsafeCall(\"Kotlin_${thisKind.capitalized}_toString\")"
} }
} }
override fun generateAdditionalMethods(thisKind: PrimitiveType): List<MethodDescription> { override fun ClassBuilder.generateAdditionalMethods(thisKind: PrimitiveType) {
val hashCode = MethodDescription( generateCustomEquals(thisKind)
doc = null, generateHashCode(thisKind)
signature = MethodSignature( if (thisKind in PrimitiveType.floatingPoint) {
isOverride = true, generateBits(thisKind)
name = "hashCode",
arg = null,
returnType = PrimitiveType.INT.capitalized
)
).apply {
when (thisKind) {
PrimitiveType.LONG -> "return ((this ushr 32) xor this).toInt()".addAsMultiLineBody()
PrimitiveType.FLOAT -> "toBits()".addAsSingleLineBody()
PrimitiveType.DOUBLE -> "toBits().hashCode()".addAsSingleLineBody()
else -> "return this${thisKind.castToIfNecessary(PrimitiveType.INT)}".addAsMultiLineBody()
}
} }
}
val customEquals = MethodDescription( private fun ClassBuilder.generateHashCode(thisKind: PrimitiveType) {
doc = null, method {
annotations = mutableListOf("kotlin.internal.IntrinsicConstEvaluation"), signature {
signature = MethodSignature( isOverride = true
name = "equals", methodName = "hashCode"
arg = MethodParameter("other", thisKind.capitalized), returnType = PrimitiveType.INT.capitalized
}
when (thisKind) {
PrimitiveType.LONG -> "((this ushr 32) xor this).toInt()"
PrimitiveType.FLOAT -> "toBits()"
PrimitiveType.DOUBLE -> "toBits().hashCode()"
else -> "this${thisKind.castToIfNecessary(PrimitiveType.INT)}"
}.addAsSingleLineBody()
}
}
private fun ClassBuilder.generateCustomEquals(thisKind: PrimitiveType) {
method {
annotations += "kotlin.internal.IntrinsicConstEvaluation"
signature {
methodName = "equals"
parameter {
name = "other"
type = thisKind.capitalized
}
returnType = PrimitiveType.BOOLEAN.capitalized returnType = PrimitiveType.BOOLEAN.capitalized
) }
).apply {
when (thisKind) { when (thisKind) {
in PrimitiveType.floatingPoint -> "toBits() == other.toBits()".addAsSingleLineBody(bodyOnNewLine = false) in PrimitiveType.floatingPoint -> "toBits() == other.toBits()".addAsSingleLineBody(bodyOnNewLine = false)
else -> "kotlin.native.internal.areEqualByValue(this, other)".addAsSingleLineBody(bodyOnNewLine = false) else -> "kotlin.native.internal.areEqualByValue(this, other)".addAsSingleLineBody(bodyOnNewLine = false)
} }
} }
}
val bits = MethodDescription( private fun ClassBuilder.generateBits(thisKind: PrimitiveType) {
doc = null, method {
signature = MethodSignature( signature {
isExternal = true, isExternal = true
visibility = MethodVisibility.INTERNAL, visibility = MethodVisibility.INTERNAL
name = "bits", methodName = "bits"
arg = null,
returnType = if (thisKind == PrimitiveType.FLOAT) PrimitiveType.INT.capitalized else PrimitiveType.LONG.capitalized returnType = if (thisKind == PrimitiveType.FLOAT) PrimitiveType.INT.capitalized else PrimitiveType.LONG.capitalized
) }
).apply {
this.addAnnotation("TypedIntrinsic(IntrinsicType.REINTERPRET)")
this.addAnnotation("PublishedApi")
}
return if (thisKind in PrimitiveType.floatingPoint) { annotations += "TypedIntrinsic(IntrinsicType.REINTERPRET)"
listOf(customEquals, hashCode, bits) annotations += "PublishedApi"
} else {
listOf(customEquals, hashCode)
} }
} }
@@ -241,9 +251,9 @@ class NativePrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(w
return this.uppercase(Locale.getDefault()) return this.uppercase(Locale.getDefault())
} }
private fun MethodDescription.setAsExternal() { private fun MethodBuilder.setAsExternal() {
addAnnotation("TypedIntrinsic(IntrinsicType.${this.signature.name.toNativeOperator()})") annotations += "TypedIntrinsic(IntrinsicType.${methodName.toNativeOperator()})"
this.signature.isExternal = true modifySignature { isExternal = true }
} }
} }
} }
@@ -10,21 +10,24 @@ import java.io.PrintWriter
import java.util.* import java.util.*
class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(writer) { class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(writer) {
override fun FileDescription.modifyGeneratedFile() { override fun FileBuilder.modifyGeneratedFile() {
this.addSuppress("OVERRIDE_BY_INLINE") suppress("OVERRIDE_BY_INLINE")
this.addSuppress("NOTHING_TO_INLINE") suppress("NOTHING_TO_INLINE")
this.addSuppress("unused") suppress("unused")
this.addSuppress("UNUSED_PARAMETER") suppress("UNUSED_PARAMETER")
this.addImport("kotlin.wasm.internal.*") import("kotlin.wasm.internal.*")
} }
override fun ClassDescription.modifyGeneratedClass(thisKind: PrimitiveType) { override fun ClassBuilder.modifyGeneratedClass(thisKind: PrimitiveType) {
addAnnotation("WasmAutoboxed") annotations += "WasmAutoboxed"
// used here little hack with name extension just to avoid creation of specialized "ConstructorParameterDescription" // used here little hack with name extension just to avoid creation of specialized "ConstructorParameterDescription"
constructorArg = MethodParameter("private val value", thisKind.capitalized) constructorParam {
name = "private val value"
type = thisKind.capitalized
}
} }
override fun CompanionObjectDescription.modifyGeneratedCompanionObject(thisKind: PrimitiveType) { override fun CompanionObjectBuilder.modifyGeneratedCompanionObject(thisKind: PrimitiveType) {
isPublic = true isPublic = true
} }
@@ -39,36 +42,35 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
} }
} }
override fun PropertyDescription.modifyGeneratedCompanionObjectProperty(thisKind: PrimitiveType) { override fun PropertyBuilder.modifyGeneratedCompanionObjectProperty(thisKind: PrimitiveType) {
if (this.name in setOf("POSITIVE_INFINITY", "NEGATIVE_INFINITY", "NaN")) { if (this.name in setOf("POSITIVE_INFINITY", "NEGATIVE_INFINITY", "NaN")) {
this.addAnnotation("Suppress(\"DIVISION_BY_ZERO\")") annotations += "Suppress(\"DIVISION_BY_ZERO\")"
} }
} }
override fun MethodDescription.modifyGeneratedCompareTo(thisKind: PrimitiveType, otherKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedCompareTo(thisKind: PrimitiveType, otherKind: PrimitiveType) {
if (thisKind != otherKind || thisKind !in PrimitiveType.floatingPoint) { if (thisKind != otherKind || thisKind !in PrimitiveType.floatingPoint) {
this.signature.isInline = true modifySignature { isInline = true }
} }
val argName = this.signature.arg!!.name
if (otherKind == thisKind) { if (otherKind == thisKind) {
if (thisKind in PrimitiveType.floatingPoint) { if (thisKind in PrimitiveType.floatingPoint) {
""" """
// if any of values in NaN both comparisons return false // if any of values in NaN both comparisons return false
if (this > $argName) return 1 if (this > $parameterName) return 1
if (this < $argName) return -1 if (this < $parameterName) return -1
val thisBits = this.toBits() val thisBits = this.toBits()
val otherBits = $argName.toBits() val otherBits = $parameterName.toBits()
// Canonical NaN bits representation higher than any other bit represent value // Canonical NaN bit representation is higher than any other value's bit representation
return thisBits.compareTo(otherBits) return thisBits.compareTo(otherBits)
""".trimIndent().addAsMultiLineBody() """.trimIndent().addAsMultiLineBody()
} else { } else {
val body = when (thisKind) { val body = when (thisKind) {
PrimitiveType.BYTE -> "wasm_i32_compareTo(this.toInt(), $argName.toInt())" PrimitiveType.BYTE -> "wasm_i32_compareTo(this.toInt(), $parameterName.toInt())"
PrimitiveType.SHORT -> "this.toInt().compareTo($argName.toInt())" PrimitiveType.SHORT -> "this.toInt().compareTo($parameterName.toInt())"
PrimitiveType.INT, PrimitiveType.LONG -> "wasm_${thisKind.prefixLowercase}_compareTo(this, $argName)" PrimitiveType.INT, PrimitiveType.LONG -> "wasm_${thisKind.prefixLowercase}_compareTo(this, $parameterName)"
else -> throw IllegalArgumentException("Unsupported type $thisKind for generation `compareTo` method") else -> throw IllegalArgumentException("Unsupported type $thisKind for generation `compareTo` method")
} }
body.addAsSingleLineBody(bodyOnNewLine = true) body.addAsSingleLineBody(bodyOnNewLine = true)
@@ -77,29 +79,29 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
} }
val thisCasted = "this" + thisKind.castToIfNecessary(otherKind) val thisCasted = "this" + thisKind.castToIfNecessary(otherKind)
val otherCasted = argName + otherKind.castToIfNecessary(thisKind) val otherCasted = parameterName + otherKind.castToIfNecessary(thisKind)
when { when {
thisKind == PrimitiveType.FLOAT && otherKind == PrimitiveType.DOUBLE -> "- ${otherCasted}.compareTo(this)" thisKind == PrimitiveType.FLOAT && otherKind == PrimitiveType.DOUBLE -> "-${otherCasted}.compareTo(this)"
else -> "$thisCasted.compareTo($otherCasted)" else -> "$thisCasted.compareTo($otherCasted)"
}.addAsSingleLineBody(bodyOnNewLine = true) }.addAsSingleLineBody(bodyOnNewLine = true)
} }
override fun MethodDescription.modifyGeneratedBinaryOperation(thisKind: PrimitiveType, otherKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedBinaryOperation(thisKind: PrimitiveType, otherKind: PrimitiveType) {
val sign = this.signature.name.asSign() val sign = operatorSign(methodName)
val argName = this.signature.arg!!.name
if (thisKind != PrimitiveType.BYTE && thisKind != PrimitiveType.SHORT && thisKind == otherKind) { if (thisKind != PrimitiveType.BYTE && thisKind != PrimitiveType.SHORT && thisKind == otherKind) {
val type = thisKind.capitalized val type = thisKind.capitalized
when (val methodName = this.signature.name) { when (methodName) {
"div" -> { "div" -> {
val oneConst = if (thisKind == PrimitiveType.LONG) "-1L" else "-1" val oneConst = if (thisKind == PrimitiveType.LONG) "-1L" else "-1"
when (thisKind) { when (thisKind) {
PrimitiveType.INT, PrimitiveType.LONG -> "if (this == $type.MIN_VALUE && $argName == $oneConst) $type.MIN_VALUE else wasm_${thisKind.prefixLowercase}_div_s(this, $argName)" PrimitiveType.INT, PrimitiveType.LONG -> "if (this == $type.MIN_VALUE && $parameterName == $oneConst) $type.MIN_VALUE " +
"else wasm_${thisKind.prefixLowercase}_div_s(this, $parameterName)"
else -> return implementAsIntrinsic(thisKind, methodName) else -> return implementAsIntrinsic(thisKind, methodName)
} }
} }
"rem" -> when (thisKind) { "rem" -> when (thisKind) {
in PrimitiveType.floatingPoint -> "this - (wasm_${thisKind.prefixLowercase}_nearest(this / $argName) * $argName)" in PrimitiveType.floatingPoint -> "this - (wasm_${thisKind.prefixLowercase}_nearest(this / $parameterName) * $parameterName)"
else -> return implementAsIntrinsic(thisKind, methodName) else -> return implementAsIntrinsic(thisKind, methodName)
} }
else -> return implementAsIntrinsic(thisKind, methodName) else -> return implementAsIntrinsic(thisKind, methodName)
@@ -107,19 +109,18 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
return return
} }
this.signature.isInline = true modifySignature { isInline = true }
val returnTypeAsPrimitive = PrimitiveType.valueOf(this.signature.returnType.uppercase()) val returnTypeAsPrimitive = PrimitiveType.valueOf(returnType.uppercase())
val thisCasted = "this" + thisKind.castToIfNecessary(returnTypeAsPrimitive) val thisCasted = "this" + thisKind.castToIfNecessary(returnTypeAsPrimitive)
val otherCasted = argName + this.signature.arg.getTypeAsPrimitive().castToIfNecessary(returnTypeAsPrimitive) val otherCasted = parameterName + parameterType.toPrimitiveType().castToIfNecessary(returnTypeAsPrimitive)
"$thisCasted $sign $otherCasted".addAsSingleLineBody(bodyOnNewLine = true) "$thisCasted $sign $otherCasted".addAsSingleLineBody(bodyOnNewLine = true)
} }
override fun MethodDescription.modifyGeneratedUnaryOperation(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedUnaryOperation(thisKind: PrimitiveType) {
val methodName = this.signature.name
if (thisKind == PrimitiveType.INT && methodName == "dec") { if (thisKind == PrimitiveType.INT && methodName == "dec") {
setAdditionalDoc("TODO: Fix test compiler/testData/codegen/box/functions/invoke/invoke.kt with inline dec") additionalDoc = "TODO: Fix test compiler/testData/codegen/box/functions/invoke/invoke.kt with inline dec"
} else { } else {
this.signature.isInline = true modifySignature { isInline = true }
} }
if (methodName in setOf("inc", "dec")) { if (methodName in setOf("inc", "dec")) {
@@ -139,7 +140,7 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
return implementAsIntrinsic(thisKind, methodName) return implementAsIntrinsic(thisKind, methodName)
} }
val returnTypeAsPrimitive = PrimitiveType.valueOf(this.signature.returnType.uppercase()) val returnTypeAsPrimitive = PrimitiveType.valueOf(returnType.uppercase())
val thisCasted = "this" + thisKind.castToIfNecessary(returnTypeAsPrimitive) val thisCasted = "this" + thisKind.castToIfNecessary(returnTypeAsPrimitive)
val sign = if (methodName == "unaryMinus") { val sign = if (methodName == "unaryMinus") {
when (thisKind) { when (thisKind) {
@@ -152,41 +153,41 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
} }
} }
override fun MethodDescription.modifyGeneratedRangeTo(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedRangeTo(thisKind: PrimitiveType) {
val rangeType = PrimitiveType.valueOf(this.signature.returnType.replace("Range", "").uppercase()) val rangeType = PrimitiveType.valueOf(returnType.replace("Range", "").uppercase())
val thisCasted = "this" + thisKind.castToIfNecessary(rangeType) val thisCasted = "this" + thisKind.castToIfNecessary(rangeType)
val otherCasted = this.signature.arg!!.name + this.signature.arg.getTypeAsPrimitive().castToIfNecessary(rangeType) val otherCasted = parameterName + parameterType.toPrimitiveType().castToIfNecessary(rangeType)
"return ${this.signature.returnType}($thisCasted, $otherCasted)".addAsMultiLineBody() "return ${returnType}($thisCasted, $otherCasted)".addAsMultiLineBody()
} }
override fun MethodDescription.modifyGeneratedRangeUntil(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedRangeUntil(thisKind: PrimitiveType) {
"this until ${this.signature.arg!!.name}".addAsSingleLineBody(bodyOnNewLine = false) "this until $parameterName".addAsSingleLineBody(bodyOnNewLine = false)
} }
override fun MethodDescription.modifyGeneratedBitShiftOperators(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedBitShiftOperators(thisKind: PrimitiveType) {
if (thisKind == PrimitiveType.INT) { if (thisKind == PrimitiveType.INT) {
implementAsIntrinsic(thisKind, this.signature.name) implementAsIntrinsic(thisKind, methodName)
} else if (thisKind == PrimitiveType.LONG) { } else if (thisKind == PrimitiveType.LONG) {
this.signature.isInline = true modifySignature { isInline = true }
"wasm_i64_${this.signature.name.toWasmOperator().lowercase()}(this, ${signature.arg!!.name}.toLong())".addAsSingleLineBody(bodyOnNewLine = true) "wasm_i64_${methodName.toWasmOperator().lowercase()}(this, ${parameterName}.toLong())".addAsSingleLineBody(bodyOnNewLine = true)
} }
} }
override fun MethodDescription.modifyGeneratedBitwiseOperators(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedBitwiseOperators(thisKind: PrimitiveType) {
if (this.signature.name == "inv") { if (methodName == "inv") {
this.signature.isInline = true modifySignature { isInline = true }
val oneConst = if (thisKind == PrimitiveType.LONG) "-1L" else "-1" val oneConst = if (thisKind == PrimitiveType.LONG) "-1L" else "-1"
"this.xor($oneConst)".addAsSingleLineBody(bodyOnNewLine = true) "this.xor($oneConst)".addAsSingleLineBody(bodyOnNewLine = true)
return return
} }
implementAsIntrinsic(thisKind, this.signature.name) implementAsIntrinsic(thisKind, methodName)
} }
override fun MethodDescription.modifyGeneratedConversions(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedConversions(thisKind: PrimitiveType) {
val returnTypeAsPrimitive = PrimitiveType.valueOf(this.signature.returnType.uppercase()) val returnTypeAsPrimitive = PrimitiveType.valueOf(returnType.uppercase())
if (returnTypeAsPrimitive == thisKind) { if (returnTypeAsPrimitive == thisKind) {
this.signature.isInline = true modifySignature { isInline = true }
"this".addAsSingleLineBody(bodyOnNewLine = true) "this".addAsSingleLineBody(bodyOnNewLine = true)
return return
} }
@@ -194,7 +195,7 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
when (thisKind) { when (thisKind) {
PrimitiveType.BYTE, PrimitiveType.SHORT -> when (returnTypeAsPrimitive) { PrimitiveType.BYTE, PrimitiveType.SHORT -> when (returnTypeAsPrimitive) {
// byte to byte conversion impossible here due to earlier check on type equality // byte to byte conversion impossible here due to earlier check on type equality
PrimitiveType.BYTE -> "this.toInt().toByte()".also { this.signature.isInline = true } PrimitiveType.BYTE -> "this.toInt().toByte()".also { modifySignature { isInline = true } }
PrimitiveType.CHAR -> "reinterpretAsInt().reinterpretAsChar()" PrimitiveType.CHAR -> "reinterpretAsInt().reinterpretAsChar()"
PrimitiveType.SHORT -> "reinterpretAsInt().reinterpretAsShort()" PrimitiveType.SHORT -> "reinterpretAsInt().reinterpretAsShort()"
PrimitiveType.INT -> "reinterpretAsInt()" PrimitiveType.INT -> "reinterpretAsInt()"
@@ -214,7 +215,7 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
} }
PrimitiveType.LONG -> when (returnTypeAsPrimitive) { PrimitiveType.LONG -> when (returnTypeAsPrimitive) {
PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT -> "this.toInt().to${returnTypeAsPrimitive.capitalized}()" PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT -> "this.toInt().to${returnTypeAsPrimitive.capitalized}()"
.also { this.signature.isInline = true } .also { modifySignature { isInline = true } }
PrimitiveType.INT -> "wasm_i32_wrap_i64(this)" PrimitiveType.INT -> "wasm_i32_wrap_i64(this)"
PrimitiveType.FLOAT -> "wasm_f32_convert_i64_s(this)" PrimitiveType.FLOAT -> "wasm_f32_convert_i64_s(this)"
PrimitiveType.DOUBLE -> "wasm_f64_convert_i64_s(this)" PrimitiveType.DOUBLE -> "wasm_f64_convert_i64_s(this)"
@@ -222,7 +223,7 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
} }
in PrimitiveType.floatingPoint -> when (returnTypeAsPrimitive) { in PrimitiveType.floatingPoint -> when (returnTypeAsPrimitive) {
PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT -> "this.toInt().to${returnTypeAsPrimitive.capitalized}()" PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT -> "this.toInt().to${returnTypeAsPrimitive.capitalized}()"
.also { this.signature.isInline = true } .also { modifySignature { isInline = true } }
PrimitiveType.INT -> "wasm_i32_trunc_sat_${thisKind.prefixLowercase}_s(this)" PrimitiveType.INT -> "wasm_i32_trunc_sat_${thisKind.prefixLowercase}_s(this)"
PrimitiveType.LONG -> "wasm_i64_trunc_sat_${thisKind.prefixLowercase}_s(this)" PrimitiveType.LONG -> "wasm_i64_trunc_sat_${thisKind.prefixLowercase}_s(this)"
PrimitiveType.FLOAT -> "wasm_f32_demote_f64(this)" PrimitiveType.FLOAT -> "wasm_f32_demote_f64(this)"
@@ -233,20 +234,19 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
}.addAsSingleLineBody(bodyOnNewLine = false) }.addAsSingleLineBody(bodyOnNewLine = false)
} }
override fun MethodDescription.modifyGeneratedEquals(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedEquals(thisKind: PrimitiveType) {
val argName = this.signature.arg!!.name
val additionalCheck = when (thisKind) { val additionalCheck = when (thisKind) {
PrimitiveType.LONG -> "wasm_i64_eq(this, $argName)" PrimitiveType.LONG -> "wasm_i64_eq(this, $parameterName)"
PrimitiveType.FLOAT -> "this.equals(other)" PrimitiveType.FLOAT -> "this.equals(other)"
PrimitiveType.DOUBLE -> "this.toBits() == other.toBits()" PrimitiveType.DOUBLE -> "this.toBits() == other.toBits()"
else -> { else -> {
"wasm_i32_eq(this${thisKind.castToIfNecessary(PrimitiveType.INT)}, $argName${thisKind.castToIfNecessary(PrimitiveType.INT)})" "wasm_i32_eq(this${thisKind.castToIfNecessary(PrimitiveType.INT)}, $parameterName${thisKind.castToIfNecessary(PrimitiveType.INT)})"
} }
} }
"\t$argName is ${thisKind.capitalized} && $additionalCheck".addAsSingleLineBody(bodyOnNewLine = true) "$parameterName is ${thisKind.capitalized} && $additionalCheck".addAsSingleLineBody(bodyOnNewLine = true)
} }
override fun MethodDescription.modifyGeneratedToString(thisKind: PrimitiveType) { override fun MethodBuilder.modifyGeneratedToString(thisKind: PrimitiveType) {
when (thisKind) { when (thisKind) {
in PrimitiveType.floatingPoint -> "dtoa(this${thisKind.castToIfNecessary(PrimitiveType.DOUBLE)})" in PrimitiveType.floatingPoint -> "dtoa(this${thisKind.castToIfNecessary(PrimitiveType.DOUBLE)})"
PrimitiveType.INT, PrimitiveType.LONG -> "itoa${thisKind.bitSize}(this, 10)" PrimitiveType.INT, PrimitiveType.LONG -> "itoa${thisKind.bitSize}(this, 10)"
@@ -254,62 +254,64 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
}.addAsSingleLineBody(bodyOnNewLine = true) }.addAsSingleLineBody(bodyOnNewLine = true)
} }
override fun generateAdditionalMethods(thisKind: PrimitiveType): List<MethodDescription> { override fun ClassBuilder.generateAdditionalMethods(thisKind: PrimitiveType) {
val hashCode = MethodDescription( generateCustomEquals(thisKind)
doc = null, generateHashCode(thisKind)
signature = MethodSignature( when {
isOverride = true, thisKind == PrimitiveType.BYTE || thisKind == PrimitiveType.SHORT -> generateReinterpret(PrimitiveType.INT)
isInline = true, thisKind == PrimitiveType.INT -> {
name = "hashCode", setOf(PrimitiveType.BOOLEAN, PrimitiveType.BYTE, PrimitiveType.SHORT, PrimitiveType.CHAR)
arg = null, .forEach { generateReinterpret(it) }
returnType = PrimitiveType.INT.capitalized
)
).apply {
when (thisKind) {
PrimitiveType.LONG -> "return ((this ushr 32) xor this).toInt()".addAsMultiLineBody()
PrimitiveType.FLOAT -> "toBits()".addAsSingleLineBody()
PrimitiveType.DOUBLE -> "toBits().hashCode()".addAsSingleLineBody()
else -> "return this${thisKind.castToIfNecessary(PrimitiveType.INT)}".addAsMultiLineBody()
} }
} }
}
val customEquals = MethodDescription( private fun ClassBuilder.generateHashCode(thisKind: PrimitiveType) {
doc = null, method {
annotations = mutableListOf("kotlin.internal.IntrinsicConstEvaluation"), signature {
signature = MethodSignature( isOverride = true
isInline = thisKind in PrimitiveType.floatingPoint, methodName = "hashCode"
name = "equals", returnType = PrimitiveType.INT.capitalized
arg = MethodParameter("other", thisKind.capitalized), }
when (thisKind) {
PrimitiveType.LONG -> "((this ushr 32) xor this).toInt()"
PrimitiveType.FLOAT -> "toBits()"
PrimitiveType.DOUBLE -> "toBits().hashCode()"
else -> "this${thisKind.castToIfNecessary(PrimitiveType.INT)}"
}.addAsSingleLineBody()
}
}
private fun ClassBuilder.generateCustomEquals(thisKind: PrimitiveType) {
method {
annotations += "kotlin.internal.IntrinsicConstEvaluation"
signature {
isInline = thisKind in PrimitiveType.floatingPoint
methodName = "equals"
parameter {
name = "other"
type = thisKind.capitalized
}
returnType = PrimitiveType.BOOLEAN.capitalized returnType = PrimitiveType.BOOLEAN.capitalized
) }
).apply {
when (thisKind) { when (thisKind) {
in PrimitiveType.floatingPoint -> "toBits() == other.toBits()".addAsSingleLineBody(bodyOnNewLine = false) in PrimitiveType.floatingPoint -> "toBits() == other.toBits()".addAsSingleLineBody(bodyOnNewLine = false)
else -> implementAsIntrinsic(thisKind, this.signature.name) else -> implementAsIntrinsic(thisKind, methodName)
} }
} }
}
val reinterprets = setOf(PrimitiveType.INT, PrimitiveType.BOOLEAN, PrimitiveType.BYTE, PrimitiveType.SHORT, PrimitiveType.CHAR) private fun ClassBuilder.generateReinterpret(otherKind: PrimitiveType) {
.map { method {
MethodDescription( annotations += "WasmNoOpCast"
doc = null, annotations += "PublishedApi"
annotations = mutableListOf("WasmNoOpCast", "PublishedApi"), signature {
signature = MethodSignature( visibility = MethodVisibility.INTERNAL
visibility = MethodVisibility.INTERNAL, methodName = "reinterpretAs${otherKind.capitalized}"
name = "reinterpretAs${it.capitalized}", returnType = otherKind.capitalized
arg = null,
returnType = it.capitalized
)
).apply { "implementedAsIntrinsic".addAsSingleLineBody(bodyOnNewLine = true) }
} }
"implementedAsIntrinsic".addAsSingleLineBody(bodyOnNewLine = true)
val reinterpretInt = reinterprets.first()
val otherReinterprets = reinterprets.drop(1).toTypedArray()
return when (thisKind) {
PrimitiveType.BYTE, PrimitiveType.SHORT -> listOf(customEquals, hashCode, reinterpretInt)
PrimitiveType.INT -> listOf(customEquals, hashCode, *otherReinterprets)
else -> listOf(customEquals, hashCode)
} }
} }
@@ -328,9 +330,9 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
} }
} }
private fun MethodDescription.implementAsIntrinsic(thisKind: PrimitiveType, methodName: String) { private fun MethodBuilder.implementAsIntrinsic(thisKind: PrimitiveType, methodName: String) {
this.signature.isInline = false modifySignature { isInline = false }
addAnnotation("WasmOp(WasmOp.${thisKind.prefixUppercase}_${methodName.toWasmOperator()})") annotations += "WasmOp(WasmOp.${thisKind.prefixUppercase}_${methodName.toWasmOperator()})"
"implementedAsIntrinsic".addAsSingleLineBody(bodyOnNewLine = true) "implementedAsIntrinsic".addAsSingleLineBody(bodyOnNewLine = true)
} }
+301
View File
@@ -0,0 +1,301 @@
/*
* 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 org.jetbrains.kotlin.generators.builtins.numbers.primitives
import java.io.File
private fun String.shift(): String {
return this.split(END_LINE).joinToString(separator = END_LINE) { if (it.isEmpty()) it else " $it" }
}
internal fun file(init: FileBuilder.() -> Unit): FileBuilder {
val file = FileBuilder()
file.init()
return file
}
internal interface PrimitiveBuilder {
fun build(): String
fun throwIfAlreadyInitialized(arg: Any?, propertyName: String, className: String) {
if (arg != null) {
throw AssertionError("Property '$propertyName' for '$className' was already initialized")
}
}
fun throwIfWasNotInitialized(arg: Any?, propertyName: String, className: String) {
if (arg == null) {
throw AssertionError("Property '$propertyName' for '$className' wasn't set to its value")
}
}
fun throwNotInitialized(propertyName: String, className: String): Nothing {
throw AssertionError("Property '$propertyName' for '$className' wasn't initialized to access")
}
}
internal abstract class AnnotatedAndDocumented {
private var doc: String? = null
val annotations: MutableList<String> = mutableListOf()
var additionalDoc: String? = null
fun appendDoc(doc: String) {
if (this.doc == null) {
this.doc = doc
} else {
this.doc += "$END_LINE$doc"
}
}
protected fun StringBuilder.printDocumentationAndAnnotations(forceMultiLineDoc: Boolean = false) {
if (doc != null) {
appendLine(doc!!.printAsDoc(forceMultiLineDoc))
}
if (annotations.isNotEmpty()) {
appendLine(annotations.joinToString(separator = END_LINE) { "@$it" })
}
if (additionalDoc != null) {
appendLine("// $additionalDoc")
}
}
private fun String.printAsDoc(forceMultiLine: Boolean = false): String {
if (this.contains(END_LINE) || forceMultiLine) {
return this.split(END_LINE).joinToString(
separator = END_LINE, prefix = "/**$END_LINE", postfix = "$END_LINE */"
) { if (it.isEmpty()) " *" else " * $it" }
}
return "/** $this */"
}
}
internal class FileBuilder : PrimitiveBuilder {
private val suppresses: MutableList<String> = mutableListOf()
private val imports: MutableList<String> = mutableListOf()
private val classes: MutableList<ClassBuilder> = mutableListOf()
fun suppress(suppress: String) {
suppresses += suppress
}
fun import(newImport: String) {
imports += newImport
}
fun klass(init: ClassBuilder.() -> Unit): ClassBuilder {
val classBuilder = ClassBuilder()
classes += classBuilder.apply(init)
return classBuilder
}
override fun build(): String {
return buildString {
appendLine(File("license/COPYRIGHT_HEADER.txt").readText())
appendLine()
appendLine("// Auto-generated file. DO NOT EDIT!")
appendLine()
if (suppresses.isNotEmpty()) {
appendLine(suppresses.joinToString(separator = ", ", prefix = "@file:Suppress(", postfix = ")") { "\"$it\"" })
appendLine()
}
appendLine("package kotlin")
appendLine()
if (imports.isNotEmpty()) {
appendLine(imports.joinToString(separator = END_LINE) { "import $it" })
appendLine()
}
append(classes.joinToString(separator = END_LINE) { it.build() })
}
}
}
internal class ClassBuilder : AnnotatedAndDocumented(), PrimitiveBuilder {
var isFinal: Boolean = false
var name: String = ""
private var constructorParam: MethodParameterBuilder? = null
private var companionObject: CompanionObjectBuilder? = null
private val methods: MutableList<MethodBuilder> = mutableListOf()
fun constructorParam(init: MethodParameterBuilder.() -> Unit) {
throwIfAlreadyInitialized(constructorParam, "constructorParam", "ClassBuilder")
constructorParam = MethodParameterBuilder().apply(init)
}
fun companionObject(init: CompanionObjectBuilder.() -> Unit): CompanionObjectBuilder {
throwIfAlreadyInitialized(companionObject, "companionObject", "ClassBuilder")
val companionObjectBuilder = CompanionObjectBuilder()
companionObject = companionObjectBuilder.apply(init)
return companionObjectBuilder
}
fun method(init: MethodBuilder.() -> Unit): MethodBuilder {
val methodBuilder = MethodBuilder()
methods += methodBuilder.apply(init)
return methodBuilder
}
override fun build(): String {
return buildString {
this.printDocumentationAndAnnotations()
append("public ")
if (isFinal) append("final ")
appendLine("class $name private constructor(${constructorParam?.build() ?: ""}) : Number(), Comparable<$name> {")
companionObject?.let { appendLine(it.build().shift()) }
appendLine(methods.joinToString(separator = END_LINE + END_LINE) { it.build().shift() })
appendLine("}")
}
}
}
internal class CompanionObjectBuilder : AnnotatedAndDocumented(), PrimitiveBuilder {
var isPublic: Boolean = false
private val properties: MutableList<PropertyBuilder> = mutableListOf()
fun property(init: PropertyBuilder.() -> Unit): PropertyBuilder {
val propertyBuilder = PropertyBuilder()
properties += propertyBuilder.apply(init)
return propertyBuilder
}
override fun build(): String {
return buildString {
printDocumentationAndAnnotations()
if (isPublic) append("public ")
appendLine("companion object {")
appendLine(properties.joinToString(separator = END_LINE + END_LINE) { it.build().shift() })
appendLine("}")
}
}
}
internal class MethodSignatureBuilder : PrimitiveBuilder {
var isExternal: Boolean = false
var visibility: MethodVisibility = MethodVisibility.PUBLIC
var isOverride: Boolean = false
var isInline: Boolean = false
var isInfix: Boolean = false
var isOperator: Boolean = false
var methodName: String? = null
private var parameter: MethodParameterBuilder? = null
var returnType: String? = null
val parameterName: String
get() = parameter?.name ?: throwNotInitialized("name", "MethodParameterBuilder")
val parameterType: String
get() = parameter?.type ?: throwNotInitialized("type", "MethodParameterBuilder")
fun parameter(init: MethodParameterBuilder.() -> Unit): MethodParameterBuilder {
throwIfAlreadyInitialized(parameter, "parameter", "MethodSignatureBuilder")
val argBuilder = MethodParameterBuilder()
parameter = argBuilder.apply(init)
return argBuilder
}
override fun build(): String {
throwIfWasNotInitialized(methodName, "methodName", "MethodSignatureBuilder")
throwIfWasNotInitialized(returnType, "returnType", "MethodSignatureBuilder")
return buildString {
if (isExternal) append("external ")
append("${visibility.name.lowercase()} ")
if (isOverride) append("override ")
if (isInline) append("inline ")
if (isInfix) append("infix ")
if (isOperator) append("operator ")
append("fun $methodName(${parameter?.build() ?: ""}): $returnType")
}
}
}
internal enum class MethodVisibility {
PUBLIC, INTERNAL, PRIVATE
}
internal class MethodParameterBuilder : PrimitiveBuilder {
var name: String? = null
var type: String? = null
override fun build(): String {
throwIfWasNotInitialized(name, "name", "MethodParameterBuilder")
throwIfWasNotInitialized(type, "type", "MethodParameterBuilder")
return "$name: $type"
}
}
internal class MethodBuilder : AnnotatedAndDocumented(), PrimitiveBuilder {
private var signature: MethodSignatureBuilder? = null
private var body: String? = null
val methodName: String
get() = signature?.methodName ?: throwNotInitialized("methodName", "MethodSignatureBuilder")
val returnType: String
get() = signature?.returnType ?: throwNotInitialized("returnType", "MethodSignatureBuilder")
val parameterName: String
get() = signature?.parameterName ?: throwNotInitialized("name", "MethodParameterBuilder")
val parameterType: String
get() = signature?.parameterType ?: throwNotInitialized("type", "MethodParameterBuilder")
fun signature(init: MethodSignatureBuilder.() -> Unit): MethodSignatureBuilder {
throwIfAlreadyInitialized(signature, "signature", "MethodBuilder")
val signatureBuilder = MethodSignatureBuilder()
signature = signatureBuilder.apply(init)
return signatureBuilder
}
fun modifySignature(modify: MethodSignatureBuilder.() -> Unit) {
throwIfWasNotInitialized(signature, "signature", "MethodBuilder")
signature!!.apply(modify)
}
override fun build(): String {
throwIfWasNotInitialized(signature, "signature", "MethodBuilder")
return buildString {
printDocumentationAndAnnotations()
append(signature!!.build())
append(body ?: "")
}
}
fun String.addAsSingleLineBody(bodyOnNewLine: Boolean = false) {
val skip = if (bodyOnNewLine) "$END_LINE " else " "
body = " =$skip$this"
}
fun String.addAsMultiLineBody() {
body = " {$END_LINE${this.shift()}$END_LINE}"
}
}
internal class PropertyBuilder : AnnotatedAndDocumented(), PrimitiveBuilder {
var name: String? = null
var type: String? = null
var value: String? = null
override fun build(): String {
throwIfWasNotInitialized(name, "name", "PropertyBuilder")
throwIfWasNotInitialized(type, "type", "PropertyBuilder")
throwIfWasNotInitialized(value, "value", "PropertyBuilder")
return buildString {
printDocumentationAndAnnotations(forceMultiLineDoc = true)
append("public const val $name: $type = $value")
}
}
}
@@ -1,214 +0,0 @@
/*
* 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 org.jetbrains.kotlin.generators.builtins.numbers.primitives
import org.jetbrains.kotlin.generators.builtins.PrimitiveType
import java.io.File
internal val END_LINE = "\n"
private fun String.shift(): String {
return this.split(END_LINE).joinToString(separator = END_LINE) { if (it.isEmpty()) it else " $it" }
}
internal abstract class AnnotatedAndDocumented {
protected abstract var doc: String?
protected abstract val annotations: MutableList<String>
private var additionalDoc: String? = null
fun addDoc(doc: String) {
if (this.doc == null) {
this.doc = doc
} else {
this.doc += "$END_LINE$doc"
}
}
fun addAnnotation(annotation: String) {
annotations += annotation
}
fun setAdditionalDoc(doc: String) {
additionalDoc = doc
}
fun StringBuilder.printDocumentationAndAnnotations(forceMultiLineDoc: Boolean = false) {
if (doc != null) {
appendLine(doc!!.printAsDoc(forceMultiLineDoc))
}
if (annotations.isNotEmpty()) {
appendLine(annotations.joinToString(separator = END_LINE) { "@$it" })
}
if (additionalDoc != null) {
appendLine("// $additionalDoc")
}
}
private fun String.printAsDoc(forceMultiLine: Boolean = false): String {
if (this.contains(END_LINE) || forceMultiLine) {
return this.split(END_LINE).joinToString(
separator = END_LINE, prefix = "/**$END_LINE", postfix = "$END_LINE */"
) { if (it.isEmpty()) " *" else " * $it" }
}
return "/** $this */"
}
}
internal data class FileDescription(
private val suppresses: MutableList<String> = mutableListOf(),
private val imports: MutableList<String> = mutableListOf(),
val classes: List<ClassDescription>
) {
fun addSuppress(suppress: String) {
suppresses += suppress
}
fun addImport(newImport: String) {
imports += newImport
}
override fun toString(): String {
return buildString {
appendLine(File("license/COPYRIGHT_HEADER.txt").readText())
appendLine()
appendLine("// Auto-generated file. DO NOT EDIT!")
appendLine()
if (suppresses.isNotEmpty()) {
appendLine(suppresses.joinToString(separator = ", ", prefix = "@file:Suppress(", postfix = ")") { "\"$it\"" })
appendLine()
}
appendLine("package kotlin")
appendLine()
if (imports.isNotEmpty()) {
appendLine(imports.joinToString(separator = END_LINE) { "import $it" })
appendLine()
}
append(classes.joinToString(separator = END_LINE))
}
}
}
internal data class ClassDescription(
override var doc: String?,
override val annotations: MutableList<String>,
var isFinal: Boolean = false,
val name: String,
var constructorArg: MethodParameter? = null,
val companionObject: CompanionObjectDescription,
val methods: List<MethodDescription>
) : AnnotatedAndDocumented() {
override fun toString(): String {
return buildString {
this.printDocumentationAndAnnotations()
append("public ")
if (isFinal) append("final ")
appendLine("class $name private constructor(${constructorArg?.toString() ?: ""}) : Number(), Comparable<$name> {")
appendLine(companionObject.toString().shift())
appendLine(methods.joinToString(separator = END_LINE + END_LINE) { it.toString().shift() })
appendLine("}")
}
}
}
internal data class CompanionObjectDescription(
override var doc: String? = null,
override val annotations: MutableList<String> = mutableListOf(),
var isPublic: Boolean = false,
val properties: List<PropertyDescription>
) : AnnotatedAndDocumented() {
override fun toString(): String {
return buildString {
printDocumentationAndAnnotations()
if (isPublic) append("public ")
appendLine("companion object {")
appendLine(properties.joinToString(separator = END_LINE + END_LINE) { it.toString().shift() })
appendLine("}")
}
}
}
internal data class MethodSignature(
var isExternal: Boolean = false,
val visibility: MethodVisibility = MethodVisibility.PUBLIC,
var isOverride: Boolean = false,
var isInline: Boolean = false,
var isInfix: Boolean = false,
var isOperator: Boolean = false,
val name: String,
val arg: MethodParameter?,
val returnType: String
) {
override fun toString(): String {
return buildString {
if (isExternal) append("external ")
append("${visibility.name.lowercase()} ")
if (isOverride) append("override ")
if (isInline) append("inline ")
if (isInfix) append("infix ")
if (isOperator) append("operator ")
append("fun $name(${arg ?: ""}): $returnType")
}
}
}
internal enum class MethodVisibility {
PUBLIC, INTERNAL, PRIVATE
}
internal data class MethodParameter(val name: String, val type: String) {
fun getTypeAsPrimitive(): PrimitiveType = PrimitiveType.valueOf(type.uppercase())
override fun toString(): String {
return "$name: $type"
}
}
internal data class MethodDescription(
override var doc: String?,
override val annotations: MutableList<String> = mutableListOf(),
val signature: MethodSignature,
private var body: String? = null
) : AnnotatedAndDocumented() {
override fun toString(): String {
return buildString {
printDocumentationAndAnnotations()
append(signature)
append(body ?: "")
}
}
fun String.addAsSingleLineBody(bodyOnNewLine: Boolean = false) {
val skip = if (bodyOnNewLine) "$END_LINE\t" else ""
body = " = $skip$this"
}
fun String.addAsMultiLineBody() {
body = " {$END_LINE${this.shift()}$END_LINE}"
}
}
internal data class PropertyDescription(
override var doc: String?,
override val annotations: MutableList<String> = mutableListOf(),
val name: String,
val type: String,
val value: String
) : AnnotatedAndDocumented() {
override fun toString(): String {
return buildString {
printDocumentationAndAnnotations(forceMultiLineDoc = true)
append("public const val $name: $type = $value")
}
}
}
+9 -3
View File
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.generators.builtins.numbers.primitives
import org.jetbrains.kotlin.generators.builtins.PrimitiveType import org.jetbrains.kotlin.generators.builtins.PrimitiveType
internal const val END_LINE = "\n"
internal fun PrimitiveType.castToIfNecessary(otherType: PrimitiveType): String { internal fun PrimitiveType.castToIfNecessary(otherType: PrimitiveType): String {
if (this !in PrimitiveType.onlyNumeric || otherType !in PrimitiveType.onlyNumeric) { if (this !in PrimitiveType.onlyNumeric || otherType !in PrimitiveType.onlyNumeric) {
throw IllegalArgumentException("Cannot cast to non-numeric type") throw IllegalArgumentException("Cannot cast to non-numeric type")
@@ -21,13 +23,17 @@ internal fun PrimitiveType.castToIfNecessary(otherType: PrimitiveType): String {
return "" return ""
} }
internal fun String.asSign(): String { internal fun operatorSign(methodName: String): String {
return when (this) { return when (methodName) {
"plus" -> "+" "plus" -> "+"
"minus" -> "-" "minus" -> "-"
"times" -> "*" "times" -> "*"
"div" -> "/" "div" -> "/"
"rem" -> "%" "rem" -> "%"
else -> throw IllegalArgumentException("Unsupported binary operation: ${this}") else -> throw IllegalArgumentException("Unsupported binary operation: ${methodName}")
} }
} }
internal fun String.toPrimitiveType(): PrimitiveType {
return PrimitiveType.valueOf(this.uppercase())
}
File diff suppressed because it is too large Load Diff
+22 -22
View File
@@ -274,7 +274,7 @@ public class Byte private constructor() : Number(), Comparable<Byte> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Byte): IntRange public operator fun rangeUntil(other: Byte): IntRange = this until other
/** /**
* Creates a range from this value up to but excluding the specified [other] value. * Creates a range from this value up to but excluding the specified [other] value.
@@ -283,7 +283,7 @@ public class Byte private constructor() : Number(), Comparable<Byte> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Short): IntRange public operator fun rangeUntil(other: Short): IntRange = this until other
/** /**
* Creates a range from this value up to but excluding the specified [other] value. * Creates a range from this value up to but excluding the specified [other] value.
@@ -292,7 +292,7 @@ public class Byte private constructor() : Number(), Comparable<Byte> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Int): IntRange public operator fun rangeUntil(other: Int): IntRange = this until other
/** /**
* Creates a range from this value up to but excluding the specified [other] value. * Creates a range from this value up to but excluding the specified [other] value.
@@ -301,7 +301,7 @@ public class Byte private constructor() : Number(), Comparable<Byte> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Long): LongRange public operator fun rangeUntil(other: Long): LongRange = this until other
/** Returns this value. */ /** Returns this value. */
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
@@ -370,10 +370,10 @@ public class Byte private constructor() : Number(), Comparable<Byte> {
public override fun toDouble(): Double public override fun toDouble(): Double
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean public override fun toString(): String
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String public override fun equals(other: Any?): Boolean
public override fun hashCode(): Int public override fun hashCode(): Int
} }
@@ -643,7 +643,7 @@ public class Short private constructor() : Number(), Comparable<Short> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Byte): IntRange public operator fun rangeUntil(other: Byte): IntRange = this until other
/** /**
* Creates a range from this value up to but excluding the specified [other] value. * Creates a range from this value up to but excluding the specified [other] value.
@@ -652,7 +652,7 @@ public class Short private constructor() : Number(), Comparable<Short> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Short): IntRange public operator fun rangeUntil(other: Short): IntRange = this until other
/** /**
* Creates a range from this value up to but excluding the specified [other] value. * Creates a range from this value up to but excluding the specified [other] value.
@@ -661,7 +661,7 @@ public class Short private constructor() : Number(), Comparable<Short> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Int): IntRange public operator fun rangeUntil(other: Int): IntRange = this until other
/** /**
* Creates a range from this value up to but excluding the specified [other] value. * Creates a range from this value up to but excluding the specified [other] value.
@@ -670,7 +670,7 @@ public class Short private constructor() : Number(), Comparable<Short> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Long): LongRange public operator fun rangeUntil(other: Long): LongRange = this until other
/** /**
* Converts this [Short] value to [Byte]. * Converts this [Short] value to [Byte].
@@ -737,10 +737,10 @@ public class Short private constructor() : Number(), Comparable<Short> {
public override fun toDouble(): Double public override fun toDouble(): Double
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean public override fun toString(): String
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String public override fun equals(other: Any?): Boolean
public override fun hashCode(): Int public override fun hashCode(): Int
} }
@@ -1010,7 +1010,7 @@ public class Int private constructor() : Number(), Comparable<Int> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Byte): IntRange public operator fun rangeUntil(other: Byte): IntRange = this until other
/** /**
* Creates a range from this value up to but excluding the specified [other] value. * Creates a range from this value up to but excluding the specified [other] value.
@@ -1019,7 +1019,7 @@ public class Int private constructor() : Number(), Comparable<Int> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Short): IntRange public operator fun rangeUntil(other: Short): IntRange = this until other
/** /**
* Creates a range from this value up to but excluding the specified [other] value. * Creates a range from this value up to but excluding the specified [other] value.
@@ -1028,7 +1028,7 @@ public class Int private constructor() : Number(), Comparable<Int> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Int): IntRange public operator fun rangeUntil(other: Int): IntRange = this until other
/** /**
* Creates a range from this value up to but excluding the specified [other] value. * Creates a range from this value up to but excluding the specified [other] value.
@@ -1037,7 +1037,7 @@ public class Int private constructor() : Number(), Comparable<Int> {
*/ */
@SinceKotlin("1.7") @SinceKotlin("1.7")
@ExperimentalStdlibApi @ExperimentalStdlibApi
public operator fun rangeUntil(other: Long): LongRange public operator fun rangeUntil(other: Long): LongRange = this until other
/** /**
* Shifts this value left by the [bitCount] number of bits. * Shifts this value left by the [bitCount] number of bits.
@@ -1150,10 +1150,10 @@ public class Int private constructor() : Number(), Comparable<Int> {
public override fun toDouble(): Double public override fun toDouble(): Double
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean public override fun toString(): String
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String public override fun equals(other: Any?): Boolean
public override fun hashCode(): Int public override fun hashCode(): Int
} }
@@ -1485,10 +1485,10 @@ public class Float private constructor() : Number(), Comparable<Float> {
public override fun toDouble(): Double public override fun toDouble(): Double
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean public override fun toString(): String
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String public override fun equals(other: Any?): Boolean
public override fun hashCode(): Int public override fun hashCode(): Int
} }
@@ -1822,10 +1822,10 @@ public class Double private constructor() : Number(), Comparable<Double> {
public override fun toDouble(): Double public override fun toDouble(): Double
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean public override fun toString(): String
@kotlin.internal.IntrinsicConstEvaluation @kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String public override fun equals(other: Any?): Boolean
public override fun hashCode(): Int public override fun hashCode(): Int
} }
File diff suppressed because it is too large Load Diff