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

Commits on Sep 2, 2016

  1. [ji] regression not handling Ruby types implementing 'ext' interfaces

    ... by moving .rb extensions to core Java types over from Ruby (in 9.1) and assuming they will be  called on Java objects Ruby extensions do not work
    
    e.g. a pure Ruby "included" java.lang.Iterable fails to keep its Ruby Enumerable nature working. 
    
    this only concerns enhanced interfaces and happens only if those enhanced methods are being re-used (from Ruby)
    
    reported as #4132
    kares committed Sep 2, 2016
    Copy the full SHA
    974bafb View commit details
  2. Copy the full SHA
    7a7b349 View commit details
8 changes: 4 additions & 4 deletions core/src/main/java/org/jruby/javasupport/JavaUtil.java
Original file line number Diff line number Diff line change
@@ -293,15 +293,15 @@ public static <T> T unwrapJavaObject(final IRubyObject object) {
* @return java object or passed object
* @see JavaUtil#isJavaObject(IRubyObject)
*/
public static Object unwrapIfJavaObject(final IRubyObject object) {
public static <T> T unwrapIfJavaObject(final IRubyObject object) {
if ( object instanceof JavaProxy ) {
return ((JavaProxy) object).getObject();
return (T) ((JavaProxy) object).getObject();
}
final Object unwrap = object.dataGetStruct();
if ( unwrap instanceof JavaObject ) {
return ((JavaObject) unwrap).getValue();
return (T) ((JavaObject) unwrap).getValue();
}
return object;
return (T) object; // assume correct instance
}

@Deprecated // no longer used
12 changes: 6 additions & 6 deletions core/src/main/java/org/jruby/javasupport/ext/JavaIo.java
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;

import static org.jruby.javasupport.JavaUtil.unwrapJavaObject;
import static org.jruby.javasupport.JavaUtil.unwrapIfJavaObject;
import static org.jruby.runtime.Visibility.PUBLIC;

/**
@@ -66,12 +66,12 @@ private static final class InputStreamToIO extends JavaMethod.JavaMethodZeroOrOn

@Override
public RubyIO call(ThreadContext context, IRubyObject self, RubyModule clazz, String name) {
return to_io(context, (java.io.InputStream) unwrapJavaObject(self), null);
return to_io(context, (java.io.InputStream) unwrapIfJavaObject(self), null);
}

@Override
public RubyIO call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject opts) {
return to_io(context, (java.io.InputStream) unwrapJavaObject(self), opts);
return to_io(context, (java.io.InputStream) unwrapIfJavaObject(self), opts);
}

}
@@ -90,12 +90,12 @@ private static final class OutputStreamToIO extends JavaMethod.JavaMethodZeroOrO

@Override
public RubyIO call(ThreadContext context, IRubyObject self, RubyModule clazz, String name) {
return to_io(context, (java.io.OutputStream) unwrapJavaObject(self), null);
return to_io(context, (java.io.OutputStream) unwrapIfJavaObject(self), null);
}

@Override
public RubyIO call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject opts) {
return to_io(context, (java.io.OutputStream) unwrapJavaObject(self), opts);
return to_io(context, (java.io.OutputStream) unwrapIfJavaObject(self), opts);
}

}
@@ -123,7 +123,7 @@ public RubyIO call(ThreadContext context, IRubyObject self, RubyModule clazz, St
}

private static RubyIO to_io(final ThreadContext context, final IRubyObject self, final IRubyObject opts) {
final RubyIO io = new RubyIO(context.runtime, (java.nio.channels.Channel) unwrapJavaObject(self));
final RubyIO io = new RubyIO(context.runtime, (java.nio.channels.Channel) unwrapIfJavaObject(self));
setAutoclose(context, io, opts);
return io;
}
26 changes: 13 additions & 13 deletions core/src/main/java/org/jruby/javasupport/ext/JavaLang.java
Original file line number Diff line number Diff line change
@@ -86,7 +86,7 @@ public static IRubyObject each(final ThreadContext context, final IRubyObject se
if ( ! block.isGiven() ) { // ... Enumerator.new(self, :each)
return runtime.getEnumerator().callMethod("new", self, runtime.newSymbol("each"));
}
java.lang.Iterable iterable = unwrapJavaObject(self);
java.lang.Iterable iterable = unwrapIfJavaObject(self);
java.util.Iterator iterator = iterable.iterator();
while ( iterator.hasNext() ) {
final Object value = iterator.next();
@@ -101,7 +101,7 @@ public static IRubyObject each_with_index(final ThreadContext context, final IRu
if ( ! block.isGiven() ) { // ... Enumerator.new(self, :each)
return runtime.getEnumerator().callMethod("new", self, runtime.newSymbol("each_with_index"));
}
java.lang.Iterable iterable = unwrapJavaObject(self);
java.lang.Iterable iterable = unwrapIfJavaObject(self);
java.util.Iterator iterator = iterable.iterator();
final boolean arity2 = block.getSignature().arity() == Arity.TWO_ARGUMENTS;
int i = 0; while ( iterator.hasNext() ) {
@@ -121,7 +121,7 @@ public static IRubyObject each_with_index(final ThreadContext context, final IRu
public static IRubyObject to_a(final ThreadContext context, final IRubyObject self, final Block block) {
final Ruby runtime = context.runtime;
final RubyArray ary = runtime.newArray();
java.lang.Iterable iterable = unwrapJavaObject(self);
java.lang.Iterable iterable = unwrapIfJavaObject(self);
java.util.Iterator iterator = iterable.iterator();
while ( iterator.hasNext() ) {
final Object value = iterator.next();
@@ -133,7 +133,7 @@ public static IRubyObject to_a(final ThreadContext context, final IRubyObject se
@JRubyMethod(name = "count") // @override Enumerable#count
public static IRubyObject count(final ThreadContext context, final IRubyObject self, final Block block) {
final Ruby runtime = context.runtime;
java.lang.Iterable iterable = unwrapJavaObject(self);
java.lang.Iterable iterable = unwrapIfJavaObject(self);
if ( block.isGiven() ) {
return countBlock(context, iterable.iterator(), block);
}
@@ -158,7 +158,7 @@ static RubyFixnum countBlock(final ThreadContext context, final java.util.Iterat
public static IRubyObject count(final ThreadContext context, final IRubyObject self, final IRubyObject obj, final Block unused) {
// unused block due DescriptorInfo not (yet) supporting if a method receives block and an override doesn't
final Ruby runtime = context.runtime;
java.lang.Iterable iterable = unwrapJavaObject(self);
java.lang.Iterable iterable = unwrapIfJavaObject(self);
int count = 0; for ( java.util.Iterator it = iterable.iterator(); it.hasNext(); ) {
IRubyObject next = convertJavaToUsableRubyObject( runtime, it.next() );
if ( RubyObject.equalInternal(context, next, obj) ) count++;
@@ -180,7 +180,7 @@ static RubyModule define(final Ruby runtime) {

@JRubyMethod(name = "<=>")
public static IRubyObject cmp(final ThreadContext context, final IRubyObject self, final IRubyObject other) {
java.lang.Comparable comparable = unwrapJavaObject(self);
java.lang.Comparable comparable = unwrapIfJavaObject(self);
if ( other.isNil() ) return context.nil;

final java.lang.Object otherComp = unwrapIfJavaObject(other);
@@ -209,7 +209,7 @@ static RubyModule define(final Ruby runtime) {
@JRubyMethod // stackTrace => backtrace
public static IRubyObject backtrace(final ThreadContext context, final IRubyObject self) {
final Ruby runtime = context.runtime;
java.lang.Throwable throwable = unwrapJavaObject(self);
java.lang.Throwable throwable = unwrapIfJavaObject(self);
// TODO instead this should get aligned with NativeException !?!
StackTraceElement[] stackTrace = throwable.getStackTrace();
if ( stackTrace == null ) return context.nil; // never actually happens
@@ -229,7 +229,7 @@ public static IRubyObject set_backtrace(final IRubyObject self, final IRubyObjec

@JRubyMethod
public static IRubyObject message(final ThreadContext context, final IRubyObject self) {
java.lang.Throwable throwable = unwrapJavaObject(self);
java.lang.Throwable throwable = unwrapIfJavaObject(self);
final String msg = throwable.getLocalizedMessage(); // does getMessage
return msg == null ? RubyString.newEmptyString(context.runtime) : RubyString.newString(context.runtime, msg);
}
@@ -241,7 +241,7 @@ public static IRubyObject to_s(final ThreadContext context, final IRubyObject se

@JRubyMethod
public static IRubyObject inspect(final ThreadContext context, final IRubyObject self) {
java.lang.Throwable throwable = unwrapJavaObject(self);
java.lang.Throwable throwable = unwrapIfJavaObject(self);
return RubyString.newString(context.runtime, throwable.toString());
}

@@ -270,7 +270,7 @@ static RubyModule define(final Ruby runtime) {
@JRubyMethod
public static IRubyObject to_proc(final ThreadContext context, final IRubyObject self) {
final Ruby runtime = context.runtime;
final java.lang.Runnable runnable = unwrapJavaObject(self);
final java.lang.Runnable runnable = unwrapIfJavaObject(self);
final Block block = new Block(new RunBody(runtime, runnable));
return new RubyProc(runtime, runtime.getProc(), block, null, -1);
}
@@ -505,21 +505,21 @@ static RubyModule define(final Ruby runtime) {

@JRubyMethod
public static IRubyObject resource_as_url(final ThreadContext context, final IRubyObject self, final IRubyObject name) {
final java.lang.ClassLoader loader = unwrapJavaObject(self);
final java.lang.ClassLoader loader = unwrapIfJavaObject(self);
final String resName = name.convertToString().toString();
return convertJavaToUsableRubyObject(context.runtime, loader.getResource(resName));
}

@JRubyMethod
public static IRubyObject resource_as_stream(final ThreadContext context, final IRubyObject self, final IRubyObject name) {
final java.lang.ClassLoader loader = unwrapJavaObject(self);
final java.lang.ClassLoader loader = unwrapIfJavaObject(self);
final String resName = name.convertToString().toString();
return convertJavaToUsableRubyObject(context.runtime, loader.getResourceAsStream(resName));
}

@JRubyMethod
public static IRubyObject resource_as_string(final ThreadContext context, final IRubyObject self, final IRubyObject name) {
final java.lang.ClassLoader loader = unwrapJavaObject(self);
final java.lang.ClassLoader loader = unwrapIfJavaObject(self);
final String resName = name.convertToString().toString();
return new RubyIO(context.runtime, loader.getResourceAsStream(resName)).read(context);
}
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/javasupport/ext/JavaNet.java
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@
import java.io.IOException;
import java.io.InputStream;

import static org.jruby.javasupport.JavaUtil.unwrapJavaObject;
import static org.jruby.javasupport.JavaUtil.unwrapIfJavaObject;
import static org.jruby.runtime.Visibility.PUBLIC;

/**
@@ -65,7 +65,7 @@ private static final class URLOpenMethod extends JavaMethod.JavaMethodZeroOrNBlo

@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, Block block) {
java.net.URL url = unwrapJavaObject(self);
java.net.URL url = unwrapIfJavaObject(self);
final InputStream stream; final RubyIO io;
try {
stream = url.openStream();
58 changes: 30 additions & 28 deletions core/src/main/java/org/jruby/javasupport/ext/JavaUtil.java
Original file line number Diff line number Diff line change
@@ -45,6 +45,7 @@
import static org.jruby.javasupport.JavaUtil.CAN_SET_ACCESSIBLE;
import static org.jruby.javasupport.JavaUtil.convertJavaArrayToRuby;
import static org.jruby.javasupport.JavaUtil.convertJavaToUsableRubyObject;
import static org.jruby.javasupport.JavaUtil.unwrapIfJavaObject;
import static org.jruby.javasupport.JavaUtil.unwrapJavaObject;
import static org.jruby.runtime.Helpers.invokedynamic;
import static org.jruby.runtime.invokedynamic.MethodNames.OP_EQUAL;
@@ -77,7 +78,7 @@ static RubyModule define(final Ruby runtime) {
@JRubyMethod
public static IRubyObject each(final ThreadContext context, final IRubyObject self, final Block block) {
final Ruby runtime = context.runtime;
java.util.Enumeration enumeration = unwrapJavaObject(self);
java.util.Enumeration enumeration = unwrapIfJavaObject(self);
while ( enumeration.hasMoreElements() ) {
final Object value = enumeration.nextElement();
block.yield(context, convertJavaToUsableRubyObject(runtime, value));
@@ -101,7 +102,7 @@ static RubyModule define(final Ruby runtime) {
@JRubyMethod
public static IRubyObject each(final ThreadContext context, final IRubyObject self, final Block block) {
final Ruby runtime = context.runtime;
java.util.Iterator iterator = unwrapJavaObject(self);
java.util.Iterator iterator = unwrapIfJavaObject(self);
while ( iterator.hasNext() ) {
final Object value = iterator.next();
block.yield(context, convertJavaToUsableRubyObject(runtime, value));
@@ -124,7 +125,7 @@ static RubyModule define(final Ruby runtime) {

@JRubyMethod(name = { "length", "size" })
public static RubyNumeric length(final ThreadContext context, final IRubyObject self) {
return RubyFixnum.int2fix(context.runtime, ((java.util.Collection) unwrapJavaObject(self)).size());
return RubyFixnum.int2fix(context.runtime, ((java.util.Collection) unwrapIfJavaObject(self)).size());
}

@JRubyMethod
@@ -139,20 +140,20 @@ public static IRubyObject each_with_index(final ThreadContext context, final IRu

@JRubyMethod(name = { "include?", "member?" }) // @override Enumerable#include?
public static RubyBoolean include_p(final ThreadContext context, final IRubyObject self, final IRubyObject obj) {
final java.util.Collection coll = unwrapJavaObject(self);
final java.util.Collection coll = unwrapIfJavaObject(self);
return context.runtime.newBoolean( coll.contains( obj.toJava(java.lang.Object.class) ) );
}

// NOTE: first might conflict with some Java types (e.g. java.util.Deque) thus providing a ruby_ alias
@JRubyMethod(name = { "first", "ruby_first" }) // re-def Enumerable#first
public static IRubyObject first(final ThreadContext context, final IRubyObject self) {
final java.util.Collection coll = unwrapJavaObject(self);
final java.util.Collection coll = unwrapIfJavaObject(self);
return coll.isEmpty() ? context.nil : convertJavaToUsableRubyObject(context.runtime, coll.iterator().next());
}

@JRubyMethod(name = { "first", "ruby_first" }) // re-def Enumerable#first(n)
public static IRubyObject first(final ThreadContext context, final IRubyObject self, final IRubyObject count) {
final java.util.Collection coll = unwrapJavaObject(self);
final java.util.Collection coll = unwrapIfJavaObject(self);
int len = count.convertToInteger().getIntValue();
int size = coll.size(); if ( len > size ) len = size;
final Ruby runtime = context.runtime;
@@ -166,14 +167,14 @@ public static IRubyObject first(final ThreadContext context, final IRubyObject s

@JRubyMethod(name = { "<<" })
public static IRubyObject append(final IRubyObject self, final IRubyObject item) {
java.util.Collection coll = unwrapJavaObject(self);
java.util.Collection coll = unwrapIfJavaObject(self);
coll.add( item.toJava(java.lang.Object.class) );
return self;
}

@JRubyMethod(name = { "to_a", "entries" })
public static RubyArray to_a(final ThreadContext context, final IRubyObject self) {
final Object[] array = ((java.util.Collection) unwrapJavaObject(self)).toArray();
final Object[] array = ((java.util.Collection) unwrapIfJavaObject(self)).toArray();
if ( IRubyObject.class.isAssignableFrom(array.getClass().getComponentType()) ) {
return RubyArray.newArrayMayCopy(context.runtime, (IRubyObject[]) array);
}
@@ -184,7 +185,7 @@ public static RubyArray to_a(final ThreadContext context, final IRubyObject self
@JRubyMethod(name = "count") // @override Enumerable#count
public IRubyObject count(final ThreadContext context, final IRubyObject self, final Block block) {
final Ruby runtime = context.runtime;
final java.util.Collection coll = unwrapJavaObject(self);
final java.util.Collection coll = unwrapIfJavaObject(self);
if ( block.isGiven() ) {
return JavaLang.Iterable.countBlock(context, coll.iterator(), block);
}
@@ -199,7 +200,7 @@ public static IRubyObject count(final ThreadContext context, final IRubyObject s
@JRubyMethod(name = "+", required = 1)
public static IRubyObject op_plus(final ThreadContext context, final IRubyObject self, final IRubyObject coll) {
final IRubyObject dup = self.callMethod(context, "dup");
java.util.Collection javaDup = unwrapJavaObject(dup);
java.util.Collection javaDup = unwrapIfJavaObject(dup);
if ( coll instanceof java.util.Collection ) { // e.g. RubyArray
javaDup.addAll((java.util.Collection) coll);
}
@@ -212,7 +213,7 @@ public static IRubyObject op_plus(final ThreadContext context, final IRubyObject
@JRubyMethod(name = "-", required = 1)
public static IRubyObject op_minus(final ThreadContext context, final IRubyObject self, final IRubyObject coll) {
final IRubyObject dup = self.callMethod(context, "dup");
java.util.Collection javaDup = unwrapJavaObject(dup);
java.util.Collection javaDup = unwrapIfJavaObject(dup);
if ( coll instanceof java.util.Collection ) { // e.g. RubyArray
javaDup.removeAll((java.util.Collection) coll);
}
@@ -224,7 +225,7 @@ public static IRubyObject op_minus(final ThreadContext context, final IRubyObjec

@JRubyMethod
public static IRubyObject dup(final ThreadContext context, final IRubyObject self) {
java.util.Collection coll = unwrapJavaObject(self);
java.util.Collection coll = unwrapIfJavaObject(self);
final JavaProxy dup = (JavaProxy) self.dup();
if ( coll == dup.getObject() ) { // not Cloneable
dup.setObject( tryNewEqualInstance(coll) );
@@ -234,7 +235,7 @@ public static IRubyObject dup(final ThreadContext context, final IRubyObject sel

@JRubyMethod
public static IRubyObject clone(final ThreadContext context, final IRubyObject self) {
java.util.Collection coll = unwrapJavaObject(self);
java.util.Collection coll = unwrapIfJavaObject(self);
final JavaProxy dup = (JavaProxy) self.rbClone();
if ( coll == dup.getObject() ) { // not Cloneable
dup.setObject( tryNewEqualInstance(coll) );
@@ -268,7 +269,7 @@ static RubyModule define(final Ruby runtime) {

@JRubyMethod(name = "[]") // act safe on indexes compared to get(idx) throwing IndexOutOfBoundsException
public static IRubyObject aref(final ThreadContext context, final IRubyObject self, final IRubyObject idx) {
final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
final int size = list.size();

if ( idx instanceof RubyRange ) {
@@ -295,7 +296,7 @@ public static IRubyObject aref(final ThreadContext context, final IRubyObject se

if ( len.isNil() ) return aref(context, self, idx);

final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);

int i = idx.convertToInteger().getIntValue();
final int size = list.size();
@@ -313,7 +314,7 @@ public static IRubyObject aref(final ThreadContext context, final IRubyObject se
public static IRubyObject aset(final ThreadContext context, final IRubyObject self,
final IRubyObject idx, final IRubyObject val) {

final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
final int size = list.size();

if ( idx instanceof RubyRange ) {
@@ -345,13 +346,13 @@ public static IRubyObject aset(final ThreadContext context, final IRubyObject se
// NOTE: first conflicts with some Java types e.g. with java.util.LinkedList#getFirst
@JRubyMethod(name = { "first", "ruby_first" }) // re-def Enumerable#first (to skip iterator)
public static IRubyObject first(final ThreadContext context, final IRubyObject self) {
final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
return list.isEmpty() ? context.nil : convertJavaToUsableRubyObject(context.runtime, list.get(0));
}

@JRubyMethod(name = { "first", "ruby_first" }) // #first ext like with array: [1, 2, 3].first(2) == [1, 2]
public static IRubyObject first(final ThreadContext context, final IRubyObject self, final IRubyObject count) {
final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
int len = count.convertToInteger().getIntValue();
int size = list.size(); if ( len > size ) len = size;
return Java.getInstance(context.runtime, list.subList(0, len));
@@ -360,13 +361,13 @@ public static IRubyObject first(final ThreadContext context, final IRubyObject s
// NOTE: first conflicts with some Java types e.g. with java.util.LinkedList#getLast
@JRubyMethod(name = { "last", "ruby_last" }) // like with [].last
public static IRubyObject last(final ThreadContext context, final IRubyObject self) {
final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
return list.isEmpty() ? context.nil : convertJavaToUsableRubyObject(context.runtime, list.get(list.size() - 1));
}

@JRubyMethod(name = { "last", "ruby_last" }) // #last ext like with array: [1, 2, 3].last(2) == [2, 3]
public static IRubyObject last(final ThreadContext context, final IRubyObject self, final IRubyObject count) {
final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
int len = count.convertToInteger().getIntValue();
int size = list.size();
int start = size - len; if ( start < 0 ) start = 0;
@@ -381,7 +382,7 @@ public static IRubyObject index(final ThreadContext context, final IRubyObject s
return runtime.getEnumerator().callMethod("new", self, runtime.newSymbol("index"));
}

final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
if ( list instanceof java.util.RandomAccess ) {
for ( int i = 0; i < list.size(); i++ ) {
IRubyObject ret = block.yield(context, convertJavaToUsableRubyObject(runtime, list.get(i)));
@@ -404,7 +405,7 @@ public static IRubyObject index(final ThreadContext context, final IRubyObject s
final Block ignoredBlock) {

final Ruby runtime = context.runtime;
final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
if ( list instanceof java.util.RandomAccess ) {
for ( int i = 0; i < list.size(); i++ ) {
final Object elem = list.get(i);
@@ -434,7 +435,7 @@ public static IRubyObject rindex(final ThreadContext context, final IRubyObject
return runtime.getEnumerator().callMethod("new", self, runtime.newSymbol("rindex"));
}

final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
if ( list instanceof java.util.RandomAccess ) {
for ( int i = list.size() - 1; i >= 0; i-- ) {
IRubyObject ret = block.yield(context, convertJavaToUsableRubyObject(runtime, list.get(i)));
@@ -458,7 +459,7 @@ public static IRubyObject rindex(final ThreadContext context, final IRubyObject
final Block ignoredBlock) {

final Ruby runtime = context.runtime;
final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
if ( list instanceof java.util.RandomAccess ) {
for ( int i = list.size() - 1; i >= 0; i-- ) {
final Object elem = list.get(i);
@@ -486,7 +487,7 @@ public static IRubyObject rindex(final ThreadContext context, final IRubyObject
public static RubyArray to_a(final ThreadContext context, final IRubyObject self) {
// re-implemented to skip an intermediate toArray() conversion :
final Ruby runtime = context.runtime;
final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
final IRubyObject[] array = new IRubyObject[ list.size() ];
int i = 0; for ( Object elem : list ) {
array[i++] = convertJavaToUsableRubyObject(runtime, elem);;
@@ -497,8 +498,9 @@ public static RubyArray to_a(final ThreadContext context, final IRubyObject self
@SuppressWarnings("unchecked")
@JRubyMethod(name = { "sort", "ruby_sort" }) // name conflict on Java 8, but users can alias if they want
public static IRubyObject sort(final ThreadContext context, final IRubyObject self, final Block block) {
java.util.List dupList = unwrapJavaObject(self.callMethod(context, "dup"));
if ( dupList == unwrapJavaObject(self) ) {
final IRubyObject dup = self.callMethod(context, "dup");
java.util.List dupList = unwrapIfJavaObject(dup);
if ( dup == self ) {
// just in case dup failed - make sure we do not use the same list :
dupList = new java.util.ArrayList(dupList);
// NOTE: prior to JRuby 9.1 this method always returned an ArrayList
@@ -510,7 +512,7 @@ public static IRubyObject sort(final ThreadContext context, final IRubyObject se
@SuppressWarnings("unchecked")
@JRubyMethod(name = "sort!")
public static IRubyObject sort_bang(final ThreadContext context, final IRubyObject self, final Block block) {
final java.util.List list = unwrapJavaObject(self);
final java.util.List list = unwrapIfJavaObject(self);
sortImpl(context, list, block);
return self;
}
21 changes: 21 additions & 0 deletions spec/java_integration/addons/throwable_spec.rb
Original file line number Diff line number Diff line change
@@ -121,4 +121,25 @@ def x.foo
end
expect(i).to eq 2
end

describe 'Ruby sub-class' do

class RubyThrowable < java.lang.Exception

def initialize(msg) super(); @msg = msg end

def getMessage; @msg end
end

it 'has Throwable extensions' do
throwable = RubyThrowable.new 'foo'
expect( throwable.backtrace ).to_not be nil
expect( throwable.backtrace ).to_not be_empty

expect( throwable.message ).to eql 'foo'
expect( throwable.to_s ).to eql 'foo'
end

end

end
49 changes: 49 additions & 0 deletions spec/java_integration/extensions/collection_spec.rb
Original file line number Diff line number Diff line change
@@ -222,4 +222,53 @@ def to_ary
expect(cdr).to eq(:y)
end
end

describe 'Ruby class' do

require 'delegate'

class RubyCollectionWrapper < Delegator
include java.util.Collection

def initialize(coll) @coll = coll end

def size; @coll.empty? ? -1 : @coll.size end

def __getobj__ ; @coll end
end

it 'reports expected size' do
obj = Object.new
def obj.empty?; true end

wrapper = RubyCollectionWrapper.new(obj)
expect( wrapper.size ).to eql -1

wrapper = RubyCollectionWrapper.new java.util.Collections::EMPTY_SET
expect( wrapper.size ).to eql -1

wrapper = RubyCollectionWrapper.new coll = java.util.LinkedList.new
coll.add 1; coll.add 2
wrapper.add 3
expect( wrapper.size ).to eql 3
end

it 'is usable as a Collection' do
wrapper = RubyCollectionWrapper.new coll = java.util.LinkedHashSet.new([1, 2])
java.util.Collections.addAll wrapper, 1, 2, 3
expect( wrapper.size ).to eql 3
expect( wrapper.toString ).to eql '[1, 2, 3]'
end

it 'iterates as an Enumerable' do
wrapper = RubyCollectionWrapper.new coll = java.util.LinkedHashSet.new([1, 2])
elems = [] ; wrapper.map { |el| elems << el * 3 }
expect( elems ).to eql [3, 6]

elems = [] ; wrapper.each_with_index { |el, i| elems << [el, i] }
expect( elems ).to eql [[1, 0], [2, 1]]
end

end

end
23 changes: 23 additions & 0 deletions spec/java_integration/extensions/iterable_spec.rb
Original file line number Diff line number Diff line change
@@ -92,4 +92,27 @@ def iterate_path(path)
res
end

describe 'Ruby class' do

class RubyIterableWrapper
include java.lang.Iterable

def initialize(coll) @coll = coll end

def iterator; @coll.iterator end

end

it 'iterates as an Enumerable' do
wrapper = RubyIterableWrapper.new coll = java.util.ArrayList.new([1, 2, 3])
elems = [] ; wrapper.map { |el| elems << el + 1 }
expect( elems ).to eql [2, 3, 4]
expect( wrapper.to_a ).to eql [1, 2, 3]

elems = [] ; wrapper.each_with_index { |el, i| elems << [el, i] }
expect( elems ).to eql [[1, 0], [2, 1], [3, 2]]
end

end

end