lucy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nwelln...@apache.org
Subject [lucy-commits] [07/11] git commit: Switch from implicit to explicit dependencies
Date Mon, 17 Mar 2014 20:36:20 GMT
Switch from implicit to explicit dependencies

Stop inferring the dependencies from the types used in a parcel. Use the
prerequisites from the parcel definition instead.


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

Branch: refs/heads/master
Commit: 0b2d24ede7c81cb8ce22a6a81624c22e09df38f1
Parents: 9abd6a8
Author: Nick Wellnhofer <wellnhofer@aevum.de>
Authored: Wed Mar 12 17:01:08 2014 +0100
Committer: Nick Wellnhofer <wellnhofer@aevum.de>
Committed: Mon Mar 17 18:25:30 2014 +0100

----------------------------------------------------------------------
 compiler/perl/lib/Clownfish/CFC.xs | 11 +----
 compiler/perl/t/403-parcel.t       | 12 +----
 compiler/src/CFCBindCore.c         | 39 ++++++++--------
 compiler/src/CFCClass.c            |  8 ++++
 compiler/src/CFCParcel.c           | 80 +++++++++++++--------------------
 compiler/src/CFCParcel.h           | 24 +++++-----
 compiler/src/CFCTestParcel.c       | 14 +++++-
 compiler/src/CFCType.c             | 26 ++---------
 8 files changed, 91 insertions(+), 123 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0b2d24ed/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC.xs b/compiler/perl/lib/Clownfish/CFC.xs
index 410658d..faa74f3 100644
--- a/compiler/perl/lib/Clownfish/CFC.xs
+++ b/compiler/perl/lib/Clownfish/CFC.xs
@@ -1148,13 +1148,6 @@ CODE:
 OUTPUT: RETVAL
 
 void
-add_dependent_parcel(self, dependent)
-    CFCParcel *self;
-    CFCParcel *dependent;
-PPCODE:
-    CFCParcel_add_dependent_parcel(self, dependent);
-
-void
 add_inherited_parcel(self, inherited)
     CFCParcel *self;
     CFCParcel *inherited;
@@ -1178,7 +1171,7 @@ ALIAS:
     get_PREFIX = 10
     get_version = 12
     included    = 14
-    dependent_parcels = 16
+    prereq_parcels    = 16
     inherited_parcels = 18
 PPCODE:
 {
@@ -1217,7 +1210,7 @@ PPCODE:
             retval = newSViv(CFCParcel_included(self));
             break;
         case 16: {
-                CFCParcel **parcels = CFCParcel_dependent_parcels(self);
+                CFCParcel **parcels = CFCParcel_prereq_parcels(self);
                 retval = S_array_of_cfcbase_to_av((CFCBase**)parcels);
                 FREEMEM(parcels);
             }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0b2d24ed/compiler/perl/t/403-parcel.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/403-parcel.t b/compiler/perl/t/403-parcel.t
index c311987..540e6ba 100644
--- a/compiler/perl/t/403-parcel.t
+++ b/compiler/perl/t/403-parcel.t
@@ -16,7 +16,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 18;
+use Test::More tests => 17;
 use File::Spec::Functions qw( catfile );
 
 BEGIN { use_ok('Clownfish::CFC::Model::Parcel') }
@@ -50,17 +50,7 @@ my $parcels = Clownfish::CFC::Model::Parcel->all_parcels;
 my @names = sort(map { $_->get_name } @$parcels);
 is_deeply( \@names, [ "Foo", "IncludedFoo" ], "all_parcels" );
 
-my $dependent_foo = Clownfish::CFC::Model::Parcel->new(
-    name        => "DependentFoo",
-    is_included => 1,
-);
-$dependent_foo->register;
-
 $foo->add_inherited_parcel($included_foo);
-$foo->add_dependent_parcel($dependent_foo);
-my @dep_names = sort(map { $_->get_name } @{ $foo->dependent_parcels });
-is_deeply( \@dep_names, [ "DependentFoo", "IncludedFoo" ],
-           "dependent_parcels" );
 my @inh_names = sort(map { $_->get_name } @{ $foo->inherited_parcels });
 is_deeply( \@inh_names, [ "IncludedFoo" ], "inherited_parcels" );
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0b2d24ed/compiler/src/CFCBindCore.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindCore.c b/compiler/src/CFCBindCore.c
index 5ae8ac6..e8d49e6 100644
--- a/compiler/src/CFCBindCore.c
+++ b/compiler/src/CFCBindCore.c
@@ -283,14 +283,15 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
         extra_defs = "";
         extra_includes = CFCUtil_strdup("");
 
-        // Include parcel.h of dependent parcels.
-        CFCParcel **dep_parcels = CFCParcel_dependent_parcels(parcel);
-        for (size_t i = 0; dep_parcels[i]; ++i) {
-            const char *dep_prefix = CFCParcel_get_prefix(dep_parcels[i]);
+        // Include parcel.h of prerequisite parcels.
+        CFCParcel **prereq_parcels = CFCParcel_prereq_parcels(parcel);
+        for (size_t i = 0; prereq_parcels[i]; ++i) {
+            const char *prereq_prefix
+                = CFCParcel_get_prefix(prereq_parcels[i]);
             extra_includes = CFCUtil_cat(extra_includes, "#include <",
-                                         dep_prefix, "parcel.h>\n", NULL);
+                                         prereq_prefix, "parcel.h>\n", NULL);
         }
-        FREEMEM(dep_parcels);
+        FREEMEM(prereq_parcels);
     }
 
     const char pattern[] =
