[macruby-changes] [206] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed May 21 18:08:41 PDT 2008


Revision: 206
          http://trac.macosforge.org/projects/ruby/changeset/206
Author:   lsansonetti at apple.com
Date:     2008-05-21 18:08:40 -0700 (Wed, 21 May 2008)

Log Message:
-----------
export to objc methods mixed in modules, fixed/better String#format

Modified Paths:
--------------
    MacRuby/trunk/class.c
    MacRuby/trunk/objc.m
    MacRuby/trunk/test/ruby/test_objc.rb

Modified: MacRuby/trunk/class.c
===================================================================
--- MacRuby/trunk/class.c	2008-05-21 21:48:39 UTC (rev 205)
+++ MacRuby/trunk/class.c	2008-05-22 01:08:40 UTC (rev 206)
@@ -685,23 +685,26 @@
 
 	if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
 	    rb_raise(rb_eArgError, "cyclic include detected");
-       /* ignore if the module included already in superclasses */
-       for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
-           switch (BUILTIN_TYPE(p)) {
-             case T_ICLASS:
-               if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
-                   if (!superclass_seen) {
-                       c = p;  /* move insertion point */
-                   }
-                   goto skip;
-               }
-               break;
-             case T_CLASS:
-               superclass_seen = Qtrue;
-               break;
-           }
-       }
-       c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
+	/* ignore if the module included already in superclasses */
+	for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
+	    switch (BUILTIN_TYPE(p)) {
+		case T_ICLASS:
+		    if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
+			if (!superclass_seen) {
+			    c = p;  /* move insertion point */
+			}
+			goto skip;
+		    }
+		    break;
+		case T_CLASS:
+		    superclass_seen = Qtrue;
+		    break;
+	    }
+	}
+#if WITH_OBJC
+	rb_objc_sync_ruby_methods(module, klass);
+#endif
+	c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
 	changed = 1;
       skip:
 	module = RCLASS_SUPER(module);

Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m	2008-05-21 21:48:39 UTC (rev 205)
+++ MacRuby/trunk/objc.m	2008-05-22 01:08:40 UTC (rev 206)
@@ -1267,7 +1267,6 @@
     }
 }
 
-#if 0
 static int
 __rb_objc_add_ruby_method(ID mid, NODE *body, VALUE mod)
 {
@@ -1277,15 +1276,26 @@
     if (body == NULL || body->nd_body->nd_body == NULL)
 	return ST_CONTINUE;
 
-    if (VISI(body->nd_body->nd_noex) != NOEX_PUBLIC)
+    if ((body->nd_body->nd_noex & NOEX_MASK) != NOEX_PUBLIC)
 	return ST_CONTINUE;
 
     rb_objc_sync_ruby_method(mod, mid, body->nd_body->nd_body, 0);
 
     return ST_CONTINUE;
 }
-#endif
 
+void
+rb_objc_sync_ruby_methods(VALUE mod, VALUE klass)
+{
+    for (;;) {
+	st_foreach(RCLASS_M_TBL(mod), __rb_objc_add_ruby_method, 
+		   (st_data_t)klass);
+	mod = RCLASS_SUPER(mod);
+	if (mod == 0 || BUILTIN_TYPE(mod) != T_ICLASS)
+	    break;
+    }
+}
+
 static inline unsigned
 is_ignored_selector(SEL sel)
 {
@@ -2674,11 +2684,8 @@
 				? (VALUE)CFSTR("0B") : (VALUE)CFSTR("0b");
 			   rb_str_update(arg, 0, 0, prefix);
 			}
-			if (*new_fmt == NULL) {
-			    *new_fmt = (char *)malloc(sizeof(char) * 
-						      format_str_len);
-			    strncpy(*new_fmt, format_str, format_str_len);
-			}
+			if (*new_fmt == NULL)
+			    *new_fmt = strdup(format_str);
 			(*new_fmt)[i] = '@';
 			args[j] = arg;
 			type = "@"; 
@@ -2711,6 +2718,7 @@
     ffi_cif *cif;
     int i;
     void *null;
+    char *new_fmt;
 
     if (argc == 0)
 	return fmt;
@@ -2720,23 +2728,21 @@
     ffi_args = (void **)alloca(sizeof(void *) * argc + 4);
 
     null = NULL;
+    new_fmt = NULL;
 
-    if (argc > 0) {
-	char *new_fmt = NULL;
-
-	rb_objc_get_types_for_format_str(types, argc, (VALUE *)argv, 
+    rb_objc_get_types_for_format_str(types, argc, (VALUE *)argv, 
 	    RSTRING_CPTR(fmt), &new_fmt);
-	if (new_fmt != NULL) {
-	    fmt = (VALUE)CFStringCreateWithCString(NULL, new_fmt, 
+    if (new_fmt != NULL) {
+	fmt = (VALUE)CFStringCreateWithCString(NULL, new_fmt, 
 		kCFStringEncodingUTF8);
-	    free(new_fmt);
-	}  
+	free(new_fmt);
+	CFMakeCollectable((void *)fmt);
+    }  
 
-	for (i = 0; i < argc; i++) {
-	    ffi_argtypes[i + 3] = rb_objc_octype_to_ffitype(types[i]);
-	    ffi_args[i + 3] = (void *)alloca(ffi_argtypes[i + 3]->size);
-	    rb_objc_rval_to_ocval(argv[i], types[i], ffi_args[i + 3]);
-	}
+    for (i = 0; i < argc; i++) {
+	ffi_argtypes[i + 3] = rb_objc_octype_to_ffitype(types[i]);
+	ffi_args[i + 3] = (void *)alloca(ffi_argtypes[i + 3]->size);
+	rb_objc_rval_to_ocval(argv[i], types[i], ffi_args[i + 3]);
     }
 
     ffi_argtypes[0] = &ffi_type_pointer;

Modified: MacRuby/trunk/test/ruby/test_objc.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_objc.rb	2008-05-21 21:48:39 UTC (rev 205)
+++ MacRuby/trunk/test/ruby/test_objc.rb	2008-05-22 01:08:40 UTC (rev 206)
@@ -55,5 +55,24 @@
     assert_equal(['xxx'], a)
   end
 
+  module DispatchModule
+    def foo(x)
+      x
+    end
+    def foo(x, with:y)
+      x + y
+    end
+  end
+  class DispatchClass 
+    include DispatchModule
+  end
+  def test_objc_dispatch_on_module_function
+    o = DispatchClass.new
+    r = o.performSelector('foo:', withObject:'xxx')
+    assert_equal('xxx', r)
+    r = o.performSelector('foo:with:', withObject:'xxx', withObject:'yyy')
+    assert_equal('xxxyyy', r)
+  end
+
 end
 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080521/0a8ebdad/attachment.htm 


More information about the macruby-changes mailing list