Add CFCType_get_class

Store a weak pointer to CFCClass in CFCType for object types.


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

Branch: refs/heads/master
Commit: 850d69bfff9f64dbf1a6a9929639b05bf9cc0fc7
Parents: c502223
Author: Nick Wellnhofer <wellnho...@aevum.de>
Authored: Mon Feb 27 19:45:52 2017 +0100
Committer: Nick Wellnhofer <wellnho...@aevum.de>
Committed: Thu Mar 2 20:08:03 2017 +0100

----------------------------------------------------------------------
 compiler/src/CFCBindMethod.c  |  3 +--
 compiler/src/CFCCHtml.c       | 22 +++++++++-------------
 compiler/src/CFCGoTypeMap.c   | 31 ++++++-------------------------
 compiler/src/CFCPerlMethod.c  | 23 ++++++++++-------------
 compiler/src/CFCPerlTypeMap.c |  5 +++--
 compiler/src/CFCPyMethod.c    |  6 ++++--
 compiler/src/CFCType.c        | 20 +++++++++-----------
 compiler/src/CFCType.h        |  7 +++----
 8 files changed, 45 insertions(+), 72 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCBindMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindMethod.c b/compiler/src/CFCBindMethod.c
index d57a29e..e6880b4 100644
--- a/compiler/src/CFCBindMethod.c
+++ b/compiler/src/CFCBindMethod.c
@@ -165,8 +165,7 @@ char*
 CFCBindMeth_abstract_method_def(CFCMethod *method, CFCClass *klass) {
     CFCType    *ret_type      = CFCMethod_get_return_type(method);
     const char *ret_type_str  = CFCType_to_c(ret_type);
-    CFCType    *type          = CFCMethod_self_type(method);
-    const char *class_var     = CFCType_get_class_var(type);
+    const char *class_var     = CFCClass_full_class_var(klass);
     const char *meth_name     = CFCMethod_get_name(method);
     CFCParamList *param_list  = CFCMethod_get_param_list(method);
     const char *params        = CFCParamList_to_c(param_list);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCCHtml.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCCHtml.c b/compiler/src/CFCCHtml.c
index 016c15b..6383ada 100644
--- a/compiler/src/CFCCHtml.c
+++ b/compiler/src/CFCCHtml.c
@@ -1071,19 +1071,15 @@ S_type_to_html(CFCType *type, const char *sep, CFCClass 
*doc_class) {
     char *specifier_html = NULL;
 
     if (CFCType_is_object(type)) {
-        CFCClass   *klass = NULL;
-
-        // Don't link to doc class.
-        if (strcmp(specifier, CFCClass_full_struct_sym(doc_class)) != 0) {
-            klass = CFCClass_fetch_by_struct_sym(specifier);
-            if (!klass) {
-                CFCUtil_warn("Class '%s' not found", specifier);
-            }
-            else if (!CFCClass_public(klass)) {
-                CFCUtil_warn("Non-public class '%s' used in public method",
-                             specifier);
-                klass = NULL;
-            }
+        CFCClass *klass = CFCType_get_class(type);
+        if (klass == doc_class) {
+            // Don't link to doc class.
+            klass = NULL;
+        }
+        else if (!CFCClass_public(klass)) {
+            CFCUtil_warn("Non-public class '%s' used in public method",
+                         specifier);
+            klass = NULL;
         }
 
         const char *underscore = strchr(specifier, '_');

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCGoTypeMap.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoTypeMap.c b/compiler/src/CFCGoTypeMap.c
index 281fb21..a9f65d1 100644
--- a/compiler/src/CFCGoTypeMap.c
+++ b/compiler/src/CFCGoTypeMap.c
@@ -24,6 +24,7 @@
 #include "CFCVariable.h"
 #include "CFCType.h"
 #include "CFCUtil.h"
+#include "CFCClass.h"
 
 #ifndef true
     #define true 1
@@ -109,32 +110,12 @@ CFCGoTypeMap_go_type_name(CFCType *type, CFCParcel 
*current_parcel) {
     }
     else if (CFCType_is_object(type)) {
         // Divide the specifier into prefix and struct name.
-        const char *specifier  = CFCType_get_specifier(type);
-        size_t      prefix_len = 0;
-        for (size_t max = strlen(specifier); prefix_len < max; prefix_len++) {
-            if (CFCUtil_isupper(specifier[prefix_len])) {
-                break;
-            }
-        }
-        if (!prefix_len) {
-            CFCUtil_die("Can't convert object type name '%s'", specifier);
-        }
-        const char *struct_sym = specifier + prefix_len;
-
-        // Find the parcel that the type lives in.
-        CFCParcel** all_parcels = CFCParcel_all_parcels();
-        CFCParcel *parcel = NULL;
-        for (int i = 0; all_parcels[i] != NULL; i++) {
-            const char *candidate = CFCParcel_get_prefix(all_parcels[i]);
-            if (strncmp(candidate, specifier, prefix_len) == 0
-                && strlen(candidate) == prefix_len
-               ) {
-                parcel = all_parcels[i];
-                break;
-            }
-        }
+        CFCClass   *klass      = CFCType_get_class(type);
+        const char *struct_sym = CFCClass_get_struct_sym(klass);
+        CFCParcel  *parcel     = CFCClass_get_parcel(klass);
         if (!parcel) {
-            CFCUtil_die("Can't find parcel for type '%s'", specifier);
+            CFCUtil_die("Can't find parcel for type '%s'",
+                        CFCType_get_specifier(type));
         }
 
         // If the type lives in this parcel, return only the struct sym

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCPerlMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlMethod.c b/compiler/src/CFCPerlMethod.c
index 9f25f92..6a59313 100644
--- a/compiler/src/CFCPerlMethod.c
+++ b/compiler/src/CFCPerlMethod.c
@@ -42,7 +42,7 @@ S_xsub_body(CFCPerlMethod *self, CFCClass *klass);
 
 // Create an assignment statement for extracting $self from the Perl stack.
 static char*
-S_self_assign_statement(CFCPerlMethod *self);
+S_self_assign_statement(CFCPerlMethod *self, CFCClass *klass);
 
 // Return code for an xsub which uses labeled params.
 static char*
@@ -214,19 +214,16 @@ S_xsub_body(CFCPerlMethod *self, CFCClass *klass) {
 
 // Create an assignment statement for extracting $self from the Perl stack.
 static char*
-S_self_assign_statement(CFCPerlMethod *self) {
+S_self_assign_statement(CFCPerlMethod *self, CFCClass *klass) {
     CFCParamList *param_list = CFCMethod_get_param_list(self->method);
     CFCVariable **vars = CFCParamList_get_variables(param_list);
-    CFCType *type = CFCVariable_get_type(vars[0]);
-    const char *self_name = CFCVariable_get_name(vars[0]);
-    const char *type_c = CFCType_to_c(type);
-    if (!CFCType_is_object(type)) {
-        CFCUtil_die("Not an object type: %s", type_c);
-    }
-    const char *class_var = CFCType_get_class_var(type);
-    char pattern[] = "arg_%s = (%s)XSBind_perl_to_cfish_noinc("
+    const char *self_name  = CFCVariable_get_name(vars[0]);
+    const char *struct_sym = CFCClass_full_struct_sym(klass);
+    const char *class_var  = CFCClass_full_class_var(klass);
+    char pattern[] = "arg_%s = (%s*)XSBind_perl_to_cfish_noinc("
                      "aTHX_ ST(0), %s, NULL);";
-    char *statement = CFCUtil_sprintf(pattern, self_name, type_c, class_var);
+    char *statement = CFCUtil_sprintf(pattern, self_name, struct_sym,
+                                      class_var);
 
     return statement;
 }
@@ -244,7 +241,7 @@ S_xsub_def_labeled_params(CFCPerlMethod *self, CFCClass 
*klass) {
     char *param_specs = CFCPerlSub_build_param_specs((CFCPerlSub*)self, 1);
     char *arg_decls   = CFCPerlSub_arg_declarations((CFCPerlSub*)self, 0);
     char *meth_type_c = CFCMethod_full_typedef(method, klass);
-    char *self_assign = S_self_assign_statement(self);
+    char *self_assign = S_self_assign_statement(self, klass);
     char *arg_assigns = CFCPerlSub_arg_assignments((CFCPerlSub*)self);
     char *body        = S_xsub_body(self, klass);
 
@@ -314,7 +311,7 @@ S_xsub_def_positional_args(CFCPerlMethod *self, CFCClass 
*klass) {
     int num_vars = CFCParamList_num_vars(param_list);
     char *arg_decls   = CFCPerlSub_arg_declarations((CFCPerlSub*)self, 0);
     char *meth_type_c = CFCMethod_full_typedef(method, klass);
-    char *self_assign = S_self_assign_statement(self);
+    char *self_assign = S_self_assign_statement(self, klass);
     char *arg_assigns = CFCPerlSub_arg_assignments((CFCPerlSub*)self);
     char *body        = S_xsub_body(self, klass);
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCPerlTypeMap.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlTypeMap.c b/compiler/src/CFCPerlTypeMap.c
index 022aa7f..a94ccdf 100644
--- a/compiler/src/CFCPerlTypeMap.c
+++ b/compiler/src/CFCPerlTypeMap.c
@@ -41,8 +41,9 @@ CFCPerlTypeMap_from_perl(CFCType *type, const char *xs_var,
     char *result = NULL;
 
     if (CFCType_is_object(type)) {
-        const char *struct_sym   = CFCType_get_specifier(type);
-        const char *class_var    = CFCType_get_class_var(type);
+        CFCClass *klass = CFCType_get_class(type);
+        const char *struct_sym   = CFCClass_full_struct_sym(klass);
+        const char *class_var    = CFCClass_full_class_var(klass);
         const char *nullable_str = CFCType_nullable(type) ? "_nullable" : "";
         const char *allocation;
         if (strcmp(struct_sym, "cfish_String") == 0

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 05626a6..9c1328a 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -113,7 +113,8 @@ S_gen_declaration(CFCVariable *var, const char *val) {
             if (strcmp(specifier, "cfish_Hash") != 0
                 && strcmp(specifier, "cfish_Vector") != 0
                 ) {
-                const char *class_var = CFCType_get_class_var(type);
+                CFCClass *klass = CFCType_get_class(type);
+                const char *class_var = CFCClass_full_class_var(klass);
                 char pattern[] =
                     "    CFBindArg wrap_arg_%s = {%s, &%s_ARG};\n"
                     ;
@@ -262,9 +263,10 @@ S_build_pymeth_invocation(CFCMethod *method) {
         invocation = CFCUtil_sprintf(pattern, micro_sym);
     }
     else if (CFCType_is_object(return_type)) {
+        CFCClass *klass = CFCType_get_class(return_type);
+        const char *ret_class = CFCClass_full_class_var(klass);
         const char *nullable
             = CFCType_nullable(return_type) ? "true" : "false";
-        const char *ret_class = CFCType_get_class_var(return_type);
         const char pattern[] =
             "    %s cfcb_RESULT = (%s)CALL_PYMETH_OBJ((PyObject*)self, \"%s\", 
cfcb_ARGS, %s, %s);";
         invocation = CFCUtil_sprintf(pattern, ret_type_str, ret_type_str, 
micro_sym,

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCType.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCType.c b/compiler/src/CFCType.c
index 9489c76..791a65b 100644
--- a/compiler/src/CFCType.c
+++ b/compiler/src/CFCType.c
@@ -35,9 +35,9 @@ struct CFCType {
     CFCBase  base;
     int      flags;
     char    *specifier;
-    char    *class_var;
     int      indirection;
     CFCWeakPtr parcel;
+    CFCWeakPtr klass;
     char    *c_string;
     size_t   width;
     char    *array;
@@ -99,7 +99,6 @@ CFCType_init(CFCType *self, int flags, struct CFCParcel 
*parcel,
     self->width       = 0;
     self->array       = NULL;
     self->child       = NULL;
-    self->class_var   = NULL;
 
     return self;
 }
@@ -300,6 +299,7 @@ CFCType_resolve(CFCType *self) {
         if (!klass) {
             CFCUtil_die("No class found for type '%s'", specifier);
         }
+        CFCWeakPtr_set(&self->klass, (CFCBase*)klass);
 
         // Upgrade specifier to full struct sym.
         self->specifier = CFCUtil_strdup(CFCClass_full_struct_sym(klass));
@@ -313,10 +313,10 @@ CFCType_destroy(CFCType *self) {
         CFCBase_decref((CFCBase*)self->child);
     }
     CFCWeakPtr_destroy(&self->parcel);
+    CFCWeakPtr_destroy(&self->klass);
     FREEMEM(self->specifier);
     FREEMEM(self->c_string);
     FREEMEM(self->array);
-    FREEMEM(self->class_var);
     CFCBase_destroy((CFCBase*)self);
 }
 
@@ -377,15 +377,13 @@ CFCType_get_specifier(CFCType *self) {
     return self->specifier;
 }
 
-const char*
-CFCType_get_class_var(CFCType *self) {
-    if (!self->class_var) {
-        self->class_var = CFCUtil_strdup(self->specifier);
-        for (int i = 0; self->class_var[i] != 0; i++) {
-            self->class_var[i] = CFCUtil_toupper(self->class_var[i]);
-        }
+CFCClass*
+CFCType_get_class(CFCType *self) {
+    CFCClass *klass = (CFCClass*)CFCWeakPtr_deref(self->klass);
+    if (!klass) {
+        CFCUtil_die("Type has no class");
     }
-    return self->class_var;
+    return klass;
 }
 
 int

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCType.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCType.h b/compiler/src/CFCType.h
index 4fa5042..010c33f 100644
--- a/compiler/src/CFCType.h
+++ b/compiler/src/CFCType.h
@@ -203,11 +203,10 @@ CFCType_set_specifier(CFCType *self, const char 
*specifier);
 const char*
 CFCType_get_specifier(CFCType *self);
 
-/** Return the name of the Class variable which corresponds to the object
- * type.  Returns NULL for non-object types.
+/** Return the Class object which corresponds to the object type.
  */
-const char*
-CFCType_get_class_var(CFCType *self);
+struct CFCClass*
+CFCType_get_class(CFCType *self);
 
 int
 CFCType_get_indirection(CFCType *self);

Reply via email to