Generate range downTos with templates DSL

This commit is contained in:
Ilya Gorbunov
2015-07-10 21:18:56 +03:00
parent e677049d00
commit 808170a84b
6 changed files with 331 additions and 534 deletions
@@ -1,71 +0,0 @@
package generators
import java.io.File
import java.io.FileWriter
import java.io.PrintWriter
private fun generateDownTos(outputFile: File, header: String) {
fun getMaxType(fromType: String, toType: String): String {
return when {
fromType == "Double" || toType == "Double" -> "Double"
fromType == "Float" || toType == "Float" -> "Float"
fromType == "Long" || toType == "Long" -> "Long"
fromType == "Int" || toType == "Int" -> "Int"
fromType == "Short" || toType == "Short" -> "Short"
fromType == "Char" || toType == "Char" -> "Char"
else -> "Byte"
}
}
fun generateDownTo(writer: PrintWriter, fromType: String, toType: String) {
val elementType = getMaxType(fromType, toType)
val progressionType = elementType + "Progression"
val fromExpr = if (elementType == fromType) "this" else "this.to$elementType()"
val toExpr = if (elementType == toType) "to" else "to.to$elementType()"
val incrementExpr = when (elementType) {
"Long" -> "-1.toLong()"
"Float" -> "-1.toFloat()"
"Double" -> "-1.0"
else -> "-1"
}
val deprecated =
if ((fromType == "Char") != (toType == "Char")) {
"""deprecated("This operation doesn't make sense and shall be removed in M13. Consider converting Char operand to Int or other operand to Char.")"""
} else ""
writer.println("""
/**
* Returns a progression from this value down to the specified [to] value.
*
* The [to] value has to be less than this value.
*/
$deprecated
public fun $fromType.downTo(to: $toType): $progressionType {
return $progressionType($fromExpr, $toExpr, $incrementExpr)
}""".replace("\n\n","\n"))
}
println("Writing $outputFile")
outputFile.getParentFile()?.mkdirs()
val writer = PrintWriter(FileWriter(outputFile))
try {
writer.println(header)
writer.println("""
$COMMON_AUTOGENERATED_WARNING
""")
val types = arrayOf("Byte", "Char", "Short", "Int", "Long", "Float", "Double")
for (fromType in types) {
for (toType in types) {
generateDownTo(writer, fromType, toType)
}
}
} finally {
writer.close()
}
}
@@ -28,7 +28,6 @@ fun main(args: Array<String>) {
generateCollectionsAPI(outDir)
generateCollectionsJsAPI(jsCoreDir)
generateDownTos(File(outDir, "_DownTo.kt"), "package kotlin")
}
fun List<GenericFunction>.writeTo(file: File, builder: GenericFunction.() -> String) {
@@ -44,7 +44,13 @@ enum class PrimitiveType {
companion object {
val defaultPrimitives = PrimitiveType.values().toSet()
val numericPrimitives = setOf(PrimitiveType.Int, PrimitiveType.Long, PrimitiveType.Byte, PrimitiveType.Short, PrimitiveType.Double, PrimitiveType.Float)
val numericPrimitives = setOf(Int, Long, Byte, Short, Double, Float)
val descendingByDomainCapacity = listOf(Double, Float, Long, Int, Short, Char, Byte)
fun getMaxCapacityType(fromType: PrimitiveType, toType: PrimitiveType): PrimitiveType = descendingByDomainCapacity.first { it == fromType || it == toType }
val primitivePermutations = numericPrimitives.flatMap { fromType -> numericPrimitives map { toType -> fromType to toType } } + (Char to Char)
}
}
@@ -46,5 +46,32 @@ fun ranges(): List<GenericFunction> {
}
}
fun downTo(fromType: PrimitiveType, toType: PrimitiveType) = f("downTo(to: $toType)") {
only(Primitives)
only(fromType)
val elementType = PrimitiveType.getMaxCapacityType(fromType, toType)
val progressionType = elementType.name + "Progression"
returns(progressionType)
doc {
"""
Returns a progression from this value down to the specified [to] value with the increment -1.
The [to] value has to be less than this value.
"""
}
val fromExpr = if (elementType == fromType) "this" else "this.to$elementType()"
val toExpr = if (elementType == toType) "to" else "to.to$elementType()"
val incrementExpr = when (elementType) {
PrimitiveType.Long -> "-1L"
PrimitiveType.Float -> "-1.0F"
PrimitiveType.Double -> "-1.0"
else -> "-1"
}
body { "return $progressionType($fromExpr, $toExpr, $incrementExpr)" }
}
templates addAll PrimitiveType.primitivePermutations.map { downTo(it.first, it.second) }
return templates
}
}