Generate JS Long using builtin generators (step 2)
This commit is contained in:
committed by
Space Team
parent
814515964d
commit
7d3f080c81
@@ -9,9 +9,6 @@ import org.jetbrains.kotlin.generators.builtins.PrimitiveType
|
||||
import java.io.PrintWriter
|
||||
|
||||
class JsPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(writer) {
|
||||
override fun PrimitiveType.shouldGenerate(): Boolean {
|
||||
return this != PrimitiveType.LONG
|
||||
}
|
||||
|
||||
override fun FileBuilder.modifyGeneratedFile() {
|
||||
suppress("NON_ABSTRACT_FUNCTION_WITH_NO_BODY")
|
||||
@@ -24,8 +21,115 @@ class JsPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(write
|
||||
}
|
||||
}
|
||||
|
||||
override fun ClassBuilder.modifyGeneratedClass(thisKind: PrimitiveType) {
|
||||
if (thisKind == PrimitiveType.LONG) {
|
||||
annotations += "Suppress(\"NOTHING_TO_INLINE\")"
|
||||
primaryConstructor {
|
||||
visibility = MethodVisibility.INTERNAL
|
||||
parameter {
|
||||
name = "internal val low"
|
||||
type = PrimitiveType.INT.capitalized
|
||||
}
|
||||
parameter {
|
||||
name = "internal val high"
|
||||
type = PrimitiveType.INT.capitalized
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun MethodBuilder.modifyGeneratedCompareTo(thisKind: PrimitiveType, otherKind: PrimitiveType) {
|
||||
modifyGeneratedBinaryOperation(thisKind, otherKind)
|
||||
}
|
||||
|
||||
override fun MethodBuilder.modifyGeneratedBinaryOperation(thisKind: PrimitiveType, otherKind: PrimitiveType) {
|
||||
if (thisKind == PrimitiveType.LONG) {
|
||||
if (thisKind == otherKind) {
|
||||
val implMethod = when (methodName) {
|
||||
"compareTo" -> "compare"
|
||||
"plus" -> "add"
|
||||
"minus" -> "subtract"
|
||||
"times" -> "multiply"
|
||||
"div" -> "divide"
|
||||
"rem" -> "modulo"
|
||||
else -> error("Unsupported binary operation: $methodName")
|
||||
}
|
||||
"this.$implMethod(other)".addAsSingleLineBody(false)
|
||||
} else {
|
||||
modifySignature { isInline = true }
|
||||
"this${thisKind.castToIfNecessary(otherKind)}.${methodName}(other${otherKind.castToIfNecessary(thisKind)})".addAsSingleLineBody(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun MethodBuilder.modifyGeneratedUnaryOperation(thisKind: PrimitiveType) {
|
||||
if (thisKind == PrimitiveType.LONG) {
|
||||
when (methodName) {
|
||||
"inc" -> "this + 1L"
|
||||
"dec" -> "this - 1L"
|
||||
"unaryMinus" -> "this.inv() + 1L"
|
||||
"unaryPlus" -> {
|
||||
modifySignature { isInline = true }
|
||||
"this"
|
||||
}
|
||||
else -> error(methodName)
|
||||
}.addAsSingleLineBody(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun MethodBuilder.modifyGeneratedRangeTo(thisKind: PrimitiveType, otherKind: PrimitiveType, opReturnType: PrimitiveType) {
|
||||
noBody()
|
||||
if (thisKind != PrimitiveType.LONG) {
|
||||
noBody()
|
||||
}
|
||||
}
|
||||
|
||||
override fun MethodBuilder.modifyGeneratedBitShiftOperators(thisKind: PrimitiveType) {
|
||||
if (thisKind == PrimitiveType.LONG) {
|
||||
val implMethod = when (methodName) {
|
||||
"shl" -> "shiftLeft"
|
||||
"shr" -> "shiftRight"
|
||||
"ushr" -> "shiftRightUnsigned"
|
||||
else -> error(methodName)
|
||||
}
|
||||
"$implMethod(bitCount)".addAsSingleLineBody(bodyOnNewLine = false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun MethodBuilder.modifyGeneratedBitwiseOperators(thisKind: PrimitiveType) {
|
||||
if (thisKind == PrimitiveType.LONG) {
|
||||
if (methodName == "inv") {
|
||||
"Long(low.inv(), high.inv())".addAsSingleLineBody(bodyOnNewLine = false)
|
||||
} else {
|
||||
"Long(this.low $methodName other.low, this.high $methodName other.high)".addAsSingleLineBody(bodyOnNewLine = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun MethodBuilder.modifyGeneratedConversions(thisKind: PrimitiveType, otherKind: PrimitiveType) {
|
||||
if (thisKind == PrimitiveType.LONG) {
|
||||
when (otherKind) {
|
||||
PrimitiveType.CHAR,
|
||||
PrimitiveType.BYTE,
|
||||
PrimitiveType.SHORT -> "low.to${otherKind.capitalized}()"
|
||||
PrimitiveType.INT -> "low"
|
||||
PrimitiveType.LONG -> "this"
|
||||
PrimitiveType.FLOAT -> "toDouble().toFloat()"
|
||||
PrimitiveType.DOUBLE -> "toNumber()"
|
||||
else -> error("Unsupported type $otherKind for Long conversion")
|
||||
}.addAsSingleLineBody(bodyOnNewLine = false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun MethodBuilder.modifyGeneratedEquals(thisKind: PrimitiveType) {
|
||||
if (thisKind == PrimitiveType.LONG) {
|
||||
"other is Long && equalsLong(other)".addAsSingleLineBody(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun MethodBuilder.modifyGeneratedToString(thisKind: PrimitiveType) {
|
||||
if (thisKind == PrimitiveType.LONG) {
|
||||
"this.toStringImpl(radix = 10)".addAsSingleLineBody(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun ClassBuilder.generateAdditionalMethods(thisKind: PrimitiveType) {
|
||||
@@ -35,6 +139,29 @@ class JsPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(write
|
||||
methodName = "hashCode"
|
||||
returnType = PrimitiveType.INT.capitalized
|
||||
}
|
||||
if (thisKind == PrimitiveType.LONG) {
|
||||
"hashCode(this)".addAsSingleLineBody(bodyOnNewLine = false)
|
||||
}
|
||||
}
|
||||
|
||||
if (thisKind == PrimitiveType.LONG) {
|
||||
method {
|
||||
additionalDoc = """
|
||||
This method is used by JavaScript to convert objects of type Long to primitives.
|
||||
This is essential for the JavaScript interop.
|
||||
JavaScript functions that expect `number` are imported in Kotlin as expecting `kotlin.Number`
|
||||
(in our standard library, and also in user projects if they use Dukat for generating external declarations).
|
||||
Because `kotlin.Number` is a supertype of `Long` too, there has to be a way for JS to know how to handle Longs.
|
||||
See KT-50202
|
||||
""".trimIndent()
|
||||
annotations += "JsName(\"valueOf\")"
|
||||
signature {
|
||||
visibility = MethodVisibility.INTERNAL
|
||||
methodName = "valueOf"
|
||||
returnType = PrimitiveType.DOUBLE.capitalized
|
||||
}
|
||||
"toDouble()".addAsSingleLineBody(bodyOnNewLine = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user