Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 30 additions & 10 deletions cli/src/main/kotlin/tools/samt/cli/DiagnosticFormatter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,40 @@ internal class DiagnosticFormatter(
DiagnosticSeverity.Info -> formatTextForSeverity("INFO:", severity, withBold = true)
}

private fun formatGlobalMessage(message: DiagnosticGlobalMessage): String = buildString {
append(formatSeverityIndicator(message.severity))
private fun formatSeverityAndMessage(severity: DiagnosticSeverity, message: String): String = buildString {
// <severity>: <message>
append(formatSeverityIndicator(severity))
append(" ")
append(message.message)
appendLine()

// these magic numbers relate to the amount of space each severity indicator takes up when formatted
// e.g. "ERROR: ".length == 7
// "WARNING: ".length == 9
// "INFO: ".length == 6
val indentLength = when (severity) {
DiagnosticSeverity.Error -> 7
DiagnosticSeverity.Warning -> 9
DiagnosticSeverity.Info -> 6
}

val lines = message.lines()
if (lines.size > 1) {
lines.forEachIndexed { index, it ->
if (index > 0) {
append(" ".repeat(indentLength))
}
appendLine(it)
}
} else {
appendLine(message)
}
}

private fun formatMessage(message: DiagnosticMessage, context: DiagnosticContext): String = buildString {
private fun formatGlobalMessage(message: DiagnosticGlobalMessage): String = buildString {
append(formatSeverityAndMessage(message.severity, message.message))
}

// <severity>: <message>
append(formatSeverityIndicator(message.severity))
append(" ")
append(message.message)
appendLine()
private fun formatMessage(message: DiagnosticMessage, context: DiagnosticContext): String = buildString {
append(formatSeverityAndMessage(message.severity, message.message))

val errorSourceFilePath = if (message.highlights.isNotEmpty()) {
message.highlights.first().location.source.path
Expand Down
42 changes: 42 additions & 0 deletions cli/src/test/kotlin/tools/samt/cli/DiagnosticFormatterTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,48 @@ class DiagnosticFormatterTest {
""".trimIndent().trim(), outputWithoutColors.trimIndent().trim())
}

@Test
fun `multiline error messages`() {
val source = """
package debug
enum Test {
Foo
}
""".trimIndent()

val (fileNode, context, controller) = parse(source)
assert(fileNode.statements.single() is EnumDeclarationNode)
val enumNode = fileNode.statements.single() as EnumDeclarationNode

context.error {
message("some error\nsome error\nsome error")
highlight("some highlight", enumNode.location, highlightBeginningOnly = true)
}

val output = DiagnosticFormatter.format(controller, 0, 0, terminalWidth = 40)
val outputWithoutColors = output.replace(Regex("\u001B\\[[;\\d]*m"), "")

assertEquals("""
────────────────────────────────────────
ERROR: some error
some error
some error
---> file:///tmp/DiagnosticFormatterTest.samt:2:1

1 │ package debug
2 │ enum Test {
│ ^
│ |
│ some highlight
3 │ Foo
4 │ }

────────────────────────────────────────
FAILED in 0ms (1 error(s), 0 warning(s))
""".trimIndent().trim(), outputWithoutColors.trimIndent().trim())
}

private fun parse(source: String): Triple<FileNode, DiagnosticContext, DiagnosticController> {
val baseDirectory = URI("file:///tmp")
val filePath = URI("file:///tmp/DiagnosticFormatterTest.samt")
Expand Down