Store CFCClass pointer in CFCMethod

Store a weak pointer to the class containing the method.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/a0e051a0
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/a0e051a0
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/a0e051a0

Branch: refs/heads/master
Commit: a0e051a0d15658574482b24d328e326c8389670c
Parents: 1ff6ed0
Author: Nick Wellnhofer <wellnho...@aevum.de>
Authored: Wed Mar 1 14:52:23 2017 +0100
Committer: Nick Wellnhofer <wellnho...@aevum.de>
Committed: Thu Mar 2 20:08:04 2017 +0100

----------------------------------------------------------------------
 compiler/perl/lib/Clownfish/CFC.pm      |  4 +-
 compiler/perl/lib/Clownfish/CFC.xs      |  8 ++-
 compiler/perl/t/201-method.t            | 25 ++--------
 compiler/perl/t/202-overridden_method.t |  4 +-
 compiler/perl/t/203-final_method.t      |  2 +-
 compiler/src/CFCMethod.c                | 73 ++++++++++++++++------------
 compiler/src/CFCMethod.h                |  9 ++--
 compiler/src/CFCParseHeader.y           |  3 +-
 compiler/src/CFCTestMethod.c            | 72 +++++++++++++--------------
 9 files changed, 91 insertions(+), 109 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a0e051a0/compiler/perl/lib/Clownfish/CFC.pm
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC.pm 
b/compiler/perl/lib/Clownfish/CFC.pm
index 26cb4a4..cd6dae0 100644
--- a/compiler/perl/lib/Clownfish/CFC.pm
+++ b/compiler/perl/lib/Clownfish/CFC.pm
@@ -250,7 +250,7 @@ BEGIN { XSLoader::load( 'Clownfish::CFC', '0.6.0' ) }
         param_list  => undef,
         name        => undef,
         docucomment => undef,
-        class_name  => undef,
+        class       => undef,
         abstract    => undef,
         final       => undef,
         exposure    => 'parcel',
@@ -264,7 +264,7 @@ BEGIN { XSLoader::load( 'Clownfish::CFC', '0.6.0' ) }
         $args{final}    ||= 0;
         return _new(
             @args{
-                qw( exposure name return_type param_list docucomment class_name
+                qw( exposure name return_type param_list docucomment class
                     final abstract )
                 }
         );

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a0e051a0/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC.xs 
b/compiler/perl/lib/Clownfish/CFC.xs
index 9bae35d..b6b7939 100644
--- a/compiler/perl/lib/Clownfish/CFC.xs
+++ b/compiler/perl/lib/Clownfish/CFC.xs
@@ -826,23 +826,21 @@ PPCODE:
 MODULE = Clownfish::CFC   PACKAGE = Clownfish::CFC::Model::Method
 
 SV*
-_new(exposure_sv, name, return_type, param_list, docucomment, class_name_sv, 
is_final, is_abstract)
+_new(exposure_sv, name, return_type, param_list, docucomment, klass, is_final, 
is_abstract)
     SV *exposure_sv;
     const char *name;
     CFCType *return_type;
     CFCParamList *param_list;
     CFCDocuComment *docucomment;
-    SV *class_name_sv;
+    CFCClass *klass;
     int is_final;
     int is_abstract;
 CODE:
     const char *exposure =
         SvOK(exposure_sv) ? SvPV_nolen(exposure_sv) : NULL;
-    const char *class_name =
-        SvOK(class_name_sv) ? SvPV_nolen(class_name_sv) : NULL;
     CFCMethod *self
         = CFCMethod_new(exposure, name, return_type, param_list, docucomment,
-                        class_name, is_final, is_abstract);
+                        klass, is_final, is_abstract);
     RETVAL = S_cfcbase_to_perlref(self);
     CFCBase_decref((CFCBase*)self);
 OUTPUT: RETVAL

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a0e051a0/compiler/perl/t/201-method.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/201-method.t b/compiler/perl/t/201-method.t
index 3c8a74c..6caa3a2 100644
--- a/compiler/perl/t/201-method.t
+++ b/compiler/perl/t/201-method.t
@@ -16,7 +16,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 38;
+use Test::More tests => 30;
 
 BEGIN { use_ok('Clownfish::CFC::Model::Method') }
 use Clownfish::CFC::Parser;
