summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_java.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_java.c1053
1 files changed, 1053 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_java.c b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_java.c
new file mode 100644
index 00000000..4f708027
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_java.c
@@ -0,0 +1,1053 @@
+/* -*- 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 <ctype.h>
+#include <glib.h>
+
+
+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 <a href=\"http://lxr.mozilla.org/mozilla/search?string=interface+%.*s\">\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 <foo>"
+ */
+
+ 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;
+}
+