Allow stdlib generator to distribute concrete functions between different target files.
This commit is contained in:
@@ -6,23 +6,31 @@ import templates.*
|
||||
import templates.PrimitiveType.*
|
||||
|
||||
fun generateCollectionsAPI(outDir: File) {
|
||||
elements().writeTo(File(outDir, "_Elements.kt")) { build() }
|
||||
filtering().writeTo(File(outDir, "_Filtering.kt")) { build() }
|
||||
ordering().writeTo(File(outDir, "_Ordering.kt")) { build() }
|
||||
arrays().writeTo(File(outDir, "_Arrays.kt")) { build() }
|
||||
snapshots().writeTo(File(outDir, "_Snapshots.kt")) { build() }
|
||||
mapping().writeTo(File(outDir, "_Mapping.kt")) { build() }
|
||||
sets().writeTo(File(outDir, "_Sets.kt")) { build() }
|
||||
aggregates().writeTo(File(outDir, "_Aggregates.kt")) { build() }
|
||||
guards().writeTo(File(outDir, "_Guards.kt")) { build() }
|
||||
generators().writeTo(File(outDir, "_Generators.kt")) { build() }
|
||||
strings().writeTo(File(outDir, "_Strings.kt")) { build() }
|
||||
sequences().writeTo(File(outDir, "_Sequences.kt")) { build() }
|
||||
specialJVM().writeTo(File(outDir, "_SpecialJVM.kt")) { build() }
|
||||
ranges().writeTo(File(outDir, "_Ranges.kt")) { build() }
|
||||
toPrimitiveArrays().writeTo(File(outDir, "_ArraysToPrimitiveArrays.kt")) { build() }
|
||||
numeric().writeTo(File(outDir, "_Numeric.kt")) { build() }
|
||||
comparables().writeTo(File(outDir, "_Comparables.kt")) { build() }
|
||||
val templates = sequenceOf(
|
||||
::elements,
|
||||
::filtering,
|
||||
::ordering,
|
||||
::arrays,
|
||||
::snapshots,
|
||||
::mapping,
|
||||
::sets,
|
||||
::aggregates,
|
||||
::guards,
|
||||
::generators,
|
||||
::strings,
|
||||
::sequences,
|
||||
::specialJVM,
|
||||
::ranges,
|
||||
::toPrimitiveArrays,
|
||||
::numeric,
|
||||
::comparables
|
||||
).flatMap { it().sortedBy { it.signature }.asSequence() }
|
||||
|
||||
val groupedConcreteFunctions = templates.flatMap { it.instantiate().asSequence() }.groupBy { it.sourceFile }
|
||||
|
||||
for ((sourceFile, functions) in groupedConcreteFunctions) {
|
||||
functions.writeTo(outDir, sourceFile)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateCollectionsJsAPI(outDir: File) {
|
||||
|
||||
@@ -40,8 +40,26 @@ fun List<GenericFunction>.writeTo(file: File, builder: GenericFunction.() -> Str
|
||||
its.append("import kotlin.platform.*\n") // TODO: Remove unneeded import
|
||||
its.append("import java.util.*\n\n")
|
||||
its.append("import java.util.Collections // TODO: it's temporary while we have java.util.Collections in js\n\n")
|
||||
for (t in this.sorted()) {
|
||||
for (t in this.sortedBy { it.signature }) {
|
||||
its.append(t.builder())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun List<ConcreteFunction>.writeTo(outDir: File, sourceFile: SourceFile) {
|
||||
val file = File(outDir, sourceFile.fileName)
|
||||
println("Generating file: $file")
|
||||
val its = FileWriter(file)
|
||||
|
||||
its.use {
|
||||
its.append("@file:kotlin.jvm.JvmName(\"${sourceFile.jvmClassName}\")\n\n")
|
||||
its.append("package kotlin\n\n")
|
||||
its.append("$COMMON_AUTOGENERATED_WARNING\n\n")
|
||||
its.append("import java.util.*\n\n")
|
||||
its.append("import java.util.Collections // TODO: it's temporary while we have java.util.Collections in js\n\n")
|
||||
|
||||
for (f in this) {
|
||||
f.textBuilder(its)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package generators
|
||||
|
||||
enum class SourceFile(jvmClassName: String? = null) {
|
||||
|
||||
Arrays(),
|
||||
Collections(),
|
||||
Sets(),
|
||||
Maps(),
|
||||
Sequences(),
|
||||
Ranges(),
|
||||
Strings(),
|
||||
Numbers(),
|
||||
;
|
||||
|
||||
val name = this.name()
|
||||
|
||||
val jvmClassName = jvmClassName ?: this.name().capitalize()
|
||||
|
||||
val fileName: String get() = "_${name.capitalize()}.kt"
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package templates
|
||||
|
||||
import generators.SourceFile
|
||||
import templates.Family.*
|
||||
import templates.Family.Collections
|
||||
import java.io.StringReader
|
||||
@@ -57,8 +58,9 @@ enum class PrimitiveType {
|
||||
fun PrimitiveType.isIntegral(): Boolean = this in PrimitiveType.integralPrimitives
|
||||
fun PrimitiveType.isNumeric(): Boolean = this in PrimitiveType.numericPrimitives
|
||||
|
||||
class ConcreteFunction(val textBuilder: (Appendable) -> Unit, val sourceFile: SourceFile)
|
||||
|
||||
class GenericFunction(val signature: String, val keyword: String = "fun") : Comparable<GenericFunction> {
|
||||
class GenericFunction(val signature: String, val keyword: String = "fun") {
|
||||
|
||||
open class SpecializedProperty<TKey: Any, TValue : Any>() {
|
||||
private val values = HashMap<TKey?, TValue>()
|
||||
@@ -165,6 +167,36 @@ class GenericFunction(val signature: String, val keyword: String = "fun") : Comp
|
||||
buildPrimitives.addAll(p.toList())
|
||||
}
|
||||
|
||||
fun instantiate(vararg families: Family = Family.values()): List<ConcreteFunction> {
|
||||
return families
|
||||
.sortedBy { it.name() }
|
||||
.filter { buildFamilies.contains(it) }
|
||||
.flatMap { family -> instantiate(family) }
|
||||
}
|
||||
|
||||
fun instantiate(f: Family): List<ConcreteFunction> {
|
||||
val onlyPrimitives = buildFamilyPrimitives[f]
|
||||
|
||||
if (f.isPrimitiveSpecialization || onlyPrimitives != null) {
|
||||
return (onlyPrimitives ?: buildPrimitives).sortedBy { it.name() }
|
||||
.map { primitive -> ConcreteFunction( { build(it, f, primitive) }, sourceFileFor(f) ) }
|
||||
} else {
|
||||
return listOf(ConcreteFunction( { build(it, f, null) }, sourceFileFor(f) ))
|
||||
}
|
||||
}
|
||||
|
||||
private fun sourceFileFor(f: Family) = getDefaultSourceFile(f)
|
||||
|
||||
private fun getDefaultSourceFile(f: Family): SourceFile = when (f) {
|
||||
Iterables, Collections, Lists -> SourceFile.Collections
|
||||
Sequences -> SourceFile.Sequences
|
||||
Sets -> SourceFile.Sets
|
||||
Ranges, RangesOfPrimitives, ProgressionsOfPrimitives -> SourceFile.Ranges
|
||||
ArraysOfObjects, ArraysOfObjectsSubtype, InvariantArraysOfObjects, ArraysOfPrimitives -> SourceFile.Arrays
|
||||
Maps -> SourceFile.Maps
|
||||
Strings -> SourceFile.Strings
|
||||
Primitives, Generic -> SourceFile.Numbers
|
||||
}
|
||||
|
||||
fun build(vararg families: Family = Family.values()): String {
|
||||
val builder = StringBuilder()
|
||||
@@ -185,7 +217,7 @@ class GenericFunction(val signature: String, val keyword: String = "fun") : Comp
|
||||
}
|
||||
}
|
||||
|
||||
fun build(builder: StringBuilder, f: Family, primitive: PrimitiveType?) {
|
||||
fun build(builder: Appendable, f: Family, primitive: PrimitiveType?) {
|
||||
val returnType = returns[f] ?: throw RuntimeException("No return type specified for $signature")
|
||||
|
||||
fun renderType(expression: String, receiver: String): String {
|
||||
@@ -368,7 +400,6 @@ class GenericFunction(val signature: String, val keyword: String = "fun") : Comp
|
||||
builder.append("\n")
|
||||
}
|
||||
|
||||
public override fun compareTo(other: GenericFunction): Int = this.signature.compareTo(other.signature)
|
||||
}
|
||||
|
||||
fun f(signature: String, init: GenericFunction.() -> Unit): GenericFunction {
|
||||
|
||||
Reference in New Issue
Block a user