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

Reply via email to