Skip to content

Commit

Permalink
Add java_method to peel out a specific overloaded Java method for lat…
Browse files Browse the repository at this point in the history
…er selection-free invocation. Only for instance methods atm.
  • Loading branch information
headius committed Sep 28, 2009
1 parent b5c0f19 commit 74792d7
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
5 changes: 4 additions & 1 deletion src/org/jruby/java/invokers/InstanceMethodInvoker.java
Expand Up @@ -11,11 +11,14 @@
import org.jruby.runtime.builtin.IRubyObject;

public class InstanceMethodInvoker extends MethodInvoker {

public InstanceMethodInvoker(RubyModule host, List<Method> methods) {
super(host, methods);
}

public InstanceMethodInvoker(RubyModule host, Method method) {
super(host, method);
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args) {
createJavaMethods(context.getRuntime());
Expand Down
15 changes: 13 additions & 2 deletions src/org/jruby/java/invokers/MethodInvoker.java
Expand Up @@ -3,6 +3,8 @@
import org.jruby.javasupport.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
Expand All @@ -17,10 +19,19 @@ public abstract class MethodInvoker extends RubyToJavaInvoker {
MethodInvoker(RubyModule host, List<Method> methods) {
super(host);
this.methods = methods.toArray(new Method[methods.size()]);

trySetAccessible(this.methods);
}

MethodInvoker(RubyModule host, Method method) {
super(host);
this.methods = new Method[] {method};
trySetAccessible(methods);
}

private static void trySetAccessible(Method[] methods) {
if (!Ruby.isSecurityRestricted()) {
try {
Method.setAccessible(this.methods, true);
Method.setAccessible(methods, true);
} catch(SecurityException e) {}
}
}
Expand Down
30 changes: 26 additions & 4 deletions src/org/jruby/java/proxies/JavaProxy.java
Expand Up @@ -12,12 +12,15 @@
import org.jruby.RubyClass;
import org.jruby.RubyHash;
import org.jruby.RubyHash.Visitor;
import org.jruby.RubyMethod;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
import org.jruby.anno.JRubyMethod;
import org.jruby.internal.runtime.methods.JavaMethod.JavaMethodNBlock;
import org.jruby.java.addons.ArrayJavaAddons;
import org.jruby.java.invokers.InstanceFieldGetter;
import org.jruby.java.invokers.InstanceFieldSetter;
import org.jruby.java.invokers.InstanceMethodInvoker;
import org.jruby.javasupport.Java;
import org.jruby.javasupport.JavaClass;
import org.jruby.javasupport.JavaMethod;
Expand All @@ -28,6 +31,7 @@
import org.jruby.runtime.Block;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.CodegenUtils;

Expand Down Expand Up @@ -228,7 +232,7 @@ public IRubyObject equal_p(ThreadContext context, IRubyObject other) {
return runtime.getFalse();
}

@JRubyMethod
@JRubyMethod(backtrace = true)
public IRubyObject java_send(ThreadContext context, IRubyObject rubyName) {
Class jclass = getJavaObject().getJavaClass();
String name = rubyName.asJavaString();
Expand All @@ -243,12 +247,12 @@ public IRubyObject java_send(ThreadContext context, IRubyObject rubyName) {
}
}

@JRubyMethod
@JRubyMethod(backtrace = true)
public IRubyObject java_send(ThreadContext context, IRubyObject rubyName, IRubyObject argTypes) {
throw context.getRuntime().newArgumentError(2, 3);
}

@JRubyMethod
@JRubyMethod(backtrace = true)
public IRubyObject java_send(ThreadContext context, IRubyObject rubyName, IRubyObject argTypes, IRubyObject arg0) {
String name = rubyName.asJavaString();
RubyArray argTypesAry = argTypes.convertToArray();
Expand All @@ -270,7 +274,7 @@ public IRubyObject java_send(ThreadContext context, IRubyObject rubyName, IRubyO
}
}

@JRubyMethod(required = 4, rest = true)
@JRubyMethod(required = 4, rest = true, backtrace = true)
public IRubyObject java_send(ThreadContext context, IRubyObject[] args) {
Ruby runtime = context.getRuntime();
Arity.checkArgumentCount(runtime, args, 3, -1);
Expand Down Expand Up @@ -301,6 +305,24 @@ public IRubyObject java_send(ThreadContext context, IRubyObject[] args) {
}
}

@JRubyMethod(backtrace = true)
public IRubyObject java_method(ThreadContext context, IRubyObject rubyName, IRubyObject argTypes) {
String name = rubyName.asJavaString();
RubyArray argTypesAry = argTypes.convertToArray();
Ruby runtime = context.getRuntime();

Class[] argTypesClasses = (Class[])argTypesAry.toArray(new Class[argTypesAry.size()]);
Class jclass = getJavaObject().getJavaClass();

try {
Method jmethod = jclass.getMethod(name, argTypesClasses);
InstanceMethodInvoker invoker = new InstanceMethodInvoker(getMetaClass(), jmethod);
return RubyMethod.newMethod(metaClass, name + CodegenUtils.prettyParams(argTypesClasses), metaClass, name, invoker, this);
} catch (NoSuchMethodException nsme) {
throw runtime.newNameError("Java method not found", name + CodegenUtils.prettyParams(argTypesClasses));
}
}

public Object toJava(Class type) {
getRuntime().getJavaSupport().getObjectProxyCache().put(getObject(), this);
return getObject();
Expand Down

0 comments on commit 74792d7

Please sign in to comment.