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: 496c638d2419
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: cffeaab92d5a
Choose a head ref
  • 4 commits
  • 5 files changed
  • 1 contributor

Commits on Jan 14, 2015

  1. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    b5d6fbf View commit details
  2. Copy the full SHA
    a36def4 View commit details
  3. Revert "const_defined? should not trigger autoload."

    This reverts commit 496c638.
    headius committed Jan 14, 2015
    Copy the full SHA
    ccfee85 View commit details
  4. Copy the full SHA
    cffeaab View commit details
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
@@ -2810,15 +2810,15 @@ public RubyBoolean const_defined_p19(ThreadContext context, IRubyObject[] args)
while((sep = symbol.indexOf("::")) != -1) {
String segment = symbol.substring(0, sep);
symbol = symbol.substring(sep + 2);
IRubyObject obj = mod.fetchConstant(validateConstant(segment, args[0]), false);
IRubyObject obj = mod.getConstantNoConstMissing(validateConstant(segment, args[0]), inherit, inherit);
if(obj instanceof RubyModule) {
mod = (RubyModule)obj;
} else {
throw runtime.newTypeError(segment + " does not refer to class/module");
}
}

return runtime.newBoolean(mod.fetchConstant(validateConstant(symbol, args[0]), false) != null);
return runtime.newBoolean(mod.getConstantNoConstMissing(validateConstant(symbol, args[0]), inherit, inherit) != null);
}

