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

Commits on Apr 6, 2016

  1. Copy the full SHA
    591c78f View commit details
  2. [ji] when a Ruby Class is being coerced to a Java class - auto-reify …

    …(closing #3454)
    
    ... much less confusing than for user classes to see the nearest reified class in the inheritance hierarchy (without explicitly doing `become_java!`)
    kares committed Apr 6, 2016
    Copy the full SHA
    27d8098 View commit details
8 changes: 6 additions & 2 deletions core/src/main/java/org/jruby/RubyBasicObject.java
Original file line number Diff line number Diff line change
@@ -825,6 +825,10 @@ public IRubyObject checkArrayType() {
*/
@Override
public Object toJava(Class target) {
return defaultToJava(target);
}

final <T> T defaultToJava(Class<T> target) {
// for callers that unconditionally pass null retval type (JRUBY-4737)
if (target == void.class) return null;

@@ -838,7 +842,7 @@ public Object toJava(Class target) {
if (target.isAssignableFrom(value.getClass())) {
getRuntime().getJavaSupport().getObjectProxyCache().put(value, this);

return value;
return (T) value;
}
}
else if (JavaUtil.isDuckTypeConvertable(getClass(), target)) {
@@ -847,7 +851,7 @@ else if (JavaUtil.isDuckTypeConvertable(getClass(), target)) {
}
}
else if (target.isAssignableFrom(getClass())) {
return this;
return (T) this;
}

throw getRuntime().newTypeError("cannot convert instance of " + getClass() + " to " + target);
17 changes: 7 additions & 10 deletions core/src/main/java/org/jruby/RubyClass.java
Original file line number Diff line number Diff line change
@@ -1215,11 +1215,10 @@ public Object unmarshalFrom(Ruby runtime, RubyClass type,
* @return true if the class can be reified, false otherwise
*/
public boolean isReifiable() {
RubyClass realSuper = null;

// already reified is not reifiable
if (reifiedClass != null) return false;

final RubyClass realSuper;
// root classes are not reifiable
if (superClass == null || (realSuper = superClass.getRealClass()) == null) return false;

@@ -1750,17 +1749,15 @@ public synchronized void addClassAnnotation(Class annotation, Map fields) {

@Override
public Object toJava(Class klass) {
Class returnClass = null;

if (klass == Class.class) {
if (reifiedClass == null) reifyWithAncestors(); // possibly auto-reify
// Class requested; try java_class or else return nearest reified class
if (respondsTo("java_class")) {
return callMethod("java_class").toJava(klass);
} else {
for (RubyClass current = this; current != null; current = current.getSuperClass()) {
returnClass = current.getReifiedClass();
if (returnClass != null) return returnClass;
}
}
for (RubyClass current = this; current != null; current = current.getSuperClass()) {
Class reifiedClazz = current.getReifiedClass();
if ( reifiedClazz != null ) return reifiedClazz;
}
// should never fall through, since RubyObject has a reified class
}
@@ -1770,7 +1767,7 @@ public Object toJava(Class klass) {
return this;
}

return super.toJava(klass);
return defaultToJava(klass);
}

/**
10 changes: 6 additions & 4 deletions spec/java_integration/types/coercion_spec.rb
Original file line number Diff line number Diff line change
@@ -728,15 +728,17 @@ def receive_primitive_box(obj)
end
end

it "provides nearest reified class for unreified user classes" do
rubycls = Class.new
expect(rubycls.to_java(cls)).to eq(cls.forName('org.jruby.RubyObject'));
class UserKlass < Object; end

it "reifies user class on-demand" do
expect(klass = UserKlass.to_java(cls)).to be_a java.lang.Class
expect( klass.getSuperclass ).to be cls.forName('org.jruby.RubyObject')
end

it "returns reified class for reified used classes" do
rubycls = Class.new; require 'jruby/core_ext'
rubycls.become_java!
expect(rubycls.to_java(cls)).to eq(JRuby.reference(rubycls).reified_class)
expect(rubycls.to_java(cls)).to be JRuby.reference(rubycls).getReifiedClass
end

it "converts Java proxy classes to their JavaClass/java.lang.Class equivalent" do
17 changes: 16 additions & 1 deletion test/jruby/test_higher_javasupport.rb
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@
require 'rbconfig'
require 'test/unit'
require 'test/jruby/test_helper'
require 'jruby/core_ext'

TopLevelConstantExistsProc = Proc.new do
java_import 'java.lang.String'
@@ -28,6 +27,7 @@ def test_java_int_primitive_assignment

class JRUBY5564; end
def test_reified_class_in_jruby_class_loader
require 'jruby/core_ext'
a_class = JRUBY5564.become_java!(false)

# load the java class from the classloader
@@ -39,6 +39,21 @@ def test_reified_class_in_jruby_class_loader
end
end

class Klass1 < Object
def method1(arg); arg end
end
class Klass2 < Klass1
def self.method2; end
end

def test_passing_a_java_class_auto_reifies
assert_nil Klass2.to_java.getReifiedClass
# previously TestHelper.getClassName(Klass2) returned 'org.jruby.RubyObject'
assert_equal 'rubyobj.TestHigherJavasupport.Klass2', TestHelper.getClassName(Klass2)
assert_not_nil Klass2.to_java.getReifiedClass
assert_not_nil Klass1.to_java.getReifiedClass
end

def test_java_passing_class
assert_equal("java.util.ArrayList", TestHelper.getClassName(ArrayList))
end