Add backtick string literals and formatter support

This commit is contained in:
sergeych committed 2026-04-13 23:08:18 +03:00
1 parent e925195495
commit fada848907
15 files changed
+273 -32

No files matched your search

@@ -4395,6 +4395,30 @@ class ScriptTest {
)
}
@Test
fun backtickStringsMatchRegularStringSemantics() = runTest {
val d = '$'
eval(
"""
val name = "Lyng"
val simple = `hello, $d{name}`
assertEquals("hello, Lyng", simple)
assertEquals("{\"name\":\"Lyng\"}", `{"name":"Lyng"}`)
assertEquals("use the `code` style", `use the \`code\` style`)
assertEquals("\\\"", `\"`)
assertEquals("\"", `"`)
assertEquals(
"first\n\"second\"\nthird",
`
first
"second"
third
`
)
""".trimIndent()
)
}
@Test
fun testInlineArrayLiteral() = runTest {
eval(
@@ -31,6 +31,13 @@ class UnicodeEscapeTest {
assertEquals("☺", token.value)
}
@Test
fun parserDecodesUnicodeEscapeInBacktickStringLiteral() {
val token = parseLyng("`\\u263A`".toSource()).first()
assertEquals(Token.Type.STRING, token.type)
assertEquals("☺", token.value)
}
@Test
fun parserDecodesUnicodeEscapeInCharLiteral() {
val token = parseLyng("'\\u263A'".toSource()).first()
@@ -55,6 +62,7 @@ class UnicodeEscapeTest {
@Test
fun evalDecodesUnicodeEscapes() = runTest {
assertEquals(ObjString("☺"), eval("\"\\u263A\""))
assertEquals(ObjString("☺"), eval("`\\u263A`"))
assertEquals(ObjChar('☺'), eval("'\\u263A'"))
}
}
@@ -18,9 +18,36 @@ package net.sergeych.lyng.format
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class LyngFormatterTest {
@Test
fun preferBackticksForQuoteHeavyStrings() {
val src = "val json = \"{\\\"name\\\":\\\"lyng\\\",\\\"kind\\\":\\\"lang\\\"}\""
val cfg = LyngFormatConfig(
applySpacing = true,
stringDelimiterPolicy = LyngStringDelimiterPolicy.PreferFewerEscapes
)
val out = LyngFormatter.format(src, cfg)
assertEquals("""val json = `{"name":"lyng","kind":"lang"}`""", out)
assertEquals(out, LyngFormatter.format(out, cfg))
}
@Test
fun preserveStringsWhenAlternativeWouldNotHelp() {
val src = "val sample = \"use `ticks` and keep \\` literal\""
val cfg = LyngFormatConfig(
stringDelimiterPolicy = LyngStringDelimiterPolicy.PreferFewerEscapes
)
val out = LyngFormatter.format(src, cfg)
assertEquals(src, out)
}
@Test
fun labelFormatting() {
val src = "return @label; break @outer; continue @inner"
@@ -79,9 +106,9 @@ class LyngFormatterTest {
val formatted = LyngFormatter.format(src, LyngFormatConfig(applyWrapping = true, maxLineLength = 40, continuationIndentSize = 4))
// Ensure the string literal remains intact
kotlin.test.assertTrue(formatted.contains(arg2), "String literal must be preserved")
assertTrue(formatted.contains(arg2), "String literal must be preserved")
// Ensure end-of-line comment remains
kotlin.test.assertTrue(formatted.contains("// end comment"), "EOL comment must be preserved")
assertTrue(formatted.contains("// end comment"), "EOL comment must be preserved")
// Idempotency
val formatted2 = LyngFormatter.format(formatted, LyngFormatConfig(applyWrapping = true, maxLineLength = 40, continuationIndentSize = 4))
assertEquals(formatted, formatted2)