@@ -392,18 +393,18 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
     vt_specs = CFCUtil_cat(vt_specs, "\n};\n", NULL);
     FREEMEM(ordered);
 
-    // Bootstrapping code for dependent parcels.
+    // Bootstrapping code for prerequisite parcels.
     //
     // bootstrap_inheritance() first calls bootstrap_inheritance() for all
     // parcels from which classes are inherited. Then the VTables of the parcel
     // are initialized. It aborts on recursive invocation.
     //
     // bootstrap_parcel() first calls bootstrap_inheritance() of its own
-    // parcel. Then it calls bootstrap_parcel() for all dependent parcels.
+    // parcel. Then it calls bootstrap_parcel() for all prerequisite parcels.
     // Finally, it calls init_parcel(). Recursive invocation is allowed.
 
-    char *inh_bootstrap = CFCUtil_strdup("");
-    char *dep_bootstrap = CFCUtil_strdup("");
+    char *inh_bootstrap    = CFCUtil_strdup("");
+    char *prereq_bootstrap = CFCUtil_strdup("");
     CFCParcel **inh_parcels = CFCParcel_inherited_parcels(parcel);
     for (size_t i = 0; inh_parcels[i]; ++i) {
         const char *inh_prefix = CFCParcel_get_prefix(inh_parcels[i]);
@@ -411,13 +412,13 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
                                     "bootstrap_inheritance();\n", NULL);
     }
     FREEMEM(inh_parcels);
