Example #1
0
void
CFCDumpable_add_dumpables(CFCDumpable *self, CFCClass *klass) {
    (void)self;

    if (!CFCClass_has_attribute(klass, "dumpable")) {
        CFCUtil_die("Class %s isn't dumpable", CFCClass_get_class_name(klass));
    }

    // Inherit Dump/Load from parent if no fresh member vars.
    CFCClass *parent = CFCClass_get_parent(klass);
    if (parent && CFCClass_has_attribute(parent, "dumpable")) {
        CFCVariable **fresh = CFCClass_fresh_member_vars(klass);
        int needs_autogenerated_dumpables = fresh[0] != NULL ? true : false;
        FREEMEM(fresh);
        if (!needs_autogenerated_dumpables) { return; }
    }

    if (!CFCClass_fresh_method(klass, "Dump")) {
        S_add_dump_method(klass);
    }
    if (!CFCClass_fresh_method(klass, "Load")) {
        S_add_load_method(klass);
    }
}
Example #2
0
static void
S_lazy_init_method_bindings(CFCGoClass *self) {
    if (self->method_bindings) {
        return;
    }
    CFCUTIL_NULL_CHECK(self->client);
    size_t        num_bound     = 0;
    CFCMethod   **fresh_methods = CFCClass_fresh_methods(self->client);
    CFCGoMethod **bound
        = (CFCGoMethod**)CALLOCATE(1, sizeof(CFCGoMethod*));

     // Iterate over the class's fresh methods.
    for (size_t i = 0; fresh_methods[i] != NULL; i++) {
        CFCMethod *method = fresh_methods[i];

        // Skip methods which have been explicitly excluded.
        if (CFCMethod_excluded_from_host(method)) {
            continue;
        }

        // Skip methods that shouldn't be bound.
        if (!CFCMethod_can_be_bound(method)) {
            continue;
        }

        // Only include novel methods.
        if (!CFCMethod_novel(method)) {
            continue;
        }
        const char *sym = CFCMethod_get_name(method);
        if (!CFCClass_fresh_method(self->client, sym)) {
            continue;
        }

        /* Create the binding, add it to the array.
         */
        CFCGoMethod *meth_binding = CFCGoMethod_new(method);
        size_t size = (num_bound + 2) * sizeof(CFCGoMethod*);
        bound = (CFCGoMethod**)REALLOCATE(bound, size);
        bound[num_bound] = meth_binding;
        num_bound++;
        bound[num_bound] = NULL;
    }

    self->method_bindings = bound;
    self->num_bound       = num_bound;
}
Example #3
0
char*
CFCGoClass_go_typing(CFCGoClass *self) {
    char *content = NULL;
    if (!self->client) {
        CFCUtil_die("Can't find class for %s", self->class_name);
    }
    else if (CFCClass_inert(self->client)) {
        content = CFCUtil_strdup("");
    } else {
        const char *short_struct = CFCClass_get_struct_sym(self->client);

        CFCClass *parent = CFCClass_get_parent(self->client);
        char *parent_type_str = NULL;
        if (parent) {
            const char *parent_struct = CFCClass_get_struct_sym(parent);
            CFCParcel *parent_parcel = CFCClass_get_parcel(parent);
            if (parent_parcel == self->parcel) {
                parent_type_str = CFCUtil_strdup(parent_struct);
            }
            else {
                char *parent_package
                    = CFCGoTypeMap_go_short_package(parent_parcel);
                parent_type_str = CFCUtil_sprintf("%s.%s", parent_package,
                                                  parent_struct);
                FREEMEM(parent_package);
            }
        }

        char *go_struct_def;
        if (parent && !self->suppress_struct) {
            go_struct_def
                = CFCUtil_sprintf("type %sIMP struct {\n\t%sIMP\n}\n",
                                  short_struct, parent_type_str);
        }
        else {
            go_struct_def = CFCUtil_strdup("");
        }

        char *parent_iface;
        if (parent) {
            parent_iface = CFCUtil_sprintf("\t%s\n", parent_type_str);
        }
        else {
            parent_iface = CFCUtil_strdup("");
        }

        char *novel_iface = CFCUtil_strdup("");
        S_lazy_init_method_bindings(self);
        for (int i = 0; self->method_bindings[i] != NULL; i++) {
            CFCGoMethod *meth_binding = self->method_bindings[i];
            CFCMethod *method = CFCGoMethod_get_client(meth_binding);
            if (method) {
                if (!CFCMethod_novel(method)) {
                    continue;
                }
                const char *sym = CFCMethod_get_name(method);
                if (!CFCClass_fresh_method(self->client, sym)) {
                    continue;
                }
            }

            const char *sig = CFCGoMethod_get_sig(meth_binding, self->client);
            novel_iface = CFCUtil_cat(novel_iface, "\t", sig, "\n", NULL);
        }

        char pattern[] =
            "type %s interface {\n"
            "%s"
            "%s"
            "}\n"
            "\n"
            "%s"
            ;
        content = CFCUtil_sprintf(pattern, short_struct, parent_iface,
                                  novel_iface, go_struct_def);
        FREEMEM(parent_type_str);
        FREEMEM(go_struct_def);
        FREEMEM(parent_iface);
    }
    return content;
}