stdlib sources re-added
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
package kotlin
|
||||
|
||||
import java.io.ByteArrayInputStream
|
||||
|
||||
import java.util.Arrays
|
||||
|
||||
// Array "constructor"
|
||||
inline fun <T> array(vararg t : T) : Array<T> = t
|
||||
|
||||
// "constructors" for primitive types array
|
||||
inline fun doubleArray(vararg content : Double) = content
|
||||
|
||||
inline fun floatArray(vararg content : Float) = content
|
||||
|
||||
inline fun longArray(vararg content : Long) = content
|
||||
|
||||
inline fun intArray(vararg content : Int) = content
|
||||
|
||||
inline fun charArray(vararg content : Char) = content
|
||||
|
||||
inline fun shortArray(vararg content : Short) = content
|
||||
|
||||
inline fun byteArray(vararg content : Byte) = content
|
||||
|
||||
inline fun booleanArray(vararg content : Boolean) = content
|
||||
|
||||
inline fun ByteArray.binarySearch(key: Byte) = Arrays.binarySearch(this, key)
|
||||
inline fun ShortArray.binarySearch(key: Short) = Arrays.binarySearch(this, key)
|
||||
inline fun IntArray.binarySearch(key: Int) = Arrays.binarySearch(this, key)
|
||||
inline fun LongArray.binarySearch(key: Long) = Arrays.binarySearch(this, key)
|
||||
inline fun FloatArray.binarySearch(key: Float) = Arrays.binarySearch(this, key)
|
||||
inline fun DoubleArray.binarySearch(key: Double) = Arrays.binarySearch(this, key)
|
||||
inline fun CharArray.binarySearch(key: Char) = Arrays.binarySearch(this, key)
|
||||
|
||||
inline fun ByteArray.binarySearch(fromIndex: Int, toIndex: Int, key: Byte) = Arrays.binarySearch(this, fromIndex, toIndex, key)
|
||||
inline fun ShortArray.binarySearch(fromIndex: Int, toIndex: Int, key: Short) = Arrays.binarySearch(this, fromIndex, toIndex, key)
|
||||
inline fun IntArray.binarySearch(fromIndex: Int, toIndex: Int, key: Int) = Arrays.binarySearch(this, fromIndex, toIndex, key)
|
||||
inline fun LongArray.binarySearch(fromIndex: Int, toIndex: Int, key: Long) = Arrays.binarySearch(this, fromIndex, toIndex, key)
|
||||
inline fun FloatArray.binarySearch(fromIndex: Int, toIndex: Int, key: Float) = Arrays.binarySearch(this, fromIndex, toIndex, key)
|
||||
inline fun DoubleArray.binarySearch(fromIndex: Int, toIndex: Int, key: Double) = Arrays.binarySearch(this, fromIndex, toIndex, key)
|
||||
inline fun CharArray.binarySearch(fromIndex: Int, toIndex: Int, key: Char) = Arrays.binarySearch(this, fromIndex, toIndex, key)
|
||||
|
||||
/*
|
||||
inline fun <T> Array<T>.binarySearch(key: T, comparator: fun(T,T):Int) = Arrays.binarySearch(this, key, object: java.util.Comparator<T> {
|
||||
override fun compare(a: T, b: T) = comparator(a, b)
|
||||
|
||||
override fun equals(obj: Any?) = obj.identityEquals(this)
|
||||
})
|
||||
*/
|
||||
inline fun BooleanArray.fill(value: Boolean) = Arrays.fill(this, value)
|
||||
inline fun ByteArray.fill(value: Byte) = Arrays.fill(this, value)
|
||||
inline fun ShortArray.fill(value: Short) = Arrays.fill(this, value)
|
||||
inline fun IntArray.fill(value: Int) = Arrays.fill(this, value)
|
||||
inline fun LongArray.fill(value: Long) = Arrays.fill(this, value)
|
||||
inline fun FloatArray.fill(value: Float) = Arrays.fill(this, value)
|
||||
inline fun DoubleArray.fill(value: Double) = Arrays.fill(this, value)
|
||||
inline fun CharArray.fill(value: Char) = Arrays.fill(this, value)
|
||||
|
||||
inline fun <in T: Any?> Array<T>.fill(value: T) = Arrays.fill(this as Array<Any?>, value)
|
||||
|
||||
inline fun ByteArray.sort() = Arrays.sort(this)
|
||||
inline fun ShortArray.sort() = Arrays.sort(this)
|
||||
inline fun IntArray.sort() = Arrays.sort(this)
|
||||
inline fun LongArray.sort() = Arrays.sort(this)
|
||||
inline fun FloatArray.sort() = Arrays.sort(this)
|
||||
inline fun DoubleArray.sort() = Arrays.sort(this)
|
||||
inline fun CharArray.sort() = Arrays.sort(this)
|
||||
|
||||
inline fun ByteArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex)
|
||||
inline fun ShortArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex)
|
||||
inline fun IntArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex)
|
||||
inline fun LongArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex)
|
||||
inline fun FloatArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex)
|
||||
inline fun DoubleArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex)
|
||||
inline fun CharArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex)
|
||||
|
||||
inline fun BooleanArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength)
|
||||
inline fun ByteArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength)
|
||||
inline fun ShortArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength)
|
||||
inline fun IntArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength)
|
||||
inline fun LongArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength)
|
||||
inline fun FloatArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength)
|
||||
inline fun DoubleArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength)
|
||||
inline fun CharArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength)
|
||||
|
||||
inline fun <T> Array<T>.copyOf(newLength: Int = this.size) : Array<T> = Arrays.copyOf(this, newLength).sure()
|
||||
|
||||
inline fun BooleanArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to)
|
||||
inline fun ByteArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to)
|
||||
inline fun ShortArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to)
|
||||
inline fun IntArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to)
|
||||
inline fun LongArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to)
|
||||
inline fun FloatArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to)
|
||||
inline fun DoubleArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to)
|
||||
inline fun CharArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to)
|
||||
|
||||
inline fun <T> Array<T>.copyOfRange(from: Int, to: Int) : Array<T> = Arrays.copyOfRange(this, from, to).sure()
|
||||
|
||||
inline val ByteArray.inputStream : ByteArrayInputStream
|
||||
get() = ByteArrayInputStream(this)
|
||||
|
||||
inline fun ByteArray.inputStream(offset: Int, length: Int) = ByteArrayInputStream(this, offset, length)
|
||||
|
||||
/** Returns true if the array is not empty */
|
||||
inline fun <T> Array<T>.notEmpty() : Boolean = !this.isEmpty()
|
||||
|
||||
/** Returns true if the array is empty */
|
||||
inline fun <T> Array<T>.isEmpty() : Boolean = this.size == 0
|
||||
|
||||
/** Returns the array if its not null or else returns an empty array */
|
||||
inline fun <T> Array<T?>?.orEmpty() : Array<T?> = if (this != null) this else array<T?>()
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package kotlin
|
||||
|
||||
import java.util.*
|
||||
import java.lang.Iterable
|
||||
|
||||
/** Filters given iterator */
|
||||
inline fun <T> java.util.Iterator<T>.filter(f: (T)-> Boolean) : java.util.Iterator<T> = FilterIterator<T>(this, f)
|
||||
|
||||
/** Create iterator filtering given java.lang.Iterable */
|
||||
/*
|
||||
inline fun <T> java.lang.Iterable<T>.filter(f: (T)->Boolean) : java.util.Iterator<T> = (iterator() as java.util.Iterator<T>).filter(f)
|
||||
*/
|
||||
|
||||
private class FilterIterator<T>(val original: java.util.Iterator<T>, val filter: (T)-> Boolean) : java.util.Iterator<T> {
|
||||
var state = 0
|
||||
var nextElement: T? = null
|
||||
|
||||
override fun hasNext(): Boolean =
|
||||
when(state) {
|
||||
1 -> true // checked and next present
|
||||
2 -> false // checked and next not present
|
||||
else -> {
|
||||
while(original.hasNext()) {
|
||||
val candidate = original.next()
|
||||
if((filter)(candidate)) {
|
||||
nextElement = candidate
|
||||
state = 1
|
||||
true
|
||||
}
|
||||
}
|
||||
state = 2
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override fun next(): T =
|
||||
if(state != 1)
|
||||
throw java.util.NoSuchElementException()
|
||||
else {
|
||||
val res = nextElement as T
|
||||
nextElement = null
|
||||
state = 0
|
||||
res
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
throw java.lang.UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package kotlin
|
||||
|
||||
inline fun Int.times(body : () -> Unit) {
|
||||
var count = this;
|
||||
while (count > 0) {
|
||||
body()
|
||||
count--
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package kotlin.util
|
||||
|
||||
import java.util.*
|
||||
import java.util.Iterator
|
||||
|
||||
/** Add iterated elements to given container */
|
||||
fun <T,U: Collection<in T>> java.util.Iterator<T>.to(container: U) : U {
|
||||
while(hasNext())
|
||||
container.add(next())
|
||||
return container
|
||||
}
|
||||
|
||||
/** Add iterated elements to java.util.ArrayList */
|
||||
inline fun <T> java.util.Iterator<T>.toArrayList() = to(ArrayList<T>())
|
||||
|
||||
/** Add iterated elements to java.util.LinkedList */
|
||||
inline fun <T> java.util.Iterator<T>.toLinkedList() = to(LinkedList<T>())
|
||||
|
||||
/** Add iterated elements to java.util.HashSet */
|
||||
inline fun <T> java.util.Iterator<T>.toHashSet() = to(HashSet<T>())
|
||||
|
||||
/** Add iterated elements to java.util.LinkedHashSet */
|
||||
inline fun <T> java.util.Iterator<T>.toLinkedHashSet() = to(LinkedHashSet<T>())
|
||||
|
||||
/** Add iterated elements to java.util.TreeSet */
|
||||
inline fun <T> java.util.Iterator<T>.toTreeSet() = to(TreeSet<T>())
|
||||
@@ -0,0 +1,15 @@
|
||||
package kotlin.util
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns a new List containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> java.util.Collection<T>.map(transform : (T) -> R) : java.util.List<R> {
|
||||
return mapTo(java.util.ArrayList<R>(this.size), transform)
|
||||
}
|
||||
|
||||
/** Transforms each element of this collection with the given function then adds the results to the given collection */
|
||||
inline fun <T, R, C: Collection<in R>> java.util.Collection<T>.mapTo(result: C, transform : (T) -> R) : C {
|
||||
for (item in this)
|
||||
result.add(transform(item))
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package kotlin.io
|
||||
|
||||
import java.io.*
|
||||
import java.nio.charset.*
|
||||
import java.util.NoSuchElementException
|
||||
|
||||
inline fun print(message : Any?) { System.out?.print(message) }
|
||||
inline fun print(message : Int) { System.out?.print(message) }
|
||||
inline fun print(message : Long) { System.out?.print(message) }
|
||||
inline fun print(message : Byte) { System.out?.print(message) }
|
||||
inline fun print(message : Short) { System.out?.print(message) }
|
||||
inline fun print(message : Char) { System.out?.print(message) }
|
||||
inline fun print(message : Boolean) { System.out?.print(message) }
|
||||
inline fun print(message : Float) { System.out?.print(message) }
|
||||
inline fun print(message : Double) { System.out?.print(message) }
|
||||
inline fun print(message : CharArray) { System.out?.print(message) }
|
||||
|
||||
inline fun println(message : Any?) { System.out?.println(message) }
|
||||
inline fun println(message : Int) { System.out?.println(message) }
|
||||
inline fun println(message : Long) { System.out?.println(message) }
|
||||
inline fun println(message : Byte) { System.out?.println(message) }
|
||||
inline fun println(message : Short) { System.out?.println(message) }
|
||||
inline fun println(message : Char) { System.out?.println(message) }
|
||||
inline fun println(message : Boolean) { System.out?.println(message) }
|
||||
inline fun println(message : Float) { System.out?.println(message) }
|
||||
inline fun println(message : Double) { System.out?.println(message) }
|
||||
inline fun println(message : CharArray) { System.out?.println(message) }
|
||||
inline fun println() { System.out?.println() }
|
||||
|
||||
private val stdin : BufferedReader = BufferedReader(InputStreamReader(object : InputStream() {
|
||||
override fun read() : Int {
|
||||
return System.`in`?.read() ?: -1
|
||||
}
|
||||
|
||||
override fun reset() {
|
||||
System.`in`?.reset()
|
||||
}
|
||||
|
||||
override fun read(b: ByteArray?): Int {
|
||||
return System.`in`?.read(b) ?: -1
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
System.`in`?.close()
|
||||
}
|
||||
|
||||
override fun mark(readlimit: Int) {
|
||||
System.`in`?.mark(readlimit)
|
||||
}
|
||||
|
||||
override fun skip(n: Long): Long {
|
||||
return System.`in`?.skip(n) ?: -1.toLong()
|
||||
}
|
||||
|
||||
override fun available(): Int {
|
||||
return System.`in`?.available() ?: 0
|
||||
}
|
||||
|
||||
override fun markSupported(): Boolean {
|
||||
return System.`in`?.markSupported() ?: false
|
||||
}
|
||||
|
||||
override fun read(b: ByteArray?, off: Int, len: Int): Int {
|
||||
return System.`in`?.read(b, off, len) ?: -1
|
||||
}
|
||||
}))
|
||||
|
||||
inline fun readLine() : String? = stdin.readLine()
|
||||
|
||||
/** Uses the given resource then closes it down correctly whether an exception is thrown or not */
|
||||
inline fun <T: Closeable, R> T.use(block: (T)-> R) : R {
|
||||
var closed = false
|
||||
try {
|
||||
return block(this)
|
||||
} catch (e: Exception) {
|
||||
closed = true
|
||||
try {
|
||||
this.close()
|
||||
} catch (closeException: Exception) {
|
||||
// eat the closeException as we are already throwing the original cause
|
||||
// and we don't want to mask the real exception
|
||||
|
||||
// TODO on Java 7 we should call
|
||||
// e.addSuppressed(closeException)
|
||||
// to work like try-with-resources
|
||||
// http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html#suppressed-exceptions
|
||||
}
|
||||
throw e
|
||||
} finally {
|
||||
if (!closed) {
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun InputStream.iterator() : ByteIterator =
|
||||
object: ByteIterator() {
|
||||
override val hasNext : Boolean
|
||||
get() = available() > 0
|
||||
|
||||
override fun nextByte() = read().toByte()
|
||||
}
|
||||
|
||||
inline fun InputStream.buffered(bufferSize: Int) = BufferedInputStream(this, bufferSize)
|
||||
|
||||
inline val InputStream.reader : InputStreamReader
|
||||
get() = InputStreamReader(this)
|
||||
|
||||
inline val InputStream.bufferedReader : BufferedReader
|
||||
get() = BufferedReader(reader)
|
||||
|
||||
inline fun InputStream.reader(charset: Charset) : InputStreamReader = InputStreamReader(this, charset)
|
||||
|
||||
inline fun InputStream.reader(charsetName: String) = InputStreamReader(this, charsetName)
|
||||
|
||||
inline fun InputStream.reader(charsetDecoder: CharsetDecoder) = InputStreamReader(this, charsetDecoder)
|
||||
|
||||
inline val InputStream.buffered : BufferedInputStream
|
||||
get() = if(this is BufferedInputStream) this else BufferedInputStream(this)
|
||||
|
||||
// inline val Reader.buffered : BufferedReader
|
||||
// get() = if(this is BufferedReader) this else BufferedReader(this)
|
||||
|
||||
inline fun Reader.buffered(): BufferedReader = if(this is BufferedReader) this else BufferedReader(this)
|
||||
|
||||
inline fun Reader.buffered(bufferSize: Int) = BufferedReader(this, bufferSize)
|
||||
|
||||
inline fun Reader.foreachLine(block: (String) -> Unit): Unit {
|
||||
this.use{
|
||||
val iter = buffered().lineIterator()
|
||||
while (iter.hasNext) {
|
||||
val elem = iter.next()
|
||||
block(elem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <T> Reader.useLines(block: (Iterator<String>) -> T): T = this.buffered().use<BufferedReader, T>{block(it.lineIterator())}
|
||||
/**
|
||||
* Returns an iterator over each line.
|
||||
* <b>Note</b> the caller must close the underlying <code>BufferedReader</code>
|
||||
* when the iteration is finished; as the user may not complete the iteration loop (e.g. using a method like find() or any() on the iterator
|
||||
* may terminate the iteration early.
|
||||
* <br>
|
||||
* We suggest you try the method useLines() instead which closes the stream when the processing is complete.
|
||||
*/
|
||||
inline fun BufferedReader.lineIterator() : Iterator<String> = LineIterator(this)
|
||||
|
||||
protected class LineIterator(val reader: BufferedReader) : Iterator<String> {
|
||||
private var nextValue: String? = null
|
||||
private var done = false
|
||||
|
||||
override val hasNext: Boolean
|
||||
get() {
|
||||
if (nextValue == null && !done) {
|
||||
nextValue = reader.readLine()
|
||||
if (nextValue == null) done = true
|
||||
}
|
||||
return nextValue != null
|
||||
}
|
||||
|
||||
override fun next(): String {
|
||||
if (!hasNext) {
|
||||
throw NoSuchElementException()
|
||||
}
|
||||
val answer = nextValue
|
||||
nextValue = null
|
||||
return answer.sure()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
package kotlin.util
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns true if any elements in the collection match the given predicate */
|
||||
inline fun <T> java.lang.Iterable<T>.any(predicate: (T)-> Boolean) : Boolean {
|
||||
for (elem in this) {
|
||||
if (predicate(elem)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/** Returns true if all elements in the collection match the given predicate */
|
||||
inline fun <T> java.lang.Iterable<T>.all(predicate: (T)-> Boolean) : Boolean {
|
||||
for (elem in this) {
|
||||
if (!predicate(elem)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/** Returns the number of items which match the given predicate */
|
||||
inline fun <T> java.lang.Iterable<T>.count(predicate: (T)-> Boolean) : Int {
|
||||
var answer = 0
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
answer += 1
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Returns the first item in the collection which matches the given predicate or null if none matched */
|
||||
inline fun <T> java.lang.Iterable<T>.find(predicate: (T)-> Boolean) : T? {
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
return elem
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** Returns a new List containing all elements in this collection which match the given predicate */
|
||||
inline fun <T> java.lang.Iterable<T>.filter(predicate: (T)-> Boolean) : Collection<T> = filterTo(java.util.ArrayList<T>(), predicate)
|
||||
|
||||
/** Filters all elements in this collection which match the given predicate into the given result collection */
|
||||
inline fun <T, C: Collection<in T>> java.lang.Iterable<T>.filterTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
result.add(elem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** Returns a List containing all the non null elements in this collection */
|
||||
inline fun <T> java.lang.Iterable<T?>?.filterNulls() : Collection<T> = filterNullsTo(java.util.ArrayList<T>())
|
||||
|
||||
/** Filters all the null elements in this collection winto the given result collection */
|
||||
inline fun <T, C: Collection<in T>> java.lang.Iterable<T?>?.filterNullsTo(result: C) : C {
|
||||
if (this != null) {
|
||||
for (elem in this) {
|
||||
if (elem != null)
|
||||
result.add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T> java.lang.Iterable<T>.filterNot(predicate: (T)-> Boolean) : Collection<T> = filterNotTo(ArrayList<T>(), predicate)
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T, C: Collection<in T>> java.lang.Iterable<T>.filterNotTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (!predicate(elem))
|
||||
result.add(elem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of transforming each item in the collection to a one or more values which
|
||||
* are concatenated together into a single collection
|
||||
*/
|
||||
inline fun <T, R> java.lang.Iterable<T>.flatMap(transform: (T)-> Collection<R>) : Collection<R> {
|
||||
return flatMapTo(ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of transforming each item in the collection to a one or more values which
|
||||
* are concatenated together into a single collection
|
||||
*/
|
||||
inline fun <T, R> java.lang.Iterable<T>.flatMapTo(result: Collection<R>, transform: (T)-> Collection<R>) : Collection<R> {
|
||||
for (elem in this) {
|
||||
val coll = transform(elem)
|
||||
if (coll != null) {
|
||||
for (r in coll) {
|
||||
result.add(r)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** Performs the given operation on each element inside the collection */
|
||||
inline fun <T> java.lang.Iterable<T>.foreach(operation: (element: T) -> Unit) {
|
||||
for (elem in this)
|
||||
operation(elem)
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all the values from from left to right with the initial value to perform the operation on sequential pairs of values
|
||||
*
|
||||
* For example to sum together all numeric values in a collection of numbers it would be
|
||||
* {code}val total = numbers.fold(0){(a, b) -> a + b}{code}
|
||||
*/
|
||||
inline fun <T> java.lang.Iterable<T>.fold(initial: T, operation: (it: T, it2: T) -> T): T {
|
||||
var answer = initial
|
||||
for (elem in this) {
|
||||
answer = operation(answer, elem)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all the values from right to left with the initial value to perform the operation on sequential pairs of values
|
||||
*/
|
||||
inline fun <T> java.lang.Iterable<T>.foldRight(initial: T, operation: (it: T, it2: T) -> T): T {
|
||||
val reversed = this.reverse()
|
||||
return reversed.fold(initial, operation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the collection performing the transformation on each element and using the result
|
||||
* as the key in a map to group elements by the result
|
||||
*/
|
||||
inline fun <T,K> java.lang.Iterable<T>.groupBy(result: Map<K,List<T>> = HashMap<K,List<T>>(), toKey: (T)-> K) : Map<K,List<T>> {
|
||||
for (elem in this) {
|
||||
val key = toKey(elem)
|
||||
val list = result.getOrPut(key){ ArrayList<T>() }
|
||||
list.add(elem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
/** Creates a String from all the elements in the collection, using the seperator between them and using the given prefix and postfix if supplied */
|
||||
inline fun <T> java.lang.Iterable<T>.join(separator: String, prefix: String = "", postfix: String = "") : String {
|
||||
val buffer = StringBuilder(prefix)
|
||||
var first = true
|
||||
for (elem in this) {
|
||||
if (first)
|
||||
first = false
|
||||
else
|
||||
buffer.append(separator)
|
||||
buffer.append(elem)
|
||||
}
|
||||
buffer.append(postfix)
|
||||
return buffer.toString().sure()
|
||||
}
|
||||
|
||||
/** Returns a reversed List of this collection */
|
||||
inline fun <T> java.lang.Iterable<T>.reverse() : List<T> {
|
||||
val answer = LinkedList<T>()
|
||||
for (elem in this) {
|
||||
answer.addFirst(elem)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Copies the collection into the given collection */
|
||||
inline fun <T, C: Collection<T>> java.lang.Iterable<T>.to(result: C) : C {
|
||||
for (elem in this)
|
||||
result.add(elem)
|
||||
return result
|
||||
}
|
||||
|
||||
/** Converts the collection into a LinkedList */
|
||||
inline fun <T> java.lang.Iterable<T>.toLinkedList() : LinkedList<T> = this.to(LinkedList<T>())
|
||||
|
||||
/** Converts the collection into a List */
|
||||
inline fun <T> java.lang.Iterable<T>.toList() : List<T> = this.to(ArrayList<T>())
|
||||
|
||||
/** Converts the collection into a Set */
|
||||
inline fun <T> java.lang.Iterable<T>.toSet() : Set<T> = this.to(HashSet<T>())
|
||||
|
||||
/** Converts the collection into a SortedSet */
|
||||
inline fun <T> java.lang.Iterable<T>.toSortedSet() : SortedSet<T> = this.to(TreeSet<T>())
|
||||
/**
|
||||
TODO figure out necessary variance/generics ninja stuff... :)
|
||||
inline fun <in T> java.lang.Iterable<T>.toSortedList(transform: fun(T) : java.lang.Comparable<*>) : List<T> {
|
||||
val answer = this.toList()
|
||||
answer.sort(transform)
|
||||
return answer
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,121 @@
|
||||
package kotlin.util
|
||||
// Number of extension function for java.lang.Iterable that shouldn't participate in auto generation
|
||||
|
||||
import java.util.Collection
|
||||
import java.util.List
|
||||
import java.util.AbstractList
|
||||
import java.util.Iterator
|
||||
|
||||
/**
|
||||
* Count the number of elements in collection.
|
||||
*
|
||||
* If base collection implements [[Collection]] interface method [[Collection.size()]] will be used.
|
||||
* Otherwise, this method determines the count by iterating through the all items.
|
||||
*/
|
||||
fun <T> java.lang.Iterable<T>.count() : Int {
|
||||
if (this is Collection<T>) {
|
||||
return this.size()
|
||||
}
|
||||
|
||||
var number : Int = 0
|
||||
for (elem in this) {
|
||||
++number
|
||||
}
|
||||
return number
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first element in the collection.
|
||||
*
|
||||
* Will throw an exception if there are no elements
|
||||
* TODO: Specify type of the exception
|
||||
*/
|
||||
inline fun <T> java.lang.Iterable<T>.first() : T {
|
||||
if (this is AbstractList<T>) {
|
||||
return this.get(0)
|
||||
}
|
||||
|
||||
return this.iterator().sure().next()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last element in the collection.
|
||||
*
|
||||
* If base collection implements List<T> interface, the combination of size() and get()
|
||||
* methods will be used for getting last element. Otherwise, this method determines the
|
||||
* last item by iterating through the all items.
|
||||
*
|
||||
* Will throw an exception if there are no elements.
|
||||
* TODO: Specify type of the exception
|
||||
*/
|
||||
fun <T> java.lang.Iterable<T>.last() : T {
|
||||
if (this is List<T>) {
|
||||
return this.get(this.size() - 1);
|
||||
}
|
||||
|
||||
val iterator = this.iterator().sure()
|
||||
var last : T = iterator.next()
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
last = iterator.next()
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if collection contains given item.
|
||||
*
|
||||
* Method checks equality of the objects with T.equals method.
|
||||
* If collection implements java.util.AbstractCollection an overridden implementation of the contains
|
||||
* method will be used.
|
||||
*/
|
||||
fun <T> java.lang.Iterable<T>.contains(item : T) : Boolean {
|
||||
kotlin.io.println("!!!!!")
|
||||
if (this is java.util.AbstractCollection<T>) {
|
||||
return this.contains(item);
|
||||
}
|
||||
|
||||
for (var elem in this) {
|
||||
if (elem.equals(item)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert collection of arbitrary elements to collection of
|
||||
*/
|
||||
fun <T> java.lang.Iterable<T>.withIndices() : java.lang.Iterable<#(Int, T)> {
|
||||
return object : java.lang.Iterable<#(Int, T)> {
|
||||
override fun iterator(): java.util.Iterator<#(Int, T)> {
|
||||
// TODO explicit typecast as a workaround for KT-1457, should be removed when it is fixed
|
||||
return NumberedIterator<T>(this@withIndices.iterator().sure()) as java.util.Iterator<#(Int, T)>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class NumberedIterator<TT>(private val sourceIterator : java.util.Iterator<TT>) : java.util.Iterator<#(Int, TT)> {
|
||||
private var nextIndex = 0
|
||||
|
||||
override fun remove() {
|
||||
try {
|
||||
sourceIterator.remove()
|
||||
nextIndex--;
|
||||
} catch (e : UnsupportedOperationException) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return sourceIterator.hasNext();
|
||||
}
|
||||
|
||||
override fun next(): #(Int, TT) {
|
||||
val result = #(nextIndex, sourceIterator.next())
|
||||
nextIndex++
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package kotlin
|
||||
|
||||
import java.lang.Class
|
||||
import java.lang.Object
|
||||
|
||||
import jet.runtime.Intrinsic
|
||||
|
||||
val <out T> T.javaClass : Class<T>
|
||||
[Intrinsic("kotlin.javaClass.property")] get() = (this as java.lang.Object).getClass() as Class<T>
|
||||
|
||||
[Intrinsic("kotlin.javaClass.function")] fun <out T> javaClass() : Class<T> = null as Class<T>
|
||||
@@ -0,0 +1,27 @@
|
||||
package kotlin.math
|
||||
|
||||
import java.math.BigInteger
|
||||
import java.math.BigDecimal
|
||||
|
||||
fun BigInteger.plus(other: BigInteger) = this.add(other).sure()
|
||||
|
||||
fun BigInteger.minus(other: BigInteger) = this.subtract(other).sure()
|
||||
|
||||
fun BigInteger.times(other: BigInteger) = this.multiply(other).sure()
|
||||
|
||||
fun BigInteger.div(other: BigInteger) = this.divide(other).sure()
|
||||
|
||||
fun BigInteger.minus() = this.negate().sure()
|
||||
|
||||
|
||||
fun BigDecimal.plus(other: BigDecimal) = this.add(other).sure()
|
||||
|
||||
fun BigDecimal.minus(other: BigDecimal) = this.subtract(other).sure()
|
||||
|
||||
fun BigDecimal.times(other: BigDecimal) = this.multiply(other).sure()
|
||||
|
||||
fun BigDecimal.div(other: BigDecimal) = this.divide(other).sure()
|
||||
|
||||
fun BigDecimal.mod(other: BigDecimal) = this.remainder(other).sure()
|
||||
|
||||
fun BigDecimal.minus() = this.negate().sure()
|
||||
@@ -0,0 +1,118 @@
|
||||
package kotlin.util
|
||||
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/** Returns the size of the collection */
|
||||
val Collection<*>.size : Int
|
||||
get() = size()
|
||||
|
||||
/** Returns true if this collection is empty */
|
||||
val Collection<*>.empty : Boolean
|
||||
get() = isEmpty()
|
||||
|
||||
/** Returns a new ArrayList with a variable number of initial elements */
|
||||
inline fun arrayList<T>(vararg values: T) : ArrayList<T> = values.to(ArrayList<T>(values.size))
|
||||
|
||||
/** Returns a new LinkedList with a variable number of initial elements */
|
||||
inline fun linkedList<T>(vararg values: T) : LinkedList<T> = values.to(LinkedList<T>())
|
||||
|
||||
/** Returns a new HashSet with a variable number of initial elements */
|
||||
inline fun hashSet<T>(vararg values: T) : HashSet<T> = values.to(HashSet<T>(values.size))
|
||||
|
||||
inline fun <K,V> hashMap(): HashMap<K,V> = HashMap<K,V>()
|
||||
|
||||
inline fun <K,V> sortedMap(): SortedMap<K,V> = TreeMap<K,V>()
|
||||
|
||||
|
||||
val Collection<*>.indices : IntRange
|
||||
get() = 0..size-1
|
||||
|
||||
inline fun <T> java.util.Collection<T>.toArray() : Array<T> {
|
||||
val answer = Array<T>(this.size)
|
||||
var idx = 0
|
||||
for (elem in this)
|
||||
answer[idx++] = elem
|
||||
return answer as Array<T>
|
||||
}
|
||||
|
||||
/** TODO these functions don't work when they generate the Array<T> versions when they are in JavaIterables */
|
||||
inline fun <in T: java.lang.Comparable<T>> java.lang.Iterable<T>.toSortedList() : List<T> = toList().sort()
|
||||
|
||||
inline fun <in T: java.lang.Comparable<T>> java.lang.Iterable<T>.toSortedList(comparator: java.util.Comparator<T>) : List<T> = toList().sort(comparator)
|
||||
|
||||
|
||||
|
||||
// List APIs
|
||||
|
||||
inline fun <in T: java.lang.Comparable<T>> List<T>.sort() : List<T> {
|
||||
Collections.sort(this)
|
||||
return this
|
||||
}
|
||||
|
||||
inline fun <in T: java.lang.Comparable<T>> List<T>.sort(comparator: java.util.Comparator<T>) : List<T> {
|
||||
Collections.sort(this, comparator)
|
||||
return this
|
||||
}
|
||||
|
||||
/** Returns the List if its not null otherwise returns the empty list */
|
||||
inline fun <T> java.util.List<T>?.orEmpty() : java.util.List<T>
|
||||
= if (this != null) this else Collections.EMPTY_LIST as java.util.List<T>
|
||||
|
||||
/** Returns the Set if its not null otherwise returns the empty set */
|
||||
inline fun <T> java.util.Set<T>?.orEmpty() : java.util.Set<T>
|
||||
= if (this != null) this else Collections.EMPTY_SET as java.util.Set<T>
|
||||
|
||||
/**
|
||||
TODO figure out necessary variance/generics ninja stuff... :)
|
||||
inline fun <in T> List<T>.sort(transform: fun(T) : java.lang.Comparable<*>) : List<T> {
|
||||
val comparator = java.util.Comparator<T>() {
|
||||
fun compare(o1: T, o2: T): Int {
|
||||
val v1 = transform(o1)
|
||||
val v2 = transform(o2)
|
||||
if (v1 == v2) {
|
||||
return 0
|
||||
} else {
|
||||
return v1.compareTo(v2)
|
||||
}
|
||||
}
|
||||
}
|
||||
answer.sort(comparator)
|
||||
}
|
||||
*/
|
||||
|
||||
val <T> List<T>.head : T?
|
||||
get() = this.get(0)
|
||||
|
||||
val <T> List<T>.first : T?
|
||||
get() = this.head
|
||||
|
||||
val <T> List<T>.tail : T?
|
||||
get() {
|
||||
val s = this.size
|
||||
return if (s > 0) this.get(s - 1) else null
|
||||
}
|
||||
|
||||
val <T> List<T>.last : T?
|
||||
get() = this.tail
|
||||
|
||||
|
||||
/** Returns true if the collection is not empty */
|
||||
inline fun <T> java.util.Collection<T>.notEmpty() : Boolean = !this.isEmpty()
|
||||
|
||||
/** Returns the Collection if its not null otherwise it returns the empty list */
|
||||
inline fun <T> java.util.Collection<T>?.orEmpty() : Collection<T>
|
||||
= if (this != null) this else Collections.EMPTY_LIST as Collection<T>
|
||||
|
||||
/** Converts the string into a regular expression [[Pattern]] so that strings can be split or matched on */
|
||||
inline fun String.toRegex(): Pattern {
|
||||
return Pattern.compile(this).sure()
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the string into a regular expression [[Pattern]] with the given flags from [[Pattern]] or'd together
|
||||
* so that strings can be split or matched on
|
||||
*/
|
||||
inline fun String.toRegex(flags: Int): Pattern {
|
||||
return Pattern.compile(this, flags).sure()
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package kotlin.util
|
||||
|
||||
import java.util.Map as JMap
|
||||
import java.util.HashMap
|
||||
import java.util.Collections
|
||||
|
||||
// Temporary workaround: commenting out
|
||||
//import java.util.Map.Entry as JEntry
|
||||
|
||||
// Map APIs
|
||||
|
||||
/** Returns the size of the map */
|
||||
val JMap<*,*>.size : Int
|
||||
get() = size()
|
||||
|
||||
/** Returns true if this map is empty */
|
||||
val JMap<*,*>.empty : Boolean
|
||||
get() = isEmpty()
|
||||
|
||||
/** Provides [] access to maps */
|
||||
fun <K, V> JMap<K, V>.set(key : K, value : V) = this.put(key, value)
|
||||
|
||||
/** Returns the Mao if its not null otherwise it returns the empty Map */
|
||||
inline fun <K,V> java.util.Map<K,V>?.orEmpty() : java.util.Map<K,V>
|
||||
= if (this != null) this else Collections.EMPTY_MAP as java.util.Map<K,V>
|
||||
|
||||
|
||||
/** Returns the key of the entry */
|
||||
// Temporary workaround: commenting out
|
||||
//val <K,V> JEntry<K,V>.key : K
|
||||
// get() = getKey().sure()
|
||||
|
||||
/** Returns the value of the entry */
|
||||
// Temporary workaround: commenting out
|
||||
//val <K,V> JEntry<K,V>.value : V
|
||||
// get() = getValue().sure()
|
||||
|
||||
/** Returns the value for the given key or returns the result of the defaultValue function if there was no entry for the given key */
|
||||
inline fun <K,V> java.util.Map<K,V>.getOrElse(key: K, defaultValue: ()-> V) : V {
|
||||
val current = this.get(key)
|
||||
if (current != null) {
|
||||
return current
|
||||
} else {
|
||||
return defaultValue()
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the value for the given key or the result of the defaultValue function is put into the map for the given value and returned */
|
||||
inline fun <K,V> java.util.Map<K,V>.getOrPut(key: K, defaultValue: ()-> V) : V {
|
||||
val current = this.get(key)
|
||||
if (current != null) {
|
||||
return current
|
||||
} else {
|
||||
val answer = defaultValue()
|
||||
this.put(key, answer)
|
||||
return answer
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package kotlin
|
||||
|
||||
import java.util.Collection
|
||||
import java.util.ArrayList
|
||||
import java.util.LinkedList
|
||||
import java.util.HashSet
|
||||
import java.util.LinkedHashSet
|
||||
import java.util.TreeSet
|
||||
|
||||
/**
|
||||
Helper to make jet.Iterator usable in for
|
||||
*/
|
||||
inline fun <T> jet.Iterator<T>.iterator() = this
|
||||
|
||||
/**
|
||||
Helper to make java.util.Iterator usable in for
|
||||
*/
|
||||
inline fun <T> java.util.Iterator<T>.iterator() = this
|
||||
|
||||
/**
|
||||
Helper to make java.util.Enumeration usable in for
|
||||
*/
|
||||
fun <erased T> java.util.Enumeration<T>.iterator(): Iterator<T> = object: Iterator<T> {
|
||||
override val hasNext: Boolean
|
||||
get() = hasMoreElements()
|
||||
|
||||
override fun next() = nextElement()
|
||||
}
|
||||
|
||||
/*
|
||||
* Extension functions on the standard Kotlin types to behave like the java.lang.* and java.util.* collections
|
||||
*/
|
||||
|
||||
/**
|
||||
Add iterated elements to given container
|
||||
*/
|
||||
fun <T,U: Collection<in T>> Iterator<T>.to(container: U) : U {
|
||||
while(hasNext)
|
||||
container.add(next())
|
||||
return container
|
||||
}
|
||||
|
||||
/**
|
||||
Add iterated elements to java.util.ArrayList
|
||||
*/
|
||||
inline fun <T> Iterator<T>.toArrayList() = to(ArrayList<T>())
|
||||
|
||||
/**
|
||||
Add iterated elements to java.util.LinkedList
|
||||
*/
|
||||
inline fun <T> Iterator<T>.toLinkedList() = to(LinkedList<T>())
|
||||
|
||||
/**
|
||||
Add iterated elements to java.util.HashSet
|
||||
*/
|
||||
inline fun <T> Iterator<T>.toHashSet() = to(HashSet<T>())
|
||||
|
||||
/**
|
||||
Add iterated elements to java.util.LinkedHashSet
|
||||
*/
|
||||
inline fun <T> Iterator<T>.toLinkedHashSet() = to(LinkedHashSet<T>())
|
||||
|
||||
/**
|
||||
Add iterated elements to java.util.TreeSet
|
||||
*/
|
||||
inline fun <T> Iterator<T>.toTreeSet() = to(TreeSet<T>())
|
||||
|
||||
/**
|
||||
Run function f
|
||||
*/
|
||||
inline fun <T> run(f: () -> T) = f()
|
||||
@@ -0,0 +1,167 @@
|
||||
package kotlin
|
||||
|
||||
import java.io.StringReader
|
||||
|
||||
inline fun String.lastIndexOf(str: String) = (this as java.lang.String).lastIndexOf(str)
|
||||
|
||||
inline fun String.lastIndexOf(ch: Char) = (this as java.lang.String).lastIndexOf(ch.toString())
|
||||
|
||||
inline fun String.equalsIgnoreCase(anotherString: String) = (this as java.lang.String).equalsIgnoreCase(anotherString)
|
||||
|
||||
inline fun String.indexOf(str : String) = (this as java.lang.String).indexOf(str)
|
||||
|
||||
inline fun String.indexOf(str : String, fromIndex : Int) = (this as java.lang.String).indexOf(str, fromIndex)
|
||||
|
||||
inline fun String.replace(oldChar: Char, newChar : Char) = (this as java.lang.String).replace(oldChar, newChar).sure()
|
||||
|
||||
inline fun String.replaceAll(regex: String, replacement : String) = (this as java.lang.String).replaceAll(regex, replacement).sure()
|
||||
|
||||
inline fun String.trim() = (this as java.lang.String).trim().sure()
|
||||
|
||||
/** Returns the string with leading and trailing text matching the given string removed */
|
||||
inline fun String.trim(text: String) = trimLeading(text).trimTrailing(text)
|
||||
|
||||
/** Returns the string with the prefix and postfix text trimmed */
|
||||
inline fun String.trim(prefix: String, postfix: String) = trimLeading(prefix).trimTrailing(postfix)
|
||||
|
||||
/** Returns the string with the leading prefix of this string removed */
|
||||
inline fun String.trimLeading(prefix: String): String {
|
||||
var answer = this
|
||||
if (answer.startsWith(prefix)) {
|
||||
answer = answer.substring(prefix.length())
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Returns the string with the trailing postfix of this string removed */
|
||||
inline fun String.trimTrailing(postfix: String): String {
|
||||
var answer = this
|
||||
if (answer.endsWith(postfix)) {
|
||||
answer = answer.substring(0, length() - postfix.length())
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
inline fun String.toUpperCase() = (this as java.lang.String).toUpperCase().sure()
|
||||
|
||||
inline fun String.toLowerCase() = (this as java.lang.String).toLowerCase().sure()
|
||||
|
||||
inline fun String.length() = (this as java.lang.String).length()
|
||||
|
||||
inline fun String.getBytes() = (this as java.lang.String).getBytes().sure()
|
||||
|
||||
inline fun String.toCharArray() = (this as java.lang.String).toCharArray().sure()
|
||||
|
||||
inline fun String.format(format : String, vararg args : Any?) = java.lang.String.format(format, args).sure()
|
||||
|
||||
inline fun String.split(regex : String) = (this as java.lang.String).split(regex)
|
||||
|
||||
inline fun String.substring(beginIndex : Int) = (this as java.lang.String).substring(beginIndex).sure()
|
||||
|
||||
inline fun String.substring(beginIndex : Int, endIndex : Int) = (this as java.lang.String).substring(beginIndex, endIndex).sure()
|
||||
|
||||
inline fun String.startsWith(prefix: String) = (this as java.lang.String).startsWith(prefix)
|
||||
|
||||
inline fun String.startsWith(prefix: String, toffset: Int) = (this as java.lang.String).startsWith(prefix, toffset)
|
||||
|
||||
inline fun String.contains(seq: CharSequence) : Boolean = (this as java.lang.String).contains(seq)
|
||||
|
||||
inline fun String.endsWith(suffix: String) : Boolean = (this as java.lang.String).endsWith(suffix)
|
||||
|
||||
inline val String.size : Int
|
||||
get() = length()
|
||||
|
||||
inline val String.reader : StringReader
|
||||
get() = StringReader(this)
|
||||
|
||||
// "constructors" for String
|
||||
|
||||
inline fun String(bytes : ByteArray, offset : Int, length : Int, charsetName : String) = java.lang.String(bytes, offset, length, charsetName) as String
|
||||
|
||||
inline fun String(bytes : ByteArray, offset : Int, length : Int, charset : java.nio.charset.Charset) = java.lang.String(bytes, offset, length, charset) as String
|
||||
|
||||
inline fun String(bytes : ByteArray, charsetName : String?) = java.lang.String(bytes, charsetName) as String
|
||||
|
||||
inline fun String(bytes : ByteArray, charset : java.nio.charset.Charset) = java.lang.String(bytes, charset) as String
|
||||
|
||||
inline fun String(bytes : ByteArray, i : Int, i1 : Int) = java.lang.String(bytes, i, i1) as String
|
||||
|
||||
inline fun String(bytes : ByteArray) = java.lang.String(bytes) as String
|
||||
|
||||
inline fun String(chars : CharArray) = java.lang.String(chars) as String
|
||||
|
||||
inline fun String(stringBuffer : java.lang.StringBuffer) = java.lang.String(stringBuffer) as String
|
||||
|
||||
inline fun String(stringBuilder : java.lang.StringBuilder) = java.lang.String(stringBuilder) as String
|
||||
|
||||
/** Returns true if the string is not null and not empty */
|
||||
inline fun String?.notEmpty() : Boolean = this != null && this.length() > 0
|
||||
|
||||
/**
|
||||
Iterator for characters of given CharSequence
|
||||
*/
|
||||
inline fun CharSequence.iterator() : CharIterator = object: jet.CharIterator() {
|
||||
private var index = 0
|
||||
|
||||
public override fun nextChar(): Char = get(index++)
|
||||
|
||||
public override val hasNext: Boolean
|
||||
get() = index < length
|
||||
}
|
||||
|
||||
inline fun String.replaceFirst(regex : String, replacement : String) = (this as java.lang.String).replaceFirst(regex, replacement).sure()
|
||||
|
||||
inline fun String.charAt(index : Int) = (this as java.lang.String).charAt(index).sure()
|
||||
|
||||
inline fun String.split(regex : String, limit : Int) = (this as java.lang.String).split(regex, limit).sure()
|
||||
|
||||
inline fun String.codePointAt(index : Int) = (this as java.lang.String).codePointAt(index).sure()
|
||||
|
||||
inline fun String.codePointBefore(index : Int) = (this as java.lang.String).codePointBefore(index).sure()
|
||||
|
||||
inline fun String.codePointCount(beginIndex : Int, endIndex : Int) = (this as java.lang.String).codePointCount(beginIndex, endIndex)
|
||||
|
||||
inline fun String.compareToIgnoreCase(str : String) = (this as java.lang.String).compareToIgnoreCase(str).sure()
|
||||
|
||||
inline fun String.concat(str : String) = (this as java.lang.String).concat(str).sure()
|
||||
|
||||
inline fun String.contentEquals(cs : CharSequence) = (this as java.lang.String).contentEquals(cs).sure()
|
||||
|
||||
inline fun String.contentEquals(sb : StringBuffer) = (this as java.lang.String).contentEquals(sb).sure()
|
||||
|
||||
inline fun String.getBytes(charset : java.nio.charset.Charset) = (this as java.lang.String).getBytes(charset).sure()
|
||||
|
||||
inline fun String.getBytes(charsetName : String) = (this as java.lang.String).getBytes(charsetName).sure()
|
||||
|
||||
inline fun String.getChars(srcBegin : Int, srcEnd : Int, dst : CharArray, dstBegin : Int) = (this as java.lang.String).getChars(srcBegin, srcEnd, dst, dstBegin).sure()
|
||||
|
||||
inline fun String.indexOf(ch : Char) = (this as java.lang.String).indexOf(ch.toString()).sure()
|
||||
|
||||
inline fun String.indexOf(ch : Char, fromIndex : Int) = (this as java.lang.String).indexOf(ch.toString(), fromIndex).sure()
|
||||
|
||||
inline fun String.intern() = (this as java.lang.String).intern().sure()
|
||||
|
||||
inline fun String.isEmpty() = (this as java.lang.String).isEmpty().sure()
|
||||
|
||||
inline fun String.lastIndexOf(ch : Char, fromIndex : Int) = (this as java.lang.String).lastIndexOf(ch.toString(), fromIndex).sure()
|
||||
|
||||
inline fun String.lastIndexOf(str : String, fromIndex : Int) = (this as java.lang.String).lastIndexOf(str, fromIndex).sure()
|
||||
|
||||
inline fun String.matches(regex : String) = (this as java.lang.String).matches(regex).sure()
|
||||
|
||||
inline fun String.offsetByCodePoints(index : Int, codePointOffset : Int) = (this as java.lang.String).offsetByCodePoints(index, codePointOffset).sure()
|
||||
|
||||
inline fun String.regionMatches(ignoreCase : Boolean, toffset : Int, other : String, ooffset : Int, len : Int) = (this as java.lang.String).regionMatches(ignoreCase, toffset, other, ooffset, len).sure()
|
||||
|
||||
inline fun String.regionMatches(toffset : Int, other : String, ooffset : Int, len : Int) = (this as java.lang.String).regionMatches(toffset, other, ooffset, len).sure()
|
||||
|
||||
inline fun String.replace(target : CharSequence, replacement : CharSequence) = (this as java.lang.String).replace(target, replacement).sure()
|
||||
|
||||
inline fun String.subSequence(beginIndex : Int, endIndex : Int) = (this as java.lang.String).subSequence(beginIndex, endIndex).sure()
|
||||
|
||||
inline fun String.toLowerCase(locale : java.util.Locale) = (this as java.lang.String).toLowerCase(locale).sure()
|
||||
|
||||
inline fun String.toUpperCase(locale : java.util.Locale) = (this as java.lang.String).toUpperCase(locale).sure()
|
||||
|
||||
/** Returns the string if it is not null or the empty string if its null */
|
||||
inline fun String?.orEmpty(): String = this ?: ""
|
||||
@@ -0,0 +1,19 @@
|
||||
package kotlin.util
|
||||
|
||||
/**
|
||||
Executes current block and returns elapsed time in milliseconds
|
||||
*/
|
||||
fun measureTimeMillis(block: () -> Unit) : Long {
|
||||
val start = System.currentTimeMillis()
|
||||
block()
|
||||
return System.currentTimeMillis() - start
|
||||
}
|
||||
|
||||
/**
|
||||
Executes current block and returns elapsed time in nanoseconds
|
||||
*/
|
||||
fun measureTimeNano(block: () -> Unit) : Long {
|
||||
val start = System.nanoTime()
|
||||
block()
|
||||
return System.nanoTime() - start
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package kotlin.concurrent
|
||||
|
||||
abstract class FunctionalList<T>(public val size: Int) {
|
||||
public abstract val head: T
|
||||
public abstract val tail: FunctionalList<T>
|
||||
|
||||
val empty : Boolean
|
||||
get() = size == 0
|
||||
|
||||
fun add(element: T) : FunctionalList<T> = FunctionalList.Standard(element, this)
|
||||
|
||||
fun reversed() : FunctionalList<T> {
|
||||
if(empty)
|
||||
return this
|
||||
|
||||
var cur = tail
|
||||
var new = of(head)
|
||||
|
||||
while(!cur.empty) {
|
||||
new = new.add(cur.head)
|
||||
cur = cur.tail
|
||||
}
|
||||
return new
|
||||
}
|
||||
|
||||
fun iterator() = object: Iterator<T> {
|
||||
var cur = this@FunctionalList
|
||||
|
||||
override fun next(): T {
|
||||
if(cur.empty)
|
||||
throw java.util.NoSuchElementException()
|
||||
|
||||
val head = cur.head
|
||||
cur = cur.tail
|
||||
return head
|
||||
}
|
||||
|
||||
override val hasNext: Boolean
|
||||
get() = !cur.empty
|
||||
}
|
||||
|
||||
class object {
|
||||
class Empty<T>() : FunctionalList<T>(0) {
|
||||
override val head: T
|
||||
get() = throw java.util.NoSuchElementException()
|
||||
override val tail: FunctionalList<T>
|
||||
get() = throw java.util.NoSuchElementException()
|
||||
}
|
||||
|
||||
class Standard<T>(override val head: T, override val tail: FunctionalList<T>) : FunctionalList<T>(tail.size+1)
|
||||
|
||||
fun <T> emptyList() = Empty<T>()
|
||||
|
||||
fun <T> of(element: T) : FunctionalList<T> = FunctionalList.Standard<T>(element,emptyList())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package kotlin.concurrent
|
||||
|
||||
import java.util.concurrent.Executor
|
||||
import jet.Iterator
|
||||
|
||||
class FunctionalQueue<T> (
|
||||
val input: FunctionalList<T> = FunctionalList.emptyList<T>(),
|
||||
val output: FunctionalList<T> = FunctionalList.emptyList<T>()) {
|
||||
|
||||
val size : Int
|
||||
get() = input.size + output.size
|
||||
|
||||
val empty : Boolean
|
||||
get() = size == 0
|
||||
|
||||
fun add(element: T) = FunctionalQueue<T>(input add element, output)
|
||||
|
||||
fun addFirst(element: T) = FunctionalQueue<T>(input, output add element)
|
||||
|
||||
fun removeFirst() : #(T,FunctionalQueue<T>) =
|
||||
if(output.empty) {
|
||||
if(input.empty)
|
||||
throw java.util.NoSuchElementException()
|
||||
else
|
||||
FunctionalQueue<T>(FunctionalList.emptyList<T>(), input.reversed()).removeFirst()
|
||||
}
|
||||
else {
|
||||
#(output.head, FunctionalQueue<T>(input, output.tail))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package kotlin.concurrent
|
||||
|
||||
import java.util.concurrent.locks.Lock
|
||||
import java.util.concurrent.locks.ReadWriteLock
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock
|
||||
|
||||
/**
|
||||
Executes given calculation under lock
|
||||
Returns result of the calculation
|
||||
*/
|
||||
inline fun <erased T> Lock.withLock(action: ()->T) : T {
|
||||
lock()
|
||||
try {
|
||||
return action()
|
||||
}
|
||||
finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Executes given calculation under read lock
|
||||
Returns result of the calculation
|
||||
*/
|
||||
inline fun <erased T> ReentrantReadWriteLock.read(action: ()->T) : T {
|
||||
val rl = readLock().sure()
|
||||
rl.lock()
|
||||
try {
|
||||
return action()
|
||||
}
|
||||
finally {
|
||||
rl.unlock()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Executes given calculation under write lock.
|
||||
The method does upgrade from read to write lock if needed
|
||||
If such write has been initiated by checking some condition, the condition must be rechecked inside the action to avoid possible races
|
||||
Returns result of the calculation
|
||||
*/
|
||||
inline fun <erased T> ReentrantReadWriteLock.write(action: ()->T) : T {
|
||||
val rl = readLock().sure()
|
||||
|
||||
val readCount = if (getWriteHoldCount() == 0) getReadHoldCount() else 0
|
||||
readCount times { rl.unlock() }
|
||||
|
||||
val wl = writeLock().sure()
|
||||
wl.lock()
|
||||
try {
|
||||
return action()
|
||||
}
|
||||
finally {
|
||||
readCount times { rl.lock() }
|
||||
wl.unlock()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package kotlin.concurrent
|
||||
|
||||
import java.lang.*
|
||||
import java.util.concurrent.Executor
|
||||
|
||||
inline val currentThread : Thread
|
||||
get() = Thread.currentThread().sure()
|
||||
|
||||
inline var Thread.name : String
|
||||
get() = getName().sure()
|
||||
set(name: String) { setName(name) }
|
||||
|
||||
inline var Thread.daemon : Boolean
|
||||
get() = isDaemon()
|
||||
set(on: Boolean) { setDaemon(on) }
|
||||
|
||||
inline val Thread.alive : Boolean
|
||||
get() = isAlive()
|
||||
|
||||
inline var Thread.priority : Int
|
||||
get() = getPriority()
|
||||
set(prio: Int) { setPriority(prio) }
|
||||
|
||||
inline var Thread.contextClassLoader : ClassLoader?
|
||||
get() = getContextClassLoader()
|
||||
set(loader: ClassLoader?) { setContextClassLoader(loader) }
|
||||
|
||||
fun thread(start: Boolean = true, daemon: Boolean = false, contextClassLoader: ClassLoader? = null, name: String? = null, priority: Int = -1, block: ()->Unit) : Thread {
|
||||
val thread = object: Thread() {
|
||||
override fun run() {
|
||||
block()
|
||||
}
|
||||
}
|
||||
if(daemon)
|
||||
thread.setDaemon(true)
|
||||
if(priority > 0)
|
||||
thread.setPriority(priority)
|
||||
if(name != null)
|
||||
thread.setName(name)
|
||||
if(contextClassLoader != null)
|
||||
thread.setContextClassLoader(contextClassLoader)
|
||||
if(start)
|
||||
thread.start()
|
||||
return thread
|
||||
}
|
||||
|
||||
inline fun Executor.execute(action: ()->Unit) {
|
||||
execute(object: Runnable{
|
||||
override fun run() {
|
||||
action()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package kotlin.concurrent
|
||||
|
||||
import java.util.Timer
|
||||
import java.util.TimerTask
|
||||
import java.util.Date
|
||||
|
||||
fun Timer.schedule(delay: Long, action: TimerTask.()->Unit) : TimerTask {
|
||||
val task = createTask(action)
|
||||
schedule(task, delay)
|
||||
return task
|
||||
}
|
||||
|
||||
fun Timer.schedule(time: Date, action: TimerTask.()->Unit) : TimerTask {
|
||||
val task = createTask(action)
|
||||
schedule(task, time)
|
||||
return task
|
||||
}
|
||||
|
||||
fun Timer.schedule(delay: Long, period: Long, action: TimerTask.()->Unit) : TimerTask {
|
||||
val task = createTask(action)
|
||||
schedule(task, delay, period)
|
||||
return task
|
||||
}
|
||||
|
||||
fun Timer.schedule(time: Date, period: Long, action: TimerTask.()->Unit) : TimerTask {
|
||||
val task = createTask(action)
|
||||
schedule(task, time, period)
|
||||
return task
|
||||
}
|
||||
|
||||
fun Timer.scheduleAtFixedRate(delay: Long, period: Long, action: TimerTask.()->Unit) : TimerTask {
|
||||
val task = createTask(action)
|
||||
scheduleAtFixedRate(task, delay, period)
|
||||
return task
|
||||
}
|
||||
|
||||
fun Timer.scheduleAtFixedRate(time: Date, period: Long, action: TimerTask.()->Unit) : TimerTask {
|
||||
val task = createTask(action)
|
||||
scheduleAtFixedRate(task, time, period)
|
||||
return task
|
||||
}
|
||||
|
||||
fun timer(name: String? = null, daemon: Boolean = false, initialDelay: Long = 0.toLong(), period: Long, action: TimerTask.()->Unit) : Timer {
|
||||
val timer = if(name == null) Timer(daemon) else Timer(name, daemon)
|
||||
timer.schedule(initialDelay, period, action)
|
||||
return timer
|
||||
}
|
||||
|
||||
fun timer(name: String? = null, daemon: Boolean = false, startAt: Date, period: Long, action: TimerTask.()->Unit) : Timer {
|
||||
val timer = if(name == null) Timer(daemon) else Timer(name, daemon)
|
||||
timer.schedule(startAt, period, action)
|
||||
return timer
|
||||
}
|
||||
|
||||
fun fixedRateTimer(name: String? = null, daemon: Boolean = false, initialDelay: Long = 0.toLong(), period: Long, action: TimerTask.()->Unit) : Timer {
|
||||
val timer = if(name == null) Timer(daemon) else Timer(name, daemon)
|
||||
timer.scheduleAtFixedRate(initialDelay, period, action)
|
||||
return timer
|
||||
}
|
||||
|
||||
fun fixedRateTimer(name: String? = null, daemon: Boolean = false, startAt: Date, period : Long, action: TimerTask.()->Unit) : Timer {
|
||||
val timer = if(name == null) Timer(daemon) else Timer(name, daemon)
|
||||
timer.scheduleAtFixedRate(startAt, period, action)
|
||||
return timer
|
||||
}
|
||||
|
||||
private fun createTask(action: TimerTask.()->Unit) : TimerTask = object: TimerTask() {
|
||||
override fun run() {
|
||||
action()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
package kotlin.dom
|
||||
|
||||
import kotlin.*
|
||||
import kotlin.util.*
|
||||
import java.util.*
|
||||
import org.w3c.dom.*
|
||||
|
||||
|
||||
// Properties
|
||||
|
||||
val Document?.rootElement : Element?
|
||||
get() = if (this != null) this.getDocumentElement() else null
|
||||
|
||||
|
||||
var Node.text : String
|
||||
get() {
|
||||
if (this is Element) {
|
||||
return this.text
|
||||
} else {
|
||||
return this.getNodeValue() ?: ""
|
||||
}
|
||||
}
|
||||
set(value) {
|
||||
if (this is Element) {
|
||||
this.text = value
|
||||
} else {
|
||||
this.setNodeValue(value)
|
||||
}
|
||||
}
|
||||
|
||||
var Element.text : String
|
||||
get() {
|
||||
val buffer = StringBuilder()
|
||||
val nodeList = this.getChildNodes()
|
||||
if (nodeList != null) {
|
||||
var i = 0
|
||||
val size = nodeList.getLength()
|
||||
while (i < size) {
|
||||
val node = nodeList.item(i)
|
||||
if (node != null) {
|
||||
if (node.getNodeType() == Node.TEXT_NODE || node.getNodeType() == Node.CDATA_SECTION_NODE) {
|
||||
buffer.append(node.getNodeValue())
|
||||
}
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
return buffer.toString().sure()
|
||||
}
|
||||
set(value) {
|
||||
// lets remove all the previous text nodes first
|
||||
this.setAttribute("id", value)
|
||||
}
|
||||
|
||||
var Element.id : String
|
||||
get() = this.getAttribute("id")?: ""
|
||||
set(value) {
|
||||
this.setAttribute("id", value)
|
||||
this.setIdAttribute("id", true)
|
||||
}
|
||||
|
||||
var Element.style : String
|
||||
get() = this.getAttribute("style")?: ""
|
||||
set(value) {
|
||||
this.setAttribute("style", value)
|
||||
}
|
||||
|
||||
var Element.classes : String
|
||||
get() = this.getAttribute("class")?: ""
|
||||
set(value) {
|
||||
this.setAttribute("class", value)
|
||||
}
|
||||
|
||||
var Element.classSet : Set<String>
|
||||
get() {
|
||||
val answer = LinkedHashSet<String>()
|
||||
val array = this.classes.split("""\s""")
|
||||
for (s in array) {
|
||||
if (s != null && s.size > 0) {
|
||||
answer.add(s)
|
||||
}
|
||||
}
|
||||
return answer
|
||||
}
|
||||
set(value) {
|
||||
this.classes = value.join(" ")
|
||||
}
|
||||
|
||||
|
||||
// Helper methods
|
||||
|
||||
/** Returns true if the element has the given CSS class style in its 'class' attribute */
|
||||
fun Element.hasClass(cssClass: String): Boolean {
|
||||
val c = this.classes
|
||||
return if (c != null)
|
||||
c.matches("""(^|.*\s+)$cssClass($|\s+.*)""")
|
||||
else false
|
||||
}
|
||||
|
||||
/** Adds the given CSS class to this element's 'class' attribute */
|
||||
fun Element.addClass(cssClass: String): Boolean {
|
||||
val classSet = this.classSet
|
||||
val answer = classSet.add(cssClass)
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Removes the given CSS class to this element's 'class' attribute */
|
||||
fun Element.removeClass(cssClass: String): Boolean {
|
||||
val classSet = this.classSet
|
||||
val answer = classSet.remove(cssClass)
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** TODO this approach generates compiler errors...
|
||||
|
||||
fun Element.addClass(varargs cssClasses: Array<String>): Boolean {
|
||||
val set = this.classSet
|
||||
var answer = false
|
||||
for (cs in cssClasses) {
|
||||
if (set.add(cs)) {
|
||||
answer = true
|
||||
}
|
||||
}
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
fun Element.removeClass(varargs cssClasses: Array<String>): Boolean {
|
||||
val set = this.classSet
|
||||
var answer = false
|
||||
for (cs in cssClasses) {
|
||||
if (set.remove(cs)) {
|
||||
answer = true
|
||||
}
|
||||
}
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
*/
|
||||
|
||||
/** Searches for elements using the element name, an element ID (if prefixed with dot) or element class (if prefixed with #) */
|
||||
fun Document?.get(selector: String): List<Element> {
|
||||
val root = this?.getDocumentElement()
|
||||
return if (root != null) {
|
||||
if (selector == "*") {
|
||||
elements
|
||||
} else if (selector.startsWith(".")) {
|
||||
elements.filter{ it.hasClass(selector.substring(1)) }.toList()
|
||||
} else if (selector.startsWith("#")) {
|
||||
val id = selector.substring(1)
|
||||
val element = this?.getElementById(id)
|
||||
return if (element != null)
|
||||
Collections.singletonList(element).sure() as List<Element>
|
||||
else
|
||||
Collections.EMPTY_LIST.sure() as List<Element>
|
||||
} else {
|
||||
// assume its a vanilla element name
|
||||
elements(selector)
|
||||
}
|
||||
} else {
|
||||
Collections.EMPTY_LIST as List<Element>
|
||||
}
|
||||
}
|
||||
|
||||
/** Searches for elements using the element name, an element ID (if prefixed with dot) or element class (if prefixed with #) */
|
||||
fun Element.get(selector: String): List<Element> {
|
||||
return if (selector == "*") {
|
||||
elements
|
||||
} else if (selector.startsWith(".")) {
|
||||
elements.filter{ it.hasClass(selector.substring(1)) }.toList()
|
||||
} else if (selector.startsWith("#")) {
|
||||
val element = this.getOwnerDocument()?.getElementById(selector.substring(1))
|
||||
return if (element != null)
|
||||
Collections.singletonList(element).sure() as List<Element>
|
||||
else
|
||||
Collections.EMPTY_LIST.sure() as List<Element>
|
||||
} else {
|
||||
// assume its a vanilla element name
|
||||
elements(selector)
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the attribute value or empty string if its not present */
|
||||
inline fun Element.attribute(name: String): String {
|
||||
return this.getAttribute(name) ?: ""
|
||||
}
|
||||
|
||||
/** Returns the children of the element as a list */
|
||||
inline fun Element?.children(): List<Node> {
|
||||
return this?.getChildNodes().toList()
|
||||
}
|
||||
|
||||
/** The child elements of this document */
|
||||
val Document?.elements : List<Element>
|
||||
get() = this?.getElementsByTagName("*").toElementList()
|
||||
|
||||
/** The child elements of this elements */
|
||||
val Element?.elements : List<Element>
|
||||
get() = this?.getElementsByTagName("*").toElementList()
|
||||
|
||||
|
||||
/** Returns all the child elements given the local element name */
|
||||
inline fun Element?.elements(localName: String?): List<Element> {
|
||||
return this?.getElementsByTagName(localName).toElementList()
|
||||
}
|
||||
|
||||
/** Returns all the elements given the local element name */
|
||||
inline fun Document?.elements(localName: String?): List<Element> {
|
||||
return this?.getElementsByTagName(localName).toElementList()
|
||||
}
|
||||
|
||||
/** Returns all the child elements given the namespace URI and local element name */
|
||||
inline fun Element?.elements(namespaceUri: String?, localName: String?): List<Element> {
|
||||
return this?.getElementsByTagNameNS(namespaceUri, localName).toElementList()
|
||||
}
|
||||
|
||||
/** Returns all the elements given the namespace URI and local element name */
|
||||
inline fun Document?.elements(namespaceUri: String?, localName: String?): List<Element> {
|
||||
return this?.getElementsByTagNameNS(namespaceUri, localName).toElementList()
|
||||
}
|
||||
|
||||
val NodeList?.head : Node?
|
||||
get() = if (this != null && this.getLength() > 0) this.item(0) else null
|
||||
|
||||
val NodeList?.first : Node?
|
||||
get() = this.head
|
||||
|
||||
val NodeList?.tail : Node?
|
||||
get() {
|
||||
if (this == null) {
|
||||
return null
|
||||
} else {
|
||||
val s = this.getLength()
|
||||
return if (s > 0) this.item(s - 1) else null
|
||||
}
|
||||
}
|
||||
|
||||
val NodeList?.last : Node?
|
||||
get() = this.tail
|
||||
|
||||
|
||||
inline fun NodeList?.toList(): List<Node> {
|
||||
return if (this == null) {
|
||||
Collections.EMPTY_LIST as List<Node>
|
||||
}
|
||||
else {
|
||||
NodeListAsList(this)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun NodeList?.toElementList(): List<Element> {
|
||||
return if (this == null) {
|
||||
Collections.EMPTY_LIST as List<Element>
|
||||
}
|
||||
else {
|
||||
ElementListAsList(this)
|
||||
}
|
||||
}
|
||||
|
||||
/** Converts the node list to an XML String */
|
||||
fun NodeList?.toXmlString(xmlDeclaration: Boolean = false): String {
|
||||
return if (this == null)
|
||||
"" else {
|
||||
this.toList().toXmlString(xmlDeclaration)
|
||||
}
|
||||
}
|
||||
|
||||
class NodeListAsList(val nodeList: NodeList): AbstractList<Node>() {
|
||||
override fun get(index: Int): Node {
|
||||
val node = nodeList.item(index)
|
||||
if (node == null) {
|
||||
throw IndexOutOfBoundsException("NodeList does not contain a node at index: " + index)
|
||||
} else {
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
||||
override fun size(): Int = nodeList.getLength()
|
||||
}
|
||||
|
||||
class ElementListAsList(val nodeList: NodeList): AbstractList<Element>() {
|
||||
override fun get(index: Int): Element {
|
||||
val node = nodeList.item(index)
|
||||
if (node is Element) {
|
||||
return node
|
||||
} else {
|
||||
if (node == null) {
|
||||
throw IndexOutOfBoundsException("NodeList does not contain a node at index: " + index)
|
||||
} else {
|
||||
throw IllegalArgumentException("Node is not an Element as expected but is $node")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun size(): Int = nodeList.getLength()
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Syntax sugar
|
||||
|
||||
inline fun Node.plus(child: Node?): Node {
|
||||
if (child != null) {
|
||||
this.appendChild(child)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
inline fun Element.plus(text: String?): Element = this.addText(text)
|
||||
|
||||
inline fun Element.plusAssign(text: String?): Element = this.addText(text)
|
||||
|
||||
|
||||
// Builder
|
||||
|
||||
/**
|
||||
* Creates a new element which can be configured via a function
|
||||
*/
|
||||
fun Document.createElement(name: String, init: Element.()-> Unit): Element {
|
||||
val elem = this.createElement(name).sure()
|
||||
elem.init()
|
||||
return elem
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new element to an element which has an owner Document which can be configured via a function
|
||||
*/
|
||||
fun Element.createElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element {
|
||||
val elem = ownerDocument(doc).createElement(name).sure()
|
||||
elem.init()
|
||||
return elem
|
||||
}
|
||||
|
||||
/** Returns the owner document of the element or uses the provided document */
|
||||
fun Node.ownerDocument(doc: Document? = null): Document {
|
||||
val answer = if (this is Document) this as Document
|
||||
else if (doc == null) this.getOwnerDocument()
|
||||
else doc
|
||||
|
||||
if (answer == null) {
|
||||
throw IllegalArgumentException("Element does not have an ownerDocument and none was provided for: ${this}")
|
||||
} else {
|
||||
return answer
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a newly created element which can be configured via a function
|
||||
*/
|
||||
fun Document.addElement(name: String, init: Element.()-> Unit): Element {
|
||||
val child = createElement(name, init)
|
||||
this.appendChild(child)
|
||||
return child
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a newly created element to an element which has an owner Document which can be configured via a function
|
||||
*/
|
||||
fun Element.addElement(name: String, doc: Document? = null, init: Element.()-> Unit): Element {
|
||||
val child = createElement(name, doc, init)
|
||||
this.appendChild(child)
|
||||
return child
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a newly created text node to an element which either already has an owner Document or one must be provided as a parameter
|
||||
*/
|
||||
fun Element.addText(text: String?, doc: Document? = null): Element {
|
||||
if (text != null) {
|
||||
val child = ownerDocument(doc).createTextNode(text)
|
||||
this.appendChild(child)
|
||||
}
|
||||
return this
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* JVM specific API implementations using JAXB and so forth which would not be used when compiling to JS
|
||||
*/
|
||||
package kotlin.dom
|
||||
|
||||
import org.w3c.dom.*
|
||||
import javax.xml.parsers.DocumentBuilder
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import javax.xml.transform.Transformer
|
||||
import javax.xml.transform.TransformerFactory
|
||||
import javax.xml.transform.Source
|
||||
import javax.xml.transform.dom.DOMSource
|
||||
import javax.xml.transform.stream.StreamResult
|
||||
|
||||
import java.io.StringWriter
|
||||
import javax.xml.transform.OutputKeys
|
||||
import java.lang.Iterable
|
||||
import java.util.List
|
||||
import java.util.Collection
|
||||
|
||||
/** Creates a new document with the given document builder*/
|
||||
fun createDocument(builder: DocumentBuilder): Document {
|
||||
return builder.newDocument().sure()
|
||||
}
|
||||
|
||||
/** Creates a new document with an optional DocumentBuilderFactory */
|
||||
fun createDocument(builderFactory: DocumentBuilderFactory = DocumentBuilderFactory.newInstance().sure()): Document {
|
||||
return createDocument(builderFactory.newDocumentBuilder().sure())
|
||||
}
|
||||
|
||||
/** Creates a new TrAX transformer */
|
||||
fun createTransformer(source: Source? = null, factory: TransformerFactory = TransformerFactory.newInstance().sure()): Transformer {
|
||||
val transformer = if (source != null) {
|
||||
factory.newTransformer(source)
|
||||
} else {
|
||||
factory.newTransformer()
|
||||
}
|
||||
return transformer.sure()
|
||||
}
|
||||
|
||||
/** Converts the node to an XML String */
|
||||
fun Node.toXmlString(xmlDeclaration: Boolean = this is Document): String {
|
||||
return nodeToXmlString(this, xmlDeclaration)
|
||||
}
|
||||
|
||||
/** Converts the collection of nodes to an XML String */
|
||||
fun java.lang.Iterable<Node>.toXmlString(xmlDeclaration: Boolean = false): String {
|
||||
// TODO this should work...
|
||||
// return this.map<Node,String>{it.toXmlString()}.join("")
|
||||
val builder = StringBuilder()
|
||||
for (n in this) {
|
||||
builder.append(n.toXmlString(xmlDeclaration))
|
||||
}
|
||||
return builder.toString().sure()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
fun Document.toXmlString(xmlDeclaration: Boolean = true): String {
|
||||
return nodeToXmlString(this, xmlDeclaration)
|
||||
}
|
||||
*/
|
||||
|
||||
/** Converts the node to an XML String */
|
||||
fun nodeToXmlString(node: Node, xmlDeclaration: Boolean): String {
|
||||
val transformer = createTransformer()
|
||||
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, if (xmlDeclaration) "no" else "yes")
|
||||
val buffer = StringWriter()
|
||||
transformer.transform(DOMSource(node), StreamResult(buffer))
|
||||
return buffer.toString().sure()
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// NOTE this file is auto-generated from stdlib/ktSrc/JavaCollections.kt
|
||||
package kotlin
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns a new List containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> Array<T>.map(transform : (T) -> R) : java.util.List<R> {
|
||||
return mapTo(java.util.ArrayList<R>(this.size), transform)
|
||||
}
|
||||
|
||||
/** Transforms each element of this collection with the given function then adds the results to the given collection */
|
||||
inline fun <T, R, C: Collection<in R>> Array<T>.mapTo(result: C, transform : (T) -> R) : C {
|
||||
for (item in this)
|
||||
result.add(transform(item))
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
// NOTE this file is auto-generated from stdlib/ktSrc/JavaIterables.kt
|
||||
package kotlin
|
||||
|
||||
import kotlin.util.*
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns true if any elements in the collection match the given predicate */
|
||||
inline fun <T> Array<T>.any(predicate: (T)-> Boolean) : Boolean {
|
||||
for (elem in this) {
|
||||
if (predicate(elem)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/** Returns true if all elements in the collection match the given predicate */
|
||||
inline fun <T> Array<T>.all(predicate: (T)-> Boolean) : Boolean {
|
||||
for (elem in this) {
|
||||
if (!predicate(elem)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/** Returns the number of items which match the given predicate */
|
||||
inline fun <T> Array<T>.count(predicate: (T)-> Boolean) : Int {
|
||||
var answer = 0
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
answer += 1
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Returns the first item in the collection which matches the given predicate or null if none matched */
|
||||
inline fun <T> Array<T>.find(predicate: (T)-> Boolean) : T? {
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
return elem
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** Returns a new List containing all elements in this collection which match the given predicate */
|
||||
inline fun <T> Array<T>.filter(predicate: (T)-> Boolean) : Collection<T> = filterTo(java.util.ArrayList<T>(), predicate)
|
||||
|
||||
/** Filters all elements in this collection which match the given predicate into the given result collection */
|
||||
inline fun <T, C: Collection<in T>> Array<T>.filterTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
result.add(elem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** Returns a List containing all the non null elements in this collection */
|
||||
inline fun <T> Array<T?>?.filterNulls() : Collection<T> = filterNullsTo(java.util.ArrayList<T>())
|
||||
|
||||
/** Filters all the null elements in this collection winto the given result collection */
|
||||
inline fun <T, C: Collection<in T>> Array<T?>?.filterNullsTo(result: C) : C {
|
||||
if (this != null) {
|
||||
for (elem in this) {
|
||||
if (elem != null)
|
||||
result.add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T> Array<T>.filterNot(predicate: (T)-> Boolean) : Collection<T> = filterNotTo(ArrayList<T>(), predicate)
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T, C: Collection<in T>> Array<T>.filterNotTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (!predicate(elem))
|
||||
result.add(elem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of transforming each item in the collection to a one or more values which
|
||||
* are concatenated together into a single collection
|
||||
*/
|
||||
inline fun <T, R> Array<T>.flatMap(transform: (T)-> Collection<R>) : Collection<R> {
|
||||
return flatMapTo(ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of transforming each item in the collection to a one or more values which
|
||||
* are concatenated together into a single collection
|
||||
*/
|
||||
inline fun <T, R> Array<T>.flatMapTo(result: Collection<R>, transform: (T)-> Collection<R>) : Collection<R> {
|
||||
for (elem in this) {
|
||||
val coll = transform(elem)
|
||||
if (coll != null) {
|
||||
for (r in coll) {
|
||||
result.add(r)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** Performs the given operation on each element inside the collection */
|
||||
inline fun <T> Array<T>.foreach(operation: (element: T) -> Unit) {
|
||||
for (elem in this)
|
||||
operation(elem)
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all the values from from left to right with the initial value to perform the operation on sequential pairs of values
|
||||
*
|
||||
* For example to sum together all numeric values in a collection of numbers it would be
|
||||
* {code}val total = numbers.fold(0){(a, b) -> a + b}{code}
|
||||
*/
|
||||
inline fun <T> Array<T>.fold(initial: T, operation: (it: T, it2: T) -> T): T {
|
||||
var answer = initial
|
||||
for (elem in this) {
|
||||
answer = operation(answer, elem)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all the values from right to left with the initial value to perform the operation on sequential pairs of values
|
||||
*/
|
||||
inline fun <T> Array<T>.foldRight(initial: T, operation: (it: T, it2: T) -> T): T {
|
||||
val reversed = this.reverse()
|
||||
return reversed.fold(initial, operation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the collection performing the transformation on each element and using the result
|
||||
* as the key in a map to group elements by the result
|
||||
*/
|
||||
inline fun <T,K> Array<T>.groupBy(result: Map<K,List<T>> = HashMap<K,List<T>>(), toKey: (T)-> K) : Map<K,List<T>> {
|
||||
for (elem in this) {
|
||||
val key = toKey(elem)
|
||||
val list = result.getOrPut(key){ ArrayList<T>() }
|
||||
list.add(elem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
/** Creates a String from all the elements in the collection, using the seperator between them and using the given prefix and postfix if supplied */
|
||||
inline fun <T> Array<T>.join(separator: String, prefix: String = "", postfix: String = "") : String {
|
||||
val buffer = StringBuilder(prefix)
|
||||
var first = true
|
||||
for (elem in this) {
|
||||
if (first)
|
||||
first = false
|
||||
else
|
||||
buffer.append(separator)
|
||||
buffer.append(elem)
|
||||
}
|
||||
buffer.append(postfix)
|
||||
return buffer.toString().sure()
|
||||
}
|
||||
|
||||
/** Returns a reversed List of this collection */
|
||||
inline fun <T> Array<T>.reverse() : List<T> {
|
||||
val answer = LinkedList<T>()
|
||||
for (elem in this) {
|
||||
answer.addFirst(elem)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Copies the collection into the given collection */
|
||||
inline fun <T, C: Collection<T>> Array<T>.to(result: C) : C {
|
||||
for (elem in this)
|
||||
result.add(elem)
|
||||
return result
|
||||
}
|
||||
|
||||
/** Converts the collection into a LinkedList */
|
||||
inline fun <T> Array<T>.toLinkedList() : LinkedList<T> = this.to(LinkedList<T>())
|
||||
|
||||
/** Converts the collection into a List */
|
||||
inline fun <T> Array<T>.toList() : List<T> = this.to(ArrayList<T>())
|
||||
|
||||
/** Converts the collection into a Set */
|
||||
inline fun <T> Array<T>.toSet() : Set<T> = this.to(HashSet<T>())
|
||||
|
||||
/** Converts the collection into a SortedSet */
|
||||
inline fun <T> Array<T>.toSortedSet() : SortedSet<T> = this.to(TreeSet<T>())
|
||||
/**
|
||||
TODO figure out necessary variance/generics ninja stuff... :)
|
||||
inline fun <in T> Array<T>.toSortedList(transform: fun(T) : java.lang.Comparable<*>) : List<T> {
|
||||
val answer = this.toList()
|
||||
answer.sort(transform)
|
||||
return answer
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,16 @@
|
||||
// NOTE this file is auto-generated from stdlib/ktSrc/JavaCollections.kt
|
||||
package kotlin.util
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns a new List containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> java.lang.Iterable<T>.map(transform : (T) -> R) : java.util.List<R> {
|
||||
return mapTo(java.util.ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/** Transforms each element of this collection with the given function then adds the results to the given collection */
|
||||
inline fun <T, R, C: Collection<in R>> java.lang.Iterable<T>.mapTo(result: C, transform : (T) -> R) : C {
|
||||
for (item in this)
|
||||
result.add(transform(item))
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// NOTE this file is auto-generated from stdlib/ktSrc/JavaCollections.kt
|
||||
package kotlin
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns a new List containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> Iterable<T>.map(transform : (T) -> R) : java.util.List<R> {
|
||||
return mapTo(java.util.ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/** Transforms each element of this collection with the given function then adds the results to the given collection */
|
||||
inline fun <T, R, C: Collection<in R>> Iterable<T>.mapTo(result: C, transform : (T) -> R) : C {
|
||||
for (item in this)
|
||||
result.add(transform(item))
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
// NOTE this file is auto-generated from stdlib/ktSrc/JavaIterables.kt
|
||||
package kotlin
|
||||
|
||||
import kotlin.util.*
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns true if any elements in the collection match the given predicate */
|
||||
inline fun <T> Iterable<T>.any(predicate: (T)-> Boolean) : Boolean {
|
||||
for (elem in this) {
|
||||
if (predicate(elem)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/** Returns true if all elements in the collection match the given predicate */
|
||||
inline fun <T> Iterable<T>.all(predicate: (T)-> Boolean) : Boolean {
|
||||
for (elem in this) {
|
||||
if (!predicate(elem)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/** Returns the number of items which match the given predicate */
|
||||
inline fun <T> Iterable<T>.count(predicate: (T)-> Boolean) : Int {
|
||||
var answer = 0
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
answer += 1
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Returns the first item in the collection which matches the given predicate or null if none matched */
|
||||
inline fun <T> Iterable<T>.find(predicate: (T)-> Boolean) : T? {
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
return elem
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** Returns a new List containing all elements in this collection which match the given predicate */
|
||||
inline fun <T> Iterable<T>.filter(predicate: (T)-> Boolean) : Collection<T> = filterTo(java.util.ArrayList<T>(), predicate)
|
||||
|
||||
/** Filters all elements in this collection which match the given predicate into the given result collection */
|
||||
inline fun <T, C: Collection<in T>> Iterable<T>.filterTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
result.add(elem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T> Iterable<T>.filterNot(predicate: (T)-> Boolean) : Collection<T> = filterNotTo(ArrayList<T>(), predicate)
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T, C: Collection<in T>> Iterable<T>.filterNotTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (!predicate(elem))
|
||||
result.add(elem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of transforming each item in the collection to a one or more values which
|
||||
* are concatenated together into a single collection
|
||||
*/
|
||||
inline fun <T, R> Iterable<T>.flatMap(transform: (T)-> Collection<R>) : Collection<R> {
|
||||
return flatMapTo(ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of transforming each item in the collection to a one or more values which
|
||||
* are concatenated together into a single collection
|
||||
*/
|
||||
inline fun <T, R> Iterable<T>.flatMapTo(result: Collection<R>, transform: (T)-> Collection<R>) : Collection<R> {
|
||||
for (elem in this) {
|
||||
val coll = transform(elem)
|
||||
if (coll != null) {
|
||||
for (r in coll) {
|
||||
result.add(r)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** Performs the given operation on each element inside the collection */
|
||||
inline fun <T> Iterable<T>.foreach(operation: (element: T) -> Unit) {
|
||||
for (elem in this)
|
||||
operation(elem)
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all the values from from left to right with the initial value to perform the operation on sequential pairs of values
|
||||
*
|
||||
* For example to sum together all numeric values in a collection of numbers it would be
|
||||
* {code}val total = numbers.fold(0){(a, b) -> a + b}{code}
|
||||
*/
|
||||
inline fun <T> Iterable<T>.fold(initial: T, operation: (it: T, it2: T) -> T): T {
|
||||
var answer = initial
|
||||
for (elem in this) {
|
||||
answer = operation(answer, elem)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all the values from right to left with the initial value to perform the operation on sequential pairs of values
|
||||
*/
|
||||
inline fun <T> Iterable<T>.foldRight(initial: T, operation: (it: T, it2: T) -> T): T {
|
||||
val reversed = this.reverse()
|
||||
return reversed.fold(initial, operation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the collection performing the transformation on each element and using the result
|
||||
* as the key in a map to group elements by the result
|
||||
*/
|
||||
inline fun <T,K> Iterable<T>.groupBy(result: Map<K,List<T>> = HashMap<K,List<T>>(), toKey: (T)-> K) : Map<K,List<T>> {
|
||||
for (elem in this) {
|
||||
val key = toKey(elem)
|
||||
val list = result.getOrPut(key){ ArrayList<T>() }
|
||||
list.add(elem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
/** Creates a String from all the elements in the collection, using the seperator between them and using the given prefix and postfix if supplied */
|
||||
inline fun <T> Iterable<T>.join(separator: String, prefix: String = "", postfix: String = "") : String {
|
||||
val buffer = StringBuilder(prefix)
|
||||
var first = true
|
||||
for (elem in this) {
|
||||
if (first)
|
||||
first = false
|
||||
else
|
||||
buffer.append(separator)
|
||||
buffer.append(elem)
|
||||
}
|
||||
buffer.append(postfix)
|
||||
return buffer.toString().sure()
|
||||
}
|
||||
|
||||
/** Returns a reversed List of this collection */
|
||||
inline fun <T> Iterable<T>.reverse() : List<T> {
|
||||
val answer = LinkedList<T>()
|
||||
for (elem in this) {
|
||||
answer.addFirst(elem)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Copies the collection into the given collection */
|
||||
inline fun <T, C: Collection<T>> Iterable<T>.to(result: C) : C {
|
||||
for (elem in this)
|
||||
result.add(elem)
|
||||
return result
|
||||
}
|
||||
|
||||
/** Converts the collection into a LinkedList */
|
||||
inline fun <T> Iterable<T>.toLinkedList() : LinkedList<T> = this.to(LinkedList<T>())
|
||||
|
||||
/** Converts the collection into a List */
|
||||
inline fun <T> Iterable<T>.toList() : List<T> = this.to(ArrayList<T>())
|
||||
|
||||
/** Converts the collection into a Set */
|
||||
inline fun <T> Iterable<T>.toSet() : Set<T> = this.to(HashSet<T>())
|
||||
|
||||
/** Converts the collection into a SortedSet */
|
||||
inline fun <T> Iterable<T>.toSortedSet() : SortedSet<T> = this.to(TreeSet<T>())
|
||||
/**
|
||||
TODO figure out necessary variance/generics ninja stuff... :)
|
||||
inline fun <in T> Iterable<T>.toSortedList(transform: fun(T) : java.lang.Comparable<*>) : List<T> {
|
||||
val answer = this.toList()
|
||||
answer.sort(transform)
|
||||
return answer
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,47 @@
|
||||
package kotlin.modules
|
||||
|
||||
import java.util.*
|
||||
import jet.modules.*
|
||||
|
||||
fun module(name: String, callback: ModuleBuilder.() -> Unit) {
|
||||
val builder = ModuleBuilder(name)
|
||||
builder.callback()
|
||||
AllModules.modules.sure().get()?.add(builder)
|
||||
}
|
||||
|
||||
class SourcesBuilder(val parent: ModuleBuilder) {
|
||||
fun plusAssign(pattern: String) {
|
||||
parent.addSourceFiles(pattern)
|
||||
}
|
||||
}
|
||||
|
||||
class ClasspathBuilder(val parent: ModuleBuilder) {
|
||||
fun plusAssign(name: String) {
|
||||
parent.addClasspathEntry(name)
|
||||
}
|
||||
}
|
||||
|
||||
open class ModuleBuilder(val name: String): Module {
|
||||
// http://youtrack.jetbrains.net/issue/KT-904
|
||||
private val sourceFiles0: ArrayList<String?> = ArrayList<String?>()
|
||||
private val classpathRoots0: ArrayList<String?> = ArrayList<String?>()
|
||||
|
||||
val sources: SourcesBuilder
|
||||
get() = SourcesBuilder(this)
|
||||
|
||||
val classpath: ClasspathBuilder
|
||||
get() = ClasspathBuilder(this)
|
||||
|
||||
fun addSourceFiles(pattern: String) {
|
||||
sourceFiles0.add(pattern)
|
||||
}
|
||||
|
||||
fun addClasspathEntry(name: String) {
|
||||
classpathRoots0.add(name)
|
||||
}
|
||||
|
||||
override fun getSourceFiles(): List<String?>? = sourceFiles0
|
||||
override fun getClasspathRoots(): List<String?>? = classpathRoots0
|
||||
override fun getModuleName(): String? = name
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.jetbrains.kotlin.support
|
||||
|
||||
fun loadAsserter(): Unit {
|
||||
val c = javaClass<Runnable>()
|
||||
println("class is $c")
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package kotlin.properties
|
||||
|
||||
import kotlin.*
|
||||
import kotlin.util.*
|
||||
import java.util.List
|
||||
import java.util.Map
|
||||
import java.util.HashMap
|
||||
import java.util.ArrayList
|
||||
|
||||
class ChangeEvent(val source: Any, val name: String, val oldValue: Any?, val newValue: Any?) {
|
||||
var propogationId: Any? = null
|
||||
|
||||
fun toString() = "ChangeEvent($name, $oldValue, $newValue)"
|
||||
}
|
||||
|
||||
trait ChangeListener {
|
||||
fun onPropertyChange(event: ChangeEvent): Unit
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an object where properties can be listened to and notified on
|
||||
* updates for easier binding to user interfaces, undo/redo command stacks and
|
||||
* change tracking mechanisms for persistence or distributed change notifications.
|
||||
*/
|
||||
abstract class ChangeSupport {
|
||||
private var allListeners: List<ChangeListener>? = null
|
||||
private var nameListeners: Map<String, List<ChangeListener>>? = null
|
||||
|
||||
|
||||
fun addChangeListener(listener: ChangeListener) {
|
||||
if (allListeners == null) {
|
||||
allListeners = ArrayList<ChangeListener>()
|
||||
}
|
||||
allListeners?.add(listener)
|
||||
}
|
||||
|
||||
fun addChangeListener(name: String, listener: ChangeListener) {
|
||||
if (nameListeners == null) {
|
||||
nameListeners = HashMap<String, List<ChangeListener>>()
|
||||
}
|
||||
var listeners = nameListeners?.get(name)
|
||||
if (listeners == null) {
|
||||
listeners = arrayList<ChangeListener>()
|
||||
nameListeners?.put(name, listeners.sure())
|
||||
}
|
||||
listeners?.add(listener)
|
||||
}
|
||||
|
||||
protected fun <T> changeProperty(name: String, oldValue: T?, newValue: T?): Unit {
|
||||
if (oldValue != newValue) {
|
||||
firePropertyChanged(ChangeEvent(this, name, oldValue, newValue))
|
||||
}
|
||||
}
|
||||
|
||||
protected fun firePropertyChanged(event: ChangeEvent): Unit {
|
||||
if (nameListeners != null) {
|
||||
val listeners = nameListeners?.get(event.name)
|
||||
if (listeners != null) {
|
||||
for (listener in listeners) {
|
||||
listener.onPropertyChange(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (allListeners != null) {
|
||||
for (listener in allListeners) {
|
||||
listener.onPropertyChange(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onPropertyChange(fn: (ChangeEvent) -> Unit) {
|
||||
// TODO
|
||||
//addChangeListener(DelegateChangeListener(fn))
|
||||
}
|
||||
|
||||
fun onPropertyChange(name: String, fn: (ChangeEvent) -> Unit) {
|
||||
// TODO
|
||||
//addChangeListener(name, DelegateChangeListener(fn))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TODO this seems to generate a compiler barf!
|
||||
see http://youtrack.jetbrains.com/issue/KT-1362
|
||||
|
||||
protected fun createChangeListener(fn: (ChangeEvent) -> Unit): ChangeListener {
|
||||
return DelegateChangeListener(fn)
|
||||
}
|
||||
|
||||
protected fun createChangeListener(fn: (ChangeEvent) -> Unit): ChangeListener {
|
||||
return ChangeListener {
|
||||
override fun onPropertyChange(event: ChangeEvent): Unit {
|
||||
fn(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class DelegateChangeListener(val f: (ChangeEvent) -> Unit) : ChangeListener {
|
||||
override fun onPropertyChange(event: ChangeEvent): Unit {
|
||||
f(event)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* A number of helper methods for writing Kool unit tests
|
||||
*/
|
||||
package kotlin.test
|
||||
|
||||
import java.util.ServiceLoader
|
||||
|
||||
private var _asserter: Asserter? = null
|
||||
|
||||
fun asserter(): Asserter {
|
||||
if (_asserter == null) {
|
||||
/* TODO
|
||||
val loader = ServiceLoader.load(javaClass<Asserter>)
|
||||
for (a in loader) {
|
||||
if (a != null) {
|
||||
_asserter = a
|
||||
break
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (_asserter == null) {
|
||||
_asserter = DefaultAsserter()
|
||||
}
|
||||
}
|
||||
return _asserter.sure()
|
||||
}
|
||||
|
||||
/** Asserts that the given block returns true */
|
||||
inline fun assertTrue(message: String, block: ()-> Boolean) {
|
||||
val actual = block()
|
||||
asserter().assertTrue(message, actual)
|
||||
}
|
||||
|
||||
/** Asserts that the given block returns true */
|
||||
inline fun assertTrue(block: ()-> Boolean) = assertTrue(block.toString(), block)
|
||||
|
||||
/** Asserts that the given block returns false */
|
||||
inline fun assertNot(message: String, block: ()-> Boolean) {
|
||||
assertTrue(message){ !block() }
|
||||
}
|
||||
|
||||
/** Asserts that the given block returns true */
|
||||
inline fun assertNot(block: ()-> Boolean) = assertNot(block.toString(), block)
|
||||
|
||||
/** Asserts that the expression is true with an optional message */
|
||||
inline fun assertTrue(actual: Boolean, message: String = "") {
|
||||
return assertEquals(true, actual, message)
|
||||
}
|
||||
|
||||
/** Asserts that the expression is false with an optional message */
|
||||
inline fun assertFalse(actual: Boolean, message: String = "") {
|
||||
return assertEquals(false, actual, message)
|
||||
}
|
||||
|
||||
/** Asserts that the expected value is equal to the actual value, with an optional message */
|
||||
inline fun assertEquals(expected: Any?, actual: Any?, message: String = "") {
|
||||
asserter().assertEquals(message, expected, actual)
|
||||
}
|
||||
|
||||
/** Asserts that the expression is not null, with an optional message */
|
||||
inline fun assertNotNull(actual: Any?, message: String = "") {
|
||||
asserter().assertNotNull(message, actual)
|
||||
}
|
||||
|
||||
/** Asserts that the expression is null, with an optional message */
|
||||
inline fun assertNull(actual: Any?, message: String = "") {
|
||||
asserter().assertNull(message, actual)
|
||||
}
|
||||
|
||||
/** Marks a test as having failed if this point in the execution path is reached, with an optional message */
|
||||
inline fun fail(message: String = "") {
|
||||
asserter().fail(message)
|
||||
}
|
||||
|
||||
/** Asserts that given function block returns the given expected value */
|
||||
inline fun <T> expect(expected: T, block: ()-> T) {
|
||||
expect(expected, block.toString(), block)
|
||||
}
|
||||
|
||||
/** Asserts that given function block returns the given expected value and use the given message if it fails */
|
||||
inline fun <T> expect(expected: T, message: String, block: ()-> T) {
|
||||
val actual = block()
|
||||
assertEquals(expected, actual, message)
|
||||
}
|
||||
|
||||
/** Asserts that given function block fails by throwing an exception */
|
||||
fun fails(block: ()-> Unit): Exception? {
|
||||
try {
|
||||
block()
|
||||
asserter().fail("Expected an exception to be thrown")
|
||||
return null
|
||||
} catch (e: Exception) {
|
||||
println("Caught excepted exception: $e")
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
/** Asserts that a block fails with a specific exception being thrown */
|
||||
fun <T: Exception> failsWith(block: ()-> Unit) {
|
||||
try {
|
||||
block()
|
||||
asserter().fail("Expected an exception to be thrown")
|
||||
} catch (e: T) {
|
||||
println("Caught excepted exception: $e")
|
||||
// OK
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Comments out a block of test code until it is implemented while keeping a link to the code
|
||||
* to implement in your unit test output
|
||||
*/
|
||||
inline fun todo(block: ()-> Any) {
|
||||
println("TODO at " + (Exception() as java.lang.Throwable).getStackTrace()?.get(1) + " for " + block)
|
||||
}
|
||||
|
||||
/**
|
||||
* A plugin for performing assertions which can reuse JUnit or TestNG
|
||||
*/
|
||||
trait Asserter {
|
||||
fun assertTrue(message: String, actual: Boolean): Unit
|
||||
|
||||
fun assertEquals(message: String, expected: Any?, actual: Any?): Unit
|
||||
|
||||
fun assertNotNull(message: String, actual: Any?): Unit
|
||||
|
||||
fun assertNull(message: String, actual: Any?): Unit
|
||||
|
||||
fun fail(message: String): Unit
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation to avoid dependency on JUnit or TestNG
|
||||
*/
|
||||
class DefaultAsserter() : Asserter {
|
||||
|
||||
override fun assertTrue(message : String, actual : Boolean) {
|
||||
if (!actual) {
|
||||
fail(message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun assertEquals(message : String, expected : Any?, actual : Any?) {
|
||||
if (expected != actual) {
|
||||
fail("$message. Expected <$expected> actual <$actual>")
|
||||
}
|
||||
}
|
||||
|
||||
override fun assertNotNull(message : String, actual : Any?) {
|
||||
if (actual == null) {
|
||||
fail(message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun assertNull(message : String, actual : Any?) {
|
||||
if (actual != null) {
|
||||
fail(message)
|
||||
}
|
||||
}
|
||||
override fun fail(message : String) {
|
||||
throw AssertionError(message)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user