/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Sun Microsystems, * Inc. Portions created by Sun are * Copyright (C) 1999 Sun Microsystems, Inc. All * Rights Reserved. * * Contributor(s): * Michael Allen (michael.allen@sun.com) * Frank Mitchell (frank.mitchell@sun.com) */ /* * Generate Java interfaces from XPIDL. */ #include "xpidl.h" #include #include struct java_priv_data { GHashTable *typedefTable; }; #define TYPEDEFS(state) (((struct java_priv_data *)state->priv)->typedefTable) static gboolean write_classname_iid_define(FILE *file, const char *className) { const char *iidName; if (className[0] == 'n' && className[1] == 's') { /* backcompat naming styles */ fputs("NS_", file); iidName = className + 2; } else { iidName = className; } while (*iidName) { fputc(toupper(*iidName++), file); } fputs("_IID", file); return TRUE; } static gboolean java_prolog(TreeState *state) { #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF const char *basename; const char *ext; #endif state->priv = calloc(1, sizeof(struct java_priv_data)); if (!state->priv) return FALSE; TYPEDEFS(state) = 0; TYPEDEFS(state) = g_hash_table_new(g_str_hash, g_str_equal); if (!TYPEDEFS(state)) { /* XXX report error */ free(state->priv); return FALSE; } /* * First pass */ #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF basename = xpidl_basename(state->real_outname ? state->real_outname : state->basename); ext = strrchr(basename, '.'); if (!ext) ext = strchr(basename, '\0'); fprintf(state->file, "/**\n" " * NOTE: THIS IS A GENERATED FILE. PLEASE CONSULT THE ORIGINAL IDL FILE\n" " * FOR THE FULL DOCUMENTATION AND LICENSE.\n" " *\n" " * @see \n" " **/\n" "\n" "package org.mozilla.interfaces;\n\n" "import java.math.BigInteger;\n\n" "\n" , ext - basename >= 19 ? 19 : (int)(ext - basename), basename); g_free(basename); #else fputs("/*\n * ************* DO NOT EDIT THIS FILE ***********\n", state->file); fprintf(state->file, " *\n * This file was automatically generated from %s.idl.\n", state->basename); fputs(" */\n\n", state->file); #endif return TRUE; } static gboolean java_epilog(TreeState *state) { /* points to other elements of the tree, so just destroy the table */ g_hash_table_destroy(TYPEDEFS(state)); free(state->priv); state->priv = NULL; #ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF /* * Last pass */ fprintf(state->file, "\n/*\n * end\n */\n"); #endif return TRUE; } static gboolean forward_declaration(TreeState *state) { /* * Java doesn't need forward declarations unless the declared * class resides in a different package. */ #if 0 IDL_tree iface = state->tree; const char *className = IDL_IDENT(IDL_FORWARD_DCL(iface).ident).str; const char *pkgName = "org.mozilla.xpcom"; if (!className) return FALSE; /* XXX: Get package name and compare */ fprintf(state->file, "import %s.%s;\n", pkgName, className); #endif return TRUE; } static gboolean interface_declaration(TreeState *state) { IDL_tree interface = state->tree; IDL_tree iterator = NULL; char *interface_name = IDL_IDENT(IDL_INTERFACE(interface).ident).str; const char *iid = NULL; if (!verify_interface_declaration(interface)) return FALSE; #ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF /* * Write out JavaDoc comment */ fprintf(state->file, "\n/**\n * Interface %s\n", interface_name); #endif #ifndef LIBIDL_MAJOR_VERSION iid = IDL_tree_property_get(interface, "uuid"); #else iid = IDL_tree_property_get(IDL_INTERFACE(interface).ident, "uuid"); #endif #ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF if (iid != NULL) { fprintf(state->file, " *\n * IID: 0x%s\n */\n\n", iid); } else { fputs(" */\n\n", state->file); } #endif /* * Write "public interface " */ fprintf(state->file, "public interface %s ", interface_name); /* * Check for inheritence, and iterator over the inherited names, * if any. */ if ((iterator = IDL_INTERFACE(interface).inheritance_spec)) { fputs("extends ", state->file); do { fprintf(state->file, "%s", IDL_IDENT(IDL_LIST(iterator).data).str); if (IDL_LIST(iterator).next) { fputs(", ", state->file); } } while ((iterator = IDL_LIST(iterator).next)); } fputs("\n{\n", state->file); if (iid) { /* * Write interface constants for IID */ #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF fputs(" public static final String ", state->file); #else fputs(" public static final String ", state->file); #endif /* XXX s.b just "IID" ? */ if (!write_classname_iid_define(state->file, interface_name)) { return FALSE; } #ifdef VBOX_XPIDL_EMULATE_GENJIFACES fputs(" =\n \"{", state->file); while (*iid) { fputc(tolower(*iid++), state->file); } fputs("}\";\n", state->file); #else fprintf(state->file, "_STRING =\n \"%s\";\n\n", iid); fputs(" public static final nsID ", state->file); /* XXX s.b just "IID" ? */ if (!write_classname_iid_define(state->file, interface_name)) { return FALSE; } fprintf(state->file, " =\n new nsID(\"%s\");\n\n", iid); #endif } /* * Advance the state of the tree, go on to process more */ state->tree = IDL_INTERFACE(interface).body; if (state->tree && !xpidl_process_node(state)) { return FALSE; } fputs("\n}\n", state->file); return TRUE; } static gboolean process_list(TreeState *state) { #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF /* To make the diffing simple, group the constants, methods and attributes. */ IDL_tree list = state->tree; IDL_tree iter; for (iter = list; iter; iter = IDL_LIST(iter).next) { if (IDL_NODE_TYPE(IDL_LIST(iter).data) == IDLN_CONST_DCL) { state->tree = IDL_LIST(iter).data; if (!xpidl_process_node(state)) return FALSE; } } for (iter = list; iter; iter = IDL_LIST(iter).next) { if (IDL_NODE_TYPE(IDL_LIST(iter).data) == IDLN_ATTR_DCL) { state->tree = IDL_LIST(iter).data; if (!xpidl_process_node(state)) return FALSE; } } for (iter = list; iter; iter = IDL_LIST(iter).next) { if (IDL_NODE_TYPE(IDL_LIST(iter).data) == IDLN_OP_DCL) { state->tree = IDL_LIST(iter).data; if (!xpidl_process_node(state)) return FALSE; } } for (iter = list; iter; iter = IDL_LIST(iter).next) { if ( IDL_NODE_TYPE(IDL_LIST(iter).data) != IDLN_CONST_DCL && IDL_NODE_TYPE(IDL_LIST(iter).data) != IDLN_OP_DCL && IDL_NODE_TYPE(IDL_LIST(iter).data) != IDLN_ATTR_DCL ) { state->tree = IDL_LIST(iter).data; if (!xpidl_process_node(state)) return FALSE; } } #else IDL_tree iter; for (iter = state->tree; iter; iter = IDL_LIST(iter).next) { state->tree = IDL_LIST(iter).data; if (!xpidl_process_node(state)) return FALSE; } #endif return TRUE; } #ifdef VBOX_XPIDL_EMULATE_GENJIFACES static gboolean interface_declaration_wrapper(TreeState *state) { IDL_tree interface = state->tree; char *interface_name = IDL_IDENT(IDL_INTERFACE(interface).ident).str; FILE *org_file = state->file; char *org_name = state->real_outname; void *org_priv = state->priv; gboolean rc; /* * Skip non-scriptable interfaces. */ if ( !IDL_tree_property_get(IDL_INTERFACE(interface).ident, "scriptable") && strcmp(interface_name, "nsIAppShell") ) return TRUE; /* * GROSS HACK: If the interface isn't the same as the file name, * temporarily switch output file. */ if (state->real_outname) { const char *basename = xpidl_basename(state->real_outname); const char *ext = strrchr(basename, '.'); if ( ext && !strcmp(ext, ".java") && ( strncmp(interface_name, basename, ext - basename) || interface_name[ext - basename] != '.') ) { size_t needed = strlen(state->real_outname) + strlen(interface_name) + strlen(".java") + 4; char *tmp = malloc(needed); if (basename != state->real_outname) sprintf(tmp,"%.*s/%s.java", (int)(basename - state->real_outname - 1), state->real_outname, interface_name); else sprintf(tmp,"%s.java", interface_name); state->file = fopen(tmp, "w"); if (!state->file) { perror("error opening output file"); state->file = org_file; free(tmp); return FALSE; } state->real_outname = tmp; java_prolog(state); } g_free(basename); } rc = interface_declaration(state); if (state->file != org_file) { java_epilog(state); fclose(state->file); free(state->real_outname); state->file = org_file; state->real_outname = org_name; state->priv = org_priv; } return rc; } #endif /* VBOX_XPIDL_EMULATE_GENJIFACES */ static gboolean xpcom_to_java_type (TreeState *state) { if (!state->tree) { fputs("Object", state->file); return TRUE; } switch(IDL_NODE_TYPE(state->tree)) { case IDLN_TYPE_INTEGER: { switch(IDL_TYPE_INTEGER(state->tree).f_type) { case IDL_INTEGER_TYPE_SHORT: #ifdef VBOX_XPIDL_EMULATE_GENJIFACES if (IDL_TYPE_INTEGER(state->tree).f_signed) fputs("short", state->file); else fputs("int", state->file); #else fputs("short", state->file); #endif break; case IDL_INTEGER_TYPE_LONG: #ifdef VBOX_XPIDL_EMULATE_GENJIFACES if (IDL_TYPE_INTEGER(state->tree).f_signed) fputs("int", state->file); else fputs("long", state->file); #else fputs("int", state->file); #endif break; case IDL_INTEGER_TYPE_LONGLONG: #ifdef VBOX_XPIDL_EMULATE_GENJIFACES if (IDL_TYPE_INTEGER(state->tree).f_signed) fputs("long", state->file); else fputs("double", state->file); #else fputs("long", state->file); #endif break; default: g_error(" Unknown integer type: %d\n", IDL_TYPE_INTEGER(state->tree).f_type); return FALSE; } break; } case IDLN_TYPE_CHAR: case IDLN_TYPE_WIDE_CHAR: fputs("char", state->file); break; case IDLN_TYPE_WIDE_STRING: case IDLN_TYPE_STRING: fputs("String", state->file); break; case IDLN_TYPE_BOOLEAN: fputs("boolean", state->file); break; case IDLN_TYPE_OCTET: #ifdef VBOX_XPIDL_EMULATE_GENJIFACES fputs("short", state->file); #else fputs("byte", state->file); #endif break; case IDLN_TYPE_FLOAT: switch(IDL_TYPE_FLOAT(state->tree).f_type) { case IDL_FLOAT_TYPE_FLOAT: fputs("float", state->file); break; case IDL_FLOAT_TYPE_DOUBLE: fputs("double", state->file); break; default: g_error(" Unknown floating point typ: %d\n", IDL_NODE_TYPE(state->tree)); break; } break; case IDLN_IDENT: if (IDL_NODE_UP(state->tree) && IDL_NODE_TYPE(IDL_NODE_UP(state->tree)) == IDLN_NATIVE) { const char *user_type = IDL_NATIVE(IDL_NODE_UP(state->tree)).user_type; if (strcmp(user_type, "void") == 0) { #ifdef VBOX_XPIDL_EMULATE_GENJIFACES fputs("nsISupports", state->file); #else fputs("Object", state->file); #endif } else if (strcmp(user_type, "nsID") == 0 || strcmp(user_type, "nsIID") == 0 || strcmp(user_type, "nsCID") == 0) { /* XXX: s.b test for "iid" attribute */ /* XXX: special class for nsIDs */ #ifdef VBOX_XPIDL_EMULATE_GENJIFACES fputs("String", state->file); #else fputs("nsID", state->file); #endif } else { /* XXX: special class for opaque types */ #ifdef VBOX_XPIDL_EMULATE_GENJIFACES fputs("String", state->file); #else fputs("OpaqueValue", state->file); #endif } } else { const char *ident_str = IDL_IDENT(state->tree).str; /* XXX: big kludge; s.b. way to match to typedefs */ #ifdef VBOX_XPIDL_EMULATE_GENJIFACES if (strcmp(ident_str, "PRInt8") == 0) { fputs("byte", state->file); } else if (strcmp(ident_str, "PRInt16") == 0 || strcmp(ident_str, "PRUint8") == 0) { fputs("short", state->file); } else if (strcmp(ident_str, "PRInt32") == 0 || strcmp(ident_str, "PRUint16") == 0) { fputs("int", state->file); } else if (strcmp(ident_str, "PRInt64") == 0 || strcmp(ident_str, "PRUint32") == 0 || strcmp(ident_str, "PRThreadPriority") == 0 || strcmp(ident_str, "PRThreadScope") == 0 || strcmp(ident_str, "PRThreadState") == 0) { fputs("long", state->file); } else if (strcmp(ident_str, "PRUint64") == 0) { fputs("double", state->file); } #else if (strcmp(ident_str, "PRInt8") == 0 || strcmp(ident_str, "PRUint8") == 0) { fputs("byte", state->file); } else if (strcmp(ident_str, "PRInt16") == 0 || strcmp(ident_str, "PRUint16") == 0) { fputs("short", state->file); } else if (strcmp(ident_str, "PRInt32") == 0 || strcmp(ident_str, "PRUint32") == 0) { fputs("int", state->file); } else if (strcmp(ident_str, "PRInt64") == 0 || strcmp(ident_str, "PRUint64") == 0) { fputs("long", state->file); } #endif else if (strcmp(ident_str, "PRBool") == 0) { fputs("boolean", state->file); } else if (strcmp(ident_str, "nsrefcnt") == 0) { fputs("int", state->file); } #ifdef VBOX_XPIDL_EMULATE_GENJIFACES /* XXX: Use find_underlying_type instead? */ else if ( strcmp(ident_str, "nsresult") == 0 || strcmp(ident_str, "size_t") == 0) { fputs("long", state->file); } else if ( strcmp(ident_str, "PRTime") == 0) { fputs("double", state->file); } /* In Javaconnect, we handle weak references internally; no need for the |nsIWeakReference| interface. So just return |nsISupports|. */ else if (strcmp(ident_str, "nsIWeakReference") == 0) { fputs("nsISupports", state->file); } #endif else { IDL_tree real_type = g_hash_table_lookup(TYPEDEFS(state), ident_str); if (real_type) { IDL_tree orig_tree = state->tree; state->tree = real_type; xpcom_to_java_type(state); state->tree = orig_tree; } else { fputs(ident_str, state->file); } } } break; case IDLN_TYPE_ENUM: case IDLN_TYPE_OBJECT: default: g_error(" Unknown type: %d\n", IDL_TYPE_FLOAT(state->tree).f_type); break; } return TRUE; } static gboolean #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF xpcom_to_java_param(TreeState *state, unsigned nparam) #else xpcom_to_java_param(TreeState *state) #endif { IDL_tree param = state->tree; state->tree = IDL_PARAM_DCL(param).param_type_spec; /* * Put in type of parameter */ if (!xpcom_to_java_type(state)) { return FALSE; } /* * If the parameter is out or inout, make it a Java array of the * appropriate type */ #ifdef VBOX_XPIDL_EMULATE_GENJIFACES /* XXX: Causes nsILineInputStream::readLine(String[] arg1) where genjifaces drops the []. */ #endif if (IDL_PARAM_DCL(param).attr != IDL_PARAM_IN) { fputs("[]", state->file); } #ifdef VBOX_XPIDL_EMULATE_GENJIFACES /*XXX: nsIConsoleService::getMessageArray ends up with [][] arg1... */ /*else*/ if (IDL_tree_property_get(IDL_PARAM_DCL(param).simple_declarator, "array")) { fputs("[]", state->file); } #endif /* * Put in name of parameter */ fputc(' ', state->file); #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF fprintf(state->file, "arg%u", nparam+1); #else fputs(IDL_IDENT(IDL_PARAM_DCL(param).simple_declarator).str, state->file); #endif return TRUE; } #ifdef VBOX_XPIDL_EMULATE_GENJIFACES static gboolean is_java_keyword(char ch0, const char *name) { static const char * const kJavaKeywords[] = { "abstract", "default", "if" , "private" , "this" , "boolean" , "do" , "implements", "protected" , "throw" , "break" , "double" , "import", "public" , "throws" , "byte" , "else" , "instanceof", "return" , "transient", "case" , "extends", "int" , "short" , "try" , "catch" , "final" , "interface" , "static" , "void" , "char" , "finally", "long" , "strictfp" , "volatile" , "class" , "float" , "native" , "super" , "while" , "const" , "for" , "new" , "switch" , "continue", "goto" , "package" , "synchronized", "assert" , /* added in Java 1.4 */ "enum" , /* added in Java 5.0 */ "clone" , /* clone is a member function of java.lang.Object */ "finalize" /* finalize is a member function of java.lang.Object */ }; unsigned i; for (i = 0; i < sizeof(kJavaKeywords) / sizeof(kJavaKeywords[0]); i++) { if (kJavaKeywords[i][0] == ch0 && !strcmp(&kJavaKeywords[i][1], &name[1])) { return TRUE; } } return FALSE; } #endif static gboolean type_declaration(TreeState *state) { /* * Unlike C, Java has no type declaration directive. * Instead, we record the mapping, and look up the actual type * when needed. */ IDL_tree type = IDL_TYPE_DCL(state->tree).type_spec; IDL_tree dcls = IDL_TYPE_DCL(state->tree).dcls; /* XXX: check for illegal types */ g_hash_table_insert(TYPEDEFS(state), IDL_IDENT(IDL_LIST(dcls).data).str, type); return TRUE; } static gboolean method_declaration(TreeState *state) { /* IDL_tree method_tree = state->tree; */ 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; const char *method_name = IDL_IDENT(method->ident).str; #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF unsigned nparam = 0; #endif if (!verify_method_declaration(state->tree)) return FALSE; #ifdef VBOX_XPIDL_EMULATE_GENJIFACES /* * Skip most (todo) non-scriptable and not-xpcom methods. */ if (method_noscript || method_notxpcom) { return TRUE; } #endif fputc('\n', state->file); #ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF xpidl_write_comment(state, 4); #endif /* * Write beginning of method declaration */ #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF fputs(" ", state->file); #else fputs(" ", state->file); #endif if (!method_noscript) { /* Nonscriptable methods become package-protected */ fputs("public ", state->file); } /* * Write return type * Unlike C++ headers, Java interfaces return the declared * return value; an exception indicates XPCOM method failure. */ if (method_notxpcom || method->op_type_spec) { state->tree = method->op_type_spec; if (!xpcom_to_java_type(state)) { 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; state->tree = IDL_PARAM_DCL(state->tree).param_type_spec; /* * Put in type of parameter */ if (!xpcom_to_java_type(state)) { return FALSE; } #ifdef VBOX_XPIDL_EMULATE_GENJIFACES if (IDL_tree_property_get(IDL_PARAM_DCL(IDL_LIST(iterator).data).simple_declarator, "array")) { fputs("[]", state->file); } #endif } state->tree = original_tree; } if (retval_param == NULL) { fputs("void", state->file); } } /* * Write method name */ #ifdef VBOX_XPIDL_EMULATE_GENJIFACES if (is_java_keyword(tolower(method_name[0]), method_name)) { fprintf(state->file, " %c%s_(", tolower(method_name[0]), method_name + 1); } else { fprintf(state->file, " %c%s(", tolower(method_name[0]), method_name + 1); } #else fprintf(state->file, " %c%s(", tolower(method_name[0]), method_name + 1); #endif /* * 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; #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF if (!xpcom_to_java_param(state, nparam++)) { #else if (!xpcom_to_java_param(state)) { #endif return FALSE; } } fputs(")", state->file); 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; } static gboolean constant_declaration(TreeState *state) { struct _IDL_CONST_DCL *declaration = &IDL_CONST_DCL(state->tree); const char *name = IDL_IDENT(declaration->ident).str; IDL_tree real_type; if (!verify_const_declaration(state->tree)) return FALSE; /* Could be a typedef; try to map it to the real type. */ real_type = find_underlying_type(declaration->const_type); real_type = real_type ? real_type : declaration->const_type; fputc('\n', state->file); #ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF xpidl_write_comment(state, 4); #endif #ifdef VBOX_XPIDL_EMULATE_GENJIFACES # ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF fputs(" public static final ", state->file); # else fputs(" public static final ", state->file); # endif if (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG) { if (IDL_TYPE_INTEGER(real_type).f_signed) fprintf(state->file, "int %s = %" IDL_LL "d;\n", name, IDL_INTEGER(declaration->const_exp).value); else fprintf(state->file, "long %s = %" IDL_LL "uL;\n", name, IDL_INTEGER(declaration->const_exp).value); } else { if (IDL_TYPE_INTEGER(real_type).f_signed) fprintf(state->file, "short %s = %" IDL_LL "d;\n", name, IDL_INTEGER(declaration->const_exp).value); else fprintf(state->file, "int %s = %" IDL_LL "u;\n", name, IDL_INTEGER(declaration->const_exp).value); } #else /* !VBOX_XPIDL_EMULATE_GENJIFACES */ fprintf(state->file, " public static final %s %s = %d;\n", (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG ? "long" : "short"), name, (int) IDL_INTEGER(declaration->const_exp).value); #endif /* !VBOX_XPIDL_EMULATE_GENJIFACES */ return TRUE; } #define ATTR_IDENT(tree) (IDL_IDENT(IDL_LIST(IDL_ATTR_DCL((tree)).simple_declarations).data)) #define ATTR_PROPS(tree) (IDL_LIST(IDL_ATTR_DCL((tree)).simple_declarations).data) #define ATTR_TYPE_DECL(tree) (IDL_ATTR_DCL((tree)).param_type_spec) 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); #ifdef VBOX_XPIDL_EMULATE_GENJIFACES /* * Skip most non-scriptable attributes. */ if (method_noscript) { return TRUE; } #endif #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); #ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF xpidl_write_comment(state, 4); #endif state->tree = ATTR_TYPE_DECL(state->tree); /* * Write access permission ("public" unless nonscriptable) */ #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF fputs(" ", state->file); #else fputs(" ", state->file); #endif if (!method_noscript) { fputs("public ", state->file); } /* * Write the proper Java return value for the get operation */ if (!xpcom_to_java_type(state)) { 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) { /* Nonscriptable methods become package-protected */ #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF fputs("\n ", state->file); #else fputs(" ", state->file); #endif if (!method_noscript) { fputs("public ", state->file); } /* * 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)) { return FALSE; } /* * Write the name of the formal parameter. */ #ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF fputs(" arg1);\n", state->file); #else fputs(" value);\n", state->file); #endif } return TRUE; } static gboolean enum_declaration(TreeState *state) { XPIDL_WARNING((state->tree, IDL_WARNING1, "enums not supported, enum \'%s\' ignored", IDL_IDENT(IDL_TYPE_ENUM(state->tree).ident).str)); return TRUE; } backend * xpidl_java_dispatch(void) { static backend result; static nodeHandler table[IDLN_LAST]; static gboolean initialized = FALSE; result.emit_prolog = java_prolog; result.emit_epilog = java_epilog; if (!initialized) { #ifdef VBOX_XPIDL_EMULATE_GENJIFACES table[IDLN_INTERFACE] = interface_declaration_wrapper; #else table[IDLN_INTERFACE] = interface_declaration; #endif table[IDLN_LIST] = process_list; table[IDLN_OP_DCL] = method_declaration; table[IDLN_ATTR_DCL] = attribute_declaration; table[IDLN_CONST_DCL] = constant_declaration; table[IDLN_TYPE_DCL] = type_declaration; table[IDLN_FORWARD_DCL] = forward_declaration; table[IDLN_TYPE_ENUM] = enum_declaration; initialized = TRUE; } result.dispatch_table = table; return &result; }