Skip to content

Commit

Permalink
Kernel#warn now accepts an uplevel: kwarg which will print a filename…
Browse files Browse the repository at this point in the history
…:lineno

message up uplevels from the current stack element in the backtrace.
  • Loading branch information
enebo committed Mar 30, 2018
1 parent c78b918 commit dd996fb
Showing 1 changed file with 35 additions and 2 deletions.
37 changes: 35 additions & 2 deletions core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.jruby.anno.FrameField;
import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyModule;
import org.jruby.ast.util.ArgsUtil;
import org.jruby.common.IRubyWarnings.ID;
import org.jruby.exceptions.MainExitException;
import org.jruby.exceptions.RaiseException;
Expand All @@ -63,6 +64,7 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.backtrace.BacktraceElement;
import org.jruby.runtime.backtrace.RubyStackTraceElement;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ArraySupport;
Expand Down Expand Up @@ -1212,8 +1214,39 @@ public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObj
}

@JRubyMethod(module = true, rest = true, visibility = PRIVATE)
public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObject... messages) {
for (IRubyObject message : messages) warn(context, recv, message);
public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
boolean kwargs = false;
int uplevel = -1;
if (args.length > 1) {
IRubyObject tmp = TypeConverter.checkHashType(context.runtime, args[args.length - 1]);
if (!tmp.isNil()) {
kwargs = true;
IRubyObject[] rets = ArgsUtil.extractKeywordArgs(context, (RubyHash) tmp, "uplevel");
uplevel = RubyNumeric.num2int(rets[0]);
}
}

RubyString message = context.runtime.newString();
int numberOfMessages = kwargs ? args.length - 1 : args.length;

if (uplevel >= 0) {
RubyStackTraceElement[] elements = context.runtime.getInstanceConfig().getTraceType().getBacktrace(context).getBacktrace(context.runtime);

// User can ask for level higher than stack
if (elements.length <= uplevel + 1) uplevel = 0;

int index = uplevel + 1;
message.catString(elements[index].getFileName() + ":" + (elements[index].getLineNumber()) + " warning: ");
}

for (int i = 0; i < numberOfMessages; i++) {
message.append(args[i]);
if (i + 1 < numberOfMessages) message.cat('\n');

}

if (message.size() > 0) warn(context, recv, message);

return context.nil;
}

Expand Down

0 comments on commit dd996fb

Please sign in to comment.