Skip to content

Commit 44ba3f3

Browse files
committed
fix: emit valid array and string literals in generated java
1 parent d335364 commit 44ba3f3

1 file changed

Lines changed: 41 additions & 3 deletions

File tree

  • amber-pipeline/src/main/kotlin/dev/amber/pipeline/codegen

amber-pipeline/src/main/kotlin/dev/amber/pipeline/codegen/JavaEmitter.kt

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ class JavaEmitter {
818818

819819
"CONST_STRING" -> {
820820
val def = renderName(stmt.defs.firstOrNull() ?: return, paramNameMap)
821-
builder.addStatement("$def = \$S", stmt.imm?.stringValue ?: "")
821+
builder.addStatement("$def = ${javaStringLiteral(stmt.imm?.stringValue ?: "")}")
822822
}
823823

824824
"CONST_CLASS" -> {
@@ -850,8 +850,7 @@ class JavaEmitter {
850850
val def = renderName(stmt.defs.firstOrNull() ?: return, paramNameMap)
851851
val typeValue = annotated.emittedDescriptor(stmt.imm?.typeValue ?: return)
852852
val sizeArg = renderName(stmt.args.firstOrNull() ?: "0", paramNameMap)
853-
val componentDesc = arrayComponentDescriptor(typeValue)
854-
builder.addStatement("$def = new \$T[$sizeArg]", descriptorToTypeName(componentDesc))
853+
builder.addStatement("$def = ${newArrayExpression(typeValue, sizeArg, annotated.renameIndex)}")
855854
}
856855

857856
"INVOKE" -> {
@@ -1106,6 +1105,45 @@ class JavaEmitter {
11061105
private fun arrayComponentDescriptor(descriptor: String): String =
11071106
if (descriptor.startsWith("[")) descriptor.substring(1) else descriptor
11081107

1108+
private fun newArrayExpression(descriptor: String, sizeArg: String, renameIndex: dev.amber.pipeline.mapping.MappingRenameIndex): String {
1109+
var dimensions = 0
1110+
var component = descriptor
1111+
while (component.startsWith("[")) {
1112+
dimensions += 1
1113+
component = component.substring(1)
1114+
}
1115+
val componentType = descriptorToTypeName(component, renameIndex).toString()
1116+
val trailing = if (dimensions <= 1) "" else List(dimensions - 1) { "[]" }.joinToString("")
1117+
return "new $componentType[$sizeArg]$trailing"
1118+
}
1119+
1120+
private fun javaStringLiteral(value: String): String {
1121+
val escaped = buildString {
1122+
append('"')
1123+
value.forEach { ch ->
1124+
when (ch) {
1125+
'\\' -> append("\\\\")
1126+
'"' -> append("\\\"")
1127+
'\n' -> append("\\n")
1128+
'\r' -> append("\\r")
1129+
'\t' -> append("\\t")
1130+
'\b' -> append("\\b")
1131+
'\u000C' -> append("\\f")
1132+
else -> {
1133+
if (ch.code < 0x20 || ch == '\u0085' || ch == '\u2028' || ch == '\u2029') {
1134+
append("\\u")
1135+
append(ch.code.toString(16).padStart(4, '0'))
1136+
} else {
1137+
append(ch)
1138+
}
1139+
}
1140+
}
1141+
}
1142+
append('"')
1143+
}
1144+
return escaped
1145+
}
1146+
11091147
private fun safeClassName(dotName: String): ClassName {
11101148
val lastDot = dotName.lastIndexOf('.')
11111149
val packagePart = if (lastDot >= 0) sanitizePackageName(dotName.substring(0, lastDot)) else ""

0 commit comments

Comments
 (0)