Пример #1
0
static gboolean
typelib_attr_dcl(TreeState *state)
{
    XPTInterfaceDescriptor *id = CURRENT(state);
    XPTMethodDescriptor *meth;
    gboolean read_only = IDL_ATTR_DCL(state->tree).f_readonly;

    /* XXX this only handles the first ident; elsewhere too... */
    IDL_tree ident =
        IDL_LIST(IDL_ATTR_DCL(state->tree).simple_declarations).data;

    /* If it's marked [noscript], mark it as hidden in the typelib. */
    gboolean hidden = (IDL_tree_property_get(ident, "noscript") != NULL);

    gboolean wantsJSContext =
        (IDL_tree_property_get(ident, "implicit_jscontext") != NULL);

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

    if (!XPT_InterfaceDescriptorAddMethods(ARENA(state), id, 
                                           (PRUint16) (read_only ? 1 : 2)))
        return FALSE;

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

    return typelib_attr_accessor(state, meth, TRUE, hidden, wantsJSContext) &&
        (read_only ||
         typelib_attr_accessor(state, meth + 1, FALSE, hidden, wantsJSContext));
}
Пример #2
0
void
orte_idl_attr_fake_ops(IDL_tree attr, IDL_ns ns)
{
  IDL_tree attr_name, ident, curnode, op1, op2, intf;
  GString *attrname;
  OIDL_Attr_Info *setme;

  g_assert(attr && IDL_NODE_TYPE(attr) == IDLN_ATTR_DCL);

  attrname = g_string_new(NULL);

  for(curnode = IDL_ATTR_DCL(attr).simple_declarations; curnode; curnode = IDL_LIST(curnode).next) {
    op1 = op2 = NULL;

    attr_name = IDL_LIST(curnode).data;

    g_string_printf(attrname, "_get_%s",
		     IDL_IDENT(attr_name).str);
    ident = IDL_ident_new(g_strdup(attrname->str));
    IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name);
    op1 = IDL_op_dcl_new(0, IDL_ATTR_DCL(attr).param_type_spec, ident, NULL, NULL, NULL);
    IDL_NODE_UP(op1) = IDL_NODE_UP(attr);
    intf = IDL_NODE_UP (IDL_NODE_UP (op1));
    IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident);
    IDL_ns_place_new(ns, ident);

    if(!IDL_ATTR_DCL(attr).f_readonly) {
      g_string_printf(attrname, "_set_%s",
		       IDL_IDENT(attr_name).str);
      ident = IDL_ident_new(g_strdup(attrname->str));
      IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name);
      op2 = IDL_op_dcl_new(0, NULL, ident, NULL, NULL, NULL);
      IDL_NODE_UP(op2) = IDL_NODE_UP(attr);
      intf = IDL_NODE_UP (IDL_NODE_UP (op2));
      IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident);
      IDL_ns_place_new(ns, ident);
      IDL_OP_DCL(op2).parameter_dcls = IDL_list_new(
						    IDL_param_dcl_new(IDL_PARAM_IN,
								      IDL_ATTR_DCL(attr).param_type_spec,
								      IDL_ident_new(g_strdup("value"))));
    }

    setme = g_new0(OIDL_Attr_Info, 1);
    setme->op1 = op1;
    setme->op2 = op2;
    attr_name->data = setme;
  }

  g_string_free(attrname, TRUE);
}
Пример #3
0
static gboolean
attr_dcl(TreeState *state)
{
    GSList *doc_comments;

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

    doc_comments =
        IDL_IDENT(IDL_LIST(IDL_ATTR_DCL
                           (state->tree).simple_declarations).data).comments;

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

    /*
     * XXX lists of attributes with the same type, e.g.
     * attribute string foo, bar sil;
     * are legal IDL... but we don't do anything with 'em.
     */
    if (IDL_LIST(IDL_ATTR_DCL(state->tree).simple_declarations).next != NULL) {
        XPIDL_WARNING((state->tree, IDL_WARNING1,
                       "multiple attributes in a single declaration aren't "
                       "currently supported by xpidl"));
    }

    xpidl_write_comment(state, 2);

    write_indent(state->file);
    write_indent(state->file);
    if (!write_attr_accessor(state->tree, state->file, TRUE, NULL))
        return FALSE;
    fputs(": Longword; stdcall;\n", state->file);

    if (!IDL_ATTR_DCL(state->tree).f_readonly) {
        write_indent(state->file);
        write_indent(state->file);
        if (!write_attr_accessor(state->tree, state->file, FALSE, NULL))
            return FALSE;
        fputs(": Longword; stdcall;\n", state->file);
    }
    /*fputc('\n', state->file);*/

    return TRUE;
}
Пример #4
0
static GSList *
cc_build_interfaces (GSList *list, IDL_tree tree)
{
	if (!tree)
		return list;

	switch (IDL_NODE_TYPE (tree)) {
	case IDLN_MODULE:
		list = cc_build_interfaces (
			list, IDL_MODULE (tree).definition_list);
		break;
	case IDLN_LIST: {
		IDL_tree sub;
		for (sub = tree; sub; sub = IDL_LIST (sub).next)
			list = cc_build_interfaces (
				list, IDL_LIST (sub).data);
		break;
	}
	case IDLN_ATTR_DCL: {
		IDL_tree curitem;
      
		for (curitem = IDL_ATTR_DCL (tree).simple_declarations;
		     curitem; curitem = IDL_LIST (curitem).next) {
			OIDL_Attr_Info *ai = IDL_LIST (curitem).data->data;
	
			list = cc_build_interfaces (list, ai->op1);
			if (ai->op2)
				list = cc_build_interfaces (list, ai->op2);
		}
		break;
	}
	case IDLN_INTERFACE: {
		Interface *i = g_new0 (Interface, 1);

		i->tree = tree;

		list = g_slist_append (list, i);

		list = cc_build_interfaces (list, IDL_INTERFACE(tree).body);

		break;
	}
	case IDLN_OP_DCL: {
		Interface *i;

		g_return_val_if_fail (list != NULL, NULL);

		i = ( g_slist_last(list) )->data;
		i->methods = g_slist_append (i->methods, tree);
		break;
	}
	case IDLN_EXCEPT_DCL:
		break;
	default:
		break;
	}

	return list;
}
Пример #5
0
/*
 *  AS_DECL writes 'NS_IMETHOD foo(string bar, long sil)'
 *  AS_IMPL writes 'NS_IMETHODIMP className::foo(string bar, long sil)'
 *  AS_CALL writes 'foo(bar, sil)'
 */
