standard library: 'sum' function added (KT-3714, KT-3843, KT-3126)

This commit is contained in:
nik
2013-11-24 17:33:05 +04:00
committed by Mikhael Bogdanov
parent 4ecfab6e0b
commit cde36adbdc
14 changed files with 209 additions and 17 deletions
@@ -29,27 +29,27 @@ fun main(args: Array<String>) {
generateDomEventsAPI(File(jsCoreDir, "domEvents.kt"))
iterators().writeTo(File(outDir, "_Iterators.kt")) {
buildFor(Iterators, "")
buildFor(Iterators, null)
}
val iterables = iterables()
iterables.writeTo(File(outDir, "_Arrays.kt")) {
buildFor(Arrays, "")
val sumFunctions = PrimitiveType.values().map(::sumFunction).filterNotNull()
(iterables + sumFunctions).writeTo(File(outDir, "_Arrays.kt")) {
buildFor(Arrays, null)
}
val otherArrayNames = arrayListOf("Boolean", "Byte", "Char", "Short", "Int", "Long", "Float", "Double")
for (a in otherArrayNames) {
iterables.writeTo(File(outDir, "_${a}Arrays.kt")) {
buildFor(PrimitiveArrays, a)
for (primitive in PrimitiveType.values()) {
(iterables + sumFunction(primitive)).filterNotNull().writeTo(File(outDir, "_${primitive.name}Arrays.kt")) {
buildFor(PrimitiveArrays, primitive)
}
}
iterables.writeTo(File(outDir, "_Iterables.kt")) {
buildFor(Iterables, "")
(iterables + sumFunctions).writeTo(File(outDir, "_Iterables.kt")) {
buildFor(Iterables, null)
}
collections().writeTo(File(outDir, "_Collections.kt")) {
buildFor(Collections, "")
buildFor(Collections, null)
}
generateDownTos(File(outDir, "_DownTo.kt"), "package kotlin")
@@ -18,7 +18,8 @@ enum class Family {
class GenericFunction(val signature : String): Comparable<GenericFunction> {
var doc : String = ""
var toNullableT : Boolean = false
val isInline : Boolean = true;
var isInline : Boolean = true;
private val customReceivers = HashMap<Family, String>()
val blockedFor = HashSet<Family>()
val bodies = HashMap<Family, String>()
val returnTypes = HashMap<Family, String>()
@@ -44,6 +45,10 @@ class GenericFunction(val signature : String): Comparable<GenericFunction> {
returnTypes[this] = r
}
fun Family.customReceiver(r: String) {
customReceivers[this] = r
}
fun typeParam(t:String) {
typeParams.add(t)
}
@@ -54,7 +59,7 @@ class GenericFunction(val signature : String): Comparable<GenericFunction> {
private fun effectiveTypeParams(f : Family) : List<String> {
val types = ArrayList(typeParams)
if (typeParams.find { it.startsWith("T") } == null) {
if (typeParams.find { it.startsWith("T") } == null && !customReceivers.containsKey(f)) {
types.add(0, "T")
}
@@ -67,7 +72,7 @@ class GenericFunction(val signature : String): Comparable<GenericFunction> {
fun buildFor(f: Family, arrName : String = "") : String {
fun buildFor(f: Family, primitiveType: PrimitiveType?) : String {
if (blockedFor.contains(f)) return ""
if (returnTypes[f] == null) throw RuntimeException("No return type specified for $signature")
@@ -78,7 +83,7 @@ class GenericFunction(val signature : String): Comparable<GenericFunction> {
Collections -> "Collection<T>"
Iterators -> "Iterator<T>"
Arrays -> "Array<out T>"
PrimitiveArrays -> "${arrName}Array"
PrimitiveArrays -> "${primitiveType!!.name}Array"
}
fun String.renderType() : String {
@@ -89,7 +94,7 @@ class GenericFunction(val signature : String): Comparable<GenericFunction> {
val token = t.nextToken()
answer.append(when (token) {
"SELF" -> selftype
"T" -> if (f == Family.PrimitiveArrays) arrName else token
"T" -> if (f == Family.PrimitiveArrays) primitiveType!!.name else token
else -> token
})
}
@@ -120,7 +125,7 @@ class GenericFunction(val signature : String): Comparable<GenericFunction> {
builder.append(types.makeString(separator = ", ", prefix = "<", postfix = "> ").renderType())
}
builder.append((
builder.append((customReceivers[f] ?:
if (toNullableT) {
selftype.replace("T>", "T?>")
}
@@ -160,6 +165,6 @@ fun f(signature : String, init : GenericFunction.() -> Unit): GenericFunction {
fun main(args : Array<String>) {
val templates = collections()
for (t in templates) {
print(t.buildFor(PrimitiveArrays, "Byte"))
print(t.buildFor(PrimitiveArrays, PrimitiveType.Byte))
}
}
@@ -0,0 +1,47 @@
package templates
import templates.Family.*
enum class PrimitiveType(val name: String) {
Boolean: PrimitiveType("Boolean")
Byte: PrimitiveType("Byte")
Char: PrimitiveType("Char")
Short: PrimitiveType("Short")
Int: PrimitiveType("Int")
Long: PrimitiveType("Long")
Float: PrimitiveType("Float")
Double: PrimitiveType("Double")
}
private fun PrimitiveType.zero() = when (this) {
PrimitiveType.Int -> "0"
PrimitiveType.Byte -> "0"
PrimitiveType.Short -> "0"
PrimitiveType.Long -> "0.toLong()"
PrimitiveType.Double -> "0.0"
PrimitiveType.Float -> "0.toFloat()"
else -> null
}
private fun returnTypeForSum(primitive: PrimitiveType) = when (primitive) {
PrimitiveType.Byte -> PrimitiveType.Int
PrimitiveType.Short -> PrimitiveType.Int
else -> primitive
}
fun sumFunction(primitive: PrimitiveType) = primitive.zero()?.let { zero ->
f("sum()") {
doc = "Sums up the elements"
isInline = false
if (returnTypeForSum(primitive) != primitive) {
//this is required to avoid clash of erasured method signatures (Iterables.sum(): Int)
absentFor(Iterables)
}
Iterables.customReceiver("Iterable<${primitive.name}>")
Arrays.customReceiver("Array<${primitive.name}>")
returns(returnTypeForSum(primitive).name)
body {
"return fold($zero, {a,b -> a+b})"
}
}
}