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

Commits on Sep 15, 2015

  1. Copy the full SHA
    bdaa82b View commit details
  2. Copy the full SHA
    be6a2bf View commit details
  3. getName for JavaMethod

    kares committed Sep 15, 2015
    Copy the full SHA
    4e50bc7 View commit details
  4. Copy the full SHA
    41c9a22 View commit details
  5. Copy the full SHA
    bc6160b View commit details
  6. [ji] var-args Java method is a valid match even if the last parameter…

    … receives no arg
    
    `method(String, Object...)` will now be considered with a `method('foo')` call
    
    fixes #3279
    kares committed Sep 15, 2015
    Copy the full SHA
    e85df14 View commit details
  7. Copy the full SHA
    6544ac0 View commit details
  8. Copy the full SHA
    49061ca View commit details
  9. Copy the full SHA
    013e288 View commit details
  10. un-used local var assingment

    kares committed Sep 15, 2015
    Copy the full SHA
    3e1061e View commit details
  11. Copy the full SHA
    dcb99b9 View commit details
31 changes: 15 additions & 16 deletions core/src/main/java/org/jruby/java/dispatch/CallableSelector.java
Original file line number Diff line number Diff line change
@@ -529,7 +529,7 @@ public boolean match(Class type, IRubyObject arg) {
};

