Rewrite Mapping.kt in new DSL

This commit is contained in:
Ilya Gorbunov
2017-11-08 09:09:27 +03:00
parent efefa64ac5
commit c4ac2548d9
2 changed files with 148 additions and 122 deletions
@@ -17,7 +17,7 @@ fun main(args: Array<String>) {
Ordering, Ordering,
// ArrayOps, // ArrayOps,
Snapshots, Snapshots,
// Mapping, Mapping,
SetOps, SetOps,
Aggregates, Aggregates,
Guards, Guards,
@@ -1,14 +1,45 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package templates package templates
import templates.Family.* import templates.Family.*
import templates.SequenceClass.* import templates.SequenceClass.*
fun mapping(): List<GenericFunction> { object Mapping : TemplateGroupBase() {
val templates = arrayListOf<GenericFunction>()
templates add f("withIndex()") { init {
val terminalOperationPattern = Regex("^\\w+To")
defaultBuilder {
if (sequenceClassification.isEmpty()) {
if (terminalOperationPattern in signature)
sequenceClassification(terminal)
else
sequenceClassification(intermediate, stateless)
}
}
}
val f_withIndex = fn("withIndex()") {
includeDefault()
include(CharSequences) include(CharSequences)
doc { f -> "Returns a ${if (f == Sequences) f.mapResult else "lazy [Iterable]"} of [IndexedValue] for each ${f.element} of the original ${f.collection}." } } builder {
doc {
"Returns a ${if (f == Sequences) f.mapResult else "lazy [Iterable]"} of [IndexedValue] for each ${f.element} of the original ${f.collection}."
}
returns("Iterable<IndexedValue<T>>") returns("Iterable<IndexedValue<T>>")
body { body {
""" """
@@ -16,18 +47,17 @@ fun mapping(): List<GenericFunction> {
""" """
} }
returns(Sequences) { "Sequence<IndexedValue<T>>" } specialFor(Sequences) { returns("Sequence<IndexedValue<T>>") }
body(Sequences) { body(Sequences) { """return IndexingSequence(this)""" }
"""
return IndexingSequence(this)
"""
}
} }
templates add f("mapIndexed(transform: (index: Int, T) -> R)") { val f_mapIndexed = fn("mapIndexed(transform: (index: Int, T) -> R)") {
inline(true) includeDefault()
include(CharSequences)
} builder {
inline()
doc { f -> doc {
""" """
Returns a ${f.mapResult} containing the results of applying the given [transform] function Returns a ${f.mapResult} containing the results of applying the given [transform] function
to each ${f.element} and its index in the original ${f.collection}. to each ${f.element} and its index in the original ${f.collection}.
@@ -46,17 +76,22 @@ fun mapping(): List<GenericFunction> {
body(CharSequences) { body(CharSequences) {
"return mapIndexedTo(ArrayList<R>(length), transform)" "return mapIndexedTo(ArrayList<R>(length), transform)"
} }
inline(false, Sequences) specialFor(Sequences) {
returns(Sequences) { "Sequence<R>" } inline(Inline.No)
returns("Sequence<R>")
}
body(Sequences) { body(Sequences) {
"return TransformingIndexedSequence(this, transform)" "return TransformingIndexedSequence(this, transform)"
} }
} }
templates add f("map(transform: (T) -> R)") { val f_map = fn("map(transform: (T) -> R)") {
inline(true) includeDefault()
include(Maps, CharSequences)
} builder {
inline()
doc { f -> doc {
""" """
Returns a ${f.mapResult} containing the results of applying the given [transform] function Returns a ${f.mapResult} containing the results of applying the given [transform] function
to each ${f.element} in the original ${f.collection}. to each ${f.element} in the original ${f.collection}.
@@ -74,21 +109,22 @@ fun mapping(): List<GenericFunction> {
"return mapTo(ArrayList<R>(length), transform)" "return mapTo(ArrayList<R>(length), transform)"
} }
inline(false, Sequences) specialFor(Sequences) {
returns(Sequences) { "Sequence<R>" } inline(Inline.No)
returns("Sequence<R>")
}
body(Sequences) { body(Sequences) {
"return TransformingSequence(this, transform)" "return TransformingSequence(this, transform)"
} }
include(Maps)
} }
templates add f("mapNotNull(transform: (T) -> R?)") { val f_mapNotNull = fn("mapNotNull(transform: (T) -> R?)") {
inline(true) include(Iterables, ArraysOfObjects, Sequences, Maps, CharSequences)
include(Maps, CharSequences) } builder {
exclude(ArraysOfPrimitives) inline()
typeParam("R : Any") typeParam("R : Any")
returns("List<R>") returns("List<R>")
doc { f -> doc {
""" """
Returns a ${f.mapResult} containing only the non-null results of applying the given [transform] function Returns a ${f.mapResult} containing only the non-null results of applying the given [transform] function
to each ${f.element} in the original ${f.collection}. to each ${f.element} in the original ${f.collection}.
@@ -98,21 +134,23 @@ fun mapping(): List<GenericFunction> {
"return mapNotNullTo(ArrayList<R>(), transform)" "return mapNotNullTo(ArrayList<R>(), transform)"
} }
inline(false, Sequences) specialFor(Sequences) {
returns(Sequences) { "Sequence<R>" } inline(Inline.No)
returns("Sequence<R>")
}
body(Sequences) { body(Sequences) {
"return TransformingSequence(this, transform).filterNotNull()" "return TransformingSequence(this, transform).filterNotNull()"
} }
} }
templates add f("mapIndexedNotNull(transform: (index: Int, T) -> R?)") { val f_mapIndexedNotNull = fn("mapIndexedNotNull(transform: (index: Int, T) -> R?)") {
inline(true) include(Iterables, ArraysOfObjects, Sequences, CharSequences)
include(CharSequences) } builder {
exclude(ArraysOfPrimitives) inline()
typeParam("R : Any") typeParam("R : Any")
returns("List<R>") returns("List<R>")
doc { f -> doc {
""" """
Returns a ${f.mapResult} containing only the non-null results of applying the given [transform] function Returns a ${f.mapResult} containing only the non-null results of applying the given [transform] function
to each ${f.element} and its index in the original ${f.collection}. to each ${f.element} and its index in the original ${f.collection}.
@@ -124,17 +162,22 @@ fun mapping(): List<GenericFunction> {
"return mapIndexedNotNullTo(ArrayList<R>(), transform)" "return mapIndexedNotNullTo(ArrayList<R>(), transform)"
} }
inline(false, Sequences) specialFor(Sequences) {
returns(Sequences) { "Sequence<R>" } inline(Inline.No)
returns("Sequence<R>")
}
body(Sequences) { body(Sequences) {
"return TransformingIndexedSequence(this, transform).filterNotNull()" "return TransformingIndexedSequence(this, transform).filterNotNull()"
} }
} }
templates add f("mapTo(destination: C, transform: (T) -> R)") { val f_mapTo = fn("mapTo(destination: C, transform: (T) -> R)") {
inline(true) includeDefault()
include(Maps, CharSequences)
} builder {
inline()
doc { f -> doc {
""" """
Applies the given [transform] function to each ${f.element} of the original ${f.collection} Applies the given [transform] function to each ${f.element} of the original ${f.collection}
and appends the results to the given [destination]. and appends the results to the given [destination].
@@ -151,13 +194,15 @@ fun mapping(): List<GenericFunction> {
return destination return destination
""" """
} }
include(Maps, CharSequences)
} }
templates add f("mapIndexedTo(destination: C, transform: (index: Int, T) -> R)") { val f_mapIndexedTo = fn("mapIndexedTo(destination: C, transform: (index: Int, T) -> R)") {
inline(true) includeDefault()
include(CharSequences)
} builder {
inline()
doc { f -> doc {
""" """
Applies the given [transform] function to each ${f.element} and its index in the original ${f.collection} Applies the given [transform] function to each ${f.element} and its index in the original ${f.collection}
and appends the results to the given [destination]. and appends the results to the given [destination].
@@ -177,17 +222,16 @@ fun mapping(): List<GenericFunction> {
return destination return destination
""" """
} }
include(CharSequences)
} }
templates add f("mapNotNullTo(destination: C, transform: (T) -> R?)") { val f_mapNotNullTo = fn("mapNotNullTo(destination: C, transform: (T) -> R?)") {
inline(true) include(Iterables, ArraysOfObjects, Sequences, Maps, CharSequences)
include(Maps, CharSequences) } builder {
exclude(ArraysOfPrimitives) inline()
typeParam("R : Any") typeParam("R : Any")
typeParam("C : MutableCollection<in R>") typeParam("C : MutableCollection<in R>")
returns("C") returns("C")
doc { f -> doc {
""" """
Applies the given [transform] function to each ${f.element} in the original ${f.collection} Applies the given [transform] function to each ${f.element} in the original ${f.collection}
and appends only the non-null results to the given [destination]. and appends only the non-null results to the given [destination].
@@ -201,14 +245,14 @@ fun mapping(): List<GenericFunction> {
} }
} }
templates add f("mapIndexedNotNullTo(destination: C, transform: (index: Int, T) -> R?)") { val f_mapIndexedNotNullTo = fn("mapIndexedNotNullTo(destination: C, transform: (index: Int, T) -> R?)") {
inline(true) include(Iterables, ArraysOfObjects, Sequences, CharSequences)
include(CharSequences) } builder {
exclude(ArraysOfPrimitives) inline()
typeParam("R : Any") typeParam("R : Any")
typeParam("C : MutableCollection<in R>") typeParam("C : MutableCollection<in R>")
returns("C") returns("C")
doc { f -> doc {
""" """
Applies the given [transform] function to each ${f.element} and its index in the original ${f.collection} Applies the given [transform] function to each ${f.element} and its index in the original ${f.collection}
and appends only the non-null results to the given [destination]. and appends only the non-null results to the given [destination].
@@ -224,53 +268,38 @@ fun mapping(): List<GenericFunction> {
} }
} }
templates add f("flatMap(transform: (T) -> Iterable<R>)") { val f_flatMap = fn("flatMap(transform: (T) -> Iterable<R>)") {
inline(true) includeDefault()
include(Maps, CharSequences)
} builder {
inline()
exclude(Sequences) doc { "Returns a single list of all elements yielded from results of [transform] function being invoked on each ${f.element} of original ${f.collection}." }
doc { f -> "Returns a single list of all elements yielded from results of [transform] function being invoked on each ${f.element} of original ${f.collection}." }
typeParam("R") typeParam("R")
returns("List<R>") returns("List<R>")
body { body {
"return flatMapTo(ArrayList<R>(), transform)" "return flatMapTo(ArrayList<R>(), transform)"
} }
include(Maps, CharSequences) specialFor(Sequences) {
} inline(Inline.No)
signature("flatMap(transform: (T) -> Sequence<R>)")
templates add f("flatMap(transform: (T) -> Sequence<R>)") { doc { "Returns a single sequence of all elements from results of [transform] function being invoked on each element of original sequence." }
only(Sequences) returns("Sequence<R>")
doc { "Returns a single sequence of all elements from results of [transform] function being invoked on each element of original sequence." } body {
typeParam("R") "return FlatteningSequence(this, transform, { it.iterator() })"
returns("Sequence<R>") }
body {
"return FlatteningSequence(this, transform, { it.iterator() })"
} }
} }
templates add f("flatMapTo(destination: C, transform: (T) -> Iterable<R>)") { val f_flatMapTo = fn("flatMapTo(destination: C, transform: (T) -> Iterable<R>)") {
inline(true) includeDefault()
exclude(Sequences)
doc { f -> "Appends all elements yielded from results of [transform] function being invoked on each ${f.element} of original ${f.collection}, to the given [destination]." }
typeParam("R")
typeParam("C : MutableCollection<in R>")
returns("C")
body {
"""
for (element in this) {
val list = transform(element)
destination.addAll(list)
}
return destination
"""
}
include(Maps, CharSequences) include(Maps, CharSequences)
} } builder {
inline()
templates add f("flatMapTo(destination: C, transform: (T) -> Sequence<R>)") { doc { "Appends all elements yielded from results of [transform] function being invoked on each ${f.element} of original ${f.collection}, to the given [destination]." }
inline(true) specialFor(Sequences) {
signature("flatMapTo(destination: C, transform: (T) -> Sequence<R>)")
only(Sequences) }
doc { "Appends all elements yielded from results of [transform] function being invoked on each element of original sequence, to the given [destination]." }
typeParam("R") typeParam("R")
typeParam("C : MutableCollection<in R>") typeParam("C : MutableCollection<in R>")
returns("C") returns("C")
@@ -285,11 +314,13 @@ fun mapping(): List<GenericFunction> {
} }
} }
templates add f("groupBy(keySelector: (T) -> K)") { val f_groupBy_key = fn("groupBy(keySelector: (T) -> K)") {
inline(true) includeDefault()
include(CharSequences) include(CharSequences)
doc { f -> } builder {
inline()
doc {
""" """
Groups ${f.element.pluralize()} of the original ${f.collection} by the key returned by the given [keySelector] function Groups ${f.element.pluralize()} of the original ${f.collection} by the key returned by the given [keySelector] function
applied to each ${f.element} and returns a map where each group key is associated with a list of corresponding ${f.element.pluralize()}. applied to each ${f.element} and returns a map where each group key is associated with a list of corresponding ${f.element.pluralize()}.
@@ -305,13 +336,15 @@ fun mapping(): List<GenericFunction> {
body { "return groupByTo(LinkedHashMap<K, MutableList<T>>(), keySelector)" } body { "return groupByTo(LinkedHashMap<K, MutableList<T>>(), keySelector)" }
} }
templates add f("groupByTo(destination: M, keySelector: (T) -> K)") { val f_groupByTo_key = fn("groupByTo(destination: M, keySelector: (T) -> K)") {
inline(true) includeDefault()
include(CharSequences) include(CharSequences)
} builder {
inline()
typeParam("K") typeParam("K")
typeParam("M : MutableMap<in K, MutableList<T>>") typeParam("M : MutableMap<in K, MutableList<T>>")
doc { f -> doc {
""" """
Groups ${f.element.pluralize()} of the original ${f.collection} by the key returned by the given [keySelector] function Groups ${f.element.pluralize()} of the original ${f.collection} by the key returned by the given [keySelector] function
applied to each ${f.element} and puts to the [destination] map each group key associated with a list of corresponding ${f.element.pluralize()}. applied to each ${f.element} and puts to the [destination] map each group key associated with a list of corresponding ${f.element.pluralize()}.
@@ -335,11 +368,12 @@ fun mapping(): List<GenericFunction> {
} }
} }
templates add f("groupBy(keySelector: (T) -> K, valueTransform: (T) -> V)") { val f_groupBy_key_value = fn("groupBy(keySelector: (T) -> K, valueTransform: (T) -> V)") {
inline(true) includeDefault()
include(CharSequences) include(CharSequences)
doc { f -> } builder {
inline()
doc {
""" """
Groups values returned by the [valueTransform] function applied to each ${f.element} of the original ${f.collection} Groups values returned by the [valueTransform] function applied to each ${f.element} of the original ${f.collection}
by the key returned by the given [keySelector] function applied to the ${f.element} by the key returned by the given [keySelector] function applied to the ${f.element}
@@ -358,15 +392,16 @@ fun mapping(): List<GenericFunction> {
} }
templates add f("groupByTo(destination: M, keySelector: (T) -> K, valueTransform: (T) -> V)") { val f_groupByTo_key_value = fn("groupByTo(destination: M, keySelector: (T) -> K, valueTransform: (T) -> V)") {
inline(true) includeDefault()
include(CharSequences) include(CharSequences)
} builder {
inline()
typeParam("K") typeParam("K")
typeParam("V") typeParam("V")
typeParam("M : MutableMap<in K, MutableList<V>>") typeParam("M : MutableMap<in K, MutableList<V>>")
doc { f -> doc {
""" """
Groups values returned by the [valueTransform] function applied to each ${f.element} of the original ${f.collection} Groups values returned by the [valueTransform] function applied to each ${f.element} of the original ${f.collection}
by the key returned by the given [keySelector] function applied to the ${f.element} by the key returned by the given [keySelector] function applied to the ${f.element}
@@ -391,17 +426,18 @@ fun mapping(): List<GenericFunction> {
} }
} }
templates add f("groupingBy(crossinline keySelector: (T) -> K)") { val f_groupingBy = fn("groupingBy(crossinline keySelector: (T) -> K)") {
include(Iterables, Sequences, ArraysOfObjects, CharSequences)
} builder {
since("1.1") since("1.1")
inline(true) inline()
only(Iterables, Sequences, ArraysOfObjects, CharSequences)
typeParam("T") typeParam("T")
typeParam("K") typeParam("K")
returns("Grouping<T, K>") returns("Grouping<T, K>")
doc { f -> doc {
""" """
Creates a [Grouping] source from ${f.collection.prefixWithArticle()} to be used later with one of group-and-fold operations Creates a [Grouping] source from ${f.collection.prefixWithArticle()} to be used later with one of group-and-fold operations
using the specified [keySelector] function to extract a key from each ${f.element}. using the specified [keySelector] function to extract a key from each ${f.element}.
@@ -420,14 +456,4 @@ fun mapping(): List<GenericFunction> {
} }
} }
val terminalOperationPattern = Regex("^\\w+To") }
templates.forEach { with (it) {
if (sequenceClassification.isEmpty()) {
if (terminalOperationPattern in signature)
sequenceClassification(terminal)
else
sequenceClassification(intermediate, stateless)
}
} }
return templates
}