Greets,
This was a little hard for me to figure out what Nick's modification did,
which speaks more to the clarity of the original code than Nick's mod.
The problem is the loop logic:
FOR class IN classes
FOR method IN class.methods
IF method.novel OR (class.parent && class.parent.included)
FOR descendant IN class.descendants
generate_binding(method)
This loop construct would make more sense.
FOR class IN classes
FOR method IN class.methods
IF class.method_needs_binding(method)
generate_binding(method)
I'm trying to remember why the code doesn't do that already... I think it
was tricky to figure out whether a method needed to be bound.
Marvin Humphrey
On Mon, Mar 26, 2012 at 1:47 PM, <[email protected]> wrote:
> Author: nwellnhof
> Date: Mon Mar 26 20:47:45 2012
> New Revision: 1305573
>
> URL: http://svn.apache.org/viewvc?rev=1305573&view=rev
> Log:
> Fix writing method bindings for extension classes
>
> When writing out bindings for extension classes, non-novel methods must be
> processed if the parent class was included.
>
> Modified:
> lucy/trunk/clownfish/src/CFCPerlClass.c
>
> Modified: lucy/trunk/clownfish/src/CFCPerlClass.c
> URL:
> http://svn.apache.org/viewvc/lucy/trunk/clownfish/src/CFCPerlClass.c?rev=1305573&r1=1305572&r2=1305573&view=diff
> ==============================================================================
> --- lucy/trunk/clownfish/src/CFCPerlClass.c (original)
> +++ lucy/trunk/clownfish/src/CFCPerlClass.c Mon Mar 26 20:47:45 2012
> @@ -251,12 +251,15 @@ S_can_be_bound(CFCParamList *param_list,
> CFCPerlMethod**
> CFCPerlClass_method_bindings(CFCPerlClass *self) {
> CFCClass *client = self->client;
> + CFCClass *parent = CFCClass_get_parent(client);
> const char *class_name = self->class_name;
> size_t num_bound = 0;
> CFCMethod **fresh_methods = CFCClass_fresh_methods(client);
> CFCClass **descendants = CFCClass_tree_to_ladder(client);
> CFCPerlMethod **bound
> = (CFCPerlMethod**)CALLOCATE(1, sizeof(CFCPerlMethod*));
> +
> + int parent_included = (parent && CFCClass_included(parent));
>
> // Iterate over the class's fresh methods.
> for (size_t i = 0; fresh_methods[i] != NULL; i++) {
> @@ -264,8 +267,9 @@ CFCPerlClass_method_bindings(CFCPerlClas
> const char *alias = CFCMethod_micro_sym(method);
> const char *meth_name = CFCMethod_get_macro_sym(method);
>
> - // Only deal with methods when they are novel (i.e. first declared).
> - if (!CFCMethod_novel(method)) { continue; }
> + // Only deal with methods when they are novel (i.e. first declared)
> + // or the parent class is included.
> + if (!CFCMethod_novel(method) && !parent_included) { continue; }
>
> // Skip private methods.
> if (CFCSymbol_private((CFCSymbol*)method)) { continue; }
>
>