Skip to content

Commit

Permalink
Merge pull request #8229 from headius/java_throwable_full_message
Browse files Browse the repository at this point in the history
Fix full_message formatting and Throwable impl
  • Loading branch information
headius committed May 8, 2024
2 parents 01bea42 + 9046cfa commit 06053e4
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 30 deletions.
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
Expand Up @@ -1525,8 +1525,8 @@ public final int catWithCodeRange(ByteList other, int codeRange) {
}

public final RubyString catString(String str) {
ByteList other = encodeBytelist(str, getEncoding());
catWithCodeRange(other, CR_UNKNOWN);
ByteList other = encodeBytelist(str, UTF8);
catWithCodeRange(other, CR_VALID);
return this;
}

Expand Down
24 changes: 23 additions & 1 deletion core/src/main/java/org/jruby/javasupport/ext/JavaLang.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,29 @@ public static IRubyObject full_message(final ThreadContext context, final IRubyO

@JRubyMethod
public static IRubyObject full_message(final ThreadContext context, final IRubyObject self, final IRubyObject opts) {
return RubyString.newString(context.runtime, TraceType.printFullMessage(context, self, opts));
return TraceType.printFullMessage(context, self, opts);
}

@JRubyMethod
public static IRubyObject detailed_message(final ThreadContext context, final IRubyObject self) {
return detailed_message(context, self, (IRubyObject) null);
}

@JRubyMethod
public static IRubyObject detailed_message(final ThreadContext context, final IRubyObject self, final IRubyObject opts) {
return TraceType.printDetailedMessage(context, self, opts);
}

@JRubyMethod(optional = 1)
public static IRubyObject detailed_message(final ThreadContext context, final IRubyObject self, final IRubyObject[] args) {
switch (args.length) {
case 0:
return detailed_message(context, self);
case 1:
return detailed_message(context, self, args[0]);
default:
throw context.runtime.newArgumentError(args.length, 0, 1);
}
}

@JRubyMethod // Ruby exception to_s is the same as message
Expand Down
73 changes: 46 additions & 27 deletions core/src/main/java/org/jruby/runtime/backtrace/TraceType.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
import com.headius.backport9.stack.StackWalker;
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyBoolean;
import org.jruby.RubyClass;
import org.jruby.RubyException;
import org.jruby.RubyHash;
import org.jruby.RubyInstanceConfig;
import org.jruby.RubyString;
import org.jruby.RubySymbol;
import org.jruby.ast.util.ArgsUtil;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
Expand Down Expand Up @@ -338,51 +340,67 @@ public void renderBacktrace(RubyStackTraceElement[] elts, StringBuilder buffer,

public static IRubyObject printDetailedMessage(ThreadContext context, IRubyObject exception, IRubyObject opts) {
IRubyObject optArg = ArgsUtil.getOptionsArg(context.runtime, opts);
boolean highlight;

if (optArg.isNil()) {
highlight = false;
} else {
IRubyObject highlightArg = ((RubyHash) optArg).fastARef(context.runtime.newSymbol("highlight"));
highlight = determineHighlighting(context, highlightArg);
}
IRubyObject highlightArg = checkHighlightKeyword(context, optArg, false);

RubyString errorStream = RubyString.newEmptyString(context.runtime);

printErrMessageToStream(exception, errorStream, highlight);
printErrMessageToStream(exception, errorStream, highlightArg.isTrue());

return errorStream;
}

public static RubyString printFullMessage(ThreadContext context, IRubyObject exception, IRubyObject opts) {
IRubyObject optArg = ArgsUtil.getOptionsArg(context.runtime, opts);
boolean highlight;
boolean reverse;
Ruby runtime = context.runtime;
IRubyObject optArg = ArgsUtil.getOptionsArg(runtime, opts);

IRubyObject highlightArg = checkHighlightKeyword(context, optArg, true);
boolean reverse = checkOrderKeyword(context, optArg);

if (optArg.isNil()) {
highlight = RubyException.to_tty_p(context, context.runtime.getException()).isTrue();
optArg = RubyHash.newHash(runtime);
}

((RubyHash) optArg).fastASet(runtime.newSymbol("highlight"), highlightArg);

return printBacktraceMRI(exception, optArg, highlightArg.isTrue(), reverse);
}

private static boolean checkOrderKeyword(ThreadContext context, IRubyObject optArg) {
boolean reverse;
if (optArg.isNil()) {
reverse = false;
} else {
RubyHash optHash = (RubyHash) optArg;

IRubyObject highlightArg = optHash.fastARef(context.runtime.newSymbol("highlight"));
if (highlightArg == null) {
optHash.fastASet(context.runtime.newSymbol("highlight"), RubyException.to_tty_p(context, context.runtime.getException()));
}
highlight = determineHighlighting(context, highlightArg);
IRubyObject highlightOrder = optHash.fastARef(context.runtime.newSymbol("order"));
reverse = determineDirection(context, highlightOrder);
}

return printBacktraceMRI(exception, optArg, highlight, reverse);
return reverse;
}

private static boolean determineHighlighting(ThreadContext context, IRubyObject vHigh) {
if (vHigh == null) return false;
if (vHigh.isNil()) return RubyException.to_tty_p(context, context.runtime.getException()).isTrue();
if (vHigh == context.tru) return true;
if (vHigh == context.fals) return false;
throw context.runtime.newArgumentError("expected true or false as highlight: " + vHigh);
private static IRubyObject checkHighlightKeyword(ThreadContext context, IRubyObject optArg, boolean autoTTYDetect) {
Ruby runtime = context.runtime;
IRubyObject highlightArg = context.nil;

RubySymbol highlightSym = runtime.newSymbol("highlight");
if (!optArg.isNil()) {
RubyHash optHash = (RubyHash) optArg;

highlightArg = optHash.fastARef(highlightSym);

if (highlightArg == null) highlightArg = context.nil;
if (!(highlightArg.isNil()
|| highlightArg == context.tru
|| highlightArg == context.fals)) {
throw context.runtime.newArgumentError("expected true or false as highlight: " + highlightArg);
}
}

if (highlightArg.isNil()) {
highlightArg = RubyBoolean.newBoolean(context, autoTTYDetect && RubyException.to_tty_p(context, runtime.getException()).isTrue());
}

return highlightArg;
}

private static boolean determineDirection(ThreadContext context, IRubyObject vOrder) {
Expand Down Expand Up @@ -551,7 +569,7 @@ private static void printErrMessageToStream(IRubyObject exception, RubyString er
if (highlight) errorStream.catString(RESET);
}

if (tail != null) {
if (tail != null && tail.length() > 0) {
errorStream.cat('\n');
if (!highlight) {
errorStream.catString(tail);
Expand Down Expand Up @@ -749,6 +767,7 @@ public static void printBacktraceToStream(ThreadContext context, IRubyObject bac
}
if (stackTraceLine instanceof RubyString) {
errorStream.catString("from " + stackTraceLine);
errorStream.cat('\n');
}
else {
errorStream.append(stackTraceLine);
Expand Down

0 comments on commit 06053e4

Please sign in to comment.