Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Better singleton support

Signed-off-by: Charles Oliver Nutter <headius@headius.com>
  • Loading branch information...
commit bec6fa66b3440bb2f991cfb9ff39a5e0cfea5dbe 1 parent 5151225
@dpp dpp authored headius committed
Showing with 50 additions and 9 deletions.
  1. +50 −9 src/org/jruby/javasupport/JavaClass.java
View
59 src/org/jruby/javasupport/JavaClass.java
@@ -38,6 +38,7 @@
import org.jruby.java.invokers.StaticFieldGetter;
import org.jruby.java.invokers.StaticMethodInvoker;
+import org.jruby.java.invokers.SingletonMethodInvoker;
import org.jruby.java.invokers.InstanceFieldGetter;
import org.jruby.java.invokers.InstanceFieldSetter;
import org.jruby.java.invokers.InstanceMethodInvoker;
@@ -356,6 +357,27 @@ void install(RubyModule proxy) {
}
}
+ private static class SingletonMethodInvokerInstaller extends StaticMethodInvokerInstaller {
+ private Object singleton;
+
+ SingletonMethodInvokerInstaller(String name, Object singleton) {
+ super(name);
+ this.singleton = singleton;
+ }
+
+ void install(RubyModule proxy) {
+ if (hasLocalMethod()) {
+ RubyClass rubySingleton = proxy.getSingletonClass();
+ DynamicMethod method = new SingletonMethodInvoker(this.singleton, rubySingleton, methods);
+ rubySingleton.addMethod(name, method);
+ if (aliases != null && isPublic() ) {
+ rubySingleton.defineAliases(aliases, this.name);
+ aliases = null;
+ }
+ }
+ }
+ }
+
private static class InstanceMethodInvokerInstaller extends MethodInstaller {
InstanceMethodInvokerInstaller(String name) {
super(name,INSTANCE_METHOD);
@@ -903,14 +925,16 @@ private void setupClassMethods(Class<?> javaClass, InitializerState state) {
// check for Scala companion object
try {
- Class<?> companion = javaClass.getClassLoader().loadClass(javaClass.getName() + "$");
- Field field = companion.getField("MODULE$");
+ Class<?> companionClass = javaClass.getClassLoader().loadClass(javaClass.getName() + "$");
+ Field field = companionClass.getField("MODULE$");
Object singleton = field.get(null);
- if (singleton) {
- Method[] sMethods = getMethods(companion);
- for (j = sMethods.length; j-- >= 0;) {
+ if (singleton != null) {
+ Method[] sMethods = getMethods(companionClass);
+ for (int j = sMethods.length; j-- >= 0;) {
Method method = sMethods[j];
String name = method.getName();
+
+ System.out.println("Companion object method "+name+" for "+companionClass);
// Fix Scala names
if (name.indexOf("$") >= 0) {
@@ -919,25 +943,33 @@ private void setupClassMethods(Class<?> javaClass, InitializerState state) {
// Don't deal with static methods on companion
if (!Modifier.isStatic(method.getModifiers())) {
- AssignedName assignedName = state.instanceNames.get(name);
+ AssignedName assignedName = state.staticNames.get(name);
// For JRUBY-4505, restore __method methods for reserved names
if (INSTANCE_RESERVED_NAMES.containsKey(method.getName())) {
- installSingltonMethods(state.staticCallbacks, javaClass, singleton, method, name + METHOD_MANGLE);
+ System.out.println("in reserved "+name);
+ installSingletonMethods(state.staticCallbacks, javaClass, singleton, method, name + METHOD_MANGLE);
continue;
}
if (assignedName == null) {
state.staticNames.put(name, new AssignedName(name, Priority.METHOD));
+ System.out.println("Assigned name is null");
} else {
- if (Priority.METHOD.lessImportantThan(assignedName)) continue;
+ if (Priority.METHOD.lessImportantThan(assignedName)) {
+ System.out.println("Less important");
+ continue;
+ }
if (!Priority.METHOD.asImportantAs(assignedName)) {
state.staticCallbacks.remove(name);
state.staticCallbacks.remove(name + '=');
state.staticNames.put(name, new AssignedName(name, Priority.METHOD));
}
}
- installSingletonMethods(state.instanceCallbacks, javaClass, singleton, method, name);
+ System.out.println("Installing "+name+" "+method+" "+singleton);
+ installSingletonMethods(state.staticCallbacks, javaClass, singleton, method, name);
+ } else {
+ System.out.println("Method "+method+" is sadly static");
}
}
@@ -983,6 +1015,15 @@ private void installStaticMethods(Map<String, NamedInstaller> methodCallbacks, C
invoker.addMethod(method, javaClass);
}
+ private void installSingletonMethods(Map<String, NamedInstaller> methodCallbacks, Class<?> javaClass, Object singleton, Method method, String name) {
+ MethodInstaller invoker = (MethodInstaller) methodCallbacks.get(name);
+ if (invoker == null) {
+ invoker = new SingletonMethodInvokerInstaller(name, singleton);
+ methodCallbacks.put(name, invoker);
+ }
+ invoker.addMethod(method, javaClass);
+ }
+
// old (quasi-deprecated) interface class
private void setupInterfaceProxy(final RubyClass proxy) {
initializer.initialize();
Please sign in to comment.
Something went wrong with that request. Please try again.