Skip to content

Commit 2955f52

Browse files
committed
GH-548 Format Failures
1 parent 0a1a5fe commit 2955f52

File tree

10 files changed

+110
-79
lines changed

10 files changed

+110
-79
lines changed

examples/tests/current_test.panda

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ main {
175175
CustomThread thread = new CustomThread()
176176
thread.start()
177177

178-
// Runnable runnable = { log 'x' }
178+
Runnable runnable = { log 'x' }
179179
}
180180

181181
// simple interface

panda-framework/src/main/java/org/panda_lang/language/Failure.java

+24
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.panda_lang.language;
1818

19+
import org.jetbrains.annotations.Nullable;
1920
import org.panda_lang.language.interpreter.source.IndicatedSource;
2021
import org.panda_lang.utilities.commons.function.Option;
2122

@@ -38,4 +39,27 @@ public interface Failure {
3839
*/
3940
Option<String> getNote();
4041

42+
/**
43+
* Returns the cause of this throwable or {@code null} if the
44+
* cause is nonexistent or unknown. (The cause is the throwable that
45+
* caused this throwable to get thrown.)
46+
*
47+
* @return the cause
48+
*/
49+
@Nullable Throwable getCause();
50+
51+
/**
52+
* Get failure message
53+
*
54+
* @return the failure message
55+
*/
56+
String getMessage();
57+
58+
/**
59+
* Get failure stacktrace
60+
*
61+
* @return the array of stack trace elements
62+
*/
63+
StackTraceElement[] getStackTrace();
64+
4165
}

panda-framework/src/main/java/org/panda_lang/language/interpreter/logging/FailureListener.java

-20
This file was deleted.

panda-framework/src/main/java/org/panda_lang/language/interpreter/logging/SystemLogger.java

+65-12
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@
1717
package org.panda_lang.language.interpreter.logging;
1818

1919
import org.panda_lang.language.Failure;
20+
import org.panda_lang.language.PandaFrameworkConstants;
21+
import org.panda_lang.language.interpreter.source.IndicatedSource;
22+
import org.panda_lang.language.interpreter.source.Location;
23+
import org.panda_lang.language.interpreter.token.Snippet;
24+
import org.panda_lang.language.interpreter.token.Snippetable;
2025
import org.panda_lang.utilities.commons.StackTraceUtils;
26+
import org.panda_lang.utilities.commons.StringUtils;
27+
import org.panda_lang.utilities.commons.console.Colored;
2128
import org.panda_lang.utilities.commons.console.Effect;
2229

2330
public final class SystemLogger implements Logger {
@@ -49,26 +56,72 @@ public void exception(Throwable throwable) {
4956
StackTraceElement[] stackTrace = StackTraceUtils.startsWith(throwable.getStackTrace(), element -> element.toString().contains("org.junit"));
5057

5158
if (throwable instanceof Failure) {
59+
Failure failure = (Failure) throwable;
5260

53-
}
61+
error("");
62+
error("&b- - ~ ~< Failure >~ ~ - -&r");
63+
error("");
64+
error("&1" + failure.getMessage());
65+
error("");
5466

55-
error("");
56-
error("&b- - ~ ~< Exception >~ ~ - -&r");
57-
error("");
58-
error("Given:");
59-
error(" Message:&1 " + throwable.getMessage());
60-
error(" In:&1 " + stackTrace[0].toString());
61-
error(" By:&1 " + throwable.getClass());
62-
error("");
63-
error("Stacktrace:");
67+
failure.getNote().peek(note -> {
68+
error("Note:");
69+
error(" &1" + note);
70+
error("");
71+
});
72+
73+
IndicatedSource indicatedSource = failure.getIndicatedSource();
74+
Location location = indicatedSource.getIndicated().getLocation();
75+
76+
String source = getCurrentLine(indicatedSource.getSource(), indicatedSource.getIndicated()).toString();
77+
String element = getCurrentLine(indicatedSource.getIndicated(), indicatedSource.getIndicated()).toString();
78+
79+
int elementIndex = source.indexOf(element);
80+
int endIndex = elementIndex + element.length();
6481

65-
for (StackTraceElement element : stackTrace) {
66-
error(" at " + element.toString());
82+
String content = elementIndex < 0 ? source : source.substring(0, elementIndex)
83+
+ Colored.on(source.substring(elementIndex, endIndex)).effect(Effect.RED)
84+
+ source.substring(endIndex);
85+
86+
87+
error("Source:");
88+
error(" " + content);
89+
error(" " + StringUtils.buildSpace(source.indexOf(element)) + Colored.on("^").effect(Effect.BOLD));
90+
error("Location:");
91+
error(" Panda: &b" + location.getSource().getId() + "&r at line &1" + location.getDisplayLine() + "&r:&1" + location.getIndex());
92+
error("");
93+
error("Stacktrace:");
94+
95+
for (int index = 0; index < 2 && index < stackTrace.length; index++) {
96+
StackTraceElement stackTraceElement = stackTrace[index];
97+
error(" at " + stackTraceElement.toString());
98+
}
99+
}
100+
else {
101+
error("");
102+
error("&b- - ~ ~< Exception >~ ~ - -&r");
103+
error("");
104+
error("Given:");
105+
error(" Message:&1 " + throwable.getMessage());
106+
error(" In:&1 " + stackTrace[0].toString());
107+
error(" By:&1 " + throwable.getClass());
108+
error("");
109+
error("Stacktrace:");
110+
111+
for (StackTraceElement stackTraceElement : stackTrace) {
112+
error(" at " + stackTraceElement);
113+
}
67114
}
68115

69116
error("");
70117
error("Environment:");
118+
error(" Panda: " + PandaFrameworkConstants.VERSION);
119+
error(" Java: " + System.getProperty("java.version") + " (" + System.getProperty("os.name") + ")");
71120
error("");
72121
}
73122

123+
private Snippet getCurrentLine(Snippetable source, Snippetable indicated) {
124+
return source.toSnippet().getLine(indicated.toSnippet().getFirst().getLocation().getLine());
125+
}
126+
74127
}

