From 9ff898615a328c41274a18632f67f43eacae5637 Mon Sep 17 00:00:00 2001 From: orangain Date: Sun, 30 Apr 2023 18:24:44 +0900 Subject: [PATCH 1/4] Dump detailed string entries --- ast/src/commonMain/kotlin/ktast/ast/Dumper.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ast/src/commonMain/kotlin/ktast/ast/Dumper.kt b/ast/src/commonMain/kotlin/ktast/ast/Dumper.kt index 7b23ac615..ce741eaf8 100644 --- a/ast/src/commonMain/kotlin/ktast/ast/Dumper.kt +++ b/ast/src/commonMain/kotlin/ktast/ast/Dumper.kt @@ -76,6 +76,10 @@ class Dumper( is Node.Expression.Name -> mapOf("name" to name) is Node.Expression.Constant -> mapOf("value" to value, "form" to form) is Node.Extra.Comment -> mapOf("text" to text) + is Node.Expression.StringTemplate.Entry.Regular -> mapOf("str" to str) + is Node.Expression.StringTemplate.Entry.ShortTemplate -> mapOf("str" to str) + is Node.Expression.StringTemplate.Entry.UnicodeEscape -> mapOf("digits" to digits) + is Node.Expression.StringTemplate.Entry.RegularEscape -> mapOf("char" to char.toEscapedString()) else -> null }?.let { app.append(it.toString()) @@ -84,3 +88,13 @@ class Dumper( app.appendLine() } } + +private fun Char.toEscapedString(): String { + return when (this) { + '\b' -> "\\b" + '\n' -> "\\n" + '\r' -> "\\r" + '\t' -> "\\t" + else -> this.toString() + } +} \ No newline at end of file From a8551205f84cbed22afac322f16ca18a10dd8573 Mon Sep 17 00:00:00 2001 From: orangain Date: Sun, 30 Apr 2023 21:10:00 +0900 Subject: [PATCH 2/4] Refactor heuristic space insertion --- ast/src/commonMain/kotlin/ktast/ast/Writer.kt | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/ast/src/commonMain/kotlin/ktast/ast/Writer.kt b/ast/src/commonMain/kotlin/ktast/ast/Writer.kt index b430f7ad0..4a2f86749 100644 --- a/ast/src/commonMain/kotlin/ktast/ast/Writer.kt +++ b/ast/src/commonMain/kotlin/ktast/ast/Writer.kt @@ -23,21 +23,26 @@ open class Writer( protected fun append(ch: Char) = append(ch.toString()) protected fun append(str: String) = also { - if (str == "") return@also - if (lastAppendedToken.endsWith(">") && str.startsWith("=")) { - doAppend(" ") // Insert heuristic space between '>' and '=' not to be confused with '>=' - } - if (lastAppendedToken != "" && isNonSymbol(lastAppendedToken.last()) && isNonSymbol(str.first())) { - doAppend(" ") // Insert heuristic space between two non-symbols + if (heuristicSpaceInsertionCriteria.any { it(lastAppendedToken.lastOrNull(), str.firstOrNull()) }) { + doAppend(" ") } doAppend(str) - lastAppendedToken = str } - protected fun isNonSymbol(ch: Char) = ch == '_' || nonSymbolCategories.contains(ch.category) + protected val heuristicSpaceInsertionCriteria: List<(Char?, Char?) -> Boolean> = listOf( + // Insert heuristic space between '>' and '=' not to be confused with '>=' + { last, next -> last == '>' && next == '=' }, + // Insert heuristic space between two non-symbols + { last, next -> isNonSymbol(last) && isNonSymbol(next) }, + ) + + protected fun isNonSymbol(ch: Char?) = + ch != null && (ch == '_' || nonSymbolCategories.contains(ch.category)) protected fun doAppend(str: String) { + if (str == "") return app.append(str) + lastAppendedToken = str } fun write(v: Node) { From b25a5c4b32ce7769f0dab197e605d11e5698779e Mon Sep 17 00:00:00 2001 From: orangain Date: Sun, 30 Apr 2023 21:30:48 +0900 Subject: [PATCH 3/4] Refactor writer of StringTemplate --- ast/src/commonMain/kotlin/ktast/ast/Writer.kt | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/ast/src/commonMain/kotlin/ktast/ast/Writer.kt b/ast/src/commonMain/kotlin/ktast/ast/Writer.kt index 4a2f86749..8c619039b 100644 --- a/ast/src/commonMain/kotlin/ktast/ast/Writer.kt +++ b/ast/src/commonMain/kotlin/ktast/ast/Writer.kt @@ -376,25 +376,40 @@ open class Writer( } is Node.Expression.Parenthesized -> append('(').also { children(expression) }.append(')') - is Node.Expression.StringTemplate -> - if (raw) append("\"\"\"").also { children(entries) }.append("\"\"\"") - else append('"').also { children(entries) }.append('"') + is Node.Expression.StringTemplate -> { + if (raw) { + append("\"\"\"") + children(entries) + append("\"\"\"") + } else { + append('"') + children(entries) + append('"') + } + } is Node.Expression.StringTemplate.Entry.Regular -> append(str) - is Node.Expression.StringTemplate.Entry.ShortTemplate -> - append('$').append(str) - is Node.Expression.StringTemplate.Entry.UnicodeEscape -> - append("\\u").append(digits) - is Node.Expression.StringTemplate.Entry.RegularEscape -> - append('\\').append( - when (char) { - '\b' -> 'b' - '\n' -> 'n' - '\t' -> 't' - '\r' -> 'r' - else -> char - } + is Node.Expression.StringTemplate.Entry.ShortTemplate -> { + append("$") + append(str) + } + is Node.Expression.StringTemplate.Entry.UnicodeEscape -> { + append("\\u") + append(digits) + } + is Node.Expression.StringTemplate.Entry.RegularEscape -> { + append( + "\\${ + when (char) { + '\b' -> 'b' + '\n' -> 'n' + '\t' -> 't' + '\r' -> 'r' + else -> char + } + }" ) + } is Node.Expression.StringTemplate.Entry.LongTemplate -> append("\${").also { children(expression) }.append('}') is Node.Expression.Constant -> From f63de465a841e04148631206346d037770f12ec7 Mon Sep 17 00:00:00 2001 From: orangain Date: Sun, 30 Apr 2023 21:31:10 +0900 Subject: [PATCH 4/4] Disable heuristic space insertion inside string literal --- ast-psi/src/test/kotlin/ktast/ast/WriterTest.kt | 2 +- ast/src/commonMain/kotlin/ktast/ast/Writer.kt | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ast-psi/src/test/kotlin/ktast/ast/WriterTest.kt b/ast-psi/src/test/kotlin/ktast/ast/WriterTest.kt index 2b3ab4105..2ac2477dc 100644 --- a/ast-psi/src/test/kotlin/ktast/ast/WriterTest.kt +++ b/ast-psi/src/test/kotlin/ktast/ast/WriterTest.kt @@ -25,7 +25,7 @@ class WriterTest { @Test fun testSimpleCharacterEscaping() { - assertParseAndWriteExact("""val x = "input\b\n\t\r\'\"\\\${'$'}"""") + assertParseAndWriteExact("""val x = "input\b\nTest\t\r\u3000\'\"\\\${'$'}"""") } @Test diff --git a/ast/src/commonMain/kotlin/ktast/ast/Writer.kt b/ast/src/commonMain/kotlin/ktast/ast/Writer.kt index 8c619039b..ba7b57edb 100644 --- a/ast/src/commonMain/kotlin/ktast/ast/Writer.kt +++ b/ast/src/commonMain/kotlin/ktast/ast/Writer.kt @@ -388,17 +388,17 @@ open class Writer( } } is Node.Expression.StringTemplate.Entry.Regular -> - append(str) + doAppend(str) is Node.Expression.StringTemplate.Entry.ShortTemplate -> { - append("$") - append(str) + doAppend("$") + doAppend(str) } is Node.Expression.StringTemplate.Entry.UnicodeEscape -> { - append("\\u") - append(digits) + doAppend("\\u") + doAppend(digits) } is Node.Expression.StringTemplate.Entry.RegularEscape -> { - append( + doAppend( "\\${ when (char) { '\b' -> 'b'