if (IDL_PARAM_DCL(param).attr == IDL_PARAM_INOUT && UP_IS_NATIVE(param_type) && IDL_tree_property_get(param_type, "domstring") != NULL) { IDL_tree_error(method_tree, "[domstring] types cannot be used as inout " "parameters"); return FALSE; }    if (IDL_tree_property_get(simple_decl, "array") != NULL && UP_IS_NATIVE(param_type) && IDL_tree_property_get(param_type, "domstring") != NULL) { IDL_tree_error(method_tree, "[domstring] types cannot be used in array " "parameters"); return FALSE; }
verify_method_declaration(IDL_tree method_tree){    struct _IDL_OP_DCL *op = &IDL_OP_DCL(method_tree);    IDL_tree iface;    IDL_tree iter;    gboolean scriptable_interface;    gboolean scriptable_method;    gboolean seen_retval = FALSE;    const char *method_name = IDL_IDENT(IDL_OP_DCL(method_tree).ident).str;    if (op->f_varargs) {        /* We don't currently support varargs. */        IDL_tree_error(method_tree, "varargs are not currently supported");        return FALSE;    }    /*      * Verify that we've been called on an interface, and decide if the     * interface was marked [scriptable].     */    if (IDL_NODE_UP(method_tree) && IDL_NODE_UP(IDL_NODE_UP(method_tree)) &&        IDL_NODE_TYPE(iface = IDL_NODE_UP(IDL_NODE_UP(method_tree)))         == IDLN_INTERFACE)    {        scriptable_interface =            (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "scriptable")             != NULL);    } else {        IDL_tree_error(method_tree,                       "verify_method_declaration called on a non-interface?");        return FALSE;    }    /*     * Require that any method in an interface marked as [scriptable], that     * *isn't* scriptable because it refers to some native type, be marked     * [noscript] or [notxpcom].     *     * Also check that iid_is points to nsid, and length_is, size_is points     * to unsigned long.     */    scriptable_method = scriptable_interface &&        IDL_tree_property_get(op->ident, "notxpcom") == NULL &&        IDL_tree_property_get(op->ident, "noscript") == NULL;    /* Loop through the parameters and check. */    for (iter = op->parameter_dcls; iter; iter = IDL_LIST(iter).next) {        IDL_tree param = IDL_LIST(iter).data;        IDL_tree param_type =            IDL_PARAM_DCL(param).param_type_spec;        IDL_tree simple_decl =            IDL_PARAM_DCL(param).simple_declarator;        const char *param_name = IDL_IDENT(simple_decl).str;                /*         * Reject this method if it should be scriptable and some parameter is         * native that isn't marked with either nsid, domstring, or iid_is.         */        if (scriptable_method &&            UP_IS_NATIVE(param_type) &&            IDL_tree_property_get(param_type, "nsid") == NULL &&            IDL_tree_property_get(simple_decl, "iid_is") == NULL &&            IDL_tree_property_get(param_type, "domstring") == NULL)        {            IDL_tree_error(method_tree,                           "methods in [scriptable] interfaces that are "                           "non-scriptable because they refer to native "                           "types (parameter \"%s\") must be marked "                           "[noscript]", param_name);            return FALSE;        }        /*         * Sanity checks on return values.         */        if (IDL_tree_property_get(simple_decl, "retval") != NULL) {            if (IDL_LIST(iter).next != NULL) {                IDL_tree_error(method_tree,                               "only the last parameter can be marked [retval]");                return FALSE;            }            if (op->op_type_spec) {                IDL_tree_error(method_tree,                               "can't have [retval] with non-void return type");                return FALSE;            }            /* In case XPConnect relaxes the retval-is-last restriction. */            if (seen_retval) {                IDL_tree_error(method_tree,                               "can't have more than one [retval] parameter");                return FALSE;            }            seen_retval = TRUE;        }        /*         * Confirm that [shared] attributes are only used with string, wstring,         * or native (but not nsid or domstring)          * and can't be used with [array].         */        if (IDL_tree_property_get(simple_decl, "shared") != NULL) {            IDL_tree real_type;            real_type = find_underlying_type(param_type);            real_type = real_type ? real_type : param_type;            if (IDL_tree_property_get(simple_decl, "array") != NULL) {                IDL_tree_error(method_tree,                               "[shared] parameter \"%s\" cannot "                               "be of array type", param_name);                return FALSE;            }                            if (!(IDL_NODE_TYPE(real_type) == IDLN_TYPE_STRING ||                  IDL_NODE_TYPE(real_type) == IDLN_TYPE_WIDE_STRING ||                  (UP_IS_NATIVE(real_type) &&                   !IDL_tree_property_get(real_type, "nsid") &&                   !IDL_tree_property_get(real_type, "domstring"))))            {                IDL_tree_error(method_tree,                               "[shared] parameter \"%s\" must be of type "                               "string, wstring or native", param_name);                return FALSE;            }        }        if (!check_param_attribute(method_tree, param, IID_IS) ||            !check_param_attribute(method_tree, param, LENGTH_IS) ||            !check_param_attribute(method_tree, param, SIZE_IS))            return FALSE;    }        /* XXX q: can return type be nsid? */    /* Native return type? */    if (scriptable_method &&        op->op_type_spec != NULL && UP_IS_NATIVE(op->op_type_spec) &&        IDL_tree_property_get(op->op_type_spec, "nsid") == NULL &&        IDL_tree_property_get(op->op_type_spec, "domstring") == NULL)    {        IDL_tree_error(method_tree,                       "methods in [scriptable] interfaces that are "                       "non-scriptable because they return native "                       "types must be marked [noscript]");        return FALSE;    }    return TRUE;}