Store class array in parcel

Store an array of all classes that belong to a parcel in CFCParcel.


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

Branch: refs/heads/master
Commit: 22e055c360f32e93103b04814de7c89c8d4c3211
Parents: bfd19d2
Author: Nick Wellnhofer <wellnho...@aevum.de>
Authored: Sun Feb 26 21:32:58 2017 +0100
Committer: Nick Wellnhofer <wellnho...@aevum.de>
Committed: Thu Mar 2 20:08:03 2017 +0100

----------------------------------------------------------------------
 compiler/perl/lib/Clownfish/CFC.xs |  8 +++---
 compiler/perl/t/401-class.t        |  3 ++
 compiler/perl/t/403-parcel.t       | 17 +++++++++--
 compiler/perl/t/600-parser.t       |  2 +-
 compiler/src/CFCClass.c            | 21 ++------------
 compiler/src/CFCParcel.c           | 50 +++++++++++++++++++++++----------
 compiler/src/CFCParcel.h           |  3 +-
 compiler/src/CFCTestParcel.c       | 18 ++++++++++--
 compiler/src/CFCTestParser.c       |  4 +--
 9 files changed, 79 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/22e055c3/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC.xs 
b/compiler/perl/lib/Clownfish/CFC.xs
index c5ee7dd..588e585 100644
--- a/compiler/perl/lib/Clownfish/CFC.xs
+++ b/compiler/perl/lib/Clownfish/CFC.xs
@@ -1157,11 +1157,11 @@ CODE:
 OUTPUT: RETVAL
 
 void
-add_struct_sym(self, struct_sym)
-    CFCParcel  *self;
-    const char *struct_sym;
+add_class(self, klass)
+    CFCParcel *self;
+    CFCClass  *klass;
 PPCODE:
-    CFCParcel_add_struct_sym(self, struct_sym);
+    CFCParcel_add_class(self, klass);
 
 SV*
 lookup_struct_sym(self, struct_sym)

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/22e055c3/compiler/perl/t/401-class.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/401-class.t b/compiler/perl/t/401-class.t
index 0649b16..b7e4af8 100644
--- a/compiler/perl/t/401-class.t
+++ b/compiler/perl/t/401-class.t
@@ -246,6 +246,7 @@ $class = $parser->parse($class_content);
 ok( $class->final, "final class_declaration" );
 
 Clownfish::CFC::Model::Class->_clear_registry();
