From ac553ed15609780570d903716773a8eb2857689d Mon Sep 17 00:00:00 2001 From: minjaesong Date: Thu, 1 Jun 2023 17:50:39 +0900 Subject: [PATCH] serialiser filters Companion objs --- src/net/torvald/terrarum/QuickDirtyLint.kt | 5 +- src/net/torvald/terrarum/serialise/Common.kt | 141 +++++++++++++++++++ 2 files changed, 142 insertions(+), 4 deletions(-) diff --git a/src/net/torvald/terrarum/QuickDirtyLint.kt b/src/net/torvald/terrarum/QuickDirtyLint.kt index 7d263bacf..27c5d42e6 100644 --- a/src/net/torvald/terrarum/QuickDirtyLint.kt +++ b/src/net/torvald/terrarum/QuickDirtyLint.kt @@ -98,10 +98,7 @@ fun main() { !field.isTransient && !field.isEnum && !serialisablePrimitives.contains(field.typeSignatureOrTypeDescriptorStr) && - serialisableTypes.none { field.typeSignatureOrTypeDescriptorStr.startsWith(it) } && - !field.typeSignatureOrTypeDescriptorStr.endsWith("\$Companion;") && - !field.className.contains("$") && - !field.name.contains("$") + serialisableTypes.none { field.typeSignatureOrTypeDescriptorStr.startsWith(it) } } } diff --git a/src/net/torvald/terrarum/serialise/Common.kt b/src/net/torvald/terrarum/serialise/Common.kt index f2b4491a7..d48f2f126 100644 --- a/src/net/torvald/terrarum/serialise/Common.kt +++ b/src/net/torvald/terrarum/serialise/Common.kt @@ -215,6 +215,147 @@ object Common { }) } + + data class SpliceCmd( + var strPos: Int, + var stackDepth: Int = -1, + var objStartPos: Int = -1, + var objEndPos: Int = -1, + var prependedCommaPos: Int = -1 + ) + + fun scanForCompanionObjects(s: String): List { + val retBin = ArrayList() + + val state = Stack().also { it.push("lit") } // lit, esc, qot + val parenStack = Stack() // { [ " ' + + val searchStr = "Companion" + val strCircBuf = StringBuilder() + + val workBin = Stack() + var kvMode = "key" + + s.forEachIndexed { index, c -> + strCircBuf.append(c); if (strCircBuf.length > searchStr.length) strCircBuf.deleteCharAt(0) + + when (c) { + '{', '[', '(' -> { + parenStack.push(c) + if (workBin.isNotEmpty()) { + workBin.peek().let { + if (it.objStartPos == -1) { + it.objStartPos = index + it.stackDepth = parenStack.size + } + } + +// println("== workBin mod ==;") +// workBin.forEach { println("$it;") } + } + } + '}', ']', ')' -> { + if (workBin.isNotEmpty()) { + + workBin.peek().let { + if (it.objEndPos == -1) { + if (parenStack.size == it.stackDepth) it.objEndPos = index +// println(" parenStack.size=${parenStack.size}, it=$it;") + } + } + +// println("== workBin pop ==;") +// workBin.forEach { println("$it;") } + + retBin.add(workBin.pop()) + } + parenStack.pop() + + if (kvMode == "val") { + kvMode = "key" + } + } + '\\' -> { + if (state.peek() == "esc") { + state.pop() + } + else { + state.push("esc") + } + } + '"', '\'' -> { + if (state.peek() == "esc") + state.pop() + else if (parenStack.peek() == c) { + parenStack.pop() + state.pop() // assuming no errors :p + } + else { + parenStack.push(c) + state.push("qot") + } + } + ':' -> { + if (state.peek() == "lit" && kvMode == "key") { + kvMode = "val" + } + } + ',' -> { + if (state.peek() == "lit" && kvMode == "val") { + kvMode = "key" + } + } + else -> { + if (state.peek() == "esc") + state.pop() + } + } + + if (strCircBuf.toString() == searchStr && kvMode == "key") { + workBin.push(SpliceCmd(index)) + +// println("== workBin push ==;") +// workBin.forEach { println("$it;") } + } + +// println("$c\t${state.peek()};") + } + + return retBin + } + + fun String.jsonRemoveCompanionObjects(): String { + val objectIndices = scanForCompanionObjects(this) + + // search backwards for a valid comma + // terminate when '{' is reached (means the Companion was the first object) + objectIndices.forEach { + var c = it.strPos - 1 + while (c > 0 && this[c] != ',' && this[c-1] != '{') { + c -= 1 + } + it.prependedCommaPos = c + } + +// println(objectIndices) + + // splice the string + // when the search results are indeed correct, they will have the following properties: + // 1. str[objStartPos]='{' && str[objEndPos]='}' + // 2. str[strPos]='n' // as in 'Companio_n_' + + + // 1. fill str[prependedCommaPos : objEndPos+1] will null characters + // 2. create the new string that has null chars filtered + val sb = StringBuilder(this) + objectIndices.forEach { + for (k in it.prependedCommaPos..it.objEndPos) { + sb[k] = '\u0000' + } + } + return sb.filter { it != '\u0000' }.toString() + } + private data class LayerInfo(val h: String, val b: String, val x: Int, val y: Int) /**