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