On Sun, Jun 15, 2008 at 12:47 AM, chromatic via RT <[EMAIL PROTECTED]> wrote:
> Seems reasonable to me. If you have tests, I'll apply it. Patch updated to r28430 with a simple test added in t/oo/subclass.t -- Salu2
Index: src/pmc/class.pmc =================================================================== --- src/pmc/class.pmc (revisión: 28430) +++ src/pmc/class.pmc (copia de trabajo) @@ -734,7 +734,7 @@ STRING * const parent_name = VTABLE_get_string(interp, parent); /* get number of direct parents */ - const int parent_count = VTABLE_elements(interp, _class->parents); + int parent_count = VTABLE_elements(interp, _class->parents); int index; /* loop iterator */ @@ -765,7 +765,23 @@ "It may have been supplied by a role.", VTABLE_get_string(interp, SELF), parent_name); } + /* Check is not self */ + if (parent == SELF) + real_exception(interp, NULL, E_TypeError, "Can't be own parent"); + /* Check that none of the parents is self */ + parent_count = VTABLE_elements(interp, + PARROT_CLASS(parent)->all_parents); + for (index = 0; index < parent_count; index++) { + /* get the next parent */ + PMC * const current_parent = VTABLE_get_pmc_keyed_int(interp, + PARROT_CLASS(parent)->all_parents, index); + if (current_parent == SELF) + real_exception(interp, NULL, E_TypeError, + "Loop in class hierarchy: '%S' is an ancestor of '%S'.", + VTABLE_get_string(interp, SELF), + VTABLE_get_string(interp, parent)); + } /* Add to the lists of our immediate parents and all parents. */ VTABLE_push_pmc(interp, _class->parents, parent); Index: t/oo/subclass.t =================================================================== --- t/oo/subclass.t (revisión: 28430) +++ t/oo/subclass.t (copia de trabajo) @@ -6,7 +6,7 @@ use warnings; use lib qw( . lib ../lib ../../lib ); use Test::More; -use Parrot::Test tests => 20; +use Parrot::Test tests => 21; =head1 NAME @@ -591,6 +591,17 @@ /The class 'Bar' already has a parent class 'Foo'./ OUT +pir_error_output_like( <<'CODE', <<'OUT', 'attempts to create loops in hierarchy should be rejected'); +.sub main :main + $P0 = newclass 'Foo' + $P1 = newclass 'Bar' + addparent $P1, $P0 + addparent $P0, $P1 +.end +CODE +/Loop in class hierarchy: 'Foo' is an ancestor of 'Bar'./ +OUT + pir_output_is( <<'CODE', <<'OUT', 'subclass should do what the parent does' ); .sub 'main' :main does_pmc()