static gboolean
write_attr_accessor(IDL_tree attr_tree, FILE * outfile,
                    gboolean getter, int mode, const char *className)
{
    char *attrname = ATTR_IDENT(attr_tree).str;
    const char *binaryname;
    IDL_tree ident = IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).data;

    if (mode == AS_DECL) {
        if (IDL_tree_property_get(ident, "deprecated"))
            fputs("NS_DEPRECATED ", outfile);
        if (is_method_scriptable(attr_tree, ident))
            fputs("NS_SCRIPTABLE ", outfile);

        fputs("NS_IMETHOD ", outfile);
    } else if (mode == AS_IMPL) {
        fprintf(outfile, "NS_IMETHODIMP %s::", className);
    }
    fprintf(outfile, "%cet",
            getter ? 'G' : 'S');
    binaryname = IDL_tree_property_get(ATTR_DECLS(attr_tree), "binaryname");
    if (binaryname) {
        fprintf(outfile, "%s(",
                binaryname);
    } else {
        fprintf(outfile, "%c%s(",
                toupper(*attrname),
                attrname + 1);
    }
    if (mode == AS_DECL || mode == AS_IMPL) {
        /* Setters for string, wstring, nsid, domstring, utf8string, 
         * cstring and astring get const. 
         */
        if (!getter &&
            (IDL_NODE_TYPE(ATTR_TYPE_DECL(attr_tree)) == IDLN_TYPE_STRING ||
             IDL_NODE_TYPE(ATTR_TYPE_DECL(attr_tree)) == IDLN_TYPE_WIDE_STRING ||
             IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "nsid") ||
             IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "domstring")  ||
             IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "utf8string") ||
             IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "cstring")    ||
             IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "astring")))
        {
            fputs("const ", outfile);
        }

        if (!write_type(ATTR_TYPE_DECL(attr_tree), getter, outfile))
            return FALSE;
        fprintf(outfile, "%s%s",
                (STARRED_TYPE(attr_tree) ? "" : " "),
                (getter && !DIPPER_TYPE(ATTR_TYPE_DECL(attr_tree)))? "*" : "");
    }
    fprintf(outfile, "a%c%s)", toupper(attrname[0]), attrname + 1);
    return TRUE;
}
Пример #6
0
static void
cc_output_skels (IDL_tree       tree,
		 OIDL_Run_Info *rinfo,
		 OIDL_C_Info   *ci,
		 int           *idx)
{
	if (!tree || (tree->declspec & IDLF_DECLSPEC_PIDL))
		return;

	switch (IDL_NODE_TYPE (tree)) {
	case IDLN_MODULE:
		cc_output_skels (IDL_MODULE (tree).definition_list, rinfo, ci, idx);
		break;
	case IDLN_LIST: {
		IDL_tree node;

		for (node = tree; node; node = IDL_LIST (node).next)
			cc_output_skels (IDL_LIST (node).data, rinfo, ci, idx);
		break;
		}
	case IDLN_ATTR_DCL: {
		OIDL_Attr_Info *ai = tree->data;
		IDL_tree        node;
      
		for (node = IDL_ATTR_DCL (tree).simple_declarations; node; node = IDL_LIST (node).next) {
			ai = IDL_LIST (node).data->data;
	
			cc_output_skels (ai->op1, rinfo, ci, idx);
			if (ai->op2)
				cc_output_skels (ai->op2, rinfo, ci, idx);
		}
		break;
		}
	case IDLN_INTERFACE: {
		int real_idx = 0;

		cc_output_skels (IDL_INTERFACE (tree).body, rinfo, ci, &real_idx);
		}
		break;
	case IDLN_OP_DCL:
		cc_output_skel (tree, ci, idx);
		break;
	default:
		break;
	}
}
Пример #7
0
static void
cs_output_stubs (IDL_tree     tree,
		 OIDL_C_Info *ci,
		 int         *idx)
{
	if (!tree)
		return;
	switch (IDL_NODE_TYPE (tree)) {
	case IDLN_MODULE:
		cs_output_stubs (IDL_MODULE (tree).definition_list, ci, idx);
		break;
	case IDLN_LIST: {
		IDL_tree sub;
		for (sub = tree; sub; sub = IDL_LIST (sub).next)
			cs_output_stubs (IDL_LIST (sub).data, ci, idx);
		break;
		}
	case IDLN_ATTR_DCL: {
		IDL_tree node;
      
		for (node = IDL_ATTR_DCL (tree).simple_declarations; node; node = IDL_LIST (node).next) {
			OIDL_Attr_Info *ai;
			ai = IDL_LIST (node).data->data;
	
			cs_output_stubs (ai->op1, ci, idx);
			if (ai->op2)
				cs_output_stubs (ai->op2, ci, idx);
		}
		break;
		}
	case IDLN_INTERFACE: {
		int real_idx = 0;
		cs_output_stubs (IDL_INTERFACE (tree).body, ci, &real_idx);
		break;
		}
	case IDLN_OP_DCL:
		cs_output_stub (tree, ci, idx);
		break;
	default:
		break;
	}
}
Пример #8
0
/* Find all the interfaces referenced in the tree (uses add_interface_maybe) */
static gboolean
find_interfaces(IDL_tree_func_data *tfd, gpointer user_data)
{
    IDL_tree node = NULL;

    switch (IDL_NODE_TYPE(tfd->tree)) {
      case IDLN_ATTR_DCL:
        node = IDL_ATTR_DCL(tfd->tree).param_type_spec;
        break;
      case IDLN_OP_DCL:
         IDL_tree_walk_in_order(IDL_OP_DCL(tfd->tree).parameter_dcls, find_interfaces,
                               user_data);
        node = IDL_OP_DCL(tfd->tree).op_type_spec;
        break;
      case IDLN_PARAM_DCL:
        node = IDL_PARAM_DCL(tfd->tree).param_type_spec;
        break;
      case IDLN_INTERFACE:
        node = IDL_INTERFACE(tfd->tree).inheritance_spec;
        if (node)
            xpidl_list_foreach(node, add_interface_maybe, user_data);
        node = IDL_INTERFACE(tfd->tree).ident;
        break;
      case IDLN_FORWARD_DCL:
        node = IDL_FORWARD_DCL(tfd->tree).ident;
        break;
      default:
        node = NULL;
    }

    if (node && IDL_NODE_TYPE(node) == IDLN_IDENT) {
        IDL_tree_func_data new_tfd;
        new_tfd.tree = node;
        add_interface_maybe(&new_tfd, user_data);
    }

    return TRUE;
}
Пример #9
0
void
orte_idl_print_node(IDL_tree node, int indent_level)
{
  IDL_tree curnode;
  char *s;

  do_indent(indent_level);

  if(node == NULL) {
    g_print("(null)\n");
    return;
  }

  g_print("[%d] ", IDL_NODE_REFS(node));

  switch(IDL_NODE_TYPE(node)) {

  case IDLN_NONE:
    g_print("NONE\n");
    break;

  case IDLN_LIST:
    g_print("LIST:\n");
    for(curnode = node; curnode;
	curnode = IDL_LIST(curnode).next) {
      orte_idl_print_node(IDL_LIST(curnode).data, indent_level + INDENT_INCREMENT_1);
    }
    break;

  case IDLN_GENTREE:
    break;

  case IDLN_INTEGER:
    g_print("INTEGER: %" IDL_LL "d\n", IDL_INTEGER(node).value);
    break;

  case IDLN_STRING:
    g_print("STRING: %s\n", IDL_STRING(node).value);
    break;

  case IDLN_WIDE_STRING:
    g_print("WIDE STRING: %ls\n", IDL_WIDE_STRING(node).value);
    break;

  case IDLN_CHAR:
    g_print("CHAR: %s\n", IDL_CHAR(node).value);
    break;

  case IDLN_WIDE_CHAR:
    g_print("WIDE CHAR: %ls\n", IDL_WIDE_CHAR(node).value);
    break;

  case IDLN_FIXED:
    g_print("FIXED: %s\n", IDL_FIXED(node).value);
    break;

  case IDLN_FLOAT:
    g_print("FLOAT: %f\n", IDL_FLOAT(node).value);
    break;

  case IDLN_BOOLEAN:
    g_print("BOOLEAN: %s\n", (IDL_BOOLEAN(node).value)?"True":"False");
    break;

  case IDLN_IDENT:
    s = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(node), "_", 0);
    g_print("IDENT: %s NSQ: %s RID: \"%s\"\n",
	    IDL_IDENT(node).str, s,
	    IDL_IDENT_REPO_ID(node) ? IDL_IDENT_REPO_ID(node) : "");
    g_free(s);
    break;

  case IDLN_TYPE_DCL:
    g_print("TYPE DCL:\n");
    orte_idl_print_node(IDL_TYPE_DCL(node).type_spec, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("decls:\n");
    orte_idl_print_node(IDL_TYPE_DCL(node).dcls, indent_level + INDENT_INCREMENT_2);
    break;

  case IDLN_CONST_DCL:
    g_print("CONST DCL:\n");
    orte_idl_print_node(IDL_CONST_DCL(node).const_type, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("ident:\n");
    orte_idl_print_node(IDL_CONST_DCL(node).ident, indent_level + INDENT_INCREMENT_2);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("const_exp:\n");
    orte_idl_print_node(IDL_CONST_DCL(node).const_exp, indent_level + INDENT_INCREMENT_2);
    break;

  case IDLN_EXCEPT_DCL:
    g_print("EXCEPT DCL:\n");
    orte_idl_print_node(IDL_EXCEPT_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("members:\n");
    orte_idl_print_node(IDL_EXCEPT_DCL(node).members, indent_level + INDENT_INCREMENT_2);
    break;

  case IDLN_ATTR_DCL:
    g_print("ATTR_DCL (%s):\n", (IDL_ATTR_DCL(node).f_readonly)?"readonly":"rw");
    orte_idl_print_node(IDL_ATTR_DCL(node).param_type_spec, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("simple_declarations:\n");
    orte_idl_print_node(IDL_ATTR_DCL(node).simple_declarations, indent_level + INDENT_INCREMENT_2);
    break;

  case IDLN_OP_DCL:
    g_print("OP DCL (%s):\n", (IDL_OP_DCL(node).f_oneway)?"oneway":"normal");
    orte_idl_print_node(IDL_OP_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("op_type_spec:\n");
    orte_idl_print_node(IDL_OP_DCL(node).op_type_spec, indent_level + INDENT_INCREMENT_2);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("parameter_dcls:\n");
    orte_idl_print_node(IDL_OP_DCL(node).parameter_dcls, indent_level + INDENT_INCREMENT_2);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("raises_expr:\n");
    orte_idl_print_node(IDL_OP_DCL(node).raises_expr, indent_level + INDENT_INCREMENT_2);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("context_expr:\n");
    orte_idl_print_node(IDL_OP_DCL(node).context_expr, indent_level + INDENT_INCREMENT_2);
    break;

  case IDLN_PARAM_DCL:
    g_print("PARAM DCL: ");
    switch(IDL_PARAM_DCL(node).attr) {
    case IDL_PARAM_IN: g_print("(in)\n"); break;
    case IDL_PARAM_OUT: g_print("(out)\n"); break;
    case IDL_PARAM_INOUT: g_print("(inout)\n"); break;
    }
    orte_idl_print_node(IDL_PARAM_DCL(node).param_type_spec, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("simple_declarator:\n");
    orte_idl_print_node(IDL_PARAM_DCL(node).simple_declarator, indent_level + INDENT_INCREMENT_2);
    break;
  case IDLN_FORWARD_DCL:
    g_print("FORWARD DCL:\n");
    orte_idl_print_node(IDL_FORWARD_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
    break;
  case IDLN_INTERFACE:
    g_print("INTERFACE:\n");
    orte_idl_print_node(IDL_INTERFACE(node).ident, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("inheritance_spec:\n");
    orte_idl_print_node(IDL_INTERFACE(node).inheritance_spec, indent_level + INDENT_INCREMENT_2);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("body:\n");
    orte_idl_print_node(IDL_INTERFACE(node).body, indent_level + INDENT_INCREMENT_2);
    break;
  case IDLN_MODULE:
    g_print("MODULE:\n");
    orte_idl_print_node(IDL_MODULE(node).ident, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("definition_list:\n");
    orte_idl_print_node(IDL_MODULE(node).definition_list, indent_level + INDENT_INCREMENT_2);
    break;

  case IDLN_TYPE_INTEGER:
    if(!IDL_TYPE_INTEGER(node).f_signed) g_print("TYPE unsigned ");
    switch(IDL_TYPE_INTEGER(node).f_type) {
    case IDL_INTEGER_TYPE_SHORT: g_print("short\n"); break;
    case IDL_INTEGER_TYPE_LONG: g_print("long\n"); break;
    case IDL_INTEGER_TYPE_LONGLONG: g_print("long long\n"); break;
    }
    break;
  case IDLN_TYPE_FLOAT:
    switch(IDL_TYPE_FLOAT(node).f_type) {
    case IDL_FLOAT_TYPE_FLOAT: g_print("TYPE float\n"); break;
    case IDL_FLOAT_TYPE_DOUBLE: g_print("TYPE double\n"); break;
    case IDL_FLOAT_TYPE_LONGDOUBLE: g_print("TYPE long double\n"); break;
    }
    break;
  case IDLN_TYPE_FIXED:
    g_print("TYPE fixed:\n");
    orte_idl_print_node(IDL_TYPE_FIXED(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
    orte_idl_print_node(IDL_TYPE_FIXED(node).integer_lit, indent_level + INDENT_INCREMENT_1);
    break;
  case IDLN_TYPE_STRING:
    g_print("TYPE string:\n");
    orte_idl_print_node(IDL_TYPE_STRING(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
    break;
  case IDLN_TYPE_WIDE_STRING:
    g_print("TYPE wide string:\n");
    orte_idl_print_node(IDL_TYPE_WIDE_STRING(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
    break;
  case IDLN_TYPE_ENUM:
    g_print("TYPE enum:\n");
    orte_idl_print_node(IDL_TYPE_ENUM(node).ident, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("enumerator_list:\n");
    orte_idl_print_node(IDL_TYPE_ENUM(node).enumerator_list, indent_level + INDENT_INCREMENT_2);
    break;
  case IDLN_TYPE_ARRAY:
    g_print("TYPE array:\n");
    orte_idl_print_node(IDL_TYPE_ARRAY(node).ident, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("size_list:\n");
    orte_idl_print_node(IDL_TYPE_ARRAY(node).size_list, indent_level + INDENT_INCREMENT_2);
    break;
  case IDLN_TYPE_SEQUENCE:
    g_print("TYPE sequence:\n");
    orte_idl_print_node(IDL_TYPE_SEQUENCE(node).simple_type_spec, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("positive_int_const:\n");
    orte_idl_print_node(IDL_TYPE_SEQUENCE(node).positive_int_const, indent_level + INDENT_INCREMENT_2);
    break;
  case IDLN_TYPE_STRUCT:
    g_print("TYPE struct:\n");
    orte_idl_print_node(IDL_TYPE_STRUCT(node).ident, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("member_list:\n");
    orte_idl_print_node(IDL_TYPE_STRUCT(node).member_list, indent_level + INDENT_INCREMENT_2);
    break;
  case IDLN_TYPE_UNION:
    g_print("TYPE union:\n");
    orte_idl_print_node(IDL_TYPE_UNION(node).ident, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("switch_type_spec:\n");
    orte_idl_print_node(IDL_TYPE_UNION(node).switch_type_spec, indent_level + INDENT_INCREMENT_2);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("switch_body:\n");
    orte_idl_print_node(IDL_TYPE_UNION(node).switch_body, indent_level + INDENT_INCREMENT_2);
    break;
  case IDLN_MEMBER:
    g_print("MEMBER:\n");
    orte_idl_print_node(IDL_MEMBER(node).type_spec, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("dcls:\n");
    orte_idl_print_node(IDL_MEMBER(node).dcls, indent_level + INDENT_INCREMENT_2);
    break;
  case IDLN_CASE_STMT:
    g_print("CASE_STMT:\n");
    orte_idl_print_node(IDL_CASE_STMT(node).labels, indent_level + INDENT_INCREMENT_1);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("element_spec:\n");
    orte_idl_print_node(IDL_CASE_STMT(node).element_spec, indent_level + INDENT_INCREMENT_2);
    break;
  case IDLN_BINOP:
    g_print("BINOP ");
    switch(IDL_BINOP(node).op) {
    case IDL_BINOP_OR: g_print("or:\n"); break;
    case IDL_BINOP_XOR: g_print("xor:\n"); break;
    case IDL_BINOP_AND: g_print("and:\n"); break;
    case IDL_BINOP_SHR: g_print("shr:\n"); break;
    case IDL_BINOP_SHL: g_print("shl:\n"); break;
    case IDL_BINOP_ADD: g_print("add:\n"); break;
    case IDL_BINOP_SUB: g_print("sub:\n"); break;
    case IDL_BINOP_MULT: g_print("mult:\n"); break;
    case IDL_BINOP_DIV: g_print("div:\n"); break;
    case IDL_BINOP_MOD: g_print("mod:\n"); break;
    }
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("left:\n");
    orte_idl_print_node(IDL_BINOP(node).left, indent_level + INDENT_INCREMENT_2);
    do_indent(indent_level + INDENT_INCREMENT_1); g_print("right:\n");
    orte_idl_print_node(IDL_BINOP(node).right, indent_level + INDENT_INCREMENT_2);
    break;
  case IDLN_UNARYOP:
    g_print("UNARYOP ");
    switch(IDL_UNARYOP(node).op) {
    case IDL_UNARYOP_PLUS: g_print("plus:\n"); break;
    case IDL_UNARYOP_MINUS: g_print("minus:\n"); break;
    case IDL_UNARYOP_COMPLEMENT: g_print("complement:\n"); break;
    }
    orte_idl_print_node(IDL_UNARYOP(node).operand, indent_level + INDENT_INCREMENT_1);
    break;
  case IDLN_TYPE_CHAR:
    g_print("TYPE char\n");
    break;
  case IDLN_TYPE_WIDE_CHAR:
    g_print("TYPE wide char\n");
    break;
  case IDLN_TYPE_BOOLEAN:
    g_print("TYPE boolean\n");
    break;
  case IDLN_TYPE_OCTET:
    g_print("TYPE octet\n");
    break;
  case IDLN_TYPE_OBJECT:
    g_print("TYPE object\n");
    break;
  case IDLN_TYPE_ANY:
    g_print("TYPE any\n");
    break;
  case IDLN_TYPE_TYPECODE:
    g_print("TYPE TypeCode\n");
    break;
  case IDLN_CODEFRAG:
    g_print("CODEFRAG\n");
    break;
  default:
    g_print("unhandled %d\n", IDL_NODE_TYPE(node));
  }
}
static gboolean
interface(TreeState *state)
{
    IDL_tree iface = state->tree, iter, orig;
    char *className = IDL_IDENT(IDL_INTERFACE(iface).ident).str;
    char *classNameUpper = NULL;
    char *classNameImpl = NULL;
    char *cp;
    gboolean ok = TRUE;
    gboolean keepvtable;
    const char *iid;
    const char *name_space;
    struct nsID id;
    char iid_parsed[UUID_LENGTH];
    GSList *doc_comments = IDL_IDENT(IDL_INTERFACE(iface).ident).comments;

    if (!verify_interface_declaration(iface))
        return FALSE;

#define FAIL    do {ok = FALSE; goto out;} while(0)

    fprintf(state->file,   "\n/* starting interface:    %s */\n",
            className);

    name_space = IDL_tree_property_get(IDL_INTERFACE(iface).ident, "namespace");
    if (name_space) {
        fprintf(state->file, "/* namespace:             %s */\n",
                name_space);
        fprintf(state->file, "/* fully qualified name:  %s.%s */\n",
                name_space,className);
    }

    iid = IDL_tree_property_get(IDL_INTERFACE(iface).ident, "uuid");
    if (iid) {
        /* Redundant, but a better error than 'cannot parse.' */
        if (strlen(iid) != 36) {
            IDL_tree_error(state->tree, "IID %s is the wrong length\n", iid);
            FAIL;
        }

        /*
         * Parse uuid and then output resulting nsID to string, to validate
         * uuid and normalize resulting .h files.
         */
        if (!xpidl_parse_iid(&id, iid)) {
            IDL_tree_error(state->tree, "cannot parse IID %s\n", iid);
            FAIL;
        }
        if (!xpidl_sprint_iid(&id, iid_parsed)) {
            IDL_tree_error(state->tree, "error formatting IID %s\n", iid);
            FAIL;
        }

        /* #define NS_ISUPPORTS_IID_STR "00000000-0000-0000-c000-000000000046" */
        fputs("#define ", state->file);
        write_classname_iid_define(state->file, className);
        fprintf(state->file, "_STR \"%s\"\n", iid_parsed);
        fputc('\n', state->file);

        /* #define NS_ISUPPORTS_IID { {0x00000000 .... 0x46 }} */
        fprintf(state->file, "#define ");
        write_classname_iid_define(state->file, className);
        fprintf(state->file, " \\\n"
                "  {0x%.8x, 0x%.4x, 0x%.4x, \\\n"
                "    { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, "
                "0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }}\n",
                id.m0, id.m1, id.m2,
                id.m3[0], id.m3[1], id.m3[2], id.m3[3],
                id.m3[4], id.m3[5], id.m3[6], id.m3[7]);
        fputc('\n', state->file);
    } else {
        IDL_tree_error(state->tree, "interface %s lacks a uuid attribute\n", 
            className);
        FAIL;
    }

    if (doc_comments != NULL)
        printlist(state->file, doc_comments);

    /*
     * NS_NO_VTABLE is defined in nsISupportsUtils.h, and defined on windows
     * to __declspec(novtable) on windows.  This optimization is safe
     * whenever the constructor calls no virtual methods.  Writing in IDL
     * almost guarantees this, except for the case when a %{C++ block occurs in
     * the interface.  We detect that case, and emit a macro call that disables
     * the optimization.
     */
    keepvtable = FALSE;
    for (iter = IDL_INTERFACE(state->tree).body;
         iter != NULL;
         iter = IDL_LIST(iter).next)
    {
        IDL_tree data = IDL_LIST(iter).data;
        if (IDL_NODE_TYPE(data) == IDLN_CODEFRAG)
            keepvtable = TRUE;
    }
    
    /* The interface declaration itself. */
    fprintf(state->file,
            "class %s%s",
            (keepvtable ? "" : "NS_NO_VTABLE "), className);
    
    if ((iter = IDL_INTERFACE(iface).inheritance_spec)) {
        fputs(" : ", state->file);
        if (IDL_LIST(iter).next != NULL) {
            IDL_tree_error(iter,
                           "multiple inheritance is not supported by xpidl");
            FAIL;
        }
        fprintf(state->file, "public %s", IDL_IDENT(IDL_LIST(iter).data).str);
    }
    fputs(" {\n"
          " public: \n\n", state->file);
    if (iid) {
        fputs("  NS_DEFINE_STATIC_IID_ACCESSOR(", state->file);
        write_classname_iid_define(state->file, className);
        fputs(")\n\n", state->file);
    }

    orig = state->tree; /* It would be nice to remove this state-twiddling. */

    state->tree = IDL_INTERFACE(iface).body;

    if (state->tree && !xpidl_process_node(state))
        FAIL;

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

    /*
     * #define NS_DECL_NSIFOO - create method prototypes that can be used in
     * class definitions that support this interface.
     *
     * Walk the tree explicitly to prototype a reworking of xpidl to get rid of
     * the callback mechanism.
     */
    state->tree = orig;
    fputs("/* Use this macro when declaring classes that implement this "
          "interface. */\n", state->file);
    fputs("#define NS_DECL_", state->file);
    classNameUpper = xpidl_strdup(className);
    for (cp = classNameUpper; *cp != '\0'; cp++)
        *cp = toupper(*cp);
    fprintf(state->file, "%s \\\n", classNameUpper);
    if (IDL_INTERFACE(state->tree).body == NULL) {
        write_indent(state->file);
        fputs("/* no methods! */\n", state->file);
    }

    for (iter = IDL_INTERFACE(state->tree).body;
         iter != NULL;
         iter = IDL_LIST(iter).next)
    {
        IDL_tree data = IDL_LIST(iter).data;

        switch(IDL_NODE_TYPE(data)) {
          case IDLN_OP_DCL:
            write_indent(state->file);
            write_method_signature(data, state->file, AS_DECL, NULL);
            break;

          case IDLN_ATTR_DCL:
            write_indent(state->file);
            if (!write_attr_accessor(data, state->file, TRUE, AS_DECL, NULL))
                FAIL;
            if (!IDL_ATTR_DCL(data).f_readonly) {
                fputs("; \\\n", state->file); /* Terminate the previous one. */
                write_indent(state->file);
                if (!write_attr_accessor(data, state->file,
                                         FALSE, AS_DECL, NULL))
                    FAIL;
                /* '; \n' at end will clean up. */
            }
            break;

          case IDLN_CONST_DCL:
            /* ignore it here; it doesn't contribute to the macro. */
            continue;

          case IDLN_CODEFRAG:
            XPIDL_WARNING((iter, IDL_WARNING1,
                           "%%{ .. %%} code fragment within interface "
                           "ignored when generating NS_DECL_%s macro; "
                           "if the code fragment contains method "
                           "declarations, the macro probably isn't "
                           "complete.", classNameUpper));
            continue;

          default:
            IDL_tree_error(iter,
                           "unexpected node type %d! "
                           "Please file a bug against the xpidl component.",
                           IDL_NODE_TYPE(data));
            FAIL;
        }

        if (IDL_LIST(iter).next != NULL) {
            fprintf(state->file, "; \\\n");
        } else {
            fprintf(state->file, "; \n");
        }
    }
    fputc('\n', state->file);

    /* XXX abstract above and below into one function? */
    /*
     * #define NS_FORWARD_NSIFOO - create forwarding methods that can delegate
     * behavior from in implementation to another object.  As generated by
     * idlc.
     */
    fprintf(state->file,
            "/* Use this macro to declare functions that forward the "
            "behavior of this interface to another object. */\n"
            "#define NS_FORWARD_%s(_to) \\\n",
            classNameUpper);
    if (IDL_INTERFACE(state->tree).body == NULL) {
        write_indent(state->file);
        fputs("/* no methods! */\n", state->file);
    }

    for (iter = IDL_INTERFACE(state->tree).body;
         iter != NULL;
         iter = IDL_LIST(iter).next)
    {
        IDL_tree data = IDL_LIST(iter).data;

        switch(IDL_NODE_TYPE(data)) {
          case IDLN_OP_DCL:
            write_indent(state->file);
            write_method_signature(data, state->file, AS_DECL, NULL);
            fputs(" { return _to ", state->file);
            write_method_signature(data, state->file, AS_CALL, NULL);
            break;

          case IDLN_ATTR_DCL:
            write_indent(state->file);
            if (!write_attr_accessor(data, state->file, TRUE, AS_DECL, NULL))
                FAIL;
            fputs(" { return _to ", state->file);
            if (!write_attr_accessor(data, state->file, TRUE, AS_CALL, NULL))
                FAIL;
            if (!IDL_ATTR_DCL(data).f_readonly) {
                fputs("; } \\\n", state->file); /* Terminate the previous one. */
                write_indent(state->file);
                if (!write_attr_accessor(data, state->file,
                                         FALSE, AS_DECL, NULL))
                    FAIL;
                fputs(" { return _to ", state->file);
                if (!write_attr_accessor(data, state->file,
                                         FALSE, AS_CALL, NULL))
                    FAIL;
                /* '; } \n' at end will clean up. */
            }
            break;

          case IDLN_CONST_DCL:
          case IDLN_CODEFRAG:
              continue;

          default:
            FAIL;
        }

        if (IDL_LIST(iter).next != NULL) {
            fprintf(state->file, "; } \\\n");
        } else {
            fprintf(state->file, "; } \n");
        }
    }
    fputc('\n', state->file);


    /* XXX abstract above and below into one function? */
    /*
     * #define NS_FORWARD_SAFE_NSIFOO - create forwarding methods that can delegate
     * behavior from in implementation to another object.  As generated by
     * idlc.
     */
    fprintf(state->file,
            "/* Use this macro to declare functions that forward the "
            "behavior of this interface to another object in a safe way. */\n"
            "#define NS_FORWARD_SAFE_%s(_to) \\\n",
            classNameUpper);
    if (IDL_INTERFACE(state->tree).body == NULL) {
        write_indent(state->file);
        fputs("/* no methods! */\n", state->file);
    }

    for (iter = IDL_INTERFACE(state->tree).body;
         iter != NULL;
         iter = IDL_LIST(iter).next)
    {
        IDL_tree data = IDL_LIST(iter).data;

        switch(IDL_NODE_TYPE(data)) {
          case IDLN_OP_DCL:
            write_indent(state->file);
            write_method_signature(data, state->file, AS_DECL, NULL);
            fputs(" { return !_to ? NS_ERROR_NULL_POINTER : _to->", state->file);
            write_method_signature(data, state->file, AS_CALL, NULL);
            break;

          case IDLN_ATTR_DCL:
            write_indent(state->file);
            if (!write_attr_accessor(data, state->file, TRUE, AS_DECL, NULL))
                FAIL;
            fputs(" { return !_to ? NS_ERROR_NULL_POINTER : _to->", state->file);
            if (!write_attr_accessor(data, state->file, TRUE, AS_CALL, NULL))
                FAIL;
            if (!IDL_ATTR_DCL(data).f_readonly) {
                fputs("; } \\\n", state->file); /* Terminate the previous one. */
                write_indent(state->file);
                if (!write_attr_accessor(data, state->file,
                                         FALSE, AS_DECL, NULL))
                    FAIL;
                fputs(" { return !_to ? NS_ERROR_NULL_POINTER : _to->", state->file);
                if (!write_attr_accessor(data, state->file,
                                         FALSE, AS_CALL, NULL))
                    FAIL;
                /* '; } \n' at end will clean up. */
            }
            break;

          case IDLN_CONST_DCL:
          case IDLN_CODEFRAG:
              continue;

          default:
            FAIL;
        }

        if (IDL_LIST(iter).next != NULL) {
            fprintf(state->file, "; } \\\n");
        } else {
            fprintf(state->file, "; } \n");
        }
    }
    fputc('\n', state->file);

    /*
     * Build a sample implementation template.
     */
    if (strlen(className) >= 3 && className[2] == 'I') {
        classNameImpl = xpidl_strdup(className);
        if (!classNameImpl)
            FAIL;
        memmove(&classNameImpl[2], &classNameImpl[3], strlen(classNameImpl) - 2);
    } else {
        classNameImpl = xpidl_strdup("_MYCLASS_");
        if (!classNameImpl)
            FAIL;
    }

    fputs("#if 0\n"
          "/* Use the code below as a template for the "
          "implementation class for this interface. */\n"
          "\n"
          "/* Header file */"
          "\n",
          state->file);
    fprintf(state->file, "class %s : public %s\n", classNameImpl, className);
    fputs("{\n"
          "public:\n", state->file);
    write_indent(state->file);
    fputs("NS_DECL_ISUPPORTS\n", state->file);
    write_indent(state->file);
    fprintf(state->file, "NS_DECL_%s\n", classNameUpper);
    fputs("\n", state->file);
    write_indent(state->file);
    fprintf(state->file, "%s();\n", classNameImpl);
    fputs("\n"
          "private:\n", state->file);
    write_indent(state->file);
    fprintf(state->file, "~%s();\n", classNameImpl);
    fputs("\n"
          "protected:\n", state->file);
    write_indent(state->file);
    fputs("/* additional members */\n", state->file);
    fputs("};\n\n", state->file);

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

    fprintf(state->file, 
            "NS_IMPL_ISUPPORTS1(%s, %s)\n", classNameImpl, className);
    fputs("\n", state->file);
    
    fprintf(state->file, "%s::%s()\n", classNameImpl, classNameImpl);
    fputs("{\n", state->file);
    write_indent(state->file);
    fputs("/* member initializers and constructor code */\n", state->file);
    fputs("}\n\n", state->file);
    
    fprintf(state->file, "%s::~%s()\n", classNameImpl, classNameImpl);
    fputs("{\n", state->file);
    write_indent(state->file);
    fputs("/* destructor code */\n", state->file);
    fputs("}\n\n", state->file);

    for (iter = IDL_INTERFACE(state->tree).body;
         iter != NULL;
         iter = IDL_LIST(iter).next)
    {
        IDL_tree data = IDL_LIST(iter).data;

        switch(IDL_NODE_TYPE(data)) {
          case IDLN_OP_DCL:
            /* It would be nice to remove this state-twiddling. */
            orig = state->tree; 
            state->tree = data;
            xpidl_write_comment(state, 0);
            state->tree = orig;

            write_method_signature(data, state->file, AS_IMPL, classNameImpl);
            fputs("\n{\n", state->file);
            write_indent(state->file);
            write_indent(state->file);
            fputs("return NS_ERROR_NOT_IMPLEMENTED;\n"
                  "}\n"
                  "\n", state->file);
            break;

          case IDLN_ATTR_DCL:
            /* It would be nice to remove this state-twiddling. */
            orig = state->tree; 
            state->tree = data;
            xpidl_write_comment(state, 0);
            state->tree = orig;
            
            if (!write_attr_accessor(data, state->file, TRUE, 
                                     AS_IMPL, classNameImpl))
                FAIL;
            fputs("\n{\n", state->file);
            write_indent(state->file);
            write_indent(state->file);
            fputs("return NS_ERROR_NOT_IMPLEMENTED;\n"
                  "}\n", state->file);

            if (!IDL_ATTR_DCL(data).f_readonly) {
                if (!write_attr_accessor(data, state->file, FALSE, 
                                         AS_IMPL, classNameImpl))
                    FAIL;
                fputs("\n{\n", state->file);
                write_indent(state->file);
                write_indent(state->file);
                fputs("return NS_ERROR_NOT_IMPLEMENTED;\n"
                      "}\n", state->file);
            }
            fputs("\n", state->file);
            break;

          case IDLN_CONST_DCL:
          case IDLN_CODEFRAG:
              continue;

          default:
            FAIL;
        }
    }

    fputs("/* End of implementation class template. */\n"
          "#endif\n"
          "\n", state->file);

#undef FAIL

out:
    if (classNameUpper)
        free(classNameUpper);
    if (classNameImpl)
        free(classNameImpl);
    return ok;
}
Пример #11
0
gboolean
verify_attribute_declaration(IDL_tree attr_tree)
{
    IDL_tree iface;
    IDL_tree ident;
    IDL_tree attr_type;
    gboolean scriptable_interface;

    /* We don't support attributes named IID, conflicts with static GetIID 
     * member. The conflict is due to certain compilers (VC++) choosing a
     * different vtable order, placing GetIID at the beginning regardless
     * of it's placement
     */
    if (strcmp(
        IDL_IDENT(
            IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).data).str, 
        "IID") == 0) {
        IDL_tree_error(attr_tree,
                       "Attributes named IID not supported, causes vtable "
                       "ordering problems");
        return FALSE;
    }
    /* 
     * Verify that we've been called on an interface, and decide if the
     * interface was marked [scriptable].
     */
    if (IDL_NODE_UP(attr_tree) && IDL_NODE_UP(IDL_NODE_UP(attr_tree)) &&
        IDL_NODE_TYPE(iface = IDL_NODE_UP(IDL_NODE_UP(attr_tree))) 
        == IDLN_INTERFACE)
    {
        scriptable_interface =
            (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "scriptable")
             != NULL);
    } else {
        IDL_tree_error(attr_tree,
                    "verify_attribute_declaration called on a non-interface?");
        return FALSE;
    }

    /*
     * Grab the first of the list of idents and hope that it'll
     * say scriptable or no.
     */
    ident = IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).data;

    /*
     * If the interface isn't scriptable, or the attribute is marked noscript,
     * there's no need to check.
     */
    if (!scriptable_interface ||
        IDL_tree_property_get(ident, "noscript") != NULL)
        return TRUE;

    /*
     * If it should be scriptable, check that the type is non-native. nsid,
     * domstring, utf8string, cstring, astring are exempted.
     */
    attr_type = IDL_ATTR_DCL(attr_tree).param_type_spec;

    if (attr_type != NULL)
    {
        if (UP_IS_NATIVE(attr_type) &&
            IDL_tree_property_get(attr_type, "nsid") == NULL &&
            IDL_tree_property_get(attr_type, "domstring") == NULL &&
            IDL_tree_property_get(attr_type, "utf8string") == NULL &&
            IDL_tree_property_get(attr_type, "cstring") == NULL &&
            IDL_tree_property_get(attr_type, "astring") == NULL)
        {
            IDL_tree_error(attr_tree,
                           "attributes in [scriptable] interfaces that are "
                           "non-scriptable because they refer to native "
                           "types must be marked [noscript]\n");
            return FALSE;
        }
        /*
         * We currently don't support properties of type nsid that aren't 
         * pointers or references, unless they are marked [notxpcom} and 
         * must be read-only 
         */
         
        if ((IDL_tree_property_get(ident, "notxpcom") == NULL || !(IDL_ATTR_DCL(attr_tree).f_readonly)) &&
            IDL_tree_property_get(attr_type,"nsid") != NULL &&
            IDL_tree_property_get(attr_type,"ptr") == NULL &&
            IDL_tree_property_get(attr_type,"ref") == NULL)
        {
            IDL_tree_error(attr_tree,
                           "Feature not currently supported: "
                           "attributes with a type of nsid must be marked "
                           "either [ptr] or [ref], or "
                           "else must be marked [notxpcom] "
                           "and must be read-only\n");
            return FALSE;
        }

        /* 
         * Run additional error checks on the attribute type if targetting an 
         * older version of XPConnect.
         */

        if (!verify_type_fits_version(attr_type, attr_tree))
            return FALSE;
    }

    if (IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).next != NULL)
    {
        IDL_tree_error(attr_tree,
            "multiple attributes in a single declaration is not supported\n");
        return FALSE;
    }
    return TRUE;
}
Пример #12
0
static gboolean
attribute_declaration(TreeState *state)
{
    gboolean read_only = IDL_ATTR_DCL(state->tree).f_readonly;
    char *attribute_name = ATTR_IDENT(state->tree).str;

    gboolean method_noscript = 
        (IDL_tree_property_get(ATTR_PROPS(state->tree), "noscript") != NULL);

    gboolean method_notxpcom = 
        (IDL_tree_property_get(ATTR_PROPS(state->tree), "notxpcom") != NULL);

#if 0
    /*
     * Disabled here because I can't verify this check against possible
     * users of the java xpidl backend.
     */
    if (!verify_attribute_declaration(state->tree))
        return FALSE;
#endif

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

#if 1
    /*
     * Write access permission ("public")
     */
    fputs("    public ", state->file);
#else
    if (method_notxpcom || method_noscript)
        return TRUE;

    /*
     * Write access permission ("public" unless nonscriptable)
     */
    fputs("    ", state->file);
    if (!method_noscript) {
        fputs("public ", state->file);
    }
#endif

    /*
     * Write the proper Java return value for the get operation
     */
    if (!xpcom_to_java_type(state, ATTR_TYPE_DECL(state->tree))) {
        return FALSE;
    }
    
    /*
     * Write the name of the accessor ("get") method.
     */
    fprintf(state->file, " get%c%s();\n",
            toupper(attribute_name[0]), attribute_name + 1);


    if (!read_only) {
#if 1
        fputs("    public ", state->file);
#else
        /* Nonscriptable methods become package-protected */
        fputs("    ", state->file);
        if (!method_noscript) {
            fputs("public ", state->file);
        }
#endif

        /*
         * Write attribute access method name and return type
         */
        fprintf(state->file, "void set%c%s(",
                toupper(attribute_name[0]), 
                attribute_name+1);
        
        /*
         * Write the proper Java type for the set operation
         */
        if (!xpcom_to_java_type(state, ATTR_TYPE_DECL(state->tree))) {
            return FALSE;
        }

        /*
         * Write the name of the formal parameter.
         */
        fprintf(state->file, " a%c%s);\n", toupper(attribute_name[0]), attribute_name + 1);
    }

    return TRUE;
}