-    CFCParcel **dep_parcels = CFCParcel_dependent_parcels(parcel);
-    for (size_t i = 0; dep_parcels[i]; ++i) {
-        const char *dep_prefix = CFCParcel_get_prefix(dep_parcels[i]);
-        dep_bootstrap = CFCUtil_cat(dep_bootstrap, "    ", dep_prefix,
-                                    "bootstrap_parcel();\n", NULL);
+    CFCParcel **prereq_parcels = CFCParcel_prereq_parcels(parcel);
+    for (size_t i = 0; prereq_parcels[i]; ++i) {
+        const char *prereq_prefix = CFCParcel_get_prefix(prereq_parcels[i]);
+        prereq_bootstrap = CFCUtil_cat(prereq_bootstrap, "    ", prereq_prefix,
+                                       "bootstrap_parcel();\n", NULL);
     }
-    FREEMEM(dep_parcels);
+    FREEMEM(prereq_parcels);
 
     char pattern[] =
         "%s\n"
@@ -462,7 +463,7 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
         "    if (bootstrap_state >= 3) { return; }\n"
         "    %sbootstrap_inheritance();\n"
         "    bootstrap_state = 3;\n"
-        "%s" // Finish bootstrapping of all dependent parcels.
+        "%s" // Finish bootstrapping of all prerequisite parcels.
         "    %sinit_parcel();\n"
         "}\n"
         "\n"
@@ -470,7 +471,7 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
     char *file_content
         = CFCUtil_sprintf(pattern, self->header, privacy_syms, prefix,
                           includes, c_data, vt_specs, prefix, inh_bootstrap,
-                          num_specs, prefix, prefix, dep_bootstrap, prefix,
+                          num_specs, prefix, prefix, prereq_bootstrap, prefix,
                           self->footer);
 
     // Unlink then open file.
@@ -486,7 +487,7 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
     FREEMEM(c_data);
     FREEMEM(vt_specs);
     FREEMEM(inh_bootstrap);
-    FREEMEM(dep_bootstrap);
+    FREEMEM(prereq_bootstrap);
     FREEMEM(file_content);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0b2d24ed/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCClass.c b/compiler/src/CFCClass.c
index c2d5a2b..61a9d42 100644
--- a/compiler/src/CFCClass.c
+++ b/compiler/src/CFCClass.c
@@ -361,6 +361,14 @@ CFCClass_add_child(CFCClass *self, CFCClass *child) {
     // Add parcel dependency.
     CFCParcel *parcel       = CFCClass_get_parcel(self);
     CFCParcel *child_parcel = CFCClass_get_parcel(child);
+    if (!CFCParcel_has_prereq(child_parcel, parcel)) {
+        CFCUtil_die("Class '%s' inherits from '%s', but parcel '%s' is not a"
+                    " prerequisite of '%s'",
+                    CFCClass_get_class_name(child),
+                    CFCClass_get_class_name(self),
+                    CFCParcel_get_name(parcel),
+                    CFCParcel_get_name(child_parcel));
+    }
     CFCParcel_add_inherited_parcel(child_parcel, parcel);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0b2d24ed/compiler/src/CFCParcel.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParcel.c b/compiler/src/CFCParcel.c
index b54e014..e53ff01 100644
--- a/compiler/src/CFCParcel.c
+++ b/compiler/src/CFCParcel.c
@@ -40,8 +40,6 @@ struct CFCParcel {
     char *privacy_sym;
     int is_included;
     int is_required;
-    char **dependent_parcels;
-    size_t num_dependent_parcels;
     char **inherited_parcels;
     size_t num_inherited_parcels;
     CFCPrereq **prereqs;
@@ -252,13 +250,9 @@ CFCParcel_init(CFCParcel *self, const char *name, const char *cnick,
     self->is_included = is_included;
     self->is_required = false;
 
-    // Initialize dependencies.
-    self->dependent_parcels = (char**)CALLOCATE(1, sizeof(char*));
-    self->num_dependent_parcels = 0;
+    // Initialize arrays.
     self->inherited_parcels = (char**)CALLOCATE(1, sizeof(char*));
     self->num_inherited_parcels = 0;
-
-    // Initialize prereqs.
     self->prereqs = (CFCPrereq**)CALLOCATE(1, sizeof(CFCPrereq*));
     self->num_prereqs = 0;
 
@@ -389,10 +383,6 @@ CFCParcel_destroy(CFCParcel *self) {
     FREEMEM(self->Prefix);
     FREEMEM(self->PREFIX);
     FREEMEM(self->privacy_sym);
-    for (size_t i = 0; self->dependent_parcels[i]; ++i) {
-        FREEMEM(self->dependent_parcels[i]);
-    }
-    FREEMEM(self->dependent_parcels);
     for (size_t i = 0; self->inherited_parcels[i]; ++i) {
         FREEMEM(self->inherited_parcels[i]);
     }
@@ -469,27 +459,6 @@ CFCParcel_required(CFCParcel *self) {
 }
 
 void
-CFCParcel_add_dependent_parcel(CFCParcel *self, CFCParcel *dependent) {
-    const char *name     = CFCParcel_get_name(self);
-    const char *dep_name = CFCParcel_get_name(dependent);
-
-    if (strcmp(name, dep_name) == 0) { return; }
-
-    for (size_t i = 0; self->dependent_parcels[i]; ++i) {
-        const char *other_name = self->dependent_parcels[i];
-        if (strcmp(other_name, dep_name) == 0) { return; }
-    }
-
-    size_t num_parcels = self->num_dependent_parcels;
-    self->dependent_parcels
-        = (char**)REALLOCATE(self->dependent_parcels,
-                             (num_parcels + 2) * sizeof(char*));
-    self->dependent_parcels[num_parcels]   = CFCUtil_strdup(dep_name);
-    self->dependent_parcels[num_parcels+1] = NULL;
-    self->num_dependent_parcels = num_parcels + 1;
-}
-
-void
 CFCParcel_add_inherited_parcel(CFCParcel *self, CFCParcel *inherited) {
     const char *name     = CFCParcel_get_name(self);
     const char *inh_name = CFCParcel_get_name(inherited);
@@ -508,22 +477,6 @@ CFCParcel_add_inherited_parcel(CFCParcel *self, CFCParcel *inherited)
{
     self->inherited_parcels[num_parcels]   = CFCUtil_strdup(inh_name);
     self->inherited_parcels[num_parcels+1] = NULL;
     self->num_inherited_parcels = num_parcels + 1;
-
-    // Add to dependent parcels.
-    CFCParcel_add_dependent_parcel(self, inherited);
-}
-
-CFCParcel**
-CFCParcel_dependent_parcels(CFCParcel *self) {
-    CFCParcel **parcels
-        = (CFCParcel**)CALLOCATE(self->num_dependent_parcels + 1,
-                                 sizeof(CFCParcel*));
-
-    for (size_t i = 0; self->dependent_parcels[i]; ++i) {
-        parcels[i] = CFCParcel_fetch(self->dependent_parcels[i]);
-    }
-
-    return parcels;
 }
 
 CFCParcel**
@@ -544,6 +497,19 @@ CFCParcel_get_prereqs(CFCParcel *self) {
     return self->prereqs;
 }
 
+CFCParcel**
+CFCParcel_prereq_parcels(CFCParcel *self) {
+    CFCParcel **parcels
+        = (CFCParcel**)CALLOCATE(self->num_prereqs + 1, sizeof(CFCParcel*));
+
+    for (size_t i = 0; self->prereqs[i]; ++i) {
+        const char *name = CFCPrereq_get_name(self->prereqs[i]);
+        parcels[i] = CFCParcel_fetch(name);
+    }
+
+    return parcels;
+}
+
 void
 CFCParcel_check_prereqs(CFCParcel *self) {
     // This is essentially a depth-first search of the dependency graph.
@@ -578,6 +544,24 @@ CFCParcel_check_prereqs(CFCParcel *self) {
     }
 }
 
+int
+CFCParcel_has_prereq(CFCParcel *self, CFCParcel *parcel) {
+    const char *name = CFCParcel_get_name(parcel);
+
+    if (strcmp(CFCParcel_get_name(self), name) == 0) {
+        return true;
+    }
+
+    for (int i = 0; self->prereqs[i]; ++i) {
+        const char *prereq_name = CFCPrereq_get_name(self->prereqs[i]);
+        if (strcmp(prereq_name, name) == 0) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 /**************************************************************************/
 
 struct CFCPrereq {

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0b2d24ed/compiler/src/CFCParcel.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParcel.h b/compiler/src/CFCParcel.h
index 77e8d1b..4efbdd9 100644
--- a/compiler/src/CFCParcel.h
+++ b/compiler/src/CFCParcel.h
@@ -127,23 +127,12 @@ CFCParcel_included(CFCParcel *self);
 int
 CFCParcel_required(CFCParcel *self);
 
-/** Add another Parcel that the Parcel depends on.
- */
-void
-CFCParcel_add_dependent_parcel(CFCParcel *self, CFCParcel *dependent);
-
 /** Add another Parcel containing superclasses that subclasses in the Parcel
- * extend. Also adds the other Parcel to the Parcel's dependencies.
+ * extend.
  */
 void
 CFCParcel_add_inherited_parcel(CFCParcel *self, CFCParcel *inherited);
 
-/** Return a NULL-terminated array of all Parcels that the Parcel depends on.
- * Must be freed by the caller.
- */
-CFCParcel**
-CFCParcel_dependent_parcels(CFCParcel *self);
-
 /** Return a NULL-terminated array of all Parcels containing superclasses that
  * subclasses in the Parcel extend. Must be freed by the caller.
  */
@@ -155,12 +144,23 @@ CFCParcel_inherited_parcels(CFCParcel *self);
 CFCPrereq**
 CFCParcel_get_prereqs(CFCParcel *self);
 
+/** Return a NULL-terminated array of all prerequisite Parcels. Must be freed
+ * by the caller.
+ */
+CFCParcel**
+CFCParcel_prereq_parcels(CFCParcel *self);
+
 /** Recursively verify that all prerequisite parcels are present in the
  * required version. Mark all needed parcels including 'self' as required.
  */
 void
 CFCParcel_check_prereqs(CFCParcel *self);
 
+/** Return true if parcel equals self or is a direct prerequisite of self.
+ */
+int
+CFCParcel_has_prereq(CFCParcel *self, CFCParcel *parcel);
+
 /**************************************************************************/
 
 CFCPrereq*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0b2d24ed/compiler/src/CFCTestParcel.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestParcel.c b/compiler/src/CFCTestParcel.c
index 2abd7c0..c8fb528 100644
--- a/compiler/src/CFCTestParcel.c
+++ b/compiler/src/CFCTestParcel.c
@@ -20,6 +20,7 @@
 #include "CFCBase.h"
 #include "CFCParcel.h"
 #include "CFCSymbol.h"
+#include "CFCUtil.h"
 #include "CFCVersion.h"
 #include "CFCTest.h"
 
@@ -39,7 +40,7 @@ S_run_parcel_tests(CFCTest *test);
 
 const CFCTestBatch CFCTEST_BATCH_PARCEL = {
     "Clownfish::CFC::Model::Parcel",
-    26,
+    32,
     S_run_tests
 };
 
@@ -204,6 +205,17 @@ S_run_parcel_tests(CFCTest *test) {
         INT_EQ(test, CFCParcel_required(cfish), true, "prereq required");
         INT_EQ(test, CFCParcel_required(crust), true, "self required");
 
+        CFCParcel **prereq_parcels = CFCParcel_prereq_parcels(crust);
+        OK(test, prereq_parcels[0] != NULL, "prereq_parcels[0]");
+        const char *name = CFCParcel_get_name(prereq_parcels[0]);
+        STR_EQ(test, name, "Clownfish", "prereq_parcels[0] name");
+        OK(test, prereq_parcels[1] == NULL, "prereq_parcels[0]");
+
+        OK(test, CFCParcel_has_prereq(crust, cfish), "has_prereq");
+        OK(test, CFCParcel_has_prereq(crust, crust), "has_prereq self");
+        OK(test, !CFCParcel_has_prereq(crust, foo), "has_prereq false");
+
+        FREEMEM(prereq_parcels);
         CFCBase_decref((CFCBase*)crust);
         CFCBase_decref((CFCBase*)cfish_version);
         CFCBase_decref((CFCBase*)cfish);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0b2d24ed/compiler/src/CFCType.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCType.c b/compiler/src/CFCType.c
index a41ecbd..3ff7db7 100644
--- a/compiler/src/CFCType.c
+++ b/compiler/src/CFCType.c
@@ -271,11 +271,10 @@ CFCType_resolve(CFCType *self, CFCClass **classes) {
         return;
     }
 
-    CFCClass *klass     = NULL;
-    char     *specifier = self->specifier;
-
-    if (isupper(self->specifier[0])) {
+    char *specifier = self->specifier;
+    if (isupper(specifier[0])) {
         // Try to find class from class list.
+        CFCClass *klass = NULL;
         for (size_t i = 0; classes[i]; ++i) {
             CFCClass   *maybe_class = classes[i];
             const char *struct_sym  = CFCClass_get_struct_sym(maybe_class);
@@ -297,25 +296,6 @@ CFCType_resolve(CFCType *self, CFCClass **classes) {
         self->specifier = CFCUtil_sprintf("%s%s", prefix, specifier);
         FREEMEM(specifier);
     }
-    else {
-        // Try to find class from class list.
-        for (size_t i = 0; classes[i]; ++i) {
-            CFCClass *maybe_class = classes[i];
-            const char *full_struct_sym
-                = CFCClass_full_struct_sym(maybe_class);
-
-            if (strcmp(specifier, full_struct_sym) == 0) {
-                klass = maybe_class;
-                break;
-            }
-        }
-    }
-
-    // Add parcel dependency.
-    if (klass) {
-        CFCParcel *class_parcel = CFCClass_get_parcel(klass);
-        CFCParcel_add_dependent_parcel(self->parcel, class_parcel);
-    }
 }
 
 void


Mime
View raw message