@@ -24,10 +24,11 @@ use Clownfish::CFC::Parser;
 my $parser = Clownfish::CFC::Parser->new;
 $parser->parse('parcel Neato;')
     or die "failed to process parcel_definition";
+my $neato_foo = $parser->parse('class Neato::Foo {}');
 
 my %args = (
     return_type => $parser->parse('Obj*'),
-    class_name  => 'Neato::Foo',
+    class       => $neato_foo,
     param_list  => $parser->parse('(Foo *self, int32_t count = 0)'),
     name        => 'Return_An_Obj',
 );
@@ -48,24 +49,6 @@ eval {
 };
 like( $@, qr/name/, "Invalid name kills constructor" );
 
-for (qw( foo 1Foo Foo_Bar 1FOOBAR )) {
-    eval {
-        Clownfish::CFC::Model::Method->new(
-            %args,
-            class_name => $_,
-        );
-    };
-    like( $@, qr/class_name/, "Reject invalid class name $_" );
-    my $bogus_middle = "Foo::" . $_ . "::Bar";
-    eval {
-        Clownfish::CFC::Model::Method->new(
-            %args,
-            class_name => $bogus_middle,
-        );
-    };
-    like( $@, qr/class_name/, "Reject invalid class name $bogus_middle" );
-}
-
 my $dupe = Clownfish::CFC::Model::Method->new(%args);
 ok( $method->compatible($dupe), "compatible()" );
 