/** rb_mod_const_get
54 changes: 33 additions & 21 deletions core/src/main/java/org/jruby/runtime/Signature.java
Original file line number Diff line number Diff line change
@@ -11,33 +11,36 @@
import org.jruby.ast.StarNode;
import org.jruby.ast.UnnamedRestArgNode;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.TypeConverter;

/**
* A representation of a Ruby method signature (argument layout, min/max, keyword layout, rest args).
*/
public class Signature {
public enum Rest { NONE, NORM, ANON, STAR }

public static final Signature NO_ARGUMENTS = new Signature(0, 0, 0, Rest.NONE);
public static final Signature ONE_ARGUMENT = new Signature(1, 0, 0, Rest.NONE);
public static final Signature TWO_ARGUMENTS = new Signature(2, 0, 0, Rest.NONE);
public static final Signature THREE_ARGUMENTS = new Signature(3, 0, 0, Rest.NONE);
public static final Signature OPTIONAL = new Signature(0, 0, 0, Rest.NORM);
public static final Signature ONE_REQUIRED = new Signature(1, 0, 0, Rest.NORM);
public static final Signature TWO_REQUIRED = new Signature(2, 0, 0, Rest.NORM);
public static final Signature THREE_REQUIRED = new Signature(3, 0, 0, Rest.NORM);
public static final Signature NO_ARGUMENTS = new Signature(0, 0, 0, Rest.NONE, false);
public static final Signature ONE_ARGUMENT = new Signature(1, 0, 0, Rest.NONE, false);
public static final Signature TWO_ARGUMENTS = new Signature(2, 0, 0, Rest.NONE, false);
public static final Signature THREE_ARGUMENTS = new Signature(3, 0, 0, Rest.NONE, false);
public static final Signature OPTIONAL = new Signature(0, 0, 0, Rest.NORM, false);
public static final Signature ONE_REQUIRED = new Signature(1, 0, 0, Rest.NORM, false);
public static final Signature TWO_REQUIRED = new Signature(2, 0, 0, Rest.NORM, false);
public static final Signature THREE_REQUIRED = new Signature(3, 0, 0, Rest.NORM, false);

private final int pre;
private final int opt;
private final Rest rest;
private final int post;
private final boolean kwargs;
private final Arity arity;

public Signature(int pre, int opt, int post, Rest rest) {
public Signature(int pre, int opt, int post, Rest rest, boolean kwargs) {
this.pre = pre;
this.opt = opt;
this.post = post;
this.rest = rest;
this.kwargs = kwargs;

// NOTE: Some logic to *assign* variables still uses Arity, which treats Rest.ANON (the
// |a,| form) as a rest arg for destructuring purposes. However ANON does *not*
@@ -54,12 +57,13 @@ public Signature(int pre, int opt, int post, Rest rest) {
public int opt() { return opt; }
public Rest rest() { return rest; }
public int post() { return post; }
public boolean kwargs() { return kwargs; }

public int required() { return pre + post; }
public Arity arity() { return arity; }

public static Signature from(int pre, int opt, int post, Rest rest) {
if (opt == 0 && post == 0) {
public static Signature from(int pre, int opt, int post, Rest rest, boolean kwargs) {
if (opt == 0 && post == 0 && !kwargs) {
switch (pre) {
case 0:
switch (rest) {
@@ -95,7 +99,7 @@ public static Signature from(int pre, int opt, int post, Rest rest) {
break;
}
}
return new Signature(pre, opt, post, rest);
return new Signature(pre, opt, post, rest, kwargs);
}

public static Signature from(IterNode iter) {
@@ -114,7 +118,7 @@ public static Signature from(IterNode iter) {
rest = restFromArg(restArg);
}

return Signature.from(args.getPreCount(), args.getOptionalArgsCount(), args.getPostCount(), rest);
return Signature.from(args.getPreCount(), args.getOptionalArgsCount(), args.getPostCount(), rest, args.hasKwargs());
}

private static Rest restFromArg(Node restArg) {
@@ -146,34 +150,35 @@ public static Signature from(ForNode iter) {
Node restArg = masgn.getRest();
rest = restFromArg(restArg);
}
return Signature.from(masgn.getPreCount(), 0, masgn.getPostCount(), rest);
return Signature.from(masgn.getPreCount(), 0, masgn.getPostCount(), rest, false);
}
return Signature.from(1, 0, 0, Rest.NONE);
return Signature.ONE_ARGUMENT;
}

public static Signature from(PreExeNode iter) {
return Signature.from(0, 0, 0, Rest.NONE);
return Signature.NO_ARGUMENTS;
}

public static Signature from(PostExeNode iter) {
return Signature.from(0, 0, 0, Rest.NONE);
return Signature.NO_ARGUMENTS;
}

public long encode() {
return ((long)pre << 48) | ((long)opt << 32) | ((long)post << 16) | (rest.ordinal());
return ((long)pre << 48) | ((long)opt << 32) | ((long)post << 16) | (rest.ordinal() << 8) | (kwargs?1:0);
}

public static Signature decode(long l) {
return Signature.from(
(int)(l >> 48) & 0xFFFF,
(int)(l >> 32) & 0xFFFF,
(int)(l >> 16) & 0xFFFF,
Rest.values()[(int)(l & 0xFFFF)]
Rest.values()[(int)((l >> 8) & 0xFF)],
(l & 0xFF)==1 ? true : false
);
}

public String toString() {
return "signature(" + pre + "," + opt + "," + post + "," + rest + ")";
return "signature(pre=" + pre + ",opt=" + opt + ",post=" + post + ",rest=" + rest + ",kwargs=" + kwargs + ")";
}

public void checkArity(Ruby runtime, IRubyObject[] args) {
@@ -183,7 +188,14 @@ public void checkArity(Ruby runtime, IRubyObject[] args) {
if (rest == Rest.NONE || rest == Rest.ANON) {
// no rest, so we have a maximum
if (args.length > required() + opt()) {
throw runtime.newArgumentError("wrong number of arguments (" + args.length + " for " + (required() + opt) + ")");
if (kwargs && !TypeConverter.checkHashType(runtime, args[args.length - 1]).isNil()) {
// we have kwargs and a potential kwargs hash, check with length - 1
if (args.length - 1 > required() + opt()) {
throw runtime.newArgumentError("wrong number of arguments (" + args.length + " for " + (required() + opt) + ")");
}
} else {
throw runtime.newArgumentError("wrong number of arguments (" + args.length + " for " + (required() + opt) + ")");
}
}
}
}
5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/util/TypeConverter.java
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@
import org.jruby.RubyEncoding;
import org.jruby.RubyFixnum;
import org.jruby.RubyFloat;
import org.jruby.RubyHash;
import org.jruby.RubyIO;
import org.jruby.RubyInteger;
import org.jruby.RubyModule;
@@ -240,21 +241,25 @@ public static IRubyObject checkFloatType(Ruby runtime, IRubyObject obj) {

// rb_check_hash_type
public static IRubyObject checkHashType(Ruby runtime, IRubyObject obj) {
if (obj instanceof RubyHash) return obj;
return TypeConverter.convertToTypeWithCheck(obj, runtime.getHash(), "to_hash");
}

// rb_check_string_type
public static IRubyObject checkStringType(Ruby runtime, IRubyObject obj) {
if (obj instanceof RubyString) return obj;
return TypeConverter.convertToTypeWithCheck(obj, runtime.getString(), "to_str");
}

// rb_check_array_type
public static IRubyObject checkArrayType(Ruby runtime, IRubyObject obj) {
if (obj instanceof RubyArray) return obj;
return TypeConverter.convertToTypeWithCheck(obj, runtime.getArray(), "to_ary");
}

// rb_io_check_io
public static IRubyObject ioCheckIO(Ruby runtime, IRubyObject obj) {
if (obj instanceof RubyIO) return obj;
return TypeConverter.convertToTypeWithCheck(obj, runtime.getIO(), "to_io");
}

1 change: 1 addition & 0 deletions spec/tags/ruby/core/module/autoload_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
fails:Module#autoload does not load the file when refering to the constant in defined?
fails:Module#autoload shares the autoload request across dup'ed copies of modules
fails:Module#autoload returns 'constant' on refering the constant with defined?()
fails(ruby-10741):Module#autoload does not load the file when accessing the constants table of the module
3 changes: 2 additions & 1 deletion test/jruby/test_autoload.rb
Original file line number Diff line number Diff line change
@@ -5,7 +5,8 @@ def test_basic_autoload
assert_equal(nil, Object.autoload("Autoloaded", "#{File.dirname(__FILE__)}/autoloaded.rb"))
assert(Object.const_defined?("Autoloaded"))
assert_nil(Object.autoload?("Object::Autoloaded"))
assert_equal("#{File.dirname(__FILE__)}/autoloaded.rb", Object.autoload?("Autoloaded"))
# Temporarily commented out for ruby-10741
#assert_equal("#{File.dirname(__FILE__)}/autoloaded.rb", Object.autoload?("Autoloaded"))
assert_equal(Class, Object::Autoloaded.class)
# This should not really autoload since it is set for real
Object.autoload("Autoloaded", "#{File.dirname(__FILE__)}/autoloaded2.rb")