Author: jonathan
Date: Mon Apr  2 17:07:27 2007
New Revision: 17950

Modified:
   trunk/src/objects.c
   trunk/t/oo/composition.t

Log:
[PDD15]: Bring alias and exclude behaviour inline with PDD15; modify the 
relavent test.

Modified: trunk/src/objects.c
==============================================================================
--- trunk/src/objects.c (original)
+++ trunk/src/objects.c Mon Apr  2 17:07:27 2007
@@ -1902,63 +1902,75 @@
         PMC *cur_method = VTABLE_get_pmc_keyed_str(interp, methods, 
method_name);
 
         /* Need to find the name we'll check for a conflict on. */
-        STRING *check_name = method_name;
+        int excluded = 0;
 
-        /* Ignore if it's in the exclude list. */
+        /* Check if it's in the exclude list. */
         if (got_exclude) {
             int exclude_count = VTABLE_elements(interp, exclude);
             for (i = 0; i < exclude_count; i++) {
                 STRING *check = VTABLE_get_string_keyed_int(interp, exclude, 
i);
                 if (string_equal(interp, check, method_name) == 0) {
-                    check_name = NULL;
+                    excluded = 1;
                     break;
                 }
             }
         }
 
-        /* If we're not in the exclude list, now see if we've an alias. */
-        if (check_name != NULL && got_alias) {
-            if (VTABLE_exists_keyed_str(interp, alias, method_name))
-                check_name = VTABLE_get_string_keyed_str(interp, alias, 
method_name);
+        /* If we weren't excluded... */
+        if (!excluded) {
+            /* Is there a method with this name already in the class?
+             * XXX TODO: multi-method handling. */
+            if (VTABLE_exists_keyed_str(interp, methods_hash, method_name)) {
+                /* Conflicts with something already in the class. */
+                real_exception(interp, NULL, ROLE_COMPOSITOIN_METH_CONFLICT,
+                    "A conflict occurred during role composition due to method 
'%S'.",
+                    method_name);
+                return;
+            }
+
+            /* What about a conflict with ourslef? */
+            if (VTABLE_exists_keyed_str(interp, proposed_add_methods, 
method_name)) {
+                /* Something very weird is going on. */
+                real_exception(interp, NULL, ROLE_COMPOSITOIN_METH_CONFLICT,
+                    "A conflict occurred during role composition;"
+                    " the method '%S' from the role managed to conflict with 
itself somehow.",
+                    method_name);
+                return;
+            }
+
+            /* If we got here, no conflicts! Add method to the "to compose" 
list. */
+            VTABLE_set_pmc_keyed_str(interp, proposed_add_methods, 
method_name, cur_method);
         }
 
-        /* If we weren't excluded... */
-        if (check_name != NULL) {
+        /* Now see if we've got an alias. */
+        if (got_alias && VTABLE_exists_keyed_str(interp, alias, method_name)) {
+            /* Got one. Get name to alias it to. */
+            STRING *alias_name = VTABLE_get_string_keyed_str(interp, alias, 
method_name);
+            
             /* Is there a method with this name already in the class?
              * XXX TODO: multi-method handling. */
-            if (VTABLE_exists_keyed_str(interp, methods_hash, check_name)) {
+            if (VTABLE_exists_keyed_str(interp, methods_hash, alias_name)) {
                 /* Conflicts with something already in the class. */
-                if (check_name == method_name)
-                    real_exception(interp, NULL, 
ROLE_COMPOSITOIN_METH_CONFLICT,
-                        "A conflict occurred during role composition due to 
method '%S'.",
-                        method_name);
-                else
-                    real_exception(interp, NULL, 
ROLE_COMPOSITOIN_METH_CONFLICT,
-                        "A conflict occurred during role composition"
-                        " due to the aliasing of '%S' to '%S'.",
-                        method_name, check_name);
+                real_exception(interp, NULL, ROLE_COMPOSITOIN_METH_CONFLICT,
+                    "A conflict occurred during role composition"
+                    " due to the aliasing of '%S' to '%S'.",
+                    method_name, alias_name);
                 return;
             }
 
             /* What about a conflict with ourslef? */
-            if (VTABLE_exists_keyed_str(interp, proposed_add_methods, 
check_name)) {
-                /* If it's due to aliasing, say so. Otherwise, something
-                 * very weird is going on. */
-                if (check_name != method_name)
-                    real_exception(interp, NULL, 
ROLE_COMPOSITOIN_METH_CONFLICT,
-                        "A conflict occurred during role composition;"
-                        " '%S' was aliased to '%S', but the role already has a 
'%S'.",
-                        method_name, check_name, check_name);
-                else
-                    real_exception(interp, NULL, 
ROLE_COMPOSITOIN_METH_CONFLICT,
-                        "A conflict occurred during role composition;"
-                        " the method '%S' from the role managed to conflict 
with itself somehow.",
-                        method_name);
+            if (VTABLE_exists_keyed_str(interp, proposed_add_methods, 
alias_name)) {
+                real_exception(interp, NULL, ROLE_COMPOSITOIN_METH_CONFLICT,
+                    "A conflict occurred during role composition"
+                    " due to the aliasing of '%S' to '%S' (role already has"
+                    " a method '%S').",
+                    method_name, alias_name, alias_name);
                 return;
             }
 
-            /* If we got here, no conflicts! Add it to the "to compose" list. 
*/
-            VTABLE_set_pmc_keyed_str(interp, proposed_add_methods, check_name, 
cur_method);
+            /* If we got here, no conflicts! Add method to the "to compose"
+             * list with its alias. */
+            VTABLE_set_pmc_keyed_str(interp, proposed_add_methods, alias_name, 
cur_method);
         }
     }
 

Modified: trunk/t/oo/composition.t
==============================================================================
--- trunk/t/oo/composition.t    (original)
+++ trunk/t/oo/composition.t    Mon Apr  2 17:07:27 2007
@@ -245,7 +245,7 @@
 ok 4 - called method from role that wasn't excluded
 OUT
 
-pir_output_is( <<'CODE', <<'OUT', 'conflict resolution by aliasing' );
+pir_output_is( <<'CODE', <<'OUT', 'conflict resolution by aliasing and 
exclude' );
 .sub 'test' :main
     $P0 = new Role
     $P1 = new Class
@@ -260,8 +260,10 @@
     $P0.'add_method'("snake", $P2)
     $P3 = new Hash
     $P3["badger"] = "role_badger"
-    $P1.'add_role'($P0, 'alias' => $P3)
-    print "ok 2 - composition worked due to aliasing\n"
+    $P4 = new ResizableStringArray
+    $P4[0] = "badger"
+    $P1.'add_role'($P0, 'alias' => $P3, 'exclude' => $P4)
+    print "ok 2 - composition worked due to aliasing and exclude\n"
 
     $P2 = $P1.'new'()
     $P2.'badger'()
@@ -285,7 +287,7 @@
 .end
 CODE
 ok 1 - class has a method
-ok 2 - composition worked due to aliasing
+ok 2 - composition worked due to aliasing and exclude
 Badger!
 ok 3 - called method from class
 Snake!

Reply via email to