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!