Revert error coloring (for development on dedicated branch) (#565)

This commit is contained in:
Philip K.F. Hölzenspies
2024-07-03 17:25:06 +01:00
committed by GitHub
parent 527d236ba4
commit 5cc2ea2d00
25 changed files with 22 additions and 168 deletions

View File

@@ -15,23 +15,15 @@
*/
package org.pkl.core.runtime;
import static org.fusesource.jansi.Ansi.ansi;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.Ansi.Color;
import org.pkl.core.StackFrame;
import org.pkl.core.util.Nullable;
public final class StackTraceRenderer {
private final Function<StackFrame, StackFrame> frameTransformer;
private static final Ansi.Color frameColor = Color.YELLOW;
private static final Ansi.Color lineNumColor = Color.BLUE;
private static final Ansi.Color repetitionColor = Color.MAGENTA;
public StackTraceRenderer(Function<StackFrame, StackFrame> frameTransformer) {
this.frameTransformer = frameTransformer;
}
@@ -48,7 +40,6 @@ public final class StackTraceRenderer {
StringBuilder builder,
String leftMargin,
boolean isFirstElement) {
var out = ansi(builder);
for (var frame : frames) {
if (frame instanceof StackFrameLoop loop) {
// ensure a cycle of length 1 doesn't get rendered as a loop
@@ -56,28 +47,20 @@ public final class StackTraceRenderer {
doRender(loop.frames, null, builder, leftMargin, isFirstElement);
} else {
if (!isFirstElement) {
out.fgBright(frameColor).a(leftMargin).reset().a("\n");
builder.append(leftMargin).append("\n");
}
out.fgBright(frameColor)
.a(leftMargin)
.a("┌─ ")
.reset()
.bold()
.fg(repetitionColor)
.a(Integer.toString(loop.count))
.reset()
.a(" repetitions of:\n");
builder.append(leftMargin).append("┌─ ").append(loop.count).append(" repetitions of:\n");
var newLeftMargin = leftMargin + "";
doRender(loop.frames, null, builder, newLeftMargin, isFirstElement);
if (isFirstElement) {
renderHint(hint, builder, newLeftMargin);
isFirstElement = false;
}
out.fgBright(frameColor).a(leftMargin).a("└─").reset().a("\n");
builder.append(leftMargin).append("└─\n");
}
} else {
if (!isFirstElement) {
out.fgBright(frameColor).a(leftMargin).reset().a('\n');
builder.append(leftMargin).append('\n');
}
renderFrame((StackFrame) frame, builder, leftMargin);
}
@@ -97,16 +80,14 @@ public final class StackTraceRenderer {
private void renderHint(@Nullable String hint, StringBuilder builder, String leftMargin) {
if (hint == null || hint.isEmpty()) return;
var out = ansi(builder);
out.a('\n');
out.fgBright(frameColor).a(leftMargin);
out.fgBright(frameColor).bold().a(hint).reset();
out.a('\n');
builder.append('\n');
builder.append(leftMargin);
builder.append(hint);
builder.append('\n');
}
private void renderSourceLine(StackFrame frame, StringBuilder builder, String leftMargin) {
var out = ansi(builder);
var originalSourceLine = frame.getSourceLines().get(0);
var leadingWhitespace = VmUtils.countLeadingWhitespace(originalSourceLine);
var sourceLine = originalSourceLine.strip();
@@ -117,36 +98,27 @@ public final class StackTraceRenderer {
: sourceLine.length();
var prefix = frame.getStartLine() + " | ";
out.fgBright(frameColor)
.a(leftMargin)
.fgBright(lineNumColor)
.a(prefix)
.reset()
.a(sourceLine)
.a('\n');
out.fgBright(frameColor).a(leftMargin).reset();
builder.append(leftMargin).append(prefix).append(sourceLine).append('\n');
builder.append(leftMargin);
//noinspection StringRepeatCanBeUsed
for (int i = 1; i < prefix.length() + startColumn; i++) {
out.append(' ');
builder.append(' ');
}
out.fgRed();
//noinspection StringRepeatCanBeUsed
for (int i = startColumn; i <= endColumn; i++) {
out.a('^');
builder.append('^');
}
out.reset().a('\n');
builder.append('\n');
}
private void renderSourceLocation(StackFrame frame, StringBuilder builder, String leftMargin) {
var out = ansi(builder);
out.fgBright(frameColor).a(leftMargin).reset().a("at ");
builder.append(leftMargin).append("at ");
if (frame.getMemberName() != null) {
out.a(frame.getMemberName());
builder.append(frame.getMemberName());
} else {
out.a("<unknown>");
builder.append("<unknown>");
}
out.a(" (").a(frame.getModuleUri()).a(')').a('\n');
builder.append(" (").append(frame.getModuleUri()).append(')').append('\n');
}
/**

View File

@@ -15,14 +15,10 @@
*/
package org.pkl.core.runtime;
import static org.fusesource.jansi.Ansi.ansi;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.Ansi.Color;
import org.pkl.core.Release;
import org.pkl.core.util.ErrorMessages;
import org.pkl.core.util.Nullable;
@@ -31,8 +27,6 @@ import org.pkl.core.util.StringBuilderWriter;
public final class VmExceptionRenderer {
private final @Nullable StackTraceRenderer stackTraceRenderer;
private static final Ansi.Color errorColor = Color.RED;
/**
* Constructs an error renderer with the given stack trace renderer. If stack trace renderer is
* {@code null}, stack traces will not be included in error output.
@@ -79,8 +73,7 @@ public final class VmExceptionRenderer {
}
private void renderException(VmException exception, StringBuilder builder) {
var out = ansi(builder);
out.fg(errorColor).a(" Pkl Error ").reset();
var header = " Pkl Error ";
String message;
var hint = exception.getHint();
@@ -101,7 +94,7 @@ public final class VmExceptionRenderer {
message = exception.getMessage();
}
out.a('\n').fgBright(errorColor).a(message).reset().a('\n');
builder.append(header).append('\n').append(message).append('\n');
// include cause's message unless it's the same as this exception's message
if (exception.getCause() != null) {

View File

@@ -1,77 +0,0 @@
/**
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.pkl.core
import org.assertj.core.api.Assertions.assertThat
import org.fusesource.jansi.Ansi
import org.junit.jupiter.api.*
class ErrorColoringTest {
companion object {
val evaluator by lazy { Evaluator.preconfigured() }
@AfterAll
@JvmStatic
fun afterAll() {
evaluator.close()
}
}
private fun evaluate(program: String, expression: String): Any {
return evaluator.evaluateExpression(ModuleSource.text(program), expression)
}
@BeforeEach
fun setup() {
// Enable colouring before each test
Ansi.setEnabled(true)
}
@AfterEach
fun teardown() {
// Disable colouring after each test
Ansi.setEnabled(false)
}
@Test
fun `simple error`() {
val error = assertThrows<PklException> { evaluate("bar = 2", "bar = 15") }
assertThat(error)
.message()
.contains("\u001B[31m Pkl Error \u001B[m")
.contains("\u001B[94m1 | \u001B[m")
.contains("\u001B[0;31m^")
}
@Test
fun `repeated error`() {
val error =
assertThrows<PklException> {
evaluate(
"""self: String = "Strings; if they were lazy, you could tie the knot on \(self.take(7))"""",
"self"
)
}
assertThat(error)
.message()
.contains("A stack overflow occurred.")
.contains("┌─ ")
.contains(" repetitions of:")
.contains("│ 1 | ")
.contains("^^^^")
}
}