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); } }
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; }
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; }