generate more methods and properties in the standard library
This commit is contained in:
@@ -19,16 +19,17 @@ fun generateCollectionsAPI(outDir: File) {
|
||||
strings().writeTo(File(outDir, "_Strings.kt")) { build() }
|
||||
streams().writeTo(File(outDir, "_Streams.kt")) { build() }
|
||||
specialJVM().writeTo(File(outDir, "_SpecialJVM.kt")) { build() }
|
||||
ranges().writeTo(File(outDir, "_Ranges.kt")) { build() }
|
||||
|
||||
numeric().writeTo(File(outDir, "_Numeric.kt")) {
|
||||
val builder = StringBuilder()
|
||||
// TODO: decide if sum for byte and short is needed and how to make it work
|
||||
for (numeric in listOf(Int, Long, /*Byte, Short, */ Double, Float)) {
|
||||
for (numeric in listOf(PrimitiveType.Int, PrimitiveType.Long, /*Byte, Short, */ PrimitiveType.Double, PrimitiveType.Float)) {
|
||||
build(builder, Iterables, numeric)
|
||||
build(builder, Streams, numeric)
|
||||
}
|
||||
|
||||
for (numeric in listOf(Int, Long, Byte, Short, Double, Float)) {
|
||||
for (numeric in listOf(PrimitiveType.Int, PrimitiveType.Long, PrimitiveType.Byte, PrimitiveType.Short, PrimitiveType.Double, PrimitiveType.Float)) {
|
||||
build(builder, ArraysOfObjects, numeric)
|
||||
build(builder, ArraysOfPrimitives, numeric)
|
||||
}
|
||||
|
||||
@@ -23,5 +23,23 @@ fun arrays(): List<GenericFunction> {
|
||||
}
|
||||
}
|
||||
|
||||
templates add pval("lastIndex") {
|
||||
only(ArraysOfObjects, ArraysOfPrimitives)
|
||||
doc { "Returns the last valid index for the array" }
|
||||
returns("Int")
|
||||
body {
|
||||
"get() = size - 1"
|
||||
}
|
||||
}
|
||||
|
||||
templates add pval("indices") {
|
||||
only(ArraysOfObjects, ArraysOfPrimitives)
|
||||
doc { "Returns the range of valid indices for the array" }
|
||||
returns("IntRange")
|
||||
body {
|
||||
"get() = IntRange(0, lastIndex)"
|
||||
}
|
||||
}
|
||||
|
||||
return templates
|
||||
}
|
||||
@@ -16,6 +16,8 @@ enum class Family {
|
||||
ArraysOfObjects
|
||||
ArraysOfPrimitives
|
||||
Strings
|
||||
RangesOfPrimitives
|
||||
ProgressionsOfPrimitives
|
||||
}
|
||||
|
||||
enum class PrimitiveType(val name: String) {
|
||||
@@ -30,7 +32,7 @@ enum class PrimitiveType(val name: String) {
|
||||
}
|
||||
|
||||
|
||||
class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
class GenericFunction(val signature: String, val keyword: String = "fun") : Comparable<GenericFunction> {
|
||||
val defaultFamilies = array(Iterables, Streams, ArraysOfObjects, ArraysOfPrimitives, Strings)
|
||||
|
||||
var toNullableT: Boolean = false
|
||||
@@ -39,7 +41,7 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
var receiverAsterisk = false
|
||||
val inlineFamilies = HashMap<Family, Boolean>()
|
||||
|
||||
val buildFamilies = HashSet(defaultFamilies.toList())
|
||||
val buildFamilies = HashSet(defaultFamilies.filter { it != RangesOfPrimitives && it != ProgressionsOfPrimitives }.toList())
|
||||
private val buildPrimitives = HashSet(PrimitiveType.values().toList())
|
||||
|
||||
var deprecate: String = ""
|
||||
@@ -50,6 +52,7 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
|
||||
var defaultBody: String = ""
|
||||
val bodies = HashMap<Family, String>()
|
||||
val customPrimitiveBodies = HashMap<Pair<Family, PrimitiveType>, String>()
|
||||
|
||||
var defaultReturnType = ""
|
||||
val returnTypes = HashMap<Family, String>()
|
||||
@@ -67,6 +70,13 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
}
|
||||
}
|
||||
|
||||
fun bodyForTypes(family: Family, vararg primitiveTypes: PrimitiveType, b: () -> String) {
|
||||
include(family)
|
||||
for (f in primitiveTypes) {
|
||||
customPrimitiveBodies.put(family to f, b())
|
||||
}
|
||||
}
|
||||
|
||||
fun doc(vararg families: Family, b: () -> String) {
|
||||
if (families.isEmpty())
|
||||
doc = b()
|
||||
@@ -149,7 +159,7 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
}
|
||||
|
||||
fun build(builder: StringBuilder, f: Family) {
|
||||
if (f == ArraysOfPrimitives) {
|
||||
if (f == ArraysOfPrimitives || f == RangesOfPrimitives || f == ProgressionsOfPrimitives) {
|
||||
for (primitive in buildPrimitives.sortBy { it.name() })
|
||||
build(builder, f, primitive)
|
||||
} else {
|
||||
@@ -172,6 +182,8 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
ArraysOfObjects -> "Array<$isAsteriskOrT>"
|
||||
Strings -> "String"
|
||||
ArraysOfPrimitives -> primitive?.let { it.name() + "Array" } ?: throw IllegalArgumentException("Primitive array should specify primitive type")
|
||||
RangesOfPrimitives -> primitive?.let { it.name() + "Range" } ?: throw IllegalArgumentException("Primitive range should specify primitive type")
|
||||
ProgressionsOfPrimitives -> primitive?.let { it.name() + "Progression" } ?: throw IllegalArgumentException("Primitive progression should specify primitive type")
|
||||
else -> throw IllegalStateException("Invalid family")
|
||||
}
|
||||
|
||||
@@ -187,7 +199,7 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
"PRIMITIVE" -> primitive?.name() ?: token
|
||||
"SUM" -> {
|
||||
when (primitive) {
|
||||
PrimitiveType.Byte, PrimitiveType.Short -> "Int"
|
||||
PrimitiveType.Byte, PrimitiveType.Short, PrimitiveType.Char -> "Int"
|
||||
else -> primitive
|
||||
}
|
||||
}
|
||||
@@ -196,6 +208,18 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
PrimitiveType.Float -> "0.0f"
|
||||
else -> "0"
|
||||
}
|
||||
"ONE" -> when (primitive) {
|
||||
PrimitiveType.Double -> "1.0"
|
||||
PrimitiveType.Float -> "1.0f"
|
||||
PrimitiveType.Long -> "1.toLong()"
|
||||
else -> "1"
|
||||
}
|
||||
"-ONE" -> when (primitive) {
|
||||
PrimitiveType.Double -> "-1.0"
|
||||
PrimitiveType.Float -> "-1.0f"
|
||||
PrimitiveType.Long -> "-1.toLong()"
|
||||
else -> "-1"
|
||||
}
|
||||
"TCollection" -> {
|
||||
when (f) {
|
||||
Strings -> "Appendable"
|
||||
@@ -209,6 +233,7 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
else -> primitive?.name() ?: token
|
||||
}
|
||||
}
|
||||
"TProgression" -> primitive!!.name + "Progression"
|
||||
else -> token
|
||||
})
|
||||
}
|
||||
@@ -253,7 +278,7 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
if (inlineFamilies[f] ?: defaultInline)
|
||||
builder.append("inline ")
|
||||
|
||||
builder.append("fun ")
|
||||
builder.append("$keyword ")
|
||||
|
||||
val types = effectiveTypeParams()
|
||||
if (!types.isEmpty()) {
|
||||
@@ -267,9 +292,10 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
|
||||
|
||||
builder.append(receiverType)
|
||||
builder.append(".${signature.renderType()}: ${returnType.renderType()} {")
|
||||
builder.append(".${signature.renderType()}: ${returnType.renderType()}")
|
||||
if (keyword == "fun") builder.append(" {")
|
||||
|
||||
val body = (bodies[f] ?: defaultBody).trim("\n")
|
||||
val body = (customPrimitiveBodies[f to primitive] ?: bodies[f] ?: defaultBody).trim("\n")
|
||||
val indent: Int = body.takeWhile { it == ' ' }.length()
|
||||
|
||||
builder.append('\n')
|
||||
@@ -281,7 +307,8 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
builder.append("\n")
|
||||
}
|
||||
}
|
||||
builder.append("}\n\n")
|
||||
if (keyword == "fun") builder.append("}\n")
|
||||
builder.append("\n")
|
||||
}
|
||||
|
||||
public override fun compareTo(other: GenericFunction): Int = this.signature.compareTo(other.signature)
|
||||
@@ -298,3 +325,15 @@ fun f(signature: String, init: GenericFunction.() -> Unit): GenericFunction {
|
||||
gf.init()
|
||||
return gf
|
||||
}
|
||||
|
||||
fun pval(signature: String, init: GenericFunction.() -> Unit): GenericFunction {
|
||||
val gf = GenericFunction(signature, "val")
|
||||
gf.init()
|
||||
return gf
|
||||
}
|
||||
|
||||
fun pvar(signature: String, init: GenericFunction.() -> Unit): GenericFunction {
|
||||
val gf = GenericFunction(signature, "var")
|
||||
gf.init()
|
||||
return gf
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package templates
|
||||
|
||||
import templates.Family.*
|
||||
|
||||
fun ranges(): List<GenericFunction> {
|
||||
val templates = arrayListOf<GenericFunction>()
|
||||
|
||||
templates add f("reversed()") {
|
||||
only(RangesOfPrimitives, ProgressionsOfPrimitives)
|
||||
exclude(PrimitiveType.Boolean)
|
||||
doc(ProgressionsOfPrimitives) { "Returns a progression that goes over the same range in the opposite direction with the same step" }
|
||||
doc(RangesOfPrimitives) { "Returns a progression that goes over this range in reverse direction" }
|
||||
returns("TProgression")
|
||||
body(RangesOfPrimitives) {
|
||||
"return TProgression(end, start, -ONE)"
|
||||
}
|
||||
body(ProgressionsOfPrimitives) {
|
||||
"return TProgression(end, start, -increment)"
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("step(step: SUM)") {
|
||||
only(RangesOfPrimitives, ProgressionsOfPrimitives)
|
||||
exclude(PrimitiveType.Boolean)
|
||||
doc(ProgressionsOfPrimitives) { "Returns a progression that goes over the same range with the given step" }
|
||||
doc(RangesOfPrimitives) { "Returns a progression that goes over this range with given step" }
|
||||
returns("TProgression")
|
||||
body(RangesOfPrimitives) {
|
||||
"""
|
||||
checkStepIsPositive(step > 0, step)
|
||||
return TProgression(start, end, step)
|
||||
"""
|
||||
}
|
||||
bodyForTypes(RangesOfPrimitives, PrimitiveType.Float, PrimitiveType.Double) {
|
||||
"""
|
||||
if (step.isNaN()) throw IllegalArgumentException("Step must not be NaN")
|
||||
checkStepIsPositive(step > 0, step)
|
||||
return TProgression(start, end, step)
|
||||
"""
|
||||
}
|
||||
body(ProgressionsOfPrimitives) {
|
||||
"""
|
||||
checkStepIsPositive(step > 0, step)
|
||||
return TProgression(start, end, if (increment > 0) step else -step)
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
return templates
|
||||
}
|
||||
Reference in New Issue
Block a user