});
// Because we implement Java interfaces now, we need a new === that's
// aware of those additional "virtual" supertypes
clazz.defineAlias("old_eqq", "===");
clazz.addMethod("===", new JavaMethodOne(clazz, Visibility.PUBLIC) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg) {
// TODO: WRONG - get interfaces from class
if (arg.respondsTo("java_object")) {
IRubyObject interfaces = self.getMetaClass().getInstanceVariables().fastGetInstanceVariable("@java_interfaces");
assert interfaces instanceof RubyArray : "interface list was not an array";
return context.getRuntime().newBoolean(((RubyArray)interfaces)
.op_diff(
((JavaClass)
((JavaObject)arg.dataGetStruct()).java_class()
).interfaces()
).equals(RubyArray.newArray(context.getRuntime())));
} else {
return RuntimeHelpers.invoke(context, self, "old_eqq", arg);
}
}
});
}
// Now we add an "implement" and "implement_all" methods to the class
if (!clazz.isMethodBound("implement", false)) {
RubyClass singleton = clazz.getSingletonClass();
// implement is called to force this class to create stubs for all
// methods in the given interface, so they'll show up in the list
// of methods and be invocable without passing through method_missing
singleton.addMethod("implement", new JavaMethodOne(clazz, Visibility.PRIVATE) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg) {
IRubyObject javaInterfaces = self.getInstanceVariables().fastGetInstanceVariable("@java_interfaces");
if (javaInterfaces != null && ((RubyArray)javaInterfaces).includes(context, arg)) {
return RuntimeHelpers.invoke(context, arg, "implement", self);
}
return context.getRuntime().getNil();
}
});
// implement all forces implementation of all interfaces we intend
// for this class to implement
singleton.addMethod("implement_all", new JavaMethodOne(clazz, Visibility.PRIVATE) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg) {
RubyArray javaInterfaces = (RubyArray)self.getInstanceVariables().fastGetInstanceVariable("@java_interfaces");
for (int i = 0; i < javaInterfaces.size(); i++) {
RuntimeHelpers.invoke(context, Java.JavaUtilities.get_interface_module(self, javaInterfaces.eltInternal(i)), "implement", self);