/*
 * A method is an `operation', therefore a method decl is an `op dcl'.
 * I blame Elliot.
 */
static gboolean
op_dcl(TreeState *state)
{
    GSList *doc_comments = IDL_IDENT(IDL_OP_DCL(state->tree).ident).comments;

    /*
     * Verify that e.g. non-scriptable methods in [scriptable] interfaces
     * are declared so.  Do this in a separate verification pass?
     */
    if (!verify_method_declaration(state->tree))
        return FALSE;

    if (doc_comments != NULL) {
        write_indent(state->file);
        printlist(state->file, doc_comments);
    }
    xpidl_write_comment(state, 2);

    write_indent(state->file);
    if (!write_method_signature(state->tree, state->file, AS_DECL, NULL))
        return FALSE;
    fputs(" = 0;\n\n", state->file);

    return TRUE;
}
static gboolean
typelib_op_dcl(TreeState *state)
{
    XPTInterfaceDescriptor *id = CURRENT(state);
    XPTMethodDescriptor *meth;
    struct _IDL_OP_DCL *op = &IDL_OP_DCL(state->tree);
    IDL_tree iter;
    uint16 num_args = 0;
    uint8 op_flags = 0;
    gboolean op_notxpcom = (IDL_tree_property_get(op->ident, "notxpcom")
                            != NULL);
    gboolean op_noscript = (IDL_tree_property_get(op->ident, "noscript")
                            != NULL);
    gboolean op_context = (IDL_tree_property_get(op->ident,
                                                 "implicit_jscontext") != NULL);
    gboolean op_opt_argc = (IDL_tree_property_get(op->ident, "optional_argc")
                            != NULL);

    if (!verify_method_declaration(state->tree))
        return FALSE;

    if (!XPT_InterfaceDescriptorAddMethods(ARENA(state), id, 1))
        return FALSE;

    meth = &id->method_descriptors[NEXT_METH(state)];

    for (iter = op->parameter_dcls; iter; iter = IDL_LIST(iter).next)
        num_args++;             /* count params */
    if (op->op_type_spec && !op_notxpcom)
        num_args++;             /* fake param for _retval */

    if (op_noscript)
        op_flags |= XPT_MD_HIDDEN;
    if (op_notxpcom)
        op_flags |= XPT_MD_NOTXPCOM;
    if (op_opt_argc)
        op_flags |= XPT_MD_OPT_ARGC;
    if (op_context)
        op_flags |= XPT_MD_CONTEXT;

    /* XXXshaver constructor? */

#ifdef DEBUG_shaver_method
    fprintf(stdout, "DBG: adding method %s (nargs %d)\n",
            IDL_IDENT(op->ident).str, num_args);
#endif
    if (!XPT_FillMethodDescriptor(ARENA(state), meth, op_flags, 
                                  IDL_IDENT(op->ident).str,
                                  (uint8) num_args))
        return FALSE;

    for (num_args = 0, iter = op->parameter_dcls; iter;
         iter = IDL_LIST(iter).next, num_args++) {
        XPTParamDescriptor *pd = &meth->params[num_args];
        if (!fill_pd_from_param(state, pd, IDL_LIST(iter).data))
            return FALSE;
    }

    /* stick retval param where we can see it later */
    state->tree = op->op_type_spec;

    /* XXX unless [notxpcom] */
    if (!op_notxpcom) {
        if (op->op_type_spec) {
            uint8 pdflags = DIPPER_TYPE(op->op_type_spec) ?
                                (XPT_PD_RETVAL | XPT_PD_IN | XPT_PD_DIPPER) :
                                (XPT_PD_RETVAL | XPT_PD_OUT);
    
            if (!fill_pd_from_type(state, &meth->params[num_args],
                                   pdflags, op->op_type_spec))
                return FALSE;
        }

        if (!fill_pd_as_nsresult(meth->result))
            return FALSE;
    } else {
#ifdef DEBUG_shaver_notxpcom
        fprintf(stderr, "%s is notxpcom\n", IDL_IDENT(op->ident).str);
#endif
        if (!fill_pd_from_type(state, meth->result, XPT_PD_RETVAL,
                               op->op_type_spec))
            return FALSE;
    }
    NEXT_METH(state)++;
    return TRUE;
}
Esempio n. 3
0
static gboolean
method_declaration(TreeState *state) 
{
    const char* array = NULL;
    struct _IDL_OP_DCL *method = &IDL_OP_DCL(state->tree);
    gboolean method_notxpcom = 
        (IDL_tree_property_get(method->ident, "notxpcom") != NULL);
    gboolean method_noscript = 
        (IDL_tree_property_get(method->ident, "noscript") != NULL);
    IDL_tree iterator = NULL;
    IDL_tree retval_param = NULL;
    char *method_name =
                  g_strdup_printf("%c%s",
                                  tolower(IDL_IDENT(method->ident).str[0]),
                                  IDL_IDENT(method->ident).str + 1);

    if (!verify_method_declaration(state->tree))
        return FALSE;

    fputc('\n', state->file);
    xpidl_write_comment(state, 4);

#if 1
    /* do not write non-xpcom methods */
    if (method_notxpcom) {
        return TRUE;
    }

    /*
     * Write beginning of method declaration
     */
    fputs("    public ", state->file);
#else
    /* do not write nonscriptable methods */
    if (method_notxpcom || method_noscript) {
        return TRUE;
    }

    /*
     * Write beginning of method declaration
     */
    fputs("    ", state->file);
    if (!method_noscript) {
        /* Nonscriptable methods become package-protected */
        fputs("public ", state->file);
    }
#endif

    /*
     * Write return type
     * Unlike C++ headers, Java interfaces return the declared 
     * return value; an exception indicates XPCOM method failure.
     */
    if (method->op_type_spec) {
        state->tree = method->op_type_spec;
        if (!xpcom_to_java_type(state, method->op_type_spec)) {
            return FALSE;
        }
    } else {
        /* Check for retval attribute */
        for (iterator = method->parameter_dcls; iterator != NULL; 
             iterator = IDL_LIST(iterator).next) {

            IDL_tree original_tree = state->tree;

            state->tree = IDL_LIST(iterator).data;

            if (IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator, 
                                      "retval")) {
                retval_param = iterator;

                array = 
                    IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator,
                                          "array");

                /*
                 * Put in type of parameter
                 */
                if (!xpcom_to_java_type(state,
                                        IDL_PARAM_DCL(state->tree).param_type_spec)) {
                    return FALSE;
                }
                if (array)
                    fputs("[]", state->file);
            }

            state->tree = original_tree;
        }

        if (retval_param == NULL) {
            fputs("void", state->file);
        }
    }
 
    /*
     * Write method name
     */
    fprintf(state->file, " %s(", subscriptIdentifier(state, method_name));

    /*
     * Write parameters
     */
    for (iterator = method->parameter_dcls; iterator != NULL; 
         iterator = IDL_LIST(iterator).next) {

        /* Skip "retval" */
        if (iterator == retval_param) {
            continue;
        }

        if (iterator != method->parameter_dcls) {
            fputs(", ", state->file);
        }
        
        state->tree = IDL_LIST(iterator).data;

        if (!xpcom_to_java_param(state)) {
            return FALSE;
        }
    }

    fputs(")", state->file);

    /* XXX
       Disable this for now.  How do we specify exceptions?
    if (method->raises_expr) {
        IDL_tree iter = method->raises_expr;
        IDL_tree dataNode = IDL_LIST(iter).data;

        fputs(" throws ", state->file);
        fputs(IDL_IDENT(dataNode).str, state->file);
        iter = IDL_LIST(iter).next;

        while (iter) {
            dataNode = IDL_LIST(iter).data;
            fprintf(state->file, ", %s", IDL_IDENT(dataNode).str);
            iter = IDL_LIST(iter).next;
        }
    }   */

    fputs(";\n", state->file);

    return TRUE;
    
}