private static boolean exactMatch(ParameterTypes paramTypes, IRubyObject... args) {
Class[] types = paramTypes.getParameterTypes();
final Class[] types = paramTypes.getParameterTypes();

if (args.length != types.length) return false;

@@ -542,7 +542,7 @@ private static boolean exactMatch(ParameterTypes paramTypes, IRubyObject... args
}

private static boolean assignableAndPrimitivable(ParameterTypes paramTypes, IRubyObject... args) {
Class[] types = paramTypes.getParameterTypes();
final Class[] types = paramTypes.getParameterTypes();

if (args.length != types.length) return false;

@@ -555,7 +555,7 @@ private static boolean assignableAndPrimitivable(ParameterTypes paramTypes, IRub
}

private static boolean assignableOrDuckable(ParameterTypes paramTypes, IRubyObject... args) {
Class[] types = paramTypes.getParameterTypes();
final Class[] types = paramTypes.getParameterTypes();

if (args.length != types.length) return false;

@@ -568,31 +568,30 @@ private static boolean assignableOrDuckable(ParameterTypes paramTypes, IRubyObje
}

private static boolean assignableAndPrimitivableWithVarargs(ParameterTypes paramTypes, IRubyObject... args) {
// bail out if this is not a varargs method
if (!paramTypes.isVarArgs()) return false;
if ( ! paramTypes.isVarArgs() ) return false; // bail out if this is not a varargs method

Class[] types = paramTypes.getParameterTypes();

Class varArgArrayType = types[types.length - 1];
Class varArgType = varArgArrayType.getComponentType();
final Class[] types = paramTypes.getParameterTypes();

// if there's no args, we only match when there's just varargs
if ( args.length == 0 ) return types.length <= 1;

// dig out as many trailing args as will fit, ensuring they match varargs type
int nonVarargs = types.length - 1;
for (int i = args.length - 1; i >= nonVarargs; i--) {
if (!(ASSIGNABLE.match(varArgType, args[i]) || PRIMITIVABLE.match(varArgType, args[i]))) {
final int last = types.length - 1;

if ( args.length < last ) return false; // can't match - paramTypes method is not usable!
for ( int i = 0; i < last; i++ ) { // first check non-vararg argument types match
if (!(ASSIGNABLE.match(types[i], args[i]) || PRIMITIVABLE.match(types[i], args[i]))) {
return false;
}
}

// check remaining args
for (int i = 0; i < nonVarargs; i++) {
if (!(ASSIGNABLE.match(types[i], args[i]) || PRIMITIVABLE.match(types[i], args[i]))) {
final Class varArgType = types[last].getComponentType();
// dig out as many trailing args as will fit, ensuring they match varargs type
for ( int i = last; i < args.length; i++ ) {
if (!(ASSIGNABLE.match(varArgType, args[i]) || PRIMITIVABLE.match(varArgType, args[i]))) {
return false;
}
}

return true;
}

Original file line number Diff line number Diff line change
@@ -16,9 +16,7 @@
public final class ConstructorInvoker extends RubyToJavaInvoker {

public ConstructorInvoker(RubyModule host, List<Constructor> ctors) {
super(host, ctors.toArray(new Constructor[ctors.size()]));

trySetAccessible(getAccessibleObjects());
super(host, setAccessible( ctors.toArray(new Constructor[ctors.size()]) ) );
}

@Override
6 changes: 2 additions & 4 deletions core/src/main/java/org/jruby/java/invokers/MethodInvoker.java
Original file line number Diff line number Diff line change
@@ -11,13 +11,11 @@
public abstract class MethodInvoker extends RubyToJavaInvoker {

MethodInvoker(RubyModule host, List<Method> methods) {
super(host, methods.toArray(new Method[methods.size()]));
trySetAccessible(getAccessibleObjects());
super(host, setAccessible( methods.toArray(new Method[methods.size()]) ) );
}

MethodInvoker(RubyModule host, Method method) {
super(host, new Method[] { method });
trySetAccessible(getAccessibleObjects());
super(host, setAccessible(method));
}

@Override
113 changes: 82 additions & 31 deletions core/src/main/java/org/jruby/java/invokers/RubyToJavaInvoker.java
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@
import org.jruby.Ruby;
import org.jruby.RubyModule;
import org.jruby.exceptions.RaiseException;
import org.jruby.internal.runtime.methods.CallConfiguration;
import org.jruby.internal.runtime.methods.JavaMethod;
import org.jruby.java.dispatch.CallableSelector;
import org.jruby.java.proxies.ArrayJavaProxy;
@@ -33,48 +32,73 @@ public abstract class RubyToJavaInvoker extends JavaMethod {
protected final JavaCallable javaCallable; /* null if multiple callable members */
protected final JavaCallable[][] javaCallables; /* != null if javaCallable == null */
protected final JavaCallable[] javaVarargsCallables; /* != null if any var args callables */
protected final int minVarargsArity;

// in case multiple callables (overloaded Java method - same name different args)
// for the invoker exists CallableSelector caches resolution based on args here
final IntHashMap<JavaCallable> cache;

private final Ruby runtime;
private final Member[] members;

RubyToJavaInvoker(RubyModule host, Member member) {
super(host, Visibility.PUBLIC);
this.runtime = host.getRuntime();

final JavaCallable callable;
JavaCallable[] varargsCallables = null;
int minVarArgsArity = -1;

callable = createCallable(runtime, member);
int minArity = callable.getArity();
if ( callable.isVarArgs() ) { // TODO does it need to happen?
varargsCallables = createCallableArray(callable);
minVarArgsArity = getMemberArity(member) - 1;
}

cache = NULL_CACHE; // if there's a single callable - matching (and thus the cache) won't be used

this.javaCallable = callable;
this.javaCallables = null;
this.javaVarargsCallables = varargsCallables;

setArity(minArity, minArity, minVarArgsArity);
setupNativeCall();
}

RubyToJavaInvoker(RubyModule host, Member[] members) {
super(host, Visibility.PUBLIC, CallConfiguration.FrameNoneScopeNone);
this.members = members;
super(host, Visibility.PUBLIC);
this.runtime = host.getRuntime();
// we set all Java methods to optional, since many/most have overloads
setArity(Arity.OPTIONAL);

// initialize all the callables for this method
final JavaCallable callable;
final JavaCallable[][] callables;
JavaCallable[] varargsCallables = null;
int varArgsArity = Integer.MAX_VALUE;
int minVarArgsArity = -1; int maxArity, minArity;

final int length = members.length;
if ( length == 1 ) {
callable = createCallable(runtime, members[0]);
maxArity = minArity = callable.getArity();
if ( callable.isVarArgs() ) {
varargsCallables = createCallableArray(callable);
minVarArgsArity = getMemberArity(members[0]) - 1;
}
callables = null;

cache = NULL_CACHE; // if there's a single callable - matching (and thus the cache) won't be used
}
else {
callable = null;
callable = null; maxArity = -1; minArity = Integer.MAX_VALUE;

IntHashMap<ArrayList<JavaCallable>> arityMap = new IntHashMap<ArrayList<JavaCallable>>(length, 1);

ArrayList<JavaCallable> varArgs = null; int maxArity = 0;
ArrayList<JavaCallable> varArgs = null;
for ( int i = 0; i < length; i++ ) {
final Member method = members[i];
final int currentArity = getMemberParameterTypes(method).length;
final int currentArity = getMemberArity(method);
maxArity = Math.max(currentArity, maxArity);
minArity = Math.min(currentArity, minArity);

final JavaCallable javaMethod = createCallable(runtime, method);

ArrayList<JavaCallable> methodsForArity = arityMap.get(currentArity);
if (methodsForArity == null) {
@@ -84,14 +108,22 @@ public abstract class RubyToJavaInvoker extends JavaMethod {
methodsForArity = new ArrayList<JavaCallable>(length);
arityMap.put(currentArity, methodsForArity);
}

final JavaCallable javaMethod = createCallable(runtime, method);
methodsForArity.add(javaMethod);

if ( isMemberVarArgs(method) ) {
varArgsArity = Math.min(currentArity - 1, varArgsArity);
if ( javaMethod.isVarArgs() ) {
final int usableArity = currentArity - 1;
// (String, Object...) has usable arity == 1 ... (String)
if ((methodsForArity = arityMap.get(usableArity)) == null) {
methodsForArity = new ArrayList<JavaCallable>(length);
arityMap.put(usableArity, methodsForArity);
}
methodsForArity.add(javaMethod);

if (varArgs == null) varArgs = new ArrayList<JavaCallable>(length);
varArgs.add(javaMethod);

if ( minVarArgsArity == -1 ) minVarArgsArity = Integer.MAX_VALUE;
minVarArgsArity = Math.min(usableArity, minVarArgsArity);
}
}

@@ -113,9 +145,26 @@ public abstract class RubyToJavaInvoker extends JavaMethod {
this.javaCallable = callable;
this.javaCallables = callables;
this.javaVarargsCallables = varargsCallables;
this.minVarargsArity = varArgsArity;

// if it's not overloaded, set up a NativeCall
setArity(minArity, maxArity, minVarArgsArity);
setupNativeCall();
}

private void setArity(final int minArity, final int maxArity, final int minVarArgsArity) {
if ( minVarArgsArity == -1 ) { // no var-args
if ( minArity == maxArity ) {
setArity( Arity.fixed(minArity) );
}
else { // multiple overloads
setArity( Arity.required(minArity) ); // but <= maxArity
}
}
else {
setArity( Arity.required(minVarArgsArity < minArity ? minVarArgsArity : minArity) );
}
}

final void setupNativeCall() { // if it's not overloaded, set up a NativeCall
if (javaCallable != null) {
// no constructor support yet
if (javaCallable instanceof org.jruby.javasupport.JavaMethod) {
@@ -142,14 +191,6 @@ private boolean setNativeCallIfPublic(final Method method) {
return false;
}

protected final Member[] getMembers() {
return members;
}

protected AccessibleObject[] getAccessibleObjects() {
return (AccessibleObject[]) getMembers();
}

protected abstract JavaCallable createCallable(Ruby runtime, Member member);

protected abstract JavaCallable[] createCallableArray(JavaCallable callable);
@@ -160,11 +201,12 @@ protected AccessibleObject[] getAccessibleObjects() {

protected abstract Class[] getMemberParameterTypes(Member member);

@Deprecated // no longer used!
protected abstract boolean isMemberVarArgs(Member member);

//final int getMemberArity(Member member) {
// return getMemberParameterTypes(member).length;
//}
final int getMemberArity(Member member) {
return getMemberParameterTypes(member).length;
}

public static Object[] convertArguments(final ParameterTypes method, final IRubyObject[] args) {
final Class<?>[] paramTypes = method.getParameterTypes();
@@ -213,11 +255,20 @@ static JavaProxy castJavaProxy(final IRubyObject self) {
return (JavaProxy) self;
}

static void trySetAccessible(AccessibleObject... accesibles) {
static <T extends AccessibleObject> T setAccessible(T accessible) {
if ( ! Ruby.isSecurityRestricted() ) {
try { accessible.setAccessible(true); }
catch (SecurityException e) {}
}
return accessible;
}

static <T extends AccessibleObject> T[] setAccessible(T[] accessibles) {
if ( ! Ruby.isSecurityRestricted() ) {
try { AccessibleObject.setAccessible(accesibles, true); }
catch(SecurityException e) {}
try { AccessibleObject.setAccessible(accessibles, true); }
catch (SecurityException e) {}
}
return accessibles;
}

protected JavaCallable findCallable(IRubyObject self, String name, IRubyObject[] args, final int arity) {
4 changes: 4 additions & 0 deletions core/src/main/java/org/jruby/javasupport/JavaMethod.java
Original file line number Diff line number Diff line change
@@ -526,6 +526,10 @@ private IRubyObject convertReturn(Object result) {
// return parameterTypes;
//}

public String getName() {
return method.getName();
}

@Override
public Class<?>[] getExceptionTypes() {
return method.getExceptionTypes();
320 changes: 154 additions & 166 deletions core/src/main/java/org/jruby/runtime/ThreadContext.java

Large diffs are not rendered by default.

30 changes: 16 additions & 14 deletions core/src/main/java/org/jruby/runtime/backtrace/TraceType.java
Original file line number Diff line number Diff line change
@@ -246,16 +246,17 @@ public void renderBacktrace(RubyStackTraceElement[] elts, StringBuilder buffer,
}

protected static String printBacktraceMRI(RubyException exception, boolean console) {
Ruby runtime = exception.getRuntime();
ThreadContext context = runtime.getCurrentContext();
IRubyObject backtrace = exception.callMethod(context, "backtrace");
final Ruby runtime = exception.getRuntime();
final ThreadContext context = runtime.getCurrentContext();

final IRubyObject backtrace = exception.callMethod(context, "backtrace");

ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream errorStream = new PrintStream(baos);
boolean printedPosition = false;
if (backtrace.isNil() || !(backtrace instanceof RubyArray)) {
if (context.getFile() != null && context.getFile().length() > 0) {
errorStream.print(context.getFile() + ":" + context.getLine());
errorStream.print(context.getFile() + ':' + context.getLine());
printedPosition = true;
} else {
errorStream.print(context.getLine());
@@ -277,11 +278,10 @@ protected static String printBacktraceMRI(RubyException exception, boolean conso
RubyClass type = exception.getMetaClass();
String info = exception.toString();

if (printedPosition) errorStream.print(": ");

if (type == runtime.getRuntimeError() && (info == null || info.length() == 0)) {
errorStream.print(": unhandled exception\n");
} else {
if (printedPosition) errorStream.print(": ");
String path = type.getName();

if (info.length() == 0) {
@@ -292,9 +292,10 @@ protected static String printBacktraceMRI(RubyException exception, boolean conso
}

String tail = null;
if (info.indexOf("\n") != -1) {
tail = info.substring(info.indexOf("\n") + 1);
info = info.substring(0, info.indexOf("\n"));
int idx = info.indexOf('\n');
if (idx != -1) {
tail = info.substring(idx + 1);
info = info.substring(0, idx);
}

errorStream.print(info);
@@ -320,13 +321,14 @@ protected static String printBacktraceMRI(RubyException exception, boolean conso
private static final String CLEAR_COLOR = "\033[0m";

protected static String printBacktraceJRuby(RubyException exception, boolean console) {
Ruby runtime = exception.getRuntime();
final Ruby runtime = exception.getRuntime();
final ThreadContext context = runtime.getCurrentContext();

StringBuilder buffer = new StringBuilder();
boolean color = console && runtime.getInstanceConfig().getBacktraceColor();

// exception line
String message = exception.message(runtime.getCurrentContext()).toString();
String message = exception.message(context).toString();
if (exception.getMetaClass() == runtime.getRuntimeError() && message.length() == 0) {
message = "No current exception";
}
@@ -412,7 +414,7 @@ public static IRubyObject generateMRIBacktrace(Ruby runtime, RubyStackTraceEleme
for (int i = 0; i < trace.length; i++) {
RubyStackTraceElement element = trace[i];

RubyString str = RubyString.newString(runtime, element.getFileName() + ":" + element.getLineNumber() + ":in `" + element.getMethodName() + "'");
RubyString str = RubyString.newString(runtime, element.getFileName() + ':' + element.getLineNumber() + ":in `" + element.getMethodName() + "'");
traceArray.append(str);
}

@@ -422,10 +424,10 @@ public static IRubyObject generateMRIBacktrace(Ruby runtime, RubyStackTraceEleme
private static void printErrorPos(ThreadContext context, PrintStream errorStream) {
if (context.getFile() != null && context.getFile().length() > 0) {
if (context.getFrameName() != null) {
errorStream.print(context.getFile() + ":" + context.getLine());
errorStream.print(context.getFile() + ':' + context.getLine());
errorStream.print(":in '" + context.getFrameName() + '\'');
} else if (context.getLine() != 0) {
errorStream.print(context.getFile() + ":" + context.getLine());
errorStream.print(context.getFile() + ':' + context.getLine());
} else {
errorStream.print(context.getFile());
}
37 changes: 29 additions & 8 deletions spec/java_integration/methods/basics_spec.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,39 @@
require File.dirname(__FILE__) + "/../spec_helper"

describe "Java instance methods" do
it "should have Ruby arity -1" do
expect do
expect(java.lang.String.instance_method(:toString).arity).to eq(-1)
end.not_to raise_error
it "have correct (fixed) arity" do
expect(java.lang.String.instance_method(:length).arity).to eq(0)
expect(java.lang.String.instance_method(:toString).arity).to eq(0)
expect(java.lang.String.instance_method(:charAt).arity).to eq(1)

expect(java.lang.String.instance_method(:replace).arity).to eq(2)
end
it "(overloads) have correct arity" do
expect(java.lang.String.instance_method(:lastIndexOf).arity).to eq(-2)
expect(java.lang.String.instance_method(:toLowerCase).arity).to eq(-1)

expect(java.lang.StringBuilder.instance_method(:append).arity).to eq(-2)
expect(java.lang.StringBuilder.instance_method(:insert).arity).to eq(-3)

expect(java.util.ArrayList.instance_method(:toArray).arity).to eq(-1)
end
end

describe "Java static methods" do
it "should have Ruby arity -1" do
expect do
expect(java.lang.System.method(:getProperty).arity).to eq(-1)
end.not_to raise_error
it "have correct arity" do
expect(java.lang.System.method(:exit).arity).to eq(1)
expect(java.lang.System.method(:gc).arity).to eq(0)
expect(java.lang.System.method(:arraycopy).arity).to eq(5)

expect(java.util.Arrays.method(:asList).arity).to eq(-1) # (T... a)
end
it "(overloads) have correct arity" do
expect(java.lang.System.method(:getProperty).arity).to eq(-2)
# format(String format, Object... args)
# format(Locale l, String format, Object... args)
expect(java.lang.String.method(:format).arity).to eq(-2)
# not fixed due valueOf(char[] data, int offset, int count)
expect(java.lang.String.method(:valueOf).arity).to eq(-2)
end
end

50 changes: 27 additions & 23 deletions spec/java_integration/methods/dispatch_spec.rb
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@
expect(CoreTypeMethods.getType(1.0, obj)).to eq("double,object")
expect(CoreTypeMethods.getType(1.0, obj, obj)).to eq("double,object,object")
expect(CoreTypeMethods.getType(1.0, obj, obj, obj)).to eq("double,object,object,object")

obj = "foo"
expect(CoreTypeMethods.getType(1)).to eq("long")
expect(CoreTypeMethods.getType(1, obj)).to eq("long,string")
@@ -34,14 +34,15 @@
expect(CoreTypeMethods.getType(1.0, obj)).to eq("double,string")
expect(CoreTypeMethods.getType(1.0, obj, obj)).to eq("double,string,string")
expect(CoreTypeMethods.getType(1.0, obj, obj, obj)).to eq("double,string,string,string")
expect(CoreTypeMethods.getType(1.0, obj.to_java)).to eq("double,string")
end

it "should raise error when called with too many args" do
expect do
obj = java.lang.Integer.new(1)
CoreTypeMethods.getType(1, obj, obj, obj, obj)
end.to raise_error(ArgumentError)

expect do
obj = "foo"
CoreTypeMethods.getType(1, obj, obj, obj, obj)
@@ -68,7 +69,7 @@
end
it "should be of the correct type" do
expect(@return_value).to be_an_instance_of(StaticMethodSelection)
end
end
end

describe "An overloaded Java instance method" do
@@ -83,7 +84,7 @@
expect(ctm.getTypeInstance(1.0, obj)).to eq("double,object")
expect(ctm.getTypeInstance(1.0, obj, obj)).to eq("double,object,object")
expect(ctm.getTypeInstance(1.0, obj, obj, obj)).to eq("double,object,object,object")

obj = "foo"
ctm = CoreTypeMethods.new
expect(ctm.getTypeInstance(1)).to eq("long")
@@ -101,7 +102,7 @@
obj = java.lang.Integer.new(1)
CoreTypeMethods.new.getTypeInstance(1, obj, obj, obj, obj)
end.to raise_error(ArgumentError)

expect do
obj = "foo"
CoreTypeMethods.new.getTypeInstance(1, obj, obj, obj, obj)
@@ -159,16 +160,16 @@
obj = ClassWithVarargs.new('foo', 'bar', 'baz', 1, 2, 3, 4)
expect(obj.constructor).to eq("3: [1, 2, 3, 4]")

skip("needs better type-driven ranking of overloads") do
obj = ClassWithVarargs.new('foo')
expect(obj.constructor).to eq("1: []")
#skip("needs better type-driven ranking of overloads") do
obj = ClassWithVarargs.new('foo')
expect(obj.constructor).to eq("1: []")

obj = ClassWithVarargs.new('foo', 'bar')
expect(obj.constructor).to eq("2: []")
obj = ClassWithVarargs.new('foo', 'bar')
expect(obj.constructor).to eq("2: []")

obj = ClassWithVarargs.new('foo', 'bar', 'baz')
expect(obj.constructor).to eq("3: []")
end
obj = ClassWithVarargs.new('foo', 'bar', 'baz')
expect(obj.constructor).to eq("3: []")
#end
end

it "should be callable with an array" do
@@ -204,11 +205,11 @@
expect(obj.varargs('foo', 'bar', 'baz', 1, 2, 3)).to eq("3: [1, 2, 3]");
expect(obj.varargs('foo', 'bar', 'baz', 1, 2, 3, 4)).to eq("3: [1, 2, 3, 4]");

skip("needs better type-driven ranking of overloads") do
expect(obj.varargs('foo')).to eq("1: []")
expect(obj.varargs('foo', 'bar')).to eq("2: []")
expect(obj.varargs('foo', 'bar', 'baz')).to eq("3: []")
end
#skip("needs better type-driven ranking of overloads") do
expect(obj.varargs('foo')).to eq("1: []")
expect(obj.varargs('foo', 'bar')).to eq("2: []")
expect(obj.varargs('foo', 'bar', 'baz')).to eq("3: []")
#end
end

it "should be callable with an array" do
@@ -243,11 +244,14 @@
expect(ClassWithVarargs.varargs_static('foo', 'bar', 'baz', 1, 2, 3)).to eq("3: [1, 2, 3]");
expect(ClassWithVarargs.varargs_static('foo', 'bar', 'baz', 1, 2, 3, 4)).to eq("3: [1, 2, 3, 4]");

skip("needs better type-driven ranking of overloads") do
expect(ClassWithVarargs.varargs_static('foo')).to eq("1: []")
expect(ClassWithVarargs.varargs_static('foo', 'bar')).to eq("2: []")
expect(ClassWithVarargs.varargs_static('foo', 'bar')).to eq("3: []")
end
#skip("needs better type-driven ranking of overloads") do
expect(ClassWithVarargs.varargs_static('foo')).to eq("1: []")
expect(ClassWithVarargs.varargs_static('foo', 'bar')).to eq("2: []")
expect(ClassWithVarargs.varargs_static('foo', 'bar', 'baz')).to eq("3: []")
#end
expect(ClassWithVarargs.varargs_static('foo'.to_java)).to eq("1: []")
expect(ClassWithVarargs.varargs_static('foo'.to_java, 'bar')).to eq("2: []")
expect(ClassWithVarargs.varargs_static('foo'.to_java, 'bar'.to_java)).to eq("2: []")
end

it "should be callable with an array" do
16 changes: 8 additions & 8 deletions spec/java_integration/types/extension_spec.rb
Original file line number Diff line number Diff line change
@@ -98,7 +98,7 @@ def size; 100; end
end.new

expect(ReceivesArrayList.new.receive_array_list(my_arraylist)).to eq(100)

thread = java.lang.Thread.new(my_arraylist)
thread.start
thread.join
@@ -121,19 +121,19 @@ def initialize
expect(my_arraylist.class.superclass).to eq(java.util.ArrayList)
expect(my_arraylist.to_java).to eq(my_arraylist)
end

it "raises argument error when super does not match superclass constructor arity" do
my_arraylist_cls = Class.new(java.util.ArrayList) do
def initialize
super('foo', 'foo', 'foo')
end
end

expect do
my_arraylist_cls.new
end.to raise_error(ArgumentError)
end

# JRUBY-4788
it "raises argument error if no matching arity method has been implemented on class or superclass" do
my_cwam_cls = Class.new(ClassWithAbstractMethods) do
@@ -143,12 +143,12 @@ def foo1
end
end
my_cwam = my_cwam_cls.new

expect do
ClassWithAbstractMethods.callFoo1(my_cwam, "ok")
end.to raise_error(ArgumentError)
end

it "dispatches to other-arity superclass methods if arities mismatch" do
my_cwam_cls = Class.new(ClassWithAbstractMethods) do
# arity should be 2, mismatch is intentional
@@ -157,15 +157,15 @@ def foo2(arg)
end
end
my_cwam = my_cwam_cls.new

expect(ClassWithAbstractMethods.callFoo2(my_cwam, "x", "y")).to eq("ok")
end
end

describe "A final Java class" do
it "should not be allowed as a superclass" do
expect do
substring = Class.new(java.lang.String)
Class.new(java.lang.String)
end.to raise_error(TypeError)
end
end
2 changes: 1 addition & 1 deletion test/jruby/test_higher_javasupport.rb
Original file line number Diff line number Diff line change
@@ -1313,7 +1313,7 @@ def test_extend_default_package_class
# JRUBY-3046
def test_java_methods_have_arity
assert_nothing_raised do
assert_equal(-1, java.lang.String.instance_method(:toString).arity)
assert java.lang.String.instance_method(:toString).arity
end
end