+Clownfish::CFC::Model::Parcel->reap_singletons();
 
 {
     eval {
@@ -256,6 +257,7 @@ Clownfish::CFC::Model::Class->_clear_registry();
     like( $@, qr/inert class/i, "inert class can't inherit" );
 
     Clownfish::CFC::Model::Class->_clear_registry();
+    Clownfish::CFC::Model::Parcel->reap_singletons();
 }
 
 {
@@ -267,5 +269,6 @@ Clownfish::CFC::Model::Class->_clear_registry();
     like( $@, qr/inert class/i, "can't inherit from inert class" );
 
     Clownfish::CFC::Model::Class->_clear_registry();
+    Clownfish::CFC::Model::Parcel->reap_singletons();
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/22e055c3/compiler/perl/t/403-parcel.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/403-parcel.t b/compiler/perl/t/403-parcel.t
index c298e55..efd86e6 100644
--- a/compiler/perl/t/403-parcel.t
+++ b/compiler/perl/t/403-parcel.t
@@ -192,9 +192,20 @@ Clownfish::CFC::Model::Parcel->reap_singletons();
     ok( $crust->has_prereq($crust), 'has_prereq self' );
     ok( !$crust->has_prereq($foo), 'has_prereq false' );
 
-    $cfish->add_struct_sym('Swim');
-    $crust->add_struct_sym('Pinch');
-    $foo->add_struct_sym('Bar');
+    Clownfish::CFC::Model::Class->create(
+        parcel     => $cfish,
+        file_spec  => $cfish_file_spec,
+        class_name => 'Clownfish::Swim',
+    );
+    Clownfish::CFC::Model::Class->create(
+        parcel     => $crust,
+        class_name => 'Crustacean::Pinch',
+    );
+    Clownfish::CFC::Model::Class->create(
+        parcel     => $foo,
+        file_spec  => $foo_file_spec,
+        class_name => 'Foo::Bar',
+    );
     my $found;
     $found = $crust->lookup_struct_sym('Swim');
     is( $found->get_name, 'Clownfish', 'lookup_struct_sym prereq' );

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/22e055c3/compiler/perl/t/600-parser.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/600-parser.t b/compiler/perl/t/600-parser.t
index 19508f9..9530dfd 100644
--- a/compiler/perl/t/600-parser.t
+++ b/compiler/perl/t/600-parser.t
@@ -143,7 +143,7 @@ SKIP: {
 }
 
 is( $parser->parse("class $_ { }")->get_name, $_, "class_name: $_" )
-    for (qw( Foo Foo::FooJr Foo::FooJr::FooIII Foo::FooJr::FooIII::Foo4th ));
+    for (qw( Moo Moo::MooJr Moo::MooJr::MooIII Moo::MooJr::MooIII::Moo4th ));
 
 SKIP: {
     skip( "Can't recover from bad class name under flex/lemon parser", 6 );

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/22e055c3/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCClass.c b/compiler/src/CFCClass.c
index e7a1aa1..501cf7a 100644
--- a/compiler/src/CFCClass.c
+++ b/compiler/src/CFCClass.c
@@ -300,6 +300,7 @@ CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel,
     CFCUTIL_TRY {
         // Store in registry.
         S_register(self);
+        CFCParcel_add_class(parcel, self);
     }
     CFCUTIL_CATCH(error);
 
@@ -308,8 +309,6 @@ CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel,
         CFCUtil_rethrow(error);
     }
 
-    CFCParcel_add_struct_sym(parcel, self->struct_sym);
-
     return self;
 }
 
@@ -367,28 +366,14 @@ S_register(CFCClass *self) {
         registry_cap = new_cap;
     }
 
-    const char *prefix     = CFCParcel_get_prefix(self->parcel);
-    const char *name       = self->name;
-    const char *nickname   = self->nickname;
-    const char *struct_sym = self->full_struct_sym;
+    const char *name = self->name;
 
     for (size_t i = 0; i < registry_size; i++) {
-        CFCClass   *other        = registry[i];
-        const char *other_prefix = CFCParcel_get_prefix(other->parcel);
+        CFCClass *other = registry[i];
 
         if (strcmp(name, other->name) == 0) {
             CFCUtil_die("Two classes with name %s", name);
         }
-        if (strcmp(struct_sym, other->full_struct_sym) == 0) {
-            CFCUtil_die("Class name conflict between %s and %s",
-                        name, other->name);
-        }
-        if (strcmp(prefix, other_prefix) == 0
-            && strcmp(nickname, other->nickname) == 0
-           ) {
-            CFCUtil_die("Class nickname conflict between %s and %s",
-                        name, other->name);
-        }
     }
 
     registry[registry_size] = (CFCClass*)CFCBase_incref((CFCBase*)self);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/22e055c3/compiler/src/CFCParcel.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParcel.c b/compiler/src/CFCParcel.c
index 409044c..2c134c5 100644
--- a/compiler/src/CFCParcel.c
+++ b/compiler/src/CFCParcel.c
@@ -46,8 +46,8 @@ struct CFCParcel {
     int is_installed;
     char **inherited_parcels;
     size_t num_inherited_parcels;
-    char **struct_syms;
-    size_t num_struct_syms;
+    CFCClass **classes;
+    size_t num_classes;
     CFCPrereq **prereqs;
     size_t num_prereqs;
 };
@@ -214,8 +214,8 @@ CFCParcel_init(CFCParcel *self, const char *name, const 
char *nickname,
     // Initialize arrays.
     self->inherited_parcels = (char**)CALLOCATE(1, sizeof(char*));
     self->num_inherited_parcels = 0;
-    self->struct_syms = (char**)CALLOCATE(1, sizeof(char*));
-    self->num_struct_syms = 0;
+    self->classes = (CFCClass**)CALLOCATE(1, sizeof(CFCClass*));
+    self->num_classes = 0;
     self->prereqs = (CFCPrereq**)CALLOCATE(1, sizeof(CFCPrereq*));
     self->num_prereqs = 0;
 
@@ -368,7 +368,10 @@ CFCParcel_destroy(CFCParcel *self) {
     FREEMEM(self->PREFIX);
     FREEMEM(self->privacy_sym);
     CFCUtil_free_string_array(self->inherited_parcels);
-    CFCUtil_free_string_array(self->struct_syms);
+    for (size_t i = 0; self->classes[i]; ++i) {
+        CFCBase_decref((CFCBase*)self->classes[i]);
+    }
+    FREEMEM(self->classes);
     for (size_t i = 0; self->prereqs[i]; ++i) {
         CFCBase_decref((CFCBase*)self->prereqs[i]);
     }
@@ -580,20 +583,37 @@ CFCParcel_read_host_data_json(CFCParcel *self, const char 
*host_lang) {
 }
 
 void
-CFCParcel_add_struct_sym(CFCParcel *self, const char *struct_sym) {
-    size_t num_struct_syms = self->num_struct_syms + 1;
-    size_t size = (num_struct_syms + 1) * sizeof(char*);
-    char **struct_syms = (char**)REALLOCATE(self->struct_syms, size);
-    struct_syms[num_struct_syms-1] = CFCUtil_strdup(struct_sym);
-    struct_syms[num_struct_syms]   = NULL;
-    self->struct_syms     = struct_syms;
-    self->num_struct_syms = num_struct_syms;
+CFCParcel_add_class(CFCParcel *self, CFCClass *klass) {
+    const char *struct_sym = CFCClass_get_struct_sym(klass);
+    const char *nickname   = CFCClass_get_nickname(klass);
+
+    for (size_t i = 0; self->classes[i]; ++i) {
+        CFCClass *other = self->classes[i];
+
+        if (strcmp(struct_sym, CFCClass_get_struct_sym(other)) == 0) {
+            CFCUtil_die("Class name conflict between %s and %s",
+                        CFCClass_get_name(klass), CFCClass_get_name(other));
+        }
+        if (strcmp(nickname, CFCClass_get_nickname(other)) == 0) {
+            CFCUtil_die("Class nickname conflict between %s and %s",
+                        CFCClass_get_name(klass), CFCClass_get_name(other));
+        }
+    }
+
+    size_t num_classes = self->num_classes;
+    size_t size = (num_classes + 2) * sizeof(CFCClass*);
+    CFCClass **classes = (CFCClass**)REALLOCATE(self->classes, size);
+    classes[num_classes]   = (CFCClass*)CFCBase_incref((CFCBase*)klass);
+    classes[num_classes+1] = NULL;
+    self->classes     = classes;
+    self->num_classes = num_classes + 1;
 }
 
 static CFCParcel*
 S_lookup_struct_sym(CFCParcel *self, const char *struct_sym) {
-    for (size_t i = 0; self->struct_syms[i]; ++i) {
-        if (strcmp(self->struct_syms[i], struct_sym) == 0) {
+    for (size_t i = 0; self->classes[i]; ++i) {
+        const char *other_sym = CFCClass_get_struct_sym(self->classes[i]);
+        if (strcmp(other_sym, struct_sym) == 0) {
             return self;
         }
     }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/22e055c3/compiler/src/CFCParcel.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParcel.h b/compiler/src/CFCParcel.h
index d173079..c8adbc9 100644
--- a/compiler/src/CFCParcel.h
+++ b/compiler/src/CFCParcel.h
@@ -38,6 +38,7 @@ extern "C" {
 
 typedef struct CFCParcel CFCParcel;
 typedef struct CFCPrereq CFCPrereq;
+struct CFCClass;
 struct CFCFileSpec;
 struct CFCVersion;
 
@@ -176,7 +177,7 @@ void
 CFCParcel_read_host_data_json(CFCParcel *self, const char *host_lang);
 
 void
-CFCParcel_add_struct_sym(CFCParcel *self, const char *struct_sym);
+CFCParcel_add_class(CFCParcel *self, struct CFCClass *klass);
 
 /** Search the parcel and all direct prerequisites for a class with
  * struct_sym. Return the parcel in which the class was found or NULL.

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/22e055c3/compiler/src/CFCTestParcel.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestParcel.c b/compiler/src/CFCTestParcel.c
index 5306182..6e6cacc 100644
--- a/compiler/src/CFCTestParcel.c
+++ b/compiler/src/CFCTestParcel.c
@@ -20,6 +20,7 @@
 
 #define CFC_USE_TEST_MACROS
 #include "CFCBase.h"
+#include "CFCClass.h"
 #include "CFCFileSpec.h"
 #include "CFCParcel.h"
 #include "CFCSymbol.h"
@@ -278,9 +279,16 @@ S_run_extended_tests(CFCTest *test) {
         OK(test, CFCParcel_has_prereq(crust, crust), "has_prereq self");
         OK(test, !CFCParcel_has_prereq(crust, foo), "has_prereq false");
 
-        CFCParcel_add_struct_sym(cfish, "Swim");
-        CFCParcel_add_struct_sym(crust, "Pinch");
-        CFCParcel_add_struct_sym(foo, "Bar");
+        CFCClass *swim
+            = CFCClass_create(cfish, NULL, "Clownfish::Swim", NULL, NULL,
+                              cfish_file_spec, "Clownfish::Obj", false, false,
+                              false);
+        CFCClass *pinch
+            = CFCClass_create(crust, NULL, "Crustacean::Pinch", NULL, NULL,
+                              NULL, "Clownfish::Obj", false, false, false);
+        CFCClass *bar
+            = CFCClass_create(foo, NULL, "Foo::Bar", NULL, NULL, foo_file_spec,
+                              "Clownfish::Obj", false, false, false);
         CFCParcel *found;
         found = CFCParcel_lookup_struct_sym(crust, "Swim");
         OK(test, found == cfish, "lookup_struct_sym prereq");
@@ -290,12 +298,16 @@ S_run_extended_tests(CFCTest *test) {
         OK(test, found == NULL, "lookup_struct_sym other");
 
         FREEMEM(prereq_parcels);
+        CFCBase_decref((CFCBase*)bar);
+        CFCBase_decref((CFCBase*)pinch);
+        CFCBase_decref((CFCBase*)swim);
         CFCBase_decref((CFCBase*)crust);
         CFCBase_decref((CFCBase*)cfish_version);
         CFCBase_decref((CFCBase*)cfish_file_spec);
         CFCBase_decref((CFCBase*)cfish);
         CFCBase_decref((CFCBase*)foo_file_spec);
         CFCBase_decref((CFCBase*)foo);
+        CFCClass_clear_registry();
         CFCParcel_reap_singletons();
     }
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/22e055c3/compiler/src/CFCTestParser.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestParser.c b/compiler/src/CFCTestParser.c
index 304c8d7..219acb6 100644
--- a/compiler/src/CFCTestParser.c
+++ b/compiler/src/CFCTestParser.c
@@ -276,8 +276,8 @@ S_run_tests(CFCTest *test) {
 
     {
         static const char *const class_names[4] = {
-            "Foo", "Foo::FooJr", "Foo::FooJr::FooIII",
-            "Foo::FooJr::FooIII::Foo4th"
+            "Moo", "Moo::MooJr", "Moo::MooJr::MooIII",
+            "Moo::MooJr::MooIII::Moo4th"
         };
         for (int i = 0; i < 4; ++i) {
             const char *class_name = class_names[i];

Reply via email to