private RubyModule buildClassFromDescriptor(ThreadContext context) { Ruby runtime = context.runtime; ObjectAllocator allocator = new ObjectAllocator() { @Override public IRubyObject allocate(Ruby runtime, RubyClass klazz) { return new RubyMessage(runtime, klazz, descriptor); } }; // rb_define_class_id RubyClass klass = RubyClass.newClass(runtime, runtime.getObject()); klass.setAllocator(allocator); klass.makeMetaClass(runtime.getObject().getMetaClass()); klass.inherit(runtime.getObject()); RubyModule messageExts = runtime.getClassFromPath("Google::Protobuf::MessageExts"); klass.include(new IRubyObject[] {messageExts}); klass.instance_variable_set(runtime.newString(Utils.DESCRIPTOR_INSTANCE_VAR), this); klass.defineAnnotatedMethods(RubyMessage.class); return klass; }
@Override public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args) { return context.runtime.getObject().include(args); } });
@Override public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args) { return context.runtime.getObject().include(args); } });
@Override public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args) { return context.runtime.getObject().include(args); } });
@Override public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args) { return context.runtime.getObject().include(args); } });
@JRubyMethod public static IRubyObject extended(ThreadContext context, IRubyObject self, IRubyObject object) { RubyClass singleton = object.getSingletonClass(); singleton.include(context, self); return singleton; }
@JRubyMethod public static IRubyObject extended(ThreadContext context, IRubyObject self, IRubyObject object) { RubyClass singleton = object.getSingletonClass(); singleton.include(context, self); return singleton; }
@JRubyMethod public static IRubyObject extended(ThreadContext context, IRubyObject self, IRubyObject object) { if (!(self instanceof RubyModule)) { throw context.runtime.newTypeError(self, context.runtime.getModule()); } RubyClass singleton = object.getSingletonClass(); singleton.include(new IRubyObject[] {self}); return singleton; }
@JRubyMethod public static IRubyObject extended(ThreadContext context, IRubyObject self, IRubyObject object) { if (!(self instanceof RubyModule)) { throw context.runtime.newTypeError(self, context.runtime.getModule()); } RubyClass singleton = object.getSingletonClass(); singleton.include(new IRubyObject[] {self}); return singleton; }
implClass.include(context, self); // ImplClass.include Interface
implClass.include(context, self); // ImplClass.include Interface
@Override public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg, Block block) { if (!(arg instanceof RubyClass)) { throw context.runtime.newTypeError("append_features called with non-class"); } RubyClass target = (RubyClass)arg; RubyArray javaInterfaceMods = (RubyArray)self.getInstanceVariables().getInstanceVariable("@java_interface_mods"); target.include(javaInterfaceMods.toJavaArray()); return Helpers.invokeAs(context, clazz.getSuperClass(), self, name, arg, block); } });
@Override public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg, Block block) { if (!(arg instanceof RubyClass)) { throw context.runtime.newTypeError("append_features called with non-class"); } RubyClass target = (RubyClass)arg; RubyArray javaInterfaceMods = (RubyArray)self.getInstanceVariables().getInstanceVariable("@java_interface_mods"); target.include(javaInterfaceMods.toJavaArray()); return Helpers.invokeAs(context, clazz.getSuperClass(), self, name, arg, block); } });
@JRubyMethod(name = "new", rest = true) public static IRubyObject rbNew(ThreadContext context, IRubyObject self, IRubyObject[] args, Block block) { Ruby runtime = context.runtime; RubyClass implClass = (RubyClass)self.getInstanceVariables().getInstanceVariable("@__implementation"); if (implClass == null) { implClass = RubyClass.newClass(runtime, (RubyClass)runtime.getClass("InterfaceJavaProxy")); implClass.include(new IRubyObject[] {self}); Helpers.setInstanceVariable(implClass, self, "@__implementation"); } return Helpers.invoke(context, implClass, "new", args, block); } }
@JRubyMethod(name = "new", rest = true) public static IRubyObject rbNew(ThreadContext context, IRubyObject self, IRubyObject[] args, Block block) { Ruby runtime = context.runtime; RubyClass implClass = (RubyClass)self.getInstanceVariables().getInstanceVariable("@__implementation"); if (implClass == null) { implClass = RubyClass.newClass(runtime, (RubyClass)runtime.getClass("InterfaceJavaProxy")); implClass.include(new IRubyObject[] {self}); Helpers.setInstanceVariable(implClass, self, "@__implementation"); } return Helpers.invoke(context, implClass, "new", args, block); } }
@JRubyMethod(rest = true) public static IRubyObject impl(ThreadContext context, IRubyObject self, IRubyObject[] args, final Block implBlock) { Ruby runtime = context.runtime; if (!implBlock.isGiven()) throw runtime.newArgumentError("block required to call #impl on a Java interface"); final RubyArray methodNames = (args.length > 0) ? runtime.newArray(args) : null; RubyClass implClass = RubyClass.newClass(runtime, runtime.getObject()); implClass.include(new IRubyObject[] {self}); IRubyObject implObject = implClass.callMethod(context, "new"); implClass.addMethod("method_missing", new org.jruby.internal.runtime.methods.JavaMethod(implClass, Visibility.PUBLIC) { @Override public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) { Arity.checkArgumentCount(context.runtime, name, args.length, 1, -1); if (methodNames == null || methodNames.include_p(context, args[0]).isTrue()) { return implBlock.call(context, args); } else { return clazz.getSuperClass().callMethod(context, "method_missing", args, block); } } }); return implObject; }
@JRubyMethod(rest = true) public static IRubyObject impl(ThreadContext context, IRubyObject self, IRubyObject[] args, final Block implBlock) { Ruby runtime = context.runtime; if (!implBlock.isGiven()) throw runtime.newArgumentError("block required to call #impl on a Java interface"); final RubyArray methodNames = (args.length > 0) ? runtime.newArray(args) : null; RubyClass implClass = RubyClass.newClass(runtime, runtime.getObject()); implClass.include(new IRubyObject[] {self}); IRubyObject implObject = implClass.callMethod(context, "new"); implClass.addMethod("method_missing", new org.jruby.internal.runtime.methods.JavaMethod(implClass, Visibility.PUBLIC) { @Override public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) { Arity.checkArgumentCount(context.runtime, name, args.length, 1, -1); if (methodNames == null || methodNames.include_p(context, args[0]).isTrue()) { return implBlock.call(context, args); } else { return clazz.getSuperClass().callMethod(context, "method_missing", args, block); } } }); return implObject; }