static char*
S_gen_code_sample(CFCCallable *func, const char *alias, CFCClass *klass,
                  int is_constructor) {
    char *prologue       = CFCUtil_sprintf("");
    char *class_var_name = S_camel_to_lower(CFCClass_get_struct_sym(klass));

    CFCType *ret_type = CFCCallable_get_return_type(func);
    if (!CFCType_is_void(ret_type)) {
        char *ret_name = S_perl_var_name(ret_type, is_constructor);

        if (!is_constructor && strcmp(ret_name, class_var_name) == 0) {
            // Return type equals `klass`. Use a generic variable name
            // to avoid confusing code samples like
            // `my $string = $string->trim`.
            prologue = CFCUtil_cat(prologue, "my $result = ", NULL);
        }
        else {
            prologue = CFCUtil_cat(prologue, "my $", ret_name, " = ", NULL);
        }

        FREEMEM(ret_name);
    }

    if (is_constructor) {
        const char *invocant = CFCClass_get_name(klass);
        prologue = CFCUtil_cat(prologue, invocant, NULL);
    }
    else {
        prologue = CFCUtil_cat(prologue, "$", class_var_name, NULL);
    }

    prologue = CFCUtil_cat(prologue, "->", alias, NULL);

    CFCParamList *param_list = CFCCallable_get_param_list(func);
    int           num_vars   = CFCParamList_num_vars(param_list);
    int           start      = is_constructor ? 0 : 1;
    char         *sample     = NULL;

    if (start == num_vars) {
        sample = CFCUtil_sprintf("    %s();\n", prologue);
    }
    else if (is_constructor || num_vars - start >= 2) {
        sample = S_gen_labeled_sample(prologue, param_list, start);
    }
    else {
        sample = S_gen_positional_sample(prologue, param_list, start);
    }

    FREEMEM(class_var_name);
    FREEMEM(prologue);
    return sample;
}
Example #2
0
static char*
S_gen_labeled_sample(const char *invocant, const char *alias,
                     CFCParamList *param_list, size_t start) {
    size_t        num_vars = CFCParamList_num_vars(param_list);
    CFCVariable **vars     = CFCParamList_get_variables(param_list);
    const char  **inits    = CFCParamList_get_initial_values(param_list);

    size_t max_label_len = 0;
    size_t max_var_len   = 0;

    // Find maximum length of label and Perl variable.
    for (size_t i = start; i < num_vars; i++) {
        CFCVariable *var = vars[i];

        const char *label = CFCVariable_get_name(var);
        size_t label_len = strlen(label);
        if (label_len > max_label_len) { max_label_len = label_len; }

        char *perl_var = S_perl_var_name(var);
        size_t perl_var_len = strlen(perl_var);
        if (perl_var_len > max_var_len) { max_var_len = perl_var_len; }
        FREEMEM(perl_var);
    }

    char *params = CFCUtil_strdup("");

    for (size_t i = start; i < num_vars; i++) {
        CFCVariable *var      = vars[i];
        const char  *label    = CFCVariable_get_name(var);
        char        *perl_var = S_perl_var_name(var);
        perl_var = CFCUtil_cat(perl_var, ",", NULL);

        char       *comment = NULL;
        const char *init    = inits[i];

        if (init) {
            if (strcmp(init, "NULL") == 0) { init = "undef"; }
            comment = CFCUtil_sprintf("default: %s", init);
        }
        else {
            comment = CFCUtil_strdup("required");
        }

        char *line = CFCUtil_sprintf("        %-*s => $%-*s  # %s\n",
                                     max_label_len, label,
                                     max_var_len + 1, perl_var,
                                     comment);
        params = CFCUtil_cat(params, line, NULL);
        FREEMEM(line);
        FREEMEM(comment);
        FREEMEM(perl_var);
    }

    const char pattern[] =
        "    %s->%s(\n"
        "%s"
        "    );\n";
    char *sample = CFCUtil_sprintf(pattern, invocant, alias, params);

    FREEMEM(params);
    return sample;
}