KorIO Language Tools
KorIO has some general language tools to make life easier.
Table of contents:
Misc
// To get the simple name of a class in all the targets without reflection.
val <T : Any> KClass<T>.portableSimpleName: String
// To build a list. Analogous to buildString
inline fun <T> buildList(callback: ArrayList<T>.() -> Unit): List<T>
inline fun Int.compareToChain(callback: () -> Int): Int = if (this != 0) this else callback()
fun String.htmlspecialchars() = Xml.Entities.encode(this)
fun Regex.Companion.quote(str: String): String
// Ranges extensions
val IntRange.length: Int get() = (this.endInclusive - this.start) + 1
val LongRange.length: Long get() = (this.endInclusive - this.start) + 1
val IntRange.endExclusive: Int get() = this.endInclusive + 1
val LongRange.endExclusive: Long get() = this.endInclusive + 1
val LongRange.endExclusiveClamped: Long get() = if (this.endInclusive == Long.MAX_VALUE) Long.MAX_VALUE else this.endInclusive + 1
val LONG_ZERO_TO_MAX_RANGE = 0L..Long.MAX_VALUE
fun IntRange.toLongRange() = this.start.toLong()..this.endInclusive.toLong()
KDynamic (Dynamic Access)
This functionality makes it easier to navigate from an untyped object hierarchy.
// To inject the KDynamic extensions in your scope
inline fun <T> KDynamic(callback: KDynamic.() -> T): T = callback(KDynamic)
inline fun <T, R> KDynamic(value: T, callback: KDynamic.(T) -> R): R = callback(KDynamic, value)
object KDynamic {
val global: Any?
interface Invokable {
fun invoke(name: String, args: Array<out Any?>): Any?
}
fun Any?.dynamicInvoke(name: String, vararg args: Any?): Any?
operator fun Any?.set(key: Any?, value: Any?)
operator fun Any?.get(key: Any?): Any?
val Any?.map: Map<Any?, Any?>
val Any?.list: List<Any?>
val Any?.keys: List<Any?>
fun Any?.toNumber(): Number
fun Any?.toBool(): Boolean
fun Any?.toByte(): Byte
fun Any?.toChar(): Char
fun Any?.toShort(): Short
fun Any?.toInt(): Int
fun Any?.toLong(): Long
fun Any?.toFloat(): Float
fun Any?.toDouble(): Double
fun Any?.toBoolOrNull(): Boolean?
fun Any?.toIntOrNull(): Int?
fun Any?.toLongOrNull(): Long?
fun Any?.toDoubleOrNull(): Double?
fun Any?.toIntDefault(default: Int = 0): Int
fun Any?.toLongDefault(default: Long = 0L): Long
fun Any?.toFloatDefault(default: Float = 0f): Float
fun Any?.toDoubleDefault(default: Double = 0.0): Double
val Any?.str: String
val Any?.int: Int
val Any?.bool: Boolean
val Any?.float: Float
val Any?.double: Double
val Any?.long: Long
val Any?.intArray: IntArray
val Any?.floatArray: FloatArray
val Any?.doubleArray: DoubleArray
val Any?.longArray: LongArray
}
Delegates
Lazy
lazyVar
class lazyVar<T : Any>(val callback: () -> T) {
var current: T? = null
operator fun getValue(obj: Any, property: KProperty<*>): T
operator fun setValue(obj: Any, property: KProperty<*>, value: T)
}
Redirected / Transformed
inline fun <V> (() -> KProperty0<V>).redirected(): RedirectFieldGen
inline fun <V> (() -> KMutableProperty0<V>).redirected(): = RedirectMutableFieldGen
inline fun <V> KMutableProperty0<V>.redirected(): RedirectMutableField
inline fun <V> KProperty0<V>.redirected(): RedirectField
fun <V, R> KMutableProperty0<V>.transformed(transform: (V) -> R, reverseTransform: (R) -> V): TransformedMutableField
fun <V, R> KProperty0<V>.transformed(transform: (V) -> R): TransformedField
class RedirectField<V>(val redirect: KProperty0<V>)
class RedirectMutableField<V>(val redirect: KMutableProperty0<V>)
class RedirectMutableFieldGen<V>(val redirect: () -> KMutableProperty0<V>)
class RedirectFieldGen<V>(val redirect: () -> KProperty0<V>)
class TransformedField<V, R>(val prop: KProperty0<V>, val transform: (V) -> R)
class TransformedMutableField<V, R>(val prop: KMutableProperty0<V>, val transform: (V) -> R, val reverseTransform: (R) -> V)
Example:
class A {
var z: Int = 10
val i: Int = 10
}
class B(val a: A) {
var z: Int by a::z.redirected()
val y: Int by this::z.redirected()
val i: Int by a::i.redirected()
val l: Int by { a::i }.redirected()
val r: Int by { a::z }.redirected()
}
Array tools
inline operator fun ByteArray.set(o: Int, v: Int)
inline operator fun ByteArray.set(o: Int, v: Long)
fun List<BooleanArray>.join(): BooleanArray
fun List<ByteArray>.join(): ByteArray
fun List<ShortArray>.join(): ShortArray
//fun List<CharArray>.join(): CharArray
fun List<IntArray>.join(): IntArray
fun List<LongArray>.join(): LongArray
fun List<FloatArray>.join(): FloatArray
fun List<DoubleArray>.join(): DoubleArray
fun BooleanArray.indexOf(v: Boolean, startOffset: Int = 0, endOffset: Int = this.size, default: Int = -1): Int
fun ByteArray.indexOf(v: Byte, startOffset: Int = 0, endOffset: Int = this.size, default: Int = -1): Int
fun ShortArray.indexOf(v: Short, startOffset: Int = 0, endOffset: Int = this.size, default: Int = -1): Int
//fun CharArray.indexOf(v: Char, startOffset: Int = 0, endOffset: Int = this.size, default: Int = -1): Int
fun IntArray.indexOf(v: Int, startOffset: Int = 0, endOffset: Int = this.size, default: Int = -1): Int
fun LongArray.indexOf(v: Long, startOffset: Int = 0, endOffset: Int = this.size, default: Int = -1): Int
fun FloatArray.indexOf(v: Float, startOffset: Int = 0, endOffset: Int = this.size, default: Int = -1): Int
fun DoubleArray.indexOf(v: Double, startOffset: Int = 0, endOffset: Int = this.size, default: Int = -1): Int