Enable method binding generation by CFCGoClass.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/6e271216 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/6e271216 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/6e271216 Branch: refs/heads/master Commit: 6e271216688d1b900e202963da3adf4a8646b54c Parents: 2ccd49c Author: Marvin Humphrey <[email protected]> Authored: Mon Apr 6 20:18:18 2015 -0700 Committer: Marvin Humphrey <[email protected]> Committed: Wed May 6 14:25:27 2015 -0700 ---------------------------------------------------------------------- compiler/src/CFCGoClass.c | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/6e271216/compiler/src/CFCGoClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCGoClass.c b/compiler/src/CFCGoClass.c index 7793959..9884707 100644 --- a/compiler/src/CFCGoClass.c +++ b/compiler/src/CFCGoClass.c @@ -29,6 +29,7 @@ #include "CFCSymbol.h" #include "CFCVariable.h" #include "CFCType.h" +#include "CFCGoMethod.h" #include "CFCGoTypeMap.h" struct CFCGoClass { @@ -36,6 +37,8 @@ struct CFCGoClass { CFCParcel *parcel; char *class_name; CFCClass *client; + CFCGoMethod **method_bindings; + size_t num_bound; }; static CFCGoClass **registry = NULL; @@ -45,6 +48,9 @@ static size_t registry_cap = 0; static void S_CFCGoClass_destroy(CFCGoClass *self); +static void +S_lazy_init_method_bindings(CFCGoClass *self); + static const CFCMeta CFCGOCLASS_META = { "Clownfish::CFC::Binding::Go::Class", sizeof(CFCGoClass), @@ -69,6 +75,10 @@ S_CFCGoClass_destroy(CFCGoClass *self) { CFCBase_decref((CFCBase*)self->parcel); CFCBase_decref((CFCBase*)self->client); FREEMEM(self->class_name); + for (int i = 0; self->method_bindings[i] != NULL; i++) { + CFCBase_decref((CFCBase*)self->method_bindings[i]); + } + FREEMEM(self->method_bindings); CFCBase_destroy((CFCBase*)self); } @@ -200,3 +210,43 @@ CFCGoClass_go_typing(CFCGoClass *self) { return content; } +static void +S_lazy_init_method_bindings(CFCGoClass *self) { + if (self->method_bindings) { + return; + } + CFCUTIL_NULL_CHECK(self->client); + CFCClass *parent = CFCClass_get_parent(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; + } + + /* 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; +} +
