Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 877bcf42c0a8
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4e1f02c813d9
Choose a head ref
  • 4 commits
  • 7 files changed
  • 1 contributor

Commits on Apr 20, 2018

  1. Copy the full SHA
    484d537 View commit details
  2. Copy the full SHA
    29d0b9c View commit details
  3. Copy the full SHA
    c2ca66e View commit details
  4. Copy the full SHA
    4e1f02c View commit details
42 changes: 31 additions & 11 deletions core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
@@ -48,6 +48,7 @@
import org.jruby.anno.JRubyModule;
import org.jruby.ast.util.ArgsUtil;
import org.jruby.common.IRubyWarnings.ID;
import org.jruby.common.RubyWarnings;
import org.jruby.exceptions.MainExitException;
import org.jruby.exceptions.RaiseException;
import org.jruby.internal.runtime.methods.DynamicMethod;
@@ -1205,42 +1206,61 @@ private static RaiseException uncaughtThrow(Ruby runtime, IRubyObject tag, IRuby
}

@JRubyMethod(module = true, visibility = PRIVATE)
public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObject message) {
public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObject _message) {
final Ruby runtime = context.runtime;

if (runtime.warningsEnabled()) RubyIO.puts1(context, runtime.getGlobalVariables().get("$stderr"), message);
if (_message instanceof RubyArray) {
RubyArray messageArray = _message.convertToArray();
for (int i = 0; i < messageArray.size(); i++) warn(context, recv, messageArray.eltOk(i));
return context.nil;
}

return context.nil;
RubyString message = _message.convertToString();
if (!message.endsWithAsciiChar('\n')) {
message = (RubyString) message.op_plus19(context, runtime.newString("\n"));
}

return sites(context).warn.call(context, recv, runtime.getWarning(), message);
}

public static final String[] WARN_VALID_KEYS = {"uplevel"};

@JRubyMethod(module = true, rest = true, visibility = PRIVATE)
public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
Ruby runtime = context.runtime;

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");
IRubyObject[] rets = ArgsUtil.extractKeywordArgs(context, (RubyHash) tmp, WARN_VALID_KEYS);
uplevel = rets[0] == UNDEF ? 0 : RubyNumeric.num2int(rets[0]);
}
}

RubyString message = context.runtime.newString();
// FIXME: This is not particularly efficient.
int numberOfMessages = kwargs ? args.length - 1 : args.length;
IRubyObject newline = runtime.newString("\n");

