Skip to content
Browse files

Fix re-coercion of a previously interface-duck-typed Ruby object to j…

…ava.lang.Object; it should from then on return the interface impl object. Broke jruby-rack because the assignable check continued returning RubyObject even if there was a contained duck-typed impl.
  • Loading branch information...
1 parent f39260c commit c248e3ade198fb26469513bfe8221ee81cf5fd67 @headius headius committed Apr 26, 2010
View
4 spec/java_integration/fixtures/UsesSingleMethodInterface.java
@@ -74,4 +74,8 @@ public static int hashCode(Object obj) {
public static String toString(Object obj) {
return obj.toString();
}
+
+ public static Class getClass(Object obj) {
+ return obj.getClass();
+ }
}
View
18 spec/java_integration/interfaces/implementation_spec.rb
@@ -182,6 +182,24 @@ def callIt
callable.should_receive(:call).and_return result
UsesSingleMethodInterface.new.callIt3(callable).should == result
end
+
+ it "coerces to that interface after duck-typed implementation has happened" do
+ callable = mock "SingleMethodInterfaceImpl"
+ callable.should_receive(:callIt).and_return :callIt
+ UsesSingleMethodInterface.callIt(callable).should == :callIt
+
+ # receives Object, but should return the coerced impl
+ cls = UsesSingleMethodInterface.getClass(callable)
+
+ # pull out interfaces from the resulting class
+ interfaces = []
+ while cls
+ interfaces.concat(cls.interfaces)
+ cls = cls.superclass
+ end
+
+ interfaces.should include(SingleMethodInterface.java_class)
+ end
end
describe "A bean-like Java interface" do
View
14 src/org/jruby/RubyBasicObject.java
@@ -751,9 +751,7 @@ public Object toJava(Class target) {
// for callers that unconditionally pass null retval type (JRUBY-4737)
if (target == void.class) return null;
- if (target.isAssignableFrom(getClass())) {
- return this;
- } else if (dataGetStruct() instanceof JavaObject) {
+ if (dataGetStruct() instanceof JavaObject) {
// for interface impls
JavaObject innerWrapper = (JavaObject)dataGetStruct();
@@ -765,12 +763,12 @@ public Object toJava(Class target) {
return innerWrapper.getValue();
}
- } else {
- if (JavaUtil.isDuckTypeConvertable(getClass(), target)) {
- if (!respondsTo("java_object")) {
- return JavaUtil.convertProcToInterface(getRuntime().getCurrentContext(), this, target);
- }
+ } else if (JavaUtil.isDuckTypeConvertable(getClass(), target)) {
+ if (!respondsTo("java_object")) {
+ return JavaUtil.convertProcToInterface(getRuntime().getCurrentContext(), this, target);
}
+ } else if (target.isAssignableFrom(getClass())) {
+ return this;
}
throw getRuntime().newTypeError("cannot convert instance of " + getClass() + " to " + target);

0 comments on commit c248e3a

Please sign in to comment.
Something went wrong with that request. Please try again.