@@ -113,7 +96,7 @@ ok( !$param_type_differs->compatible($method), "... 
reversed" );
 
 my $self_type_differs = Clownfish::CFC::Model::Method->new(
     %args,
-    class_name => 'Neato::Bar',
+    class      => $parser->parse('class Neato::Bar {}'),
     param_list => $parser->parse('(Bar *self, int32_t count = 0)'),
 );
 ok( $method->compatible($self_type_differs),

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a0e051a0/compiler/perl/t/202-overridden_method.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/202-overridden_method.t 
b/compiler/perl/t/202-overridden_method.t
index c33c928..85e0f81 100644
--- a/compiler/perl/t/202-overridden_method.t
+++ b/compiler/perl/t/202-overridden_method.t
@@ -27,7 +27,7 @@ $parser->parse('parcel Neato;')
 
 my %args = (
     return_type => $parser->parse('Obj*'),
-    class_name  => 'Neato::Foo',
+    class       => $parser->parse('class Neato::Foo {}'),
     param_list  => $parser->parse('(Foo *self)'),
     name        => 'Return_An_Obj',
 );
@@ -36,7 +36,7 @@ my $orig      = Clownfish::CFC::Model::Method->new(%args);
 my $overrider = Clownfish::CFC::Model::Method->new(
     %args,
     param_list => $parser->parse('(FooJr *self)'),
-    class_name => 'Neato::Foo::FooJr',
+    class      => $parser->parse('class Neato::Foo::FooJr {}'),
 );
 $overrider->override($orig);
 ok( !$overrider->novel, "A Method which overrides another is not 'novel'" );

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a0e051a0/compiler/perl/t/203-final_method.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/203-final_method.t 
b/compiler/perl/t/203-final_method.t
index ea98ca5..53d2b36 100644
--- a/compiler/perl/t/203-final_method.t
+++ b/compiler/perl/t/203-final_method.t
@@ -26,7 +26,7 @@ $parser->parse('parcel Neato;')
 
 my %args = (
     return_type => $parser->parse('Obj*'),
-    class_name  => 'Neato::Foo',
+    class       => $parser->parse('class Neato::Foo {}'),
     param_list  => $parser->parse('(Foo* self)'),
     name        => 'Return_An_Obj',
 );

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a0e051a0/compiler/src/CFCMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCMethod.c b/compiler/src/CFCMethod.c
index 1d449e4..1fd6557 100644
--- a/compiler/src/CFCMethod.c
+++ b/compiler/src/CFCMethod.c
@@ -36,7 +36,7 @@
 struct CFCMethod {
     CFCCallable callable;
     CFCMethod *novel_method;
-    char *fresh_class_name;
+    CFCWeakPtr fresh_class;
     char *host_alias;
     int is_final;
     int is_abstract;
@@ -44,6 +44,12 @@ struct CFCMethod {
     int is_excluded;
 };
 
+static CFCClass*
+S_fresh_class(CFCMethod *self);
+
+static const char*
+S_fresh_class_name(CFCMethod *self);
+
 static const CFCMeta CFCMETHOD_META = {
     "Clownfish::CFC::Model::Method",
     sizeof(CFCMethod),
@@ -53,10 +59,10 @@ static const CFCMeta CFCMETHOD_META = {
 CFCMethod*
 CFCMethod_new(const char *exposure, const char *name, CFCType *return_type,
               CFCParamList *param_list, CFCDocuComment *docucomment,
-              const char *class_name, int is_final, int is_abstract) {
+              CFCClass *klass, int is_final, int is_abstract) {
     CFCMethod *self = (CFCMethod*)CFCBase_allocate(&CFCMETHOD_META);
     return CFCMethod_init(self, exposure, name, return_type, param_list,
-                          docucomment, class_name, is_final, is_abstract);
+                          docucomment, klass, is_final, is_abstract);
 }
 
 static int
@@ -84,14 +90,9 @@ S_validate_meth_name(const char *meth_name) {
 CFCMethod*
 CFCMethod_init(CFCMethod *self, const char *exposure, const char *name,
                CFCType *return_type, CFCParamList *param_list,
-               CFCDocuComment *docucomment, const char *class_name,
+               CFCDocuComment *docucomment, CFCClass *klass,
                int is_final, int is_abstract) {
-    // Validate class_name.
-    CFCUTIL_NULL_CHECK(class_name);
-    if (!CFCClass_validate_class_name(class_name)) {
-        CFCBase_decref((CFCBase*)self);
-        CFCUtil_die("Invalid class_name: '%s'", class_name);
-    }
+    CFCUTIL_NULL_CHECK(klass);
     // Validate name.
     if (!S_validate_meth_name(name)) {
         CFCBase_decref((CFCBase*)self);
@@ -108,24 +109,21 @@ CFCMethod_init(CFCMethod *self, const char *exposure, 
const char *name,
     if (!args[0]) { CFCUtil_die("Missing 'self' argument"); }
     CFCType *type = CFCVariable_get_type(args[0]);
     const char *specifier  = CFCType_get_specifier(type);
-    const char *last_colon = strrchr(class_name, ':');
-    const char *struct_sym = last_colon ? last_colon + 1 : class_name;
+    const char *struct_sym = CFCClass_get_struct_sym(klass);
     if (strcmp(specifier, struct_sym) != 0) {
-        const char *first_underscore = strchr(specifier, '_');
-        int mismatch = !first_underscore
-                       || strcmp(first_underscore + 1, struct_sym) != 0;
-        if (mismatch) {
+        const char *full_struct_sym = CFCClass_full_struct_sym(klass);
+        if (strcmp(specifier, full_struct_sym) != 0) {
             CFCUtil_die("First arg type doesn't match class: '%s' '%s'",
-                        class_name, specifier);
+                        CFCClass_get_name(klass), specifier);
         }
     }
 
-    self->novel_method      = NULL;
-    self->fresh_class_name  = CFCUtil_strdup(class_name);
-    self->host_alias        = NULL;
-    self->is_final          = is_final;
-    self->is_abstract       = is_abstract;
-    self->is_excluded       = false;
+    self->novel_method = NULL;
+    self->fresh_class  = CFCWeakPtr_new((CFCBase*)klass);
+    self->host_alias   = NULL;
+    self->is_final     = is_final;
+    self->is_abstract  = is_abstract;
+    self->is_excluded  = false;
 
     // Assume that this method is novel until we discover when applying
     // inheritance that it overrides another.
@@ -142,7 +140,7 @@ CFCMethod_resolve_types(CFCMethod *self) {
 void
 CFCMethod_destroy(CFCMethod *self) {
     CFCBase_decref((CFCBase*)self->novel_method);
-    FREEMEM(self->fresh_class_name);
+    CFCWeakPtr_destroy(&self->fresh_class);
     FREEMEM(self->host_alias);
     CFCCallable_destroy((CFCCallable*)self);
 }
@@ -209,12 +207,14 @@ CFCMethod_override(CFCMethod *self, CFCMethod *orig) {
     if (CFCMethod_final(orig)) {
         const char *orig_name  = CFCMethod_get_name(orig);
         CFCUtil_die("Attempt to override final method '%s' from '%s' by '%s'",
-                    orig_name, orig->fresh_class_name, self->fresh_class_name);
+                    orig_name, S_fresh_class_name(orig),
+                    S_fresh_class_name(self));
     }
     if (!CFCMethod_compatible(self, orig)) {
         const char *orig_name  = CFCMethod_get_name(orig);
         CFCUtil_die("Non-matching signatures for method '%s' in '%s' and '%s'",
-                    orig_name, orig->fresh_class_name, self->fresh_class_name);
+                    orig_name, S_fresh_class_name(orig),
+                    S_fresh_class_name(self));
     }
 
     // Mark the Method as no longer novel.
@@ -234,7 +234,7 @@ CFCMethod_finalize(CFCMethod *self) {
                         self->callable.return_type,
                         self->callable.param_list,
                         self->callable.docucomment,
-                        self->fresh_class_name, true, self->is_abstract);
+                        S_fresh_class(self), true, self->is_abstract);
     finalized->novel_method
         = (CFCMethod*)CFCBase_incref((CFCBase*)self->novel_method);
     finalized->is_novel = self->is_novel;
@@ -289,14 +289,14 @@ CFCMethod_set_host_alias(CFCMethod *self, const char 
*alias) {
     if (!self->is_novel) {
         const char *name = CFCMethod_get_name(self);
         CFCUtil_die("Can't set_host_alias %s -- method %s not novel in %s",
-                    alias, name, self->fresh_class_name);
+                    alias, name, S_fresh_class_name(self));
     }
     if (self->host_alias) {
         const char *name = CFCMethod_get_name(self);
         if (strcmp(self->host_alias, alias) == 0) { return; }
         CFCUtil_die("Can't set_host_alias %s -- already set to %s for method"
                     " %s in %s", alias, self->host_alias, name,
-                    self->fresh_class_name);
+                    S_fresh_class_name(self));
     }
     self->host_alias = CFCUtil_strdup(alias);
 }
@@ -312,7 +312,7 @@ CFCMethod_exclude_from_host(CFCMethod *self) {
     if (!self->is_novel) {
         const char *name = CFCMethod_get_name(self);
         CFCUtil_die("Can't exclude_from_host -- method %s not novel in %s",
-                    name, self->fresh_class_name);
+                    name, S_fresh_class_name(self));
     }
     self->is_excluded = true;
 }
@@ -414,8 +414,7 @@ CFCMethod_get_exposure(CFCMethod *self) {
 
 int
 CFCMethod_is_fresh(CFCMethod *self, CFCClass *klass) {
-    const char *class_name = CFCClass_get_name(klass);
-    return strcmp(self->fresh_class_name, class_name) == 0;
+    return S_fresh_class(self) == klass;
 }
 
 int
@@ -454,3 +453,13 @@ CFCMethod_short_imp_func(CFCMethod *self, CFCClass *klass) 
{
     return S_short_method_sym(self, klass, "_IMP");
 }
 
+static CFCClass*
+S_fresh_class(CFCMethod *self) {
+    return (CFCClass*)CFCWeakPtr_deref(self->fresh_class);
+}
+
+static const char*
+S_fresh_class_name(CFCMethod *self) {
+    return CFCClass_get_name(S_fresh_class(self));
+}
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a0e051a0/compiler/src/CFCMethod.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCMethod.h b/compiler/src/CFCMethod.h
index 37c4773..3a97c7a 100644
--- a/compiler/src/CFCMethod.h
+++ b/compiler/src/CFCMethod.h
@@ -46,23 +46,22 @@ struct CFCJson;
  * method.
  * @param return_type See Clownfish::CFC::Model::Function.
  * @param param_list - A Clownfish::CFC::Model::ParamList.  The first element
- * must be an object of the class identified by C<class_name>.
+ * must be an object of C<klass>.
  * @param docucomment see Clownfish::CFC::Model::Function.  May be NULL.
- * @param class_name The full name of the class in whose namespace the
- * method is fresh.
+ * @param klass The class in whose namespace the method is fresh.
  * @param is_final - Indicate whether the method is final.
  * @param is_abstract - Indicate whether the method is abstract.
  */
 CFCMethod*
 CFCMethod_new(const char *exposure, const char *name,
               struct CFCType *return_type, struct CFCParamList *param_list,
-              struct CFCDocuComment *docucomment, const char *class_name,
+              struct CFCDocuComment *docucomment, struct CFCClass *klass,
               int is_final, int is_abstract);
 
 CFCMethod*
 CFCMethod_init(CFCMethod *self, const char *exposure, const char *name,
                struct CFCType *return_type, struct CFCParamList *param_list,
-               struct CFCDocuComment *docucomment, const char *class_name,
+               struct CFCDocuComment *docucomment, struct CFCClass *klass,
                int is_final, int is_abstract);
 
 void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a0e051a0/compiler/src/CFCParseHeader.y
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParseHeader.y b/compiler/src/CFCParseHeader.y
index 14e5f1b..500b114 100644
--- a/compiler/src/CFCParseHeader.y
+++ b/compiler/src/CFCParseHeader.y
@@ -113,9 +113,8 @@ S_new_sub(CFCParser *state, CFCDocuComment *docucomment,
             CFCUtil_die("Methods must not be inline");
         }
         CFCClass *klass = CFCParser_get_class(state);
-        const char *class_name = CFCClass_get_name(klass);
         sub = (CFCBase*)CFCMethod_new(exposure, name, type, param_list,
-                                      docucomment, class_name, is_final,
+                                      docucomment, klass, is_final,
                                       is_abstract);
     }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a0e051a0/compiler/src/CFCTestMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestMethod.c b/compiler/src/CFCTestMethod.c
index e927fe4..634e1de 100644
--- a/compiler/src/CFCTestMethod.c
+++ b/compiler/src/CFCTestMethod.c
@@ -50,7 +50,7 @@ S_run_final_tests(CFCTest *test);
 
 const CFCTestBatch CFCTEST_BATCH_METHOD = {
     "Clownfish::CFC::Model::Method",
-    84,
+    76,
     S_run_tests
 };
 
@@ -64,13 +64,13 @@ S_run_tests(CFCTest *test) {
 
 static char*
 S_try_new_method(const char *name, CFCType *return_type,
-                 CFCParamList *param_list, const char *class_name) {
+                 CFCParamList *param_list, CFCClass *klass) {
     CFCMethod *method = NULL;
     char      *error;
 
     CFCUTIL_TRY {
         method = CFCMethod_new(NULL, name, return_type, param_list, NULL,
-                               class_name, 0, 0);
+                               klass, 0, 0);
     }
     CFCUTIL_CATCH(error);
 
@@ -83,6 +83,12 @@ S_run_basic_tests(CFCTest *test) {
     CFCParser *parser = CFCParser_new();
     CFCParcel *neato_parcel
         = CFCTest_parse_parcel(test, parser, "parcel Neato;");
+    CFCClass *neato_foo
+        = CFCClass_create(neato_parcel, NULL, "Neato::Foo", NULL, NULL, NULL,
+                          NULL, false, false, false);
+    CFCClass *neato_bar
+        = CFCClass_create(neato_parcel, NULL, "Neato::Bar", NULL, NULL, NULL,
+                          NULL, false, false, false);
 
     CFCType *return_type = CFCTest_parse_type(test, parser, "Obj*");
     CFCParamList *param_list
@@ -90,48 +96,23 @@ S_run_basic_tests(CFCTest *test) {
                                    "(Foo *self, int32_t count = 0)");
     CFCMethod *method
         = CFCMethod_new(NULL, "Return_An_Obj", return_type, param_list, NULL,
-                        "Neato::Foo", 0, 0);
+                        neato_foo, 0, 0);
     OK(test, method != NULL, "new");
     OK(test, CFCSymbol_parcel((CFCSymbol*)method),
        "parcel exposure by default");
 
     {
         char *error = S_try_new_method("return_an_obj", return_type,
-                                       param_list, "Neato::Foo");
+                                       param_list, neato_foo);
         OK(test, error && strstr(error, "name"),
            "invalid name kills constructor");
         FREEMEM(error);
     }
 
     {
-        static const char *bad_class_names[4] = {
-            "foo", "1Foo", "Foo_Bar", "1FOOBAR"
-        };
-        for (int i = 0; i < 4; i++) {
-            const char *bad_class_name = bad_class_names[i];
-            char *error;
-
-            error = S_try_new_method("Return_An_Obj", return_type,
-                                     param_list, bad_class_name);
-            OK(test, error && strstr(error, "class_name"),
-               "Reject invalid class name %s", bad_class_name);
-            FREEMEM(error);
-
-            char *bogus_middle
-                = CFCUtil_sprintf("Foo::%s::Bar", bad_class_name);
-            error = S_try_new_method("Return_An_Obj", return_type,
-                                     param_list, bogus_middle);
-            OK(test, error && strstr(error, "class_name"),
-               "Reject invalid class name %s", bogus_middle);
-            FREEMEM(error);
-            FREEMEM(bogus_middle);
-        }
-    }
-
-    {
         CFCMethod *dupe
             = CFCMethod_new(NULL, "Return_An_Obj", return_type, param_list,
-                            NULL, "Neato::Foo", 0, 0);
+                            NULL, neato_foo, 0, 0);
         OK(test, CFCMethod_compatible(method, dupe), "compatible");
         CFCBase_decref((CFCBase*)dupe);
     }
@@ -139,7 +120,7 @@ S_run_basic_tests(CFCTest *test) {
     {
         CFCMethod *name_differs
             = CFCMethod_new(NULL, "Eat", return_type, param_list, NULL,
-                            "Neato::Foo", 0, 0);
+                            neato_foo, 0, 0);
         OK(test, !CFCMethod_compatible(method, name_differs),
            "different name spoils compatible");
         OK(test, !CFCMethod_compatible(name_differs, method),
@@ -167,7 +148,7 @@ S_run_basic_tests(CFCTest *test) {
                 = CFCTest_parse_param_list(test, parser, param_strings[i]);
             CFCMethod *other
                 = CFCMethod_new(NULL, "Return_An_Obj", return_type,
-                                other_param_list, NULL, "Neato::Foo", 0, 0);
+                                other_param_list, NULL, neato_foo, 0, 0);
             OK(test, !CFCMethod_compatible(method, other),
                "%s spoils compatible", test_names[i]);
             OK(test, !CFCMethod_compatible(other, method),
@@ -183,7 +164,7 @@ S_run_basic_tests(CFCTest *test) {
                                        "(Bar *self, int32_t count = 0)");
         CFCMethod *self_differs
             = CFCMethod_new(NULL, "Return_An_Obj", return_type,
-                            self_differs_list, NULL, "Neato::Bar", 0, 0);
+                            self_differs_list, NULL, neato_bar, 0, 0);
         OK(test, CFCMethod_compatible(method, self_differs),
            "different self type still compatible(),"
            " since can't test inheritance");
@@ -196,7 +177,7 @@ S_run_basic_tests(CFCTest *test) {
     {
         CFCMethod *aliased
             = CFCMethod_new(NULL, "Aliased", return_type, param_list, NULL,
-                            "Neato::Foo", 0, 0);
+                            neato_foo, 0, 0);
         OK(test, !CFCMethod_get_host_alias(aliased),
            "no host alias by default");
         CFCMethod_set_host_alias(aliased, "Host_Alias");
@@ -208,7 +189,7 @@ S_run_basic_tests(CFCTest *test) {
     {
         CFCMethod *excluded
             = CFCMethod_new(NULL, "Excluded", return_type, param_list, NULL,
-                            "Neato::Foo", 0, 0);
+                            neato_foo, 0, 0);
         OK(test, !CFCMethod_excluded_from_host(excluded),
            "not excluded by default");
         CFCMethod_exclude_from_host(excluded);
@@ -218,10 +199,13 @@ S_run_basic_tests(CFCTest *test) {
 
     CFCBase_decref((CFCBase*)parser);
     CFCBase_decref((CFCBase*)neato_parcel);
+    CFCBase_decref((CFCBase*)neato_foo);
+    CFCBase_decref((CFCBase*)neato_bar);
     CFCBase_decref((CFCBase*)return_type);
     CFCBase_decref((CFCBase*)param_list);
     CFCBase_decref((CFCBase*)method);
 
+    CFCClass_clear_registry();
     CFCParcel_reap_singletons();
 }
 
@@ -261,6 +245,7 @@ S_run_parser_tests(CFCTest *test) {
     CFCBase_decref((CFCBase*)neato_parcel);
     CFCBase_decref((CFCBase*)parser);
 
+    CFCClass_clear_registry();
     CFCParcel_reap_singletons();
 }
 
@@ -269,19 +254,25 @@ S_run_overridden_tests(CFCTest *test) {
     CFCParser *parser = CFCParser_new();
     CFCParcel *neato_parcel
         = CFCTest_parse_parcel(test, parser, "parcel Neato;");
+    CFCClass *neato_foo
+        = CFCClass_create(neato_parcel, NULL, "Neato::Foo", NULL, NULL, NULL,
+                          NULL, false, false, false);
+    CFCClass *neato_foo_jr
+        = CFCClass_create(neato_parcel, NULL, "Neato::Foo::FooJr", NULL, NULL,
+                          NULL, "Neato::Foo", false, false, false);
     CFCType *return_type = CFCTest_parse_type(test, parser, "Obj*");
 
     CFCParamList *param_list
         = CFCTest_parse_param_list(test, parser, "(Foo *self)");
     CFCMethod *orig
         = CFCMethod_new(NULL, "Return_An_Obj", return_type, param_list, NULL,
-                        "Neato::Foo", 0, 0);
+                        neato_foo, 0, 0);
 
     CFCParamList *overrider_param_list
         = CFCTest_parse_param_list(test, parser, "(FooJr *self)");
     CFCMethod *overrider
         = CFCMethod_new(NULL, "Return_An_Obj", return_type,
-                        overrider_param_list, NULL, "Neato::Foo::FooJr", 0, 0);
+                        overrider_param_list, NULL, neato_foo_jr, 0, 0);
 
     CFCMethod_override(overrider, orig);
     OK(test, !CFCMethod_novel(overrider),
@@ -289,12 +280,15 @@ S_run_overridden_tests(CFCTest *test) {
 
     CFCBase_decref((CFCBase*)parser);
     CFCBase_decref((CFCBase*)neato_parcel);
+    CFCBase_decref((CFCBase*)neato_foo);
+    CFCBase_decref((CFCBase*)neato_foo_jr);
     CFCBase_decref((CFCBase*)return_type);
     CFCBase_decref((CFCBase*)param_list);
     CFCBase_decref((CFCBase*)orig);
     CFCBase_decref((CFCBase*)overrider_param_list);
     CFCBase_decref((CFCBase*)overrider);
 
+    CFCClass_clear_registry();
     CFCParcel_reap_singletons();
 }
 
@@ -313,7 +307,7 @@ S_run_final_tests(CFCTest *test) {
 
     CFCMethod *not_final
         = CFCMethod_new(NULL, "Return_An_Obj", return_type, param_list, NULL,
-                        "Neato::Foo", 0, 0);
+                        foo_class, 0, 0);
     CFCMethod_resolve_types(not_final);
     CFCMethod *final = CFCMethod_finalize(not_final);
     OK(test, CFCMethod_compatible(not_final, final),

Reply via email to