stdlib sources re-added

This commit is contained in:
Andrey Breslav
2012-03-06 19:35:12 +04:00
parent 54d3cd156b
commit 3beec4847a
31 changed files with 2656 additions and 0 deletions
+112
View File
@@ -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?>()
+49
View File
@@ -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()
}
}
+9
View File
@@ -0,0 +1,9 @@
package kotlin
inline fun Int.times(body : () -> Unit) {
var count = this;
while (count > 0) {
body()
count--
}
}
+26
View File
@@ -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>())
+15
View File
@@ -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
}
+171
View File
@@ -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()
}
}
+197
View File
@@ -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
}
}
+11
View File
@@ -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>
+27
View File
@@ -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()
+118
View File
@@ -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()
}
+58
View File
@@ -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
}
}
+71
View File
@@ -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()
+167
View File
@@ -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 ?: ""
+19
View File
@@ -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))
}
}
+58
View File
@@ -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()
}
}
+53
View File
@@ -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()
}
})
}
+71
View File
@@ -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()
}
}
+384
View File
@@ -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
}
+73
View File
@@ -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)
}
}
+163
View File
@@ -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)
}
}