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

Commits on May 21, 2018

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    91ddfd8 View commit details
  2. Copy the full SHA
    e310f43 View commit details
  3. Copy the full SHA
    83e4e76 View commit details
  4. deprecate Class#subclasses from jruby/core_ext ... move it to JRuby

    ... this essentially clashes with Rails's core_ext
    
    resolves #4760 (follow-up on 9a3fe9c)
    kares committed May 21, 2018
    Copy the full SHA
    313e5e6 View commit details
10 changes: 10 additions & 0 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -936,6 +936,16 @@ public void addModule(RubyModule module) {
allModules.add(module);
}
}

public void eachModule(Consumer<RubyModule> func) {
synchronized (allModules) {
for (RubyModule module : allModules) {
func.accept(module);
}
}
}

@Deprecated
public void eachModule(Function1<Object, IRubyObject> func) {
synchronized (allModules) {
for (RubyModule module : allModules) {
16 changes: 5 additions & 11 deletions core/src/main/java/org/jruby/RubyObjectSpace.java
Original file line number Diff line number Diff line change
@@ -45,7 +45,6 @@
import static org.jruby.runtime.Visibility.*;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.collections.WeakValuedIdentityMap;
import org.jruby.util.func.Function1;

@JRubyModule(name="ObjectSpace")
public class RubyObjectSpace {
@@ -129,17 +128,13 @@ public static IRubyObject each_objectInternal(final ThreadContext context, IRuby
if (rubyClass == runtime.getClassClass() || rubyClass == runtime.getModule()) {

final ArrayList<IRubyObject> modules = new ArrayList<>(96);
runtime.eachModule(new Function1<Object, IRubyObject>() {
public Object apply(IRubyObject arg1) {
if (rubyClass.isInstance(arg1)) {
if (arg1 instanceof IncludedModule) {
runtime.eachModule((module) -> {
if (rubyClass.isInstance(module)) {
if (!(module instanceof IncludedModule)) {
// do nothing for included wrappers or singleton classes
} else {
modules.add(arg1); // store the module to avoid concurrent modification exceptions
modules.add(module); // store the module to avoid concurrent modification exceptions
}
}
return null;
}
});

final int count = modules.size();
@@ -155,9 +150,8 @@ public Object apply(IRubyObject arg1) {
block.yield(context, attached); int count = 1;
if (attached instanceof RubyClass) {
for (RubyClass child : ((RubyClass) attached).subclasses(true)) {
if (child instanceof IncludedModule) {
if (!(child instanceof IncludedModule)) {
// do nothing for included wrappers or singleton classes
} else {
count++; block.yield(context, child);
}
}
24 changes: 13 additions & 11 deletions core/src/main/java/org/jruby/ast/util/ArgsUtil.java
Original file line number Diff line number Diff line change
@@ -111,34 +111,36 @@ public static IRubyObject getOptionsArg(Ruby runtime, IRubyObject arg) {
*/
public static IRubyObject[] extractKeywordArgs(ThreadContext context, RubyHash options, String... validKeys) {
IRubyObject[] ret = new IRubyObject[validKeys.length];
int index = 0;
HashSet<RubySymbol> validKeySet = new HashSet<RubySymbol>();

HashSet<RubySymbol> validKeySet = new HashSet<>(ret.length);

// Build the return values
for(String key : validKeys) {
for (int i=0; i<validKeys.length; i++) {
final String key = validKeys[i];
RubySymbol keySym = context.runtime.newSymbol(key);
if (options.containsKey(keySym)) {
ret[index] = options.fastARef(keySym);
ret[i] = options.fastARef(keySym);
} else {
ret[index] = RubyBasicObject.UNDEF;
ret[i] = RubyBasicObject.UNDEF;
}
index++;
validKeySet.add(keySym);
}

// Check for any unknown keys
for(Object obj : options.keySet()) {
if (!validKeySet.contains(obj)) {
throw context.runtime.newArgumentError("unknown keyword: " + obj);
options.visitAll(context, new RubyHash.Visitor() {
public void visit(IRubyObject key, IRubyObject value) {
if (!validKeySet.contains(key)) {
throw context.runtime.newArgumentError("unknown keyword: " + key);
}
}
}
}, null);

return ret;
}

public static IRubyObject[] extractKeywordArgs(ThreadContext context, IRubyObject[] args, String... validKeys) {
IRubyObject options = ArgsUtil.getOptionsArg(context.runtime, args);
if(options instanceof RubyHash) {
if (options instanceof RubyHash) {
return extractKeywordArgs(context, (RubyHash)options, validKeys);
} else {
return null;
55 changes: 50 additions & 5 deletions core/src/main/java/org/jruby/ext/jruby/JRubyLibrary.java
Original file line number Diff line number Diff line change
@@ -37,21 +37,18 @@
import org.jruby.anno.JRubyModule;
import org.jruby.ast.Node;
import org.jruby.ast.RootNode;
import org.jruby.ast.util.ArgsUtil;
import org.jruby.ir.IRBuilder;
import org.jruby.ir.IRManager;
import org.jruby.ir.IRScriptBody;
import org.jruby.ir.targets.JVMVisitor;
import org.jruby.ir.targets.JVMVisitorMethodContext;
import org.jruby.javasupport.Java;
import org.jruby.javasupport.JavaUtil;
import org.jruby.runtime.Block;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.*;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.load.Library;
import org.jruby.util.ByteList;
import org.jruby.util.ClasspathLauncher;

import java.io.ByteArrayInputStream;

@@ -307,4 +304,52 @@ public static IRubyObject load_string_ext(ThreadContext context, IRubyObject rec
return context.nil;
}

@JRubyMethod(module = true)
public static IRubyObject subclasses_of(ThreadContext context, IRubyObject recv, IRubyObject arg) {
return subclassesOf(context, recv, arg instanceof RubyClass ? (RubyClass) arg : arg.getMetaClass(), false);
}

@JRubyMethod(module = true)
public static IRubyObject subclasses_of(ThreadContext context, IRubyObject recv, IRubyObject arg, IRubyObject opts) {
boolean recurseAll = false;
opts = ArgsUtil.getOptionsArg(context.runtime, opts);
if (opts != context.nil) {
IRubyObject all = ((RubyHash) opts).fastARef(context.runtime.newSymbol("all"));
if (all != null) recurseAll = all.isTrue();
}
return subclassesOf(context, recv, arg instanceof RubyClass ? (RubyClass) arg : arg.getMetaClass(), recurseAll);
}

private static RubyArray subclassesOf(ThreadContext context, final IRubyObject recv,
final RubyClass klass, final boolean recurseAll) {

final RubyArray subclasses = RubyArray.newArray(context.runtime);

RubyClass singletonClass = ((RubyClass) klass).getSingletonClass();
RubyObjectSpace.each_objectInternal(context, recv, new IRubyObject[] { singletonClass },
new Block(new JavaInternalBlockBody(context.runtime, Signature.ONE_ARGUMENT) {

@Override
public IRubyObject yield(ThreadContext context, IRubyObject[] args) {
return doYield(context, null, args[0]);
}

@Override
protected IRubyObject doYield(ThreadContext context, Block block, IRubyObject value) {
if (klass != value) {
if (recurseAll) {
return subclasses.append(value);
}
if (((RubyClass) value).superclass(context) == klass) {
return subclasses.append(value);
}
}
return context.nil;
}

})
);
return subclasses;
}

}
5 changes: 2 additions & 3 deletions core/src/main/java/org/jruby/util/func/Function1.java
Original file line number Diff line number Diff line change
@@ -29,6 +29,5 @@

package org.jruby.util.func;

public interface Function1<R,A0> {
public R apply(A0 a0);
}
@Deprecated
public interface Function1<R, A0> extends java.util.function.Function<A0, R> {}
5 changes: 5 additions & 0 deletions core/src/main/ruby/jruby/jruby.rb
Original file line number Diff line number Diff line change
@@ -38,6 +38,11 @@ def compile_ir(content = nil, filename = DEFAULT_FILENAME, extra_position_info =
# @note implemented in *org.jruby.ext.jruby.JRubyLibrary*
def compile(content, filename = '', extra_position_info = false); end if false

# Get all known subclasses of passed class.
# If recurse: true, include all (non-direct) descendants recursively.
# @return Enumerable[Class]
def subclasses_of(klass, recurse: false) end if false

end

# NOTE: This is not a public API and is subject to change at our whim.
15 changes: 3 additions & 12 deletions lib/ruby/stdlib/jruby/core_ext/class.rb
Original file line number Diff line number Diff line change
@@ -27,19 +27,10 @@ class Class
private_constant :JClass

##
# Get an array of all known subclasses of this class. If recursive == true,
# include all descendants.
# @deprecated since JRuby 9.2, use `JRuby.subclasses_of(klass)`
def subclasses(recursive = false)
subclasses = []
ObjectSpace.each_object(singleton_class) do |klass|
next if klass.equal? self
if recursive
subclasses << klass
else
subclasses << klass if klass.superclass.equal? self
end
end
subclasses
warn("klass.subclasses is deprecated, use JRuby.subclasses_of(klass) instead", uplevel: 1)
JRuby.subclasses_of(self, all: recursive)
end

##