Skip to content

Commit

Permalink
Trying to get KMP to work
Browse files Browse the repository at this point in the history
  • Loading branch information
deusaquilus committed Jan 26, 2024
1 parent 64b8fee commit c2e8060
Show file tree
Hide file tree
Showing 13 changed files with 937 additions and 245 deletions.
75 changes: 46 additions & 29 deletions pprint-core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,46 +1,63 @@
plugins {
java
id("java-library")
kotlin("multiplatform")
id("com.android.library")
//id("com.android.library")
id("io.kotest.multiplatform") version "5.8.0"
}

kotlin {
jvm {
compilations.all {
kotlinOptions.jvmTarget = "1.8"
}
testRuns["test"].executionTask.configure {
useJUnitPlatform()
kotlinOptions.jvmTarget = "17"
}
// testRuns["test"].executionTask.configure {
// useJUnitPlatform()
// }
// tasks.withType<Test>().configureEach {
// useJUnitPlatform()
// }
}

js()
android()
//android()

sourceSets {
val commonMain by getting {
dependencies {
// Common dependencies for all platforms
}
}
val jvmMain by getting {
dependencies {
// JVM specific dependencies
}
}
val androidMain by getting {
dependencies {
// Android specific dependencies
}
}
val jsMain by getting {
dependencies {
// JS specific dependencies
}
}
val commonMain by getting { dependencies { } }
val commonTest by getting { dependencies {
implementation("io.kotest:kotest-framework-engine:5.8.0")
implementation("io.kotest:kotest-assertions-core:5.8.0")
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))

} }
val jvmTest by getting { dependencies {
implementation("io.kotest:kotest-runner-junit5:5.8.0")
} }
// val androidMain by getting { dependencies {
// } }
val jsMain by getting { dependencies {
} }
}
}

