Support String in generators, and migrate generated functions.
This commit is contained in:
committed by
Andrey Breslav
parent
d9d5631a16
commit
cbc0e6404e
@@ -95,7 +95,7 @@ fun aggregates(): List<GenericFunction> {
|
||||
return count
|
||||
"""
|
||||
}
|
||||
body(Maps, Collections, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Maps, Collections, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"return size"
|
||||
}
|
||||
}
|
||||
@@ -324,7 +324,7 @@ fun aggregates(): List<GenericFunction> {
|
||||
templates add f("foldRight(initial: R, operation: (T, R) -> R)") {
|
||||
inline(true)
|
||||
|
||||
only(Lists, ArraysOfObjects, ArraysOfPrimitives)
|
||||
only(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives)
|
||||
doc { "Accumulates value starting with *initial* value and applying *operation* from right to left to each element and current accumulator value" }
|
||||
typeParam("R")
|
||||
returns("R")
|
||||
@@ -363,7 +363,7 @@ fun aggregates(): List<GenericFunction> {
|
||||
templates add f("reduceRight(operation: (T, T) -> T)") {
|
||||
inline(true)
|
||||
|
||||
only(Lists, ArraysOfObjects, ArraysOfPrimitives)
|
||||
only(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives)
|
||||
doc { "Accumulates value starting with last element and applying *operation* from right to left to each element and current accumulator value" }
|
||||
returns("T")
|
||||
body {
|
||||
|
||||
@@ -15,7 +15,7 @@ fun elements(): List<GenericFunction> {
|
||||
return indexOf(element) >= 0
|
||||
"""
|
||||
}
|
||||
exclude(Lists, Collections)
|
||||
exclude(Strings, Lists, Collections)
|
||||
body(ArraysOfPrimitives, ArraysOfObjects) {
|
||||
"""
|
||||
return indexOf(element) >= 0
|
||||
@@ -24,6 +24,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("indexOf(element: T)") {
|
||||
exclude(Strings)
|
||||
doc { "Returns first index of *element*, or -1 if the collection does not contain element" }
|
||||
returns("Int")
|
||||
body {
|
||||
@@ -69,6 +70,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("lastIndexOf(element: T)") {
|
||||
exclude(Strings) // has native implementation
|
||||
doc { "Returns last index of *element*, or -1 if the collection does not contain element" }
|
||||
returns("Int")
|
||||
body {
|
||||
@@ -143,7 +145,7 @@ fun elements(): List<GenericFunction> {
|
||||
throw IndexOutOfBoundsException("Collection doesn't contain element at index")
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
return get(index)
|
||||
"""
|
||||
@@ -171,7 +173,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
if (size == 0)
|
||||
throw IllegalArgumentException("Collection is empty")
|
||||
@@ -200,7 +202,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
return if (size > 0) this[0] else null
|
||||
"""
|
||||
@@ -255,7 +257,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
if (size == 0)
|
||||
throw IllegalArgumentException("Collection is empty")
|
||||
@@ -283,8 +285,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
include(Lists)
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
return if (size > 0) this[size - 1] else null
|
||||
"""
|
||||
@@ -348,7 +349,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
if (size != 1)
|
||||
throw IllegalArgumentException("Collection has ${bucks}size elements")
|
||||
@@ -376,7 +377,7 @@ fun elements(): List<GenericFunction> {
|
||||
}
|
||||
"""
|
||||
}
|
||||
body(Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
if (size == 0)
|
||||
return null
|
||||
|
||||
@@ -15,6 +15,7 @@ enum class Family {
|
||||
Maps
|
||||
ArraysOfObjects
|
||||
ArraysOfPrimitives
|
||||
Strings
|
||||
}
|
||||
|
||||
enum class PrimitiveType(val name: String) {
|
||||
@@ -30,7 +31,7 @@ enum class PrimitiveType(val name: String) {
|
||||
|
||||
|
||||
class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
val defaultFamilies = array(Iterables, Streams, ArraysOfObjects, ArraysOfPrimitives)
|
||||
val defaultFamilies = array(Iterables, Streams, ArraysOfObjects, ArraysOfPrimitives, Strings)
|
||||
|
||||
var toNullableT: Boolean = false
|
||||
|
||||
@@ -150,10 +151,12 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
Maps -> "Map<K,V>"
|
||||
Streams -> "Stream<T>"
|
||||
ArraysOfObjects -> "Array<T>"
|
||||
Strings -> "String"
|
||||
ArraysOfPrimitives -> primitive?.let { it.name() + "Array" } ?: throw IllegalArgumentException("Primitive array should specify primitive type")
|
||||
else -> throw IllegalStateException("Invalid family")
|
||||
}
|
||||
|
||||
|
||||
fun String.renderType(): String {
|
||||
val t = StringTokenizer(this, " \t\n,:()<>?.", true)
|
||||
val answer = StringBuilder()
|
||||
@@ -174,11 +177,18 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
PrimitiveType.Float -> "0.0f"
|
||||
else -> "0"
|
||||
}
|
||||
"TCollection" -> {
|
||||
when (f) {
|
||||
Strings -> "Appendable"
|
||||
else -> "MutableCollection<in T>".renderType()
|
||||
}
|
||||
}
|
||||
"T" -> {
|
||||
if (f == Maps)
|
||||
"Map.Entry<K,V>"
|
||||
else
|
||||
primitive?.name() ?: token
|
||||
when (f) {
|
||||
Strings -> "Char"
|
||||
Maps -> "Map.Entry<K,V>"
|
||||
else -> primitive?.name() ?: token
|
||||
}
|
||||
}
|
||||
else -> token
|
||||
})
|
||||
@@ -189,7 +199,7 @@ class GenericFunction(val signature: String) : Comparable<GenericFunction> {
|
||||
|
||||
fun effectiveTypeParams(): List<String> {
|
||||
val types = ArrayList(typeParams)
|
||||
if (primitive == null) {
|
||||
if (primitive == null && f != Strings) {
|
||||
val implicitTypeParameters = receiver.dropWhile { it != '<' }.drop(1).takeWhile { it != '>' }.split(",")
|
||||
for (implicit in implicitTypeParameters.reverse()) {
|
||||
if (!types.any { it.startsWith(implicit) }) {
|
||||
|
||||
@@ -28,7 +28,9 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
include(Collections)
|
||||
body(Strings) { "return substring(Math.min(n, size))" }
|
||||
returns(Strings) { "String"}
|
||||
|
||||
body(Collections, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
"""
|
||||
if (n >= size)
|
||||
@@ -60,6 +62,9 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
body(Strings) { "return substring(0, Math.min(n, size))" }
|
||||
returns(Strings) { "String"}
|
||||
|
||||
doc(Streams) { "Returns a stream containing first *n* elements" }
|
||||
returns(Streams) { "Stream<T>" }
|
||||
body(Streams) {
|
||||
@@ -105,6 +110,17 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "String"}
|
||||
body(Strings) {
|
||||
"""
|
||||
for (index in 0..length)
|
||||
if (!predicate(get(index))) {
|
||||
return substring(index)
|
||||
}
|
||||
return ""
|
||||
"""
|
||||
}
|
||||
|
||||
inline(false, Streams)
|
||||
doc(Streams) { "Returns a stream containing all elements except first elements that satisfy the given *predicate*" }
|
||||
returns(Streams) { "Stream<T>" }
|
||||
@@ -142,6 +158,17 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "String"}
|
||||
body(Strings) {
|
||||
"""
|
||||
for (index in 0..length)
|
||||
if (!predicate(get(index))) {
|
||||
return substring(0, index)
|
||||
}
|
||||
return ""
|
||||
"""
|
||||
}
|
||||
|
||||
inline(false, Streams)
|
||||
doc(Streams) { "Returns a stream containing first elements satisfying the given *predicate*" }
|
||||
returns(Streams) { "Stream<T>" }
|
||||
@@ -163,6 +190,13 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "String"}
|
||||
body(Strings) {
|
||||
"""
|
||||
return filterTo(StringBuilder(), predicate).toString()
|
||||
"""
|
||||
}
|
||||
|
||||
inline(false, Streams)
|
||||
doc(Streams) { "Returns a stream containing all elements matching the given *predicate*" }
|
||||
returns(Streams) { "Stream<T>" }
|
||||
@@ -178,7 +212,7 @@ fun filtering(): List<GenericFunction> {
|
||||
inline(true)
|
||||
|
||||
doc { "Appends all elements matching the given *predicate* into the given *collection*" }
|
||||
typeParam("C: MutableCollection<in T>")
|
||||
typeParam("C: TCollection")
|
||||
returns("C")
|
||||
|
||||
body {
|
||||
@@ -187,6 +221,18 @@ fun filtering(): List<GenericFunction> {
|
||||
return collection
|
||||
"""
|
||||
}
|
||||
|
||||
doc(Strings) { "Appends all characters matching the given *predicate* to the given *collection*" }
|
||||
body(Strings) {
|
||||
"""
|
||||
for (index in 0..length - 1) {
|
||||
val element = get(index)
|
||||
if (predicate(element)) destination.append(element)
|
||||
}
|
||||
return destination
|
||||
"""
|
||||
}
|
||||
|
||||
include(Maps)
|
||||
}
|
||||
|
||||
@@ -201,6 +247,13 @@ fun filtering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "String"}
|
||||
body(Strings) {
|
||||
"""
|
||||
return filterNotTo(StringBuilder(), predicate).toString()
|
||||
"""
|
||||
}
|
||||
|
||||
inline(false, Streams)
|
||||
doc(Streams) { "Returns a stream containing all elements not matching the given *predicate*" }
|
||||
returns(Streams) { "Stream<T>" }
|
||||
@@ -216,7 +269,7 @@ fun filtering(): List<GenericFunction> {
|
||||
inline(true)
|
||||
|
||||
doc { "Appends all elements not matching the given *predicate* to the given *collection*" }
|
||||
typeParam("C: MutableCollection<in T>")
|
||||
typeParam("C: TCollection")
|
||||
returns("C")
|
||||
|
||||
body {
|
||||
@@ -225,11 +278,19 @@ fun filtering(): List<GenericFunction> {
|
||||
return collection
|
||||
"""
|
||||
}
|
||||
|
||||
doc(Strings) { "Appends all characters not matching the given *predicate* to the given *collection*" }
|
||||
body(Strings) {
|
||||
"""
|
||||
for (element in this) if (!predicate(element)) collection.append(element)
|
||||
return collection
|
||||
"""
|
||||
}
|
||||
include(Maps)
|
||||
}
|
||||
|
||||
templates add f("filterNotNull()") {
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(ArraysOfPrimitives, Strings)
|
||||
doc { "Returns a list containing all elements that are not null" }
|
||||
typeParam("T: Any")
|
||||
returns("List<T>")
|
||||
@@ -250,11 +311,11 @@ fun filtering(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("filterNotNullTo(collection: C)") {
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(ArraysOfPrimitives, Strings)
|
||||
doc { "Appends all elements that are not null to the given *collection*" }
|
||||
typeParam("C: MutableCollection<in T>")
|
||||
typeParam("T: Any")
|
||||
returns("C")
|
||||
typeParam("C: TCollection")
|
||||
typeParam("T: Any")
|
||||
toNullableT = true
|
||||
body {
|
||||
"""
|
||||
@@ -265,7 +326,7 @@ fun filtering(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("slice(indices: Iterable<Int>)") {
|
||||
only(Lists, ArraysOfPrimitives, ArraysOfObjects)
|
||||
only(Strings, Lists, ArraysOfPrimitives, ArraysOfObjects)
|
||||
doc { "Returns a list containing elements at specified positions" }
|
||||
returns("List<T>")
|
||||
body {
|
||||
@@ -277,6 +338,17 @@ fun filtering(): List<GenericFunction> {
|
||||
return list
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "String" }
|
||||
body(Strings) {
|
||||
"""
|
||||
val result = StringBuilder()
|
||||
for (i in indices) {
|
||||
result.append(get(i))
|
||||
}
|
||||
return result.toString()
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
return templates
|
||||
|
||||
@@ -6,6 +6,7 @@ fun generators(): List<GenericFunction> {
|
||||
val templates = arrayListOf<GenericFunction>()
|
||||
|
||||
templates add f("plus(element: T)") {
|
||||
exclude(Strings)
|
||||
doc { "Returns a list containing all elements of original collection and then the given element" }
|
||||
returns("List<T>")
|
||||
body {
|
||||
@@ -26,7 +27,7 @@ fun generators(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("plus(collection: Iterable<T>)") {
|
||||
exclude(Streams)
|
||||
exclude(Strings, Streams)
|
||||
doc { "Returns a list containing all elements of original collection and then all elements of the given *collection*" }
|
||||
returns("List<T>")
|
||||
body {
|
||||
@@ -39,7 +40,7 @@ fun generators(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("plus(array: Array<T>)") {
|
||||
exclude(Streams)
|
||||
exclude(Strings, Streams)
|
||||
doc { "Returns a list containing all elements of original collection and then all elements of the given *collection*" }
|
||||
returns("List<T>")
|
||||
body {
|
||||
@@ -99,9 +100,25 @@ fun generators(): List<GenericFunction> {
|
||||
return Pair(first, second)
|
||||
"""
|
||||
}
|
||||
|
||||
returns(Strings) { "Pair<String, String>" }
|
||||
body(Strings) {
|
||||
"""
|
||||
val first = StringBuilder()
|
||||
val second = StringBuilder()
|
||||
for (element in this) {
|
||||
if (predicate(element)) {
|
||||
first.append(element)
|
||||
} else {
|
||||
second.append(element)
|
||||
}
|
||||
}
|
||||
return Pair(first.toString(), second.toString())
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("zip(collection: Iterable<R>)") {
|
||||
templates add f("zip(other: Iterable<R>)") {
|
||||
exclude(Streams)
|
||||
doc {
|
||||
"""
|
||||
@@ -113,7 +130,7 @@ fun generators(): List<GenericFunction> {
|
||||
body {
|
||||
"""
|
||||
val first = iterator()
|
||||
val second = collection.iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<T,R>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
@@ -123,6 +140,27 @@ fun generators(): List<GenericFunction> {
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("zip(other : String)") {
|
||||
only(Strings)
|
||||
doc {
|
||||
"""
|
||||
Returns a list of pairs built from characters of both strings with same indexes. List has length of shortest collection.
|
||||
"""
|
||||
}
|
||||
returns("List<Pair<Char,Char>>")
|
||||
body {
|
||||
"""
|
||||
val first = iterator()
|
||||
val second = other.iterator()
|
||||
val list = ArrayList<Pair<Char,Char>>()
|
||||
while (first.hasNext() && second.hasNext()) {
|
||||
list.add(first.next() to second.next())
|
||||
}
|
||||
return list
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("zip(array: Array<R>)") {
|
||||
exclude(Streams)
|
||||
doc {
|
||||
|
||||
@@ -10,7 +10,7 @@ fun guards(): List<GenericFunction> {
|
||||
|
||||
templates add f("requireNoNulls()") {
|
||||
include(Lists)
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(Strings, ArraysOfPrimitives)
|
||||
doc { "Returns an original collection containing all the non-*null* elements, throwing an [[IllegalArgumentException]] if there are any null elements" }
|
||||
typeParam("T:Any")
|
||||
toNullableT = true
|
||||
|
||||
@@ -45,7 +45,8 @@ fun mapping(): List<GenericFunction> {
|
||||
}
|
||||
|
||||
templates add f("mapNotNull(transform : (T) -> R)") {
|
||||
exclude(ArraysOfPrimitives)
|
||||
inline(true)
|
||||
exclude(Strings, ArraysOfPrimitives)
|
||||
doc { "Returns a list containing the results of applying the given *transform* function to each non-null element of the original collection" }
|
||||
typeParam("T: Any")
|
||||
typeParam("R")
|
||||
@@ -59,6 +60,7 @@ fun mapping(): List<GenericFunction> {
|
||||
|
||||
doc(Streams) { "Returns a stream containing the results of applying the given *transform* function to each non-null element of the original stream" }
|
||||
returns(Streams) { "Stream<R>" }
|
||||
inline(false, Streams)
|
||||
body(Streams) {
|
||||
"""
|
||||
return TransformingStream(FilteringStream(this, false, { it != null }) as Stream<T>, transform)
|
||||
@@ -91,7 +93,7 @@ fun mapping(): List<GenericFunction> {
|
||||
|
||||
templates add f("mapNotNullTo(collection: C, transform : (T) -> R)") {
|
||||
inline(true)
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(Strings, ArraysOfPrimitives)
|
||||
doc {
|
||||
"""
|
||||
Appends transformed non-null elements of original collection using the given *transform* function
|
||||
|
||||
@@ -16,6 +16,15 @@ fun ordering(): List<GenericFunction> {
|
||||
"""
|
||||
}
|
||||
|
||||
doc(Strings) { "Returns a string with characters in reversed order" }
|
||||
returns(Strings) { "String"}
|
||||
body(Strings) {
|
||||
// TODO: Replace with StringBuilder(this) when JS can handle it
|
||||
"""
|
||||
return StringBuilder().append(this).reverse().toString()
|
||||
"""
|
||||
}
|
||||
|
||||
exclude(Streams)
|
||||
}
|
||||
|
||||
@@ -38,6 +47,7 @@ fun ordering(): List<GenericFunction> {
|
||||
exclude(Streams)
|
||||
exclude(ArraysOfPrimitives) // TODO: resolve collision between inplace sort and this function
|
||||
exclude(ArraysOfObjects)
|
||||
exclude(Strings)
|
||||
}
|
||||
|
||||
templates add f("sortDescending()") {
|
||||
@@ -60,6 +70,7 @@ fun ordering(): List<GenericFunction> {
|
||||
exclude(Streams)
|
||||
exclude(ArraysOfPrimitives) // TODO: resolve collision between inplace sort and this function
|
||||
exclude(ArraysOfObjects)
|
||||
exclude(Strings)
|
||||
}
|
||||
|
||||
templates add f("sortBy(order: (T) -> R)") {
|
||||
@@ -83,6 +94,7 @@ fun ordering(): List<GenericFunction> {
|
||||
|
||||
exclude(Streams)
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(Strings)
|
||||
}
|
||||
|
||||
templates add f("sortDescendingBy(order: (T) -> R)") {
|
||||
@@ -106,6 +118,7 @@ fun ordering(): List<GenericFunction> {
|
||||
|
||||
exclude(Streams)
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(Strings)
|
||||
}
|
||||
|
||||
templates add f("sortBy(comparator : Comparator<T>)") {
|
||||
@@ -125,6 +138,7 @@ fun ordering(): List<GenericFunction> {
|
||||
|
||||
exclude(Streams)
|
||||
exclude(ArraysOfPrimitives)
|
||||
exclude(Strings)
|
||||
}
|
||||
|
||||
return templates
|
||||
|
||||
Reference in New Issue
Block a user