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];