android {
compileSdk = 32
namespace = "io.exoquery.pprint"
//android {
// compileSdk = 32
// namespace = "io.exoquery.pprint"
//}

tasks.named<Test>("jvmTest") {
useJUnitPlatform()
filter {
isFailOnNoMatchingTests = false
}
testLogging {
showExceptions = true
showStandardStreams = true
events = setOf(
org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED,
org.gradle.api.tasks.testing.logging.TestLogEvent.PASSED
)
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
}
67 changes: 36 additions & 31 deletions pprint-core/src/commonMain/kotlin/io/exoquery/fansi/Fansi.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package io.exoquery.fansi

import java.util.Arrays

typealias State = Long

fun CharSequence.toStr() = Str(this)
Expand All @@ -27,7 +25,7 @@ data class Name(val value: String) {
* giving 20% (on `++`) to >1000% (on `splitAt`, `subString`
* and `Str.parse`) speedups
*/
class Str private constructor(private val chars: Array<Char>, private val colors: Array<State>) {
class Str private constructor(private val chars: CharArray, private val colors: Array<State>) {
//require(chars.length == colors.length)

private fun require(condition: Boolean) {
Expand All @@ -41,12 +39,12 @@ class Str private constructor(private val chars: Array<Char>, private val colors
if (!condition) throw IllegalArgumentException(message)
}

override fun hashCode() = java.util.Arrays.hashCode(chars) + java.util.Arrays.hashCode(colors)
override fun hashCode() = chars.hashCode() + colors.hashCode()

override fun equals(other: Any?) =
when (other) {
is Str ->
java.util.Arrays.equals(chars, other.chars) && Arrays.equals(colors, other.colors)
chars contentEquals other.chars && colors contentEquals other.colors
else -> false
}

Expand All @@ -55,11 +53,13 @@ class Str private constructor(private val chars: Array<Char>, private val colors
* avoiding any interference between them
*/
operator fun plus(other: Str): Str {
val newChars = Arrays.copyOf(chars, chars.size + other.chars.size)
val newColors = Arrays.copyOf(colors, colors.size + other.colors.size)
System.arraycopy(other.chars, 0, newChars, chars.size, other.chars.size)
System.arraycopy(other.colors, 0, newColors, colors.size, other.colors.size)
return Str(newChars, newColors)
val newChars = chars.copyOf(chars.size + other.chars.size)
val newColors = colors.copyOf(colors.size + other.colors.size)
// System.arraycopy(other.chars, 0, newChars, chars.size, other.chars.size)
other.chars.copyInto(newChars, chars.size, 0, other.chars.size)
// System.arraycopy(other.colors, 0, newColors, colors.size, other.colors.size)
other.colors.copyInto(newColors, colors.size, 0, other.chars.size)
return Str(newChars, newColors as Array<State>)
}

/**
Expand All @@ -71,8 +71,10 @@ class Str private constructor(private val chars: Array<Char>, private val colors
*/
fun splitAt(index: Int) =
Pair(
Str(Arrays.copyOfRange(chars, 0, index), Arrays.copyOfRange(colors, 0, index)),
Str(Arrays.copyOfRange(chars, index, chars.size), Arrays.copyOfRange(colors, index, colors.size))
// Str(Arrays.copyOfRange(chars, 0, index), Arrays.copyOfRange(colors, 0, index)),
Str(chars.copyOfRange(0, index), colors.copyOfRange(0, index)),
// Str(Arrays.copyOfRange(chars, index, chars.size), Arrays.copyOfRange(colors, index, colors.size))
Str(chars.copyOfRange(index, chars.size), colors.copyOfRange(index, colors.size))
)


Expand All @@ -88,7 +90,7 @@ class Str private constructor(private val chars: Array<Char>, private val colors
require(end >= start) {
"substring end parameter $end must be >= start parameter $start"
}
return Str(Arrays.copyOfRange(chars, start, end), Arrays.copyOfRange(colors, start, end))
return Str(chars.copyOfRange(start, end), colors.copyOfRange(start, end))
}

/**
Expand All @@ -105,13 +107,13 @@ class Str private constructor(private val chars: Array<Char>, private val colors
* The plain-text `java.lang.String` represented by this [[fansi.Str]],
* without all the fansi colors or other decorations
*/
val plainText: String by lazy { String(chars.toCharArray()) }
val plainText: String by lazy { chars.concatToString() }

/**
* Returns a copy of the colors array backing this `fansi.Str`, in case
* you want to use it to
*/
fun getColors() = colors.clone()
fun getColors() = colors.copyOf()

/**
* Retrieve the color of this string at the given character index
Expand All @@ -121,7 +123,7 @@ class Str private constructor(private val chars: Array<Char>, private val colors
* Returns a copy of the character array backing this `fansi.Str`, in case
* you want to use it to
*/
fun getChars() = chars.clone()
fun getChars() = chars.copyOf()
/**
* Retrieve the character of this string at the given character index
*/
Expand Down Expand Up @@ -169,7 +171,7 @@ class Str private constructor(private val chars: Array<Char>, private val colors
overlayAll(listOf(Triple(attrs, start, end)))

fun overlayAll(attrs: List<Triple<Attrs, Int, Int>>): Str {
val newColors = colors.clone()
val newColors = colors.copyOf()
for ((attrs, start, end) in attrs) {
require(end >= start) {
"overlay end parameter $end must be >= start parameter $start"
Expand All @@ -190,7 +192,7 @@ class Str private constructor(private val chars: Array<Char>, private val colors


companion object {
val ansiRegex = "(\u009b|\u001b\\[)[0-?]*[ -\\/]*[@-~]".toRegex().toPattern()
val ansiRegex = "(\u009b|\u001b\\[)[0-?]*[ -\\/]*[@-~]".toRegex()

/** Shorthand constructor with ErrorMode.Sanitize */
fun Sanitize(raw: CharSequence) = invoke(raw, ErrorMode.Sanitize)
Expand All @@ -213,7 +215,7 @@ class Str private constructor(private val chars: Array<Char>, private val colors
* recognized by Fansi as a valid color.
*/
operator fun invoke(raw: CharSequence, errorMode: ErrorMode = ErrorMode.Throw): Str {
val chars = Array<Char>(raw.length, {Char(0)})
val chars = CharArray(raw.length)
val colors = Array<State>(raw.length, {0})

var currentColor: Long = 0
Expand Down Expand Up @@ -301,13 +303,13 @@ class Str private constructor(private val chars: Array<Char>, private val colors
}

return Str(
Arrays.copyOfRange(chars, 0, destIndex),
Arrays.copyOfRange(colors, 0, destIndex)
chars.copyOfRange(0, destIndex),
colors.copyOfRange(0, destIndex)
)
}

fun fromArrays(chars: Array<Char>, colors: Array<State>) =
Str(chars.clone(), colors.clone())
fun fromArrays(chars: CharArray, colors: Array<State>) =
Str(chars.copyOf(), colors.copyOf())

operator fun invoke(vararg args: Str): Str =
join(args.toList())
Expand All @@ -325,6 +327,10 @@ class Str private constructor(private val chars: Array<Char>, private val colors
fun join(args: Iterable<Str>): Str =
join(args, Str(""))

// In case we need to consome the sequence more than once use this because it will make it permanant
fun joinSafe(args: Iterator<Str>) =
join(args.asSequence().toList())

fun join(args: Iterator<Str>, sep: String): Str =
join(args.asSequence().toList(), sep.toStr())

Expand All @@ -333,7 +339,7 @@ class Str private constructor(private val chars: Array<Char>, private val colors

fun join(args: Iterable<Str>, sep: Str): Str {
val length = args.map { it.length + sep.length }.sum() - sep.length
val chars = Array<Char>(length, {Char(0)})
val chars = CharArray(length)
val colors = Array<State>(length, {0})
var j = 0
for (arg in args){
Expand Down Expand Up @@ -399,11 +405,11 @@ sealed interface ErrorMode {

object Throw : ErrorMode {
override fun handle(sourceIndex: Int, raw: CharSequence): Int {
val matcher = Str.ansiRegex.matcher(raw)
val result = Str.ansiRegex.find(raw)
val detail =
if (!matcher.find(sourceIndex)) ""
if (result == null) ""
else {
val end = matcher.end()
val end = result.range.last + 1 // same as range.endExclusive i.e. offset of the last char plus one
raw.subSequence(sourceIndex + 1, end)
}

Expand All @@ -420,9 +426,8 @@ sealed interface ErrorMode {

object Strip : ErrorMode {
override fun handle(sourceIndex: Int, raw: CharSequence): Int {
val matcher = Str.ansiRegex.matcher(raw)
matcher.find(sourceIndex) // what is the purpose of this?
return matcher.end()
val matches = Str.ansiRegex.find(raw)
return if (matches != null) matches.range.last + 1 else 0 // same as range.endExclusive i.e. offset of the last char plus one
}
}
}
Expand Down Expand Up @@ -475,7 +480,7 @@ sealed interface Attrs{

class Multiple(override val resetMask: Long, override val applyMask: Long, vararg val attrs: Attr): Attrs {
init {
assert(attrs.size != 1)
if (attrs.size != 1) throw IllegalArgumentException("Not allowed zero attributes")
}

override fun hashCode() = attrs.hashCode()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ data class PPrinterConfig(
* @param additionalHandlers Provide this to override how certain types are
* pretty-printed at runtime
*/
abstract class PPrinterBase(open val config: PPrinterConfig): Walker {
abstract class PPrinterBase<T>(open val config: PPrinterConfig): Walker<T> {
override val showGenericForCollections get() = config.showGenericForCollections

/**
* Converts an [[Any]] into a large colored `Str`
*/
open operator fun invoke(
x: Any?,
x: T,
width: Int = config.defaultWidth,
height: Int = config.defaultHeight,
indent: Int = config.defaultIndent,
Expand All @@ -58,15 +58,15 @@ abstract class PPrinterBase(open val config: PPrinterConfig): Walker {
/**
* Converts an [[Any]] into a large colored `Str`
*/
open fun <T> pprintln(x: T,
open fun pprintln(x: T,
width: Int = config.defaultWidth,
height: Int = config.defaultHeight,
indent: Int = config.defaultIndent,
initialOffset: Int = 0,
escapeUnicode: Boolean = config.defaultEscapeUnicode,
showFieldNames: Boolean = config.defaultShowFieldNames): Unit {
tokenize(
x as Any,
x,
width,
height,
indent,
Expand All @@ -82,7 +82,7 @@ abstract class PPrinterBase(open val config: PPrinterConfig): Walker {
* certain width and truncated at a certain height
*/
open fun tokenize(
x: Any?,
x: T,
width: Int = config.defaultWidth,
height: Int = config.defaultHeight,
indent: Int = config.defaultIndent,
Expand Down
Loading

0 comments on commit c2e8060

Please sign in to comment.