Introduce kotlin-stdlib-generator dsl block for specifying sample reference

This commit is contained in:
Ilya Gorbunov
2018-04-20 22:11:23 +03:00
parent 5dd7ff4d7f
commit 908d2d6975
12 changed files with 126 additions and 92 deletions
@@ -37,10 +37,9 @@ object Aggregates : TemplateGroupBase() {
doc {
"""
Returns `true` if all ${f.element.pluralize()} match the given [predicate].
@sample samples.collections.Collections.Aggregates.all
"""
}
sample("samples.collections.Collections.Aggregates.all")
returns("Boolean")
body {
"""
@@ -64,10 +63,9 @@ object Aggregates : TemplateGroupBase() {
doc {
"""
Returns `true` if no ${f.element.pluralize()} match the given [predicate].
@sample samples.collections.Collections.Aggregates.noneWithPredicate
"""
}
sample("samples.collections.Collections.Aggregates.noneWithPredicate")
returns("Boolean")
body {
"""
@@ -89,10 +87,9 @@ object Aggregates : TemplateGroupBase() {
doc {
"""
Returns `true` if the ${f.collection} has no ${f.element.pluralize()}.
@sample samples.collections.Collections.Aggregates.none
"""
}
sample("samples.collections.Collections.Aggregates.none")
returns("Boolean")
body {
"return !iterator().hasNext()"
@@ -119,10 +116,9 @@ object Aggregates : TemplateGroupBase() {
doc {
"""
Returns `true` if at least one ${f.element} matches the given [predicate].
@sample samples.collections.Collections.Aggregates.anyWithPredicate
"""
}
sample("samples.collections.Collections.Aggregates.anyWithPredicate")
returns("Boolean")
body {
"""
@@ -144,10 +140,9 @@ object Aggregates : TemplateGroupBase() {
doc {
"""
Returns `true` if ${f.collection} has at least one ${f.element}.
@sample samples.collections.Collections.Aggregates.any
"""
}
sample("samples.collections.Collections.Aggregates.any")
returns("Boolean")
body {
"return iterator().hasNext()"
@@ -118,10 +118,9 @@ object ArrayOps : TemplateGroupBase() {
doc {
"""
Returns a string representation of the contents of the specified array as if it is [List].
@sample samples.collections.Arrays.ContentOperations.contentToString
"""
}
sample("samples.collections.Arrays.ContentOperations.contentToString")
returns("String")
on(Platform.JVM) {
inlineOnly()
@@ -144,10 +143,9 @@ object ArrayOps : TemplateGroupBase() {
If any of arrays contains itself on any nesting level that reference
is rendered as `"[...]"` to prevent recursion.
@sample samples.collections.Arrays.ContentOperations.contentDeepToString
"""
}
sample("samples.collections.Arrays.ContentOperations.contentDeepToString")
returns("String")
on(Platform.JVM) {
inlineOnly()
@@ -36,9 +36,9 @@ object ComparableOps : TemplateGroupBase() {
Ensures that this value is not less than the specified [minimumValue].
@return this value if it's greater than or equal to the [minimumValue] or the [minimumValue] otherwise.
@sample samples.comparisons.ComparableOps.coerceAtLeast${if (f == Generic) "Comparable" else ""}
"""
}
sample("samples.comparisons.ComparableOps.coerceAtLeast${if (f == Generic) "Comparable" else ""}")
body {
"""
return if (this < minimumValue) minimumValue else this
@@ -58,9 +58,9 @@ object ComparableOps : TemplateGroupBase() {
Ensures that this value is not greater than the specified [maximumValue].
@return this value if it's less than or equal to the [maximumValue] or the [maximumValue] otherwise.
@sample samples.comparisons.ComparableOps.coerceAtMost${if (f == Generic) "Comparable" else ""}
"""
}
sample("samples.comparisons.ComparableOps.coerceAtMost${if (f == Generic) "Comparable" else ""}")
body {
"""
return if (this > maximumValue) maximumValue else this
@@ -80,9 +80,9 @@ object ComparableOps : TemplateGroupBase() {
Ensures that this value lies in the specified [range].
@return this value if it's in the [range], or `range.start` if this value is less than `range.start`, or `range.endInclusive` if this value is greater than `range.endInclusive`.
@sample samples.comparisons.ComparableOps.coerceIn${if (f == Generic) "Comparable" else ""}
"""
}
sample("samples.comparisons.ComparableOps.coerceIn${if (f == Generic) "Comparable" else ""}")
body(Generic) {
"""
if (range is ClosedFloatingPointRange) {
@@ -123,9 +123,9 @@ object ComparableOps : TemplateGroupBase() {
Ensures that this value lies in the specified [range].
@return this value if it's in the [range], or `range.start` if this value is less than `range.start`, or `range.endInclusive` if this value is greater than `range.endInclusive`.
@sample samples.comparisons.ComparableOps.coerceInFloatingPointRange
"""
}
sample("samples.comparisons.ComparableOps.coerceInFloatingPointRange")
body(Generic) {
"""
if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: ${'$'}range.")
@@ -384,9 +384,9 @@ object ComparableOps : TemplateGroupBase() {
Ensures that this value lies in the specified range [minimumValue]..[maximumValue].
@return this value if it's in the range, or [minimumValue] if this value is less than [minimumValue], or [maximumValue] if this value is greater than [maximumValue].
@sample samples.comparisons.ComparableOps.coerceIn${if (f == Generic) "Comparable" else ""}
"""
}
sample("samples.comparisons.ComparableOps.coerceIn${if (f == Generic) "Comparable" else ""}")
body(Primitives) {
"""
if (minimumValue > maximumValue) throw IllegalArgumentException("Cannot coerce value to an empty range: maximum ${'$'}maximumValue is less than minimum ${'$'}minimumValue.")
@@ -51,10 +51,9 @@ object Filtering : TemplateGroupBase() {
doc {
"""
Returns a list containing all elements except first [n] elements.
@sample samples.collections.Collections.Transformations.drop
"""
}
sample("samples.collections.Collections.Transformations.drop")
returns("List<T>")
body {
"""
@@ -138,10 +137,9 @@ object Filtering : TemplateGroupBase() {
doc {
"""
Returns a list containing first [n] elements.
@sample samples.collections.Collections.Transformations.take
"""
}
sample("samples.collections.Collections.Transformations.take")
returns("List<T>")
body {
"""
@@ -219,10 +217,9 @@ object Filtering : TemplateGroupBase() {
doc {
"""
Returns a list containing all elements except last [n] elements.
@sample samples.collections.Collections.Transformations.drop
"""
}
sample("samples.collections.Collections.Transformations.drop")
returns("List<T>")
body {
"""
@@ -249,10 +246,9 @@ object Filtering : TemplateGroupBase() {
doc {
"""
Returns a list containing last [n] elements.
@sample samples.collections.Collections.Transformations.take
"""
}
sample("samples.collections.Collections.Transformations.take")
returns("List<T>")
specialFor(Strings, CharSequences) {
@@ -316,10 +312,9 @@ object Filtering : TemplateGroupBase() {
doc {
"""
Returns a list containing all elements except first elements that satisfy the given [predicate].
@sample samples.collections.Collections.Transformations.drop
"""
}
sample("samples.collections.Collections.Transformations.drop")
returns("List<T>")
body {
"""
@@ -373,10 +368,9 @@ object Filtering : TemplateGroupBase() {
doc {
"""
Returns a list containing first elements satisfying the given [predicate].
@sample samples.collections.Collections.Transformations.take
"""
"""
}
sample("samples.collections.Collections.Transformations.take")
returns("List<T>")
body {
"""
@@ -424,10 +418,9 @@ object Filtering : TemplateGroupBase() {
doc {
"""
Returns a list containing all elements except last elements that satisfy the given [predicate].
@sample samples.collections.Collections.Transformations.drop
"""
}
sample("samples.collections.Collections.Transformations.drop")
returns("List<T>")
body {
@@ -481,10 +474,9 @@ object Filtering : TemplateGroupBase() {
doc {
"""
Returns a list containing last elements satisfying the given [predicate].
@sample samples.collections.Collections.Transformations.take
"""
}
sample("samples.collections.Collections.Transformations.take")
returns("List<T>")
body {
@@ -631,10 +631,9 @@ object Generators : TemplateGroupBase() {
@param step the number of elements to move the window forward by on an each step, by default 1
@param partialWindows controls whether or not to keep partial windows in the end if any,
by default `false` which means partial windows won't be preserved
@sample samples.collections.Sequences.Transformations.averageWindows
"""
}
sample("samples.collections.Sequences.Transformations.averageWindows")
typeParam("R")
returns("List<R>")
@@ -711,10 +710,9 @@ object Generators : TemplateGroupBase() {
@param step the number of elements to move the window forward by on an each step, by default 1
@param partialWindows controls whether or not to keep partial windows in the end if any,
by default `false` which means partial windows won't be preserved
@sample samples.collections.Sequences.Transformations.takeWindows
"""
}
sample("samples.collections.Sequences.Transformations.takeWindows")
body {
"""
@@ -765,10 +763,9 @@ object Generators : TemplateGroupBase() {
@param step the number of elements to move the window forward by on an each step, by default 1
@param partialWindows controls whether or not to keep partial windows in the end if any,
by default `false` which means partial windows won't be preserved
@sample samples.collections.Sequences.Transformations.averageWindows
"""
}
sample("samples.collections.Sequences.Transformations.averageWindows")
typeParam("R")
returns("Sequence<R>")
@@ -798,10 +795,9 @@ object Generators : TemplateGroupBase() {
@param step the number of elements to move the window forward by on an each step, by default 1
@param partialWindows controls whether or not to keep partial windows in the end if any,
by default `false` which means partial windows won't be preserved
@sample samples.collections.Sequences.Transformations.takeWindows
"""
}
sample("samples.collections.Sequences.Transformations.takeWindows")
returns("Sequence<String>")
body(CharSequences) { "return windowedSequence(size, step, partialWindows) { it.toString() }" }
@@ -823,10 +819,9 @@ object Generators : TemplateGroupBase() {
The last ${f.viewResult} may have less ${f.element.pluralize()} than the given [size].
@param size the number of elements to take in each ${f.viewResult}, must be positive and can be greater than the number of elements in this ${f.collection}.
@sample samples.text.Strings.chunkedTransform
"""
}
sample("samples.text.Strings.chunkedTransform")
typeParam("R")
returns("List<R>")
@@ -851,10 +846,9 @@ object Generators : TemplateGroupBase() {
The last ${f.snapshotResult} in the resulting ${f.mapResult} may have less ${f.element.pluralize()} than the given [size].
@param size the number of elements to take in each ${f.snapshotResult}, must be positive and can be greater than the number of elements in this ${f.collection}.
@sample samples.collections.Collections.Transformations.chunked
"""
}
sample("samples.collections.Collections.Transformations.chunked")
specialFor(Iterables) { returns("List<List<T>>") }
specialFor(Sequences) { returns("Sequence<List<T>>") }
specialFor(CharSequences) { returns("List<String>") }
@@ -880,10 +874,9 @@ object Generators : TemplateGroupBase() {
The last ${f.viewResult} may have less ${f.element.pluralize()} than the given [size].
@param size the number of elements to take in each ${f.viewResult}, must be positive and can be greater than the number of elements in this ${f.collection}.
@sample samples.text.Strings.chunkedTransformToSequence
"""
}
sample("samples.text.Strings.chunkedTransformToSequence")
typeParam("R")
returns("Sequence<R>")
@@ -906,10 +899,9 @@ object Generators : TemplateGroupBase() {
The last ${f.snapshotResult} in the resulting sequence may have less ${f.element.pluralize()} than the given [size].
@param size the number of elements to take in each ${f.snapshotResult}, must be positive and can be greater than the number of elements in this ${f.collection}.
@sample samples.collections.Collections.Transformations.chunked
"""
}
sample("samples.collections.Collections.Transformations.chunked")
returns("Sequence<String>")
body(CharSequences) { "return chunkedSequence(size) { it.toString() }" }
@@ -926,10 +918,9 @@ object Generators : TemplateGroupBase() {
to an each pair of two adjacent ${f.element.pluralize()} in this ${f.collection}.
The returned ${f.mapResult} is empty if this ${f.collection} contains less than two ${f.element.pluralize()}.
@sample samples.collections.Collections.Transformations.zipWithNextToFindDeltas
"""
}
sample("samples.collections.Collections.Transformations.zipWithNextToFindDeltas")
returns("List<R>")
inline()
body {
@@ -988,10 +979,9 @@ object Generators : TemplateGroupBase() {
Returns a ${f.mapResult} of pairs of each two adjacent ${f.element.pluralize()} in this ${f.collection}.
The returned ${f.mapResult} is empty if this ${f.collection} contains less than two ${f.element.pluralize()}.
@sample samples.collections.Collections.Transformations.zipWithNext
"""
}
sample("samples.collections.Collections.Transformations.zipWithNext")
sequenceClassification(intermediate, stateless)
specialFor(Sequences) { returns("Sequence<Pair<T, T>>") }
body {
@@ -1007,10 +997,9 @@ object Generators : TemplateGroupBase() {
Returns a list of values built from the elements of `this` ${f.collection} and the [other] collection with the same index
using the provided [transform] function applied to each pair of elements.
The returned list has length of the shortest collection.
@sample samples.collections.Iterables.Operations.zipIterableWithTransform
"""
}
sample("samples.collections.Iterables.Operations.zipIterableWithTransform")
typeParam("R")
typeParam("V")
returns("List<V>")
@@ -1048,10 +1037,9 @@ object Generators : TemplateGroupBase() {
Returns a list of values built from the elements of `this` ${f.collection} and the [other] array with the same index
using the provided [transform] function applied to each pair of elements.
The returned list has length of the shortest collection.
@sample samples.collections.Iterables.Operations.zipIterableWithTransform
"""
}
sample("samples.collections.Iterables.Operations.zipIterableWithTransform")
typeParam("R")
typeParam("V")
returns("List<V>")
@@ -1089,10 +1077,9 @@ object Generators : TemplateGroupBase() {
Returns a list of values built from the elements of `this` array and the [other] array with the same index
using the provided [transform] function applied to each pair of elements.
The returned list has length of the shortest array.
@sample samples.collections.Iterables.Operations.zipIterableWithTransform
"""
}
sample("samples.collections.Iterables.Operations.zipIterableWithTransform")
typeParam("V")
returns("List<V>")
inline()
@@ -1116,10 +1103,9 @@ object Generators : TemplateGroupBase() {
Returns a sequence of values built from the elements of `this` sequence and the [other] sequence with the same index
using the provided [transform] function applied to each pair of elements.
The resulting sequence ends as soon as the shortest input sequence ends.
@sample samples.collections.Sequences.Transformations.zipWithTransform
"""
}
sample("samples.collections.Sequences.Transformations.zipWithTransform")
sequenceClassification(intermediate, stateless)
typeParam("R")
typeParam("V")
@@ -1139,10 +1125,9 @@ object Generators : TemplateGroupBase() {
Returns a list of values built from the characters of `this` and the [other] char sequences with the same index
using the provided [transform] function applied to each pair of characters.
The returned list has length of the shortest char sequence.
@sample samples.text.Strings.zipWithTransform
"""
}
sample("samples.text.Strings.zipWithTransform")
typeParam("V")
returns("List<V>")
inline()
@@ -1168,10 +1153,9 @@ object Generators : TemplateGroupBase() {
"""
Returns a list of pairs built from the elements of `this` collection and [other] ${f.collection} with the same index.
The returned list has length of the shortest collection.
@sample samples.collections.Iterables.Operations.zipIterable
"""
}
sample("samples.collections.Iterables.Operations.zipIterable")
typeParam("R")
returns("List<Pair<T, R>>")
body {
@@ -1189,10 +1173,9 @@ object Generators : TemplateGroupBase() {
"""
Returns a list of pairs built from the characters of `this` and the [other] char sequences with the same index
The returned list has length of the shortest char sequence.
@sample samples.text.Strings.zip
"""
}
sample("samples.text.Strings.zip")
returns("List<Pair<Char, Char>>")
body {
"""
@@ -1209,10 +1192,9 @@ object Generators : TemplateGroupBase() {
"""
Returns a list of pairs built from the elements of `this` ${f.collection} and the [other] array with the same index.
The returned list has length of the shortest collection.
@sample samples.collections.Iterables.Operations.zipIterable
"""
}
sample("samples.collections.Iterables.Operations.zipIterable")
typeParam("R")
returns("List<Pair<T, R>>")
body {
@@ -1230,10 +1212,9 @@ object Generators : TemplateGroupBase() {
"""
Returns a list of pairs built from the elements of `this` array and the [other] array with the same index.
The returned list has length of the shortest collection.
@sample samples.collections.Iterables.Operations.zipIterable
"""
}
sample("samples.collections.Iterables.Operations.zipIterable")
returns("List<Pair<T, T>>")
body {
"""
@@ -1250,10 +1231,9 @@ object Generators : TemplateGroupBase() {
"""
Returns a sequence of values built from the elements of `this` sequence and the [other] sequence with the same index.
The resulting sequence ends as soon as the shortest input sequence ends.
@sample samples.collections.Sequences.Transformations.zip
"""
}
sample("samples.collections.Sequences.Transformations.zip")
sequenceClassification(intermediate, stateless)
typeParam("R")
returns("Sequence<Pair<T, R>>")
@@ -326,10 +326,9 @@ object Mapping : TemplateGroupBase() {
applied to each ${f.element} and returns a map where each group key is associated with a list of corresponding ${f.element.pluralize()}.
The returned map preserves the entry iteration order of the keys produced from the original ${f.collection}.
@sample samples.collections.Collections.Transformations.groupBy
"""
}
sample("samples.collections.Collections.Transformations.groupBy")
sequenceClassification(terminal)
typeParam("K")
returns("Map<K, List<T>>")
@@ -350,10 +349,9 @@ object Mapping : TemplateGroupBase() {
applied to each ${f.element} and puts to the [destination] map each group key associated with a list of corresponding ${f.element.pluralize()}.
@return The [destination] map.
@sample samples.collections.Collections.Transformations.groupBy
"""
}
sample("samples.collections.Collections.Transformations.groupBy")
sequenceClassification(terminal)
returns("M")
body {
@@ -380,10 +378,9 @@ object Mapping : TemplateGroupBase() {
and returns a map where each group key is associated with a list of corresponding values.
The returned map preserves the entry iteration order of the keys produced from the original ${f.collection}.
@sample samples.collections.Collections.Transformations.groupByKeysAndValues
"""
}
sample("samples.collections.Collections.Transformations.groupByKeysAndValues")
sequenceClassification(terminal)
typeParam("K")
typeParam("V")
@@ -408,10 +405,9 @@ object Mapping : TemplateGroupBase() {
and puts to the [destination] map each group key associated with a list of corresponding values.
@return The [destination] map.
@sample samples.collections.Collections.Transformations.groupByKeysAndValues
"""
}
sample("samples.collections.Collections.Transformations.groupByKeysAndValues")
sequenceClassification(terminal)
returns("M")
body {
@@ -441,10 +437,9 @@ object Mapping : TemplateGroupBase() {
"""
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}.
@sample samples.collections.Collections.Transformations.groupingByEachCount
"""
}
sample("samples.collections.Collections.Transformations.groupingByEachCount")
body {
"""
@@ -52,10 +52,11 @@ object SequenceOps : TemplateGroupBase() {
doc {
"""
Creates a [Sequence] instance that wraps the original ${f.collection} returning its ${f.element.pluralize()} when being iterated.
${if (f in listOf(ArraysOfPrimitives, ArraysOfObjects, Iterables)) "@sample samples.collections.Sequences.Building.sequenceFrom${f.doc.collection.capitalize()}" else ""}
"""
}
if (f in listOf(ArraysOfPrimitives, ArraysOfObjects, Iterables))
sample("samples.collections.Sequences.Building.sequenceFrom${f.doc.collection.capitalize()}")
returns("Sequence<T>")
body {
"""
@@ -30,10 +30,9 @@ object StringJoinOps : TemplateGroupBase() {
If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit]
elements will be appended, followed by the [truncated] string (which defaults to "...").
@sample samples.collections.Collections.Transformations.joinTo
"""
}
sample("samples.collections.Collections.Transformations.joinTo")
sequenceClassification(terminal)
typeParam("A : Appendable")
returns("A")
@@ -81,10 +80,9 @@ object StringJoinOps : TemplateGroupBase() {
If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit]
elements will be appended, followed by the [truncated] string (which defaults to "...").
@sample samples.collections.Collections.Transformations.joinToString
"""
}
sample("samples.collections.Collections.Transformations.joinToString")
sequenceClassification(terminal)
returns("String")
@@ -55,6 +55,8 @@ class MemberBuilder(
var doc: String? = null; private set
val samples = mutableListOf<String>()
val sequenceClassification = mutableListOf<SequenceClass>()
var deprecate: Deprecation? = null; private set
var since: String? = null; private set
@@ -129,6 +131,10 @@ class MemberBuilder(
@Deprecated("Use specialFor", ReplaceWith("specialFor(*fs) { doc(valueBuilder) }"))
fun doc(vararg fs: Family, valueBuilder: DocExtensions.() -> String) = specialFor(*fs) { doc(valueBuilder) }
fun sample(sampleRef: String) {
samples += sampleRef
}
fun body(valueBuilder: () -> String) {
body = valueBuilder()
}
@@ -299,6 +305,10 @@ class MemberBuilder(
StringReader(methodDoc.trim()).forEachLine { line ->
builder.append(" * ").append(line.trim()).append("\n")
}
if (samples.any()) {
builder.append(" * \n")
samples.forEach { builder.append(" * @sample $it\n")}
}
if (family == Sequences && sequenceClassification.isNotEmpty()) {
builder.append(" *\n")
builder.append(" * The operation is ${sequenceClassification.joinToString(" and ") { "_${it}_" }}.\n")