if (uplevel >= 0) {
if (kwargs) {
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;
if (elements.length <= uplevel + 1) uplevel = -1;

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

for (int i = 0; i < numberOfMessages; i++) {
warn(context, recv, args[1]);
for (int i = 0; i < numberOfMessages; i++) {
warn(context, recv, baseMessage.op_plus19(context, args[i]));
}
} else {
for (int i = 0; i < numberOfMessages; i++) {
warn(context, recv, args[i].convertToString());
}
}

return context.nil;
7 changes: 7 additions & 0 deletions core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
@@ -4430,6 +4430,13 @@ private boolean end_with_pCommon(IRubyObject tmp) {
return false;
}

public boolean endsWithAsciiChar(char c) {
ByteList value = this.value;
int size;

return value.getEncoding().isAsciiCompatible() && (size = value.realSize()) > 0 && value.get(size - 1) == c;
}

private static final ByteList SPACE_BYTELIST = RubyInteger.singleCharByteList((byte) ' ');

private IRubyObject justify(Ruby runtime, IRubyObject arg0, int jflag) {
36 changes: 23 additions & 13 deletions core/src/main/java/org/jruby/RubyStruct.java
Original file line number Diff line number Diff line change
@@ -33,6 +33,8 @@

package org.jruby;

import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jruby.anno.JRubyClass;
@@ -355,25 +357,33 @@ public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {

IRubyObject keywordInit = RubyStruct.getInternalVariable(classOf(), "__keyword_init__");

Ruby runtime = context.runtime;
IRubyObject nil = context.nil;

if (keywordInit.isTrue()) {
if (args.length != 1 || !(args[0] instanceof RubyHash)) throw context.runtime.newArgumentError("wrong number of arguments (given " + args.length + ", expected 0)");
RubyHash kwArgs = args[0].convertToHash();
IRubyObject maybeKwargs = ArgsUtil.getOptionsArg(runtime, args);

if (maybeKwargs.isNil())
throw runtime.newArgumentError("wrong number of arguments (given " + args.length + ", expected 0)");

RubyHash kwArgs = (RubyHash) maybeKwargs;
RubyArray __members__ = __member__();
String[] members = Stream.of(__members__.toJavaArray())
.map(o -> RubySymbol.objectToSymbolString(o))
.collect(Collectors.toList())
.toArray(new String[__members__.size()]);
args = ArgsUtil.extractKeywordArgs(context, kwArgs, members);
for (int i = 0; i < args.length; i++) {
if (args[i] == UNDEF) args[i] = nil;
}
Set<Map.Entry<IRubyObject, IRubyObject>> entries = kwArgs.directEntrySet();

entries.stream().forEach(
entry -> {
IRubyObject key = entry.getKey();
if (!(key instanceof RubySymbol))
key = runtime.newSymbol(key.convertToString().getByteList());
IRubyObject index = __members__.index(context, key);
if (index.isNil()) throw runtime.newArgumentError("unknown keywords: " + key);
values[index.convertToInteger().getIntValue()] = entry.getValue();
});
} else {
System.arraycopy(args, 0, values, 0, args.length);
Helpers.fillNil(values, args.length, values.length, runtime);
}

System.arraycopy(args, 0, values, 0, args.length);
Helpers.fillNil(values, args.length, values.length, context.runtime);

return nil;
}

3 changes: 3 additions & 0 deletions core/src/main/java/org/jruby/common/RubyWarnings.java
Original file line number Diff line number Diff line change
@@ -207,6 +207,9 @@ public void warning(ID id, String fileName, int lineNumber, String message) {
@JRubyMethod
public static IRubyObject warn(ThreadContext context, IRubyObject recv, IRubyObject arg) {
Ruby runtime = context.runtime;

if (!runtime.warningsEnabled()) return context.nil;

TypeConverter.checkType(context, arg, runtime.getString());
RubyString str = (RubyString) arg;
if (!str.getEncoding().isAsciiCompatible()) {
1 change: 1 addition & 0 deletions core/src/main/java/org/jruby/runtime/JavaSites.java
Original file line number Diff line number Diff line change
@@ -89,6 +89,7 @@ public static class KernelSites {
public final CheckedSites to_hash_checked = new CheckedSites("to_hash");
public final CallSite write = new FunctionalCachingCallSite("write");
public final CallSite call = new FunctionalCachingCallSite("call");
public final CallSite warn = new FunctionalCachingCallSite("warn");
}

public static class ArraySites {
25 changes: 12 additions & 13 deletions core/src/main/java/org/jruby/util/KCode.java
Original file line number Diff line number Diff line change
@@ -29,23 +29,25 @@
package org.jruby.util;

import org.jcodings.Encoding;
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.EUCJPEncoding;
import org.jcodings.specific.SJISEncoding;
import org.jcodings.specific.UTF8Encoding;

public enum KCode {
NIL(null, "ASCII-8BIT", 0),
NONE("NONE", "ASCII-8BIT", 0),
UTF8("UTF8", "UTF-8", 64),
SJIS("SJIS", "Shift-JIS", 48),
EUC("EUC", "EUC_JP", 32);
NIL(null, ASCIIEncoding.INSTANCE, 0),
NONE("NONE", ASCIIEncoding.INSTANCE, 0),
UTF8("UTF8", UTF8Encoding.INSTANCE, 64),
SJIS("SJIS", SJISEncoding.INSTANCE, 48),
EUC("EUC", EUCJPEncoding.INSTANCE, 32);

private final String kcode;
private final String encodingName;
private final Encoding encoding;
private final int code;

private volatile Encoding encoding;

private KCode(String kcode, String encodingName, int code) {
private KCode(String kcode, Encoding encoding, int code) {
this.kcode = kcode;
this.encodingName = encodingName;
this.encoding = encoding;
this.code = code;
}

@@ -89,9 +91,6 @@ public static KCode fromBits(int bits) {
}

public Encoding getEncoding() {
if (encoding == null) {
encoding = Encoding.load(encodingName);
}
return encoding;
}

1 change: 1 addition & 0 deletions spec/tags/ruby/core/module/refine_tags.txt
Original file line number Diff line number Diff line change
@@ -7,3 +7,4 @@ fails:Module#refine module inclusion activates all refinements from all ancestor
fails:Module#refine for methods accessed indirectly is honored by Kernel#send
fails:Module#refine for methods accessed indirectly is honored by BasicObject#__send__
fails:Module#refine for methods accessed indirectly is honored by Symbol#to_proc
fails:Module#refine for methods accessed indirectly is honored by string interpolation