panda-framework/src/main/java/org/panda_lang/language/interpreter/parser/expression/PandaExpressionParser.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ public ExpressionTransaction parse(Context context, Streamable streamable, Expre
106106
// if something went wrong
107107
if (worker.hasError()) {
108108
transaction.rollback();
109-
throw new PandaParserFailure(expressionContext, worker.getError().getErrorSource(), worker.getError().getErrorMessage());
109+
throw new PandaParserFailure(
110+
expressionContext, worker.getError().getErrorSource(),
111+
worker.getError().getErrorMessage(),
112+
"マルセルへの注意 \uD83E\uDD20"
113+
);
110114
}
111115

112116
// if context does not contain any results

panda-framework/src/main/java/org/panda_lang/language/interpreter/token/MutableTokenInfo.java

-39
This file was deleted.

panda-framework/src/main/java/org/panda_lang/language/interpreter/token/PandaSnippet.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public boolean isMutable() {
7070
@Override
7171
public String toString() {
7272
return ContentJoiner.on(" ")
73-
.join(tokens, representation -> representation.getToken().toString())
73+
.join(tokens, Object::toString)
7474
.toString();
7575
}
7676

panda-framework/src/main/java/org/panda_lang/language/interpreter/token/PandaTokenInfo.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public int hashCode() {
6565

6666
@Override
6767
public String toString() {
68-
return token.getValue();
68+
return token.toString();
6969
}
7070

7171
public static TokenInfo of(TokenType type, String value) {

panda-framework/src/main/java/org/panda_lang/language/interpreter/token/Snippet.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,17 @@ default Snippet getLine(int line) {
276276

277277
for (TokenInfo tokenInfo : getTokensRepresentations()) {
278278
if (tokenInfo.getType() == TokenTypes.SECTION) {
279-
selected.addAll(tokenInfo.toToken(Section.class).getContent().getLine(line).getTokensRepresentations());
280-
continue;
279+
Snippet content = tokenInfo.toToken(Section.class).getContent();
280+
Snippet selectedContent = content.getLine(line);
281+
282+
if (!selectedContent.isEmpty()) {
283+
if (!content.equals(selectedContent)) {
284+
return selectedContent;
285+
}
286+
287+
selected.add(tokenInfo);
288+
continue;
289+
}
281290
}
282291

283292
if (tokenInfo.getLocation().getLine() < line) {

panda-framework/src/main/java/org/panda_lang/language/resource/syntax/auxiliary/Section.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public Section(TokenInfo openingSeparator, Snippet content, TokenInfo closingSep
3737

3838
@Override
3939
public String getValue() {
40-
return content.toString();
40+
return getOpeningSeparator().toString() + getClosingSeparator().toString();
4141
}
4242

4343
@Override
@@ -63,7 +63,7 @@ public Separator getSeparator() {
6363

6464
@Override
6565
public String toString() {
66-
return getSeparator().toString() + " " + super.toString() + " " + getSeparator().getOpposite().toString();
66+
return getOpeningSeparator().toString() + " " + getContent() + " " + getClosingSeparator().toString();
6767
}
6868

6969
}

0 commit comments

Comments
 (0)