Revision: 410 http://trac.macosforge.org/projects/ruby/changeset/410 Author: lsansonetti@apple.com Date: 2008-08-05 19:18:19 -0700 (Tue, 05 Aug 2008) Log Message: ----------- wip Modified Paths: -------------- MacRuby/branches/lrz_unstable/class.c MacRuby/branches/lrz_unstable/hash.c MacRuby/branches/lrz_unstable/include/ruby/node.h MacRuby/branches/lrz_unstable/lib/fileutils.rb MacRuby/branches/lrz_unstable/objc.m MacRuby/branches/lrz_unstable/vm_eval.c MacRuby/branches/lrz_unstable/vm_method.c Modified: MacRuby/branches/lrz_unstable/class.c =================================================================== --- MacRuby/branches/lrz_unstable/class.c 2008-08-05 01:51:04 UTC (rev 409) +++ MacRuby/branches/lrz_unstable/class.c 2008-08-06 02:18:19 UTC (rev 410) @@ -596,13 +596,16 @@ DLOG("INCM", "%s <- %s", class_getName((Class)klass), class_getName((Class)module)); methods = class_copyMethodList((Class)module, &methods_count); - for (i = 0; i < methods_count; i++) { - Method method = methods[i]; - DLOG("DEFI", "-[%s %s]", class_getName((Class)klass), (char *)method_getName(method)); - assert(class_addMethod((Class)klass, - method_getName(method), - method_getImplementation(method), - method_getTypeEncoding(method))); + if (methods != NULL) { + for (i = 0; i < methods_count; i++) { + Method method = methods[i]; + DLOG("DEFI", "-[%s %s]", class_getName((Class)klass), (char *)method_getName(method)); + assert(class_addMethod((Class)klass, + method_getName(method), + method_getImplementation(method), + method_getTypeEncoding(method))); + } + free(methods); } #else VALUE p, c; @@ -851,6 +854,45 @@ } #endif +static void +rb_objc_push_methods(VALUE ary, VALUE mod) +{ + Method *methods; + unsigned int i, count; + + methods = class_copyMethodList((Class)mod, &count); + if (methods != NULL) { + for (i = 0; i < count; i++) { + Method method; + SEL sel; + char *sel_name, *p; + VALUE sym; + + method = methods[i]; + + sel = method_getName(method); + if (rb_ignored_selector(sel)) + continue; + + sel_name = (char *)sel_getName(sel); + p = strchr(sel_name, ':'); + if (p != NULL && strchr(p + 1, ':') == NULL) { + size_t len = strlen(sel_name); + p = alloca(len); + strncpy(p, sel_name, len); + p[len - 1] = '\0'; + sel_name = p; + } + + sym = ID2SYM(rb_intern(sel_name)); + + if (rb_ary_includes(ary, sym) == Qfalse) + rb_ary_push(ary, sym); + } + free(methods); + } +} + static VALUE class_instance_method_list(int argc, VALUE *argv, VALUE mod, int (*func) (ID, long, VALUE)) { @@ -870,19 +912,7 @@ } while (mod != 0) { - unsigned i, count; - Method *methods; - - methods = class_copyMethodList((Class)mod, &count); - if (methods != NULL) { - for (i = 0; i < count; i++) { - SEL sel = method_getName(methods[i]); - if (rb_ignored_selector(sel)) - continue; - rb_ary_push(ary, ID2SYM(rb_intern(sel_getName(sel)))); - } - free(methods); - } + rb_objc_push_methods(ary, mod); if (!recur) break; mod = (VALUE)class_getSuperclass((Class)mod); @@ -1038,8 +1068,25 @@ VALUE rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj) { -#if WITH_OBJC // TODO - return Qnil; +#if WITH_OBJC + VALUE recur, klass, ary; + + if (argc == 0) { + recur = Qtrue; + } + else { + rb_scan_args(argc, argv, "01", &recur); + } + + klass = CLASS_OF(obj); + ary = rb_ary_new(); + + do { + if (RCLASS_SINGLETON(klass)) + rb_objc_push_methods(ary, klass); + klass = RCLASS_SUPER(klass); + } + while (recur == Qtrue && klass != 0); #else VALUE recur, ary, klass; st_table *list; @@ -1065,9 +1112,9 @@ ary = rb_ary_new(); st_foreach(list, ins_methods_i, ary); st_free_table(list); +#endif return ary; -#endif } void Modified: MacRuby/branches/lrz_unstable/hash.c =================================================================== --- MacRuby/branches/lrz_unstable/hash.c 2008-08-05 01:51:04 UTC (rev 409) +++ MacRuby/branches/lrz_unstable/hash.c 2008-08-06 02:18:19 UTC (rev 410) @@ -3094,6 +3094,10 @@ rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0); rb_define_method(rb_cHash,"clear", rb_hash_clear, 0); rb_define_method(rb_cHash,"invert", rb_hash_invert, 0); +#if WITH_OBJC + /* to override the private -[NSMutableDictionary invert] method */ + rb_define_method(rb_cNSMutableHash,"invert", rb_hash_invert, 0); +#endif rb_define_method(rb_cHash,"update", rb_hash_update, 1); rb_define_method(rb_cHash,"replace", rb_hash_replace, 1); rb_define_method(rb_cHash,"merge!", rb_hash_update, 1); Modified: MacRuby/branches/lrz_unstable/include/ruby/node.h =================================================================== --- MacRuby/branches/lrz_unstable/include/ruby/node.h 2008-08-05 01:51:04 UTC (rev 409) +++ MacRuby/branches/lrz_unstable/include/ruby/node.h 2008-08-06 02:18:19 UTC (rev 410) @@ -510,6 +510,7 @@ void rb_objc_register_ruby_method(VALUE, ID, NODE *); NODE *rb_objc_method_node(VALUE, ID, IMP *, SEL *); NODE *rb_objc_method_node2(VALUE, SEL, IMP *); +NODE *rb_objc_method_node3(IMP); #endif NODE *rb_node_newnode(enum node_type,VALUE,VALUE,VALUE); Modified: MacRuby/branches/lrz_unstable/lib/fileutils.rb =================================================================== --- MacRuby/branches/lrz_unstable/lib/fileutils.rb 2008-08-05 01:51:04 UTC (rev 409) +++ MacRuby/branches/lrz_unstable/lib/fileutils.rb 2008-08-06 02:18:19 UTC (rev 410) @@ -1508,6 +1508,7 @@ METHODS = singleton_methods() - [:private_module_function, :commands, :options, :have_option?, :options_of, :collect_method] + METHODS -= NSObject.methods # # This module has all methods of FileUtils module, but it outputs messages Modified: MacRuby/branches/lrz_unstable/objc.m =================================================================== --- MacRuby/branches/lrz_unstable/objc.m 2008-08-05 01:51:04 UTC (rev 409) +++ MacRuby/branches/lrz_unstable/objc.m 2008-08-06 02:18:19 UTC (rev 410) @@ -1330,6 +1330,15 @@ } NODE * +rb_objc_method_node3(IMP imp) +{ + if (imp == NULL || ((ffi_closure *)imp)->fun != rb_ruby_to_objc_closure_handler) + return NULL; + + return ((ffi_closure *)imp)->user_data; +} + +NODE * rb_objc_method_node2(VALUE mod, SEL sel, IMP *pimp) { IMP imp; Modified: MacRuby/branches/lrz_unstable/vm_eval.c =================================================================== --- MacRuby/branches/lrz_unstable/vm_eval.c 2008-08-05 01:51:04 UTC (rev 409) +++ MacRuby/branches/lrz_unstable/vm_eval.c 2008-08-06 02:18:19 UTC (rev 410) @@ -1336,12 +1336,14 @@ rb_define_global_function("loop", rb_f_loop, 0); - rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1); - rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1); #if WITH_OBJC + rb_define_method(rb_cNSObject, "instance_eval", rb_obj_instance_eval, -1); + rb_define_method(rb_cNSObject, "instance_exec", rb_obj_instance_exec, -1); rb_define_private_method(rb_cNSObject, "method_missing", rb_method_missing, -1); rb_define_method(rb_cNSObject, "__send__", rb_f_send, -1); #else + rb_define_method(rb_cBasicObject, "instance_eval", rb_obj_instance_eval, -1); + rb_define_method(rb_cBasicObject, "instance_exec", rb_obj_instance_exec, -1); rb_define_private_method(rb_cBasicObject, "method_missing", rb_method_missing, -1); rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1); #endif Modified: MacRuby/branches/lrz_unstable/vm_method.c =================================================================== --- MacRuby/branches/lrz_unstable/vm_method.c 2008-08-05 01:51:04 UTC (rev 409) +++ MacRuby/branches/lrz_unstable/vm_method.c 2008-08-06 02:18:19 UTC (rev 410) @@ -437,7 +437,19 @@ origin = rb_method_node(RCLASS_SUPER(klass), name) == fbody ? RCLASS_SUPER(klass) : klass; } +#if 0 if (fbody == NULL) { + char buf[512]; + ID newname; + + snprintf(buf, sizeof buf, "%s:", rb_id2name(name)); + newname = rb_intern(buf); + fbody = rb_method_node(klass, newname); + if (fbody != NULL) + name = newname; + } +#endif + if (fbody == NULL) { rb_print_undef(klass, name, 0); } if (fbody->nd_noex != noex) { @@ -1109,18 +1121,32 @@ if (fbody == 0) { fbody = search_method(rb_cObject, id, &m); } +#if WITH_OBJC + if (fbody == 0) { + rb_bug("undefined method `%s'; can't happen", rb_id2name(id)); + } + if (nd_type(fbody->nd_body) != NODE_ZSUPER) { + break; /* normal case: need not to follow 'super' link */ + } +#else if (fbody == 0 || fbody->nd_body == 0) { rb_bug("undefined method `%s'; can't happen", rb_id2name(id)); } if (nd_type(fbody->nd_body->nd_body) != NODE_ZSUPER) { break; /* normal case: need not to follow 'super' link */ } +#endif m = RCLASS_SUPER(m); if (!m) break; } +#if WITH_OBJC + rb_add_method(rb_singleton_class(module), id, fbody->nd_body, + NOEX_PUBLIC); +#else rb_add_method(rb_singleton_class(module), id, fbody->nd_body->nd_body, NOEX_PUBLIC); +#endif } return module; }