1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Sun Microsystems, Inc.
19 * Portions created by the Initial Developer are Copyright (C) 1999
20 * the Initial Developer. All Rights Reserved.
23 * Michael Allen (michael.allen@sun.com)
24 * Frank Mitchell (frank.mitchell@sun.com)
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 * Generate Java interfaces from XPIDL.
50 #define PATH_MAX MAX_PATH
51 #elif defined(XP_OS2) && !defined(PATH_MAX)
53 #define PATH_MAX CCHMAXPATH
56 /* XXX Bug 331178 - nsIScriptSecurityManager inherits from non-scriptable
57 * interface nsIXPCSecurityManager. To work around that, we write out a
58 * Java interface for nsIXPCSecurityManager, but don't give it any methods.
60 #define CREATE_NSIXPCSECURITYMANAGER
62 /* XXX Bug 324035 - XPIDL cannot tell whether a forward declared interface is
63 * itself defined in an IDL file (in which case XPIDL will have also written
64 * out a Java interface file) or if it is just defined in a C header (in which
65 * case there will be an error when trying to compile the Java interfaces).
66 * This workaround lists the infringing interfaces and writes out "nsISupports"
67 * when encountering those types.
69 #define HANDLE_NON_IDL_IFACES
71 /* XXX Bug 340009 - SWT depends on several [noscript] methods in order to
72 * embed Mozilla in an SWT view. This hack makes those methods available
75 #define OUTPUT_SWT_NOSCRIPT_METHODS
77 /* XXX If an interface method throws an exception, how do we handle it? */
78 /*#define HANDLE_EXCEPTIONS*/
81 static char* subscriptIdentifier(TreeState
*state
, char *str
);
83 static char* javaKeywords
[] = {
84 "abstract", "default" , "if" , "private" , "throw" ,
85 "boolean" , "do" , "implements", "protected" , "throws" ,
86 "break" , "double" , "import", "public" , "transient" ,
87 "byte" , "else" , "instanceof", "return" , "try" ,
88 "case" , "extends" , "int" , "short" , "void" ,
89 "catch" , "final" , "interface" , "static" , "volatile" ,
90 "char" , "finally" , "long" , "super" , "while" ,
91 "class" , "float" , "native" , "switch" ,
92 "const" , "for" , "new" , "synchronized",
93 "continue", "goto" , "package" , "this" ,
94 /* added in Java 1.2 */
96 /* added in Java 1.4 */
98 /* added in Java 5.0 */
101 "true" , "false" , "null" ,
102 /* java.lang.Object methods *
103 * - don't worry about "toString", since it does the same thing *
104 * as Object's "toString" */
105 "clone" , "equals" , "finalize" , "getClass" , "hashCode" ,
106 "notify" , "notifyAll", /*"toString" ,*/ "wait"
109 #ifdef HANDLE_NON_IDL_IFACES
110 static char* nonIDLIfaces
[] = {
117 "nsILayoutHistoryState",
121 "nsIChannelSecurityInfo",
124 "nsIServiceManagerObsolete",
127 "nsIScrollbarMediator",
129 "nsIScriptGlobalObject",
135 #define NONIDLS(state) (((struct java_priv_data *)state->priv)->nonIDLIfaces)
138 #define TYPEDEFS(state) (((struct java_priv_data *)state->priv)->typedefTable)
139 #define PRIVDATA(state) (((struct java_priv_data *)state->priv))
140 #define KEYWORDS(state) (((struct java_priv_data *)state->priv)->keywords)
143 write_indent(FILE *outfile
) {
148 add_deprecated(GSList
*comments
)
153 const char deprecated
[] = "* @deprecated */";
155 /* Handle the easy case: no documentation. */
156 if (comments
== NULL
) {
157 buffer
= malloc(sizeof(deprecated
)+2);
160 strcpy(buffer
+2, deprecated
);
162 return g_slist_append(comments
, buffer
);
165 /* xpidl is so nice in that they give us the data as a single node.
166 * We are going to have to (very hackishly) strip out the the end of the
167 * documentation comment, add the tag, and then pop it back together.
170 /* Step 1: Move the comment into a larger buffer, so that we can have
171 * more space to work with.
173 last
= g_slist_last(comments
);
175 replaced
= (char *)malloc(strlen(buffer
) + sizeof(deprecated
));
176 strcpy(replaced
, buffer
);
177 last
->data
= replaced
;
180 /* Now replaced has the comment, with a large enough buffer to put in the
181 * @deprecated tag. We search for the last / in hopes that the previous
182 * character is the * we're looking for...
184 buffer
= strrchr(replaced
, '/');
185 if (buffer
== NULL
|| buffer
== replaced
|| buffer
[-1] == '*') {
186 /* We can't find a '/', so there's no comment, or this is not the end
187 * of a comment, so we'll ignore adding the deprecated tag.
191 /* buffer now points to '*' '/'. Overwrite both. */
192 strcpy(buffer
-1, deprecated
);
197 write_classname_iid_define(FILE *file
, const char *className
)
200 if (className
[0] == 'n' && className
[1] == 's') {
201 /* backcompat naming styles */
203 iidName
= className
+ 2;
209 fputc(toupper(*iidName
++), file
);
217 java_prolog(TreeState
*state
)
220 state
->priv
= calloc(1, sizeof(struct java_priv_data
));
225 TYPEDEFS(state
) = g_hash_table_new(g_str_hash
, g_str_equal
);
226 if (!TYPEDEFS(state
)) {
227 /* XXX report error */
233 KEYWORDS(state
) = g_hash_table_new(g_str_hash
, g_str_equal
);
234 if (!KEYWORDS(state
)) {
235 g_hash_table_destroy(TYPEDEFS(state
));
239 len
= sizeof(javaKeywords
)/sizeof(*javaKeywords
);
240 for (i
= 0; i
< len
; i
++) {
241 g_hash_table_insert(KEYWORDS(state
),
246 #ifdef HANDLE_NON_IDL_IFACES
248 NONIDLS(state
) = g_hash_table_new(g_str_hash
, g_str_equal
);
249 if (!NONIDLS(state
)) {
250 g_hash_table_destroy(TYPEDEFS(state
));
254 len
= sizeof(nonIDLIfaces
)/sizeof(*nonIDLIfaces
);
255 for (i
= 0; i
< len
; i
++) {
256 g_hash_table_insert(NONIDLS(state
),
266 java_epilog(TreeState
*state
)
268 /* points to other elements of the tree, so just destroy the table */
269 g_hash_table_destroy(TYPEDEFS(state
));
270 g_hash_table_destroy(KEYWORDS(state
));
271 #ifdef HANDLE_NON_IDL_IFACES
272 g_hash_table_destroy(NONIDLS(state
));
282 forward_declaration(TreeState
*state
)
285 * Java doesn't need forward declarations unless the declared
286 * class resides in a different package.
289 IDL_tree iface
= state
->tree
;
290 const char *className
= IDL_IDENT(IDL_FORWARD_DCL(iface
).ident
).str
;
291 const char *pkgName
= "org.mozilla.xpcom";
294 /* XXX: Get package name and compare */
295 fprintf(state
->file
, "import %s.%s;\n", pkgName
, className
);
303 interface_declaration(TreeState
*state
)
305 char outname
[PATH_MAX
];
307 IDL_tree interface
= state
->tree
;
308 IDL_tree iterator
= NULL
;
309 char *interface_name
=
310 subscriptIdentifier(state
, IDL_IDENT(IDL_INTERFACE(interface
).ident
).str
);
311 const char *iid
= NULL
;
312 char iid_parsed
[UUID_LENGTH
];
313 GSList
*doc_comments
= IDL_IDENT(IDL_INTERFACE(interface
).ident
).comments
;
315 if (!verify_interface_declaration(interface
))
319 * We only want to output scriptable interfaces
321 if (!IDL_tree_property_get(IDL_INTERFACE(interface
).ident
, "scriptable")) {
323 * XXX SWT uses non-scriptable interface 'nsIAppShell' (bug 270892), so
326 if (strcmp(interface_name
, "nsIAppShell") != 0
327 #ifdef CREATE_NSIXPCSECURITYMANAGER
328 && strcmp(interface_name
, "nsIXPCSecurityManager") != 0
335 * Each Java interface must be in its own file.
337 p
= strrchr(state
->filename
, '/');
339 strncpy(outname
, state
->filename
, p
+ 1 - state
->filename
);
340 outname
[p
+ 1 - state
->filename
] = '\0';
345 strcat(outname
, interface_name
);
346 strcat(outname
, ".java");
348 state
->file
= fopen(outname
, "w");
350 perror("error opening output file");
354 fprintf(state
->file
, "/*\n * DO NOT EDIT. THIS FILE IS GENERATED FROM\n"
355 " * %s.idl\n */\n", state
->basename
);
357 /* package name (namespace) */
358 fputs("\npackage org.mozilla.interfaces;\n\n", state
->file
);
361 iid
= IDL_tree_property_get(IDL_INTERFACE(interface
).ident
, "uuid");
364 * Parse uuid and then output resulting nsID to string, to
368 if (!xpidl_parse_iid(&id
, iid
)) {
369 IDL_tree_error(state
->tree
, "cannot parse IID %s\n", iid
);
372 if (!xpidl_sprint_iid(&id
, iid_parsed
)) {
373 IDL_tree_error(state
->tree
, "error formatting IID %s\n", iid
);
377 IDL_tree_error(state
->tree
, "interface %s lacks a uuid attribute\n",
383 * Add deprecated tags if the interface is deprecated
385 if (IDL_tree_property_get(IDL_INTERFACE(interface
).ident
, "deprecated")) {
386 doc_comments
= add_deprecated(doc_comments
);
390 * Write any interface comments
392 if (doc_comments
!= NULL
)
393 printlist(state
->file
, doc_comments
);
396 * Write "public interface <foo>"
398 fprintf(state
->file
, "public interface %s", interface_name
);
401 * Check for inheritence, and iterator over the inherited names,
405 if ((iterator
= IDL_INTERFACE(interface
).inheritance_spec
)) {
406 fputs(" extends ", state
->file
);
409 fprintf(state
->file
, "%s",
410 IDL_IDENT(IDL_LIST(iterator
).data
).str
);
412 if (IDL_LIST(iterator
).next
) {
413 fputs(", ", state
->file
);
415 } while ((iterator
= IDL_LIST(iterator
).next
));
418 fputs(" {\n\n", state
->file
);
421 * Write interface constants for IID
424 /* String NS_ISUPPORTS_IID = "{00000000-0000-0000-c000-000000000046}";*/
425 write_indent(state
->file
);
426 fputs("String ", state
->file
);
427 write_classname_iid_define(state
->file
, interface_name
);
428 fputs(" =\n", state
->file
);
429 write_indent(state
->file
);
430 write_indent(state
->file
);
431 fprintf(state
->file
, "\"{%s}\";\n\n", iid_parsed
);
435 * Advance the state of the tree, go on to process more
438 state
->tree
= IDL_INTERFACE(interface
).body
;
440 if (state
->tree
&& !xpidl_process_node(state
)) {
445 fputs("}", state
->file
);
453 process_list(TreeState
*state
)
456 for (iter
= state
->tree
; iter
; iter
= IDL_LIST(iter
).next
) {
457 state
->tree
= IDL_LIST(iter
).data
;
458 if (!xpidl_process_node(state
))
465 xpcom_to_java_type(TreeState
*state
, IDL_tree param
)
467 IDL_tree real_type
, type
;
471 fputs("Object", state
->file
);
475 /* Could be a typedef; try to map it to the real type */
476 real_type
= find_underlying_type(state
->tree
);
477 type
= real_type
? real_type
: state
->tree
;
479 switch(IDL_NODE_TYPE(type
)) {
481 case IDLN_TYPE_INTEGER
: {
483 switch(IDL_TYPE_INTEGER(type
).f_type
) {
485 case IDL_INTEGER_TYPE_SHORT
:
486 if (IDL_TYPE_INTEGER(type
).f_signed
)
487 fputs("short", state
->file
);
489 fputs("int", state
->file
);
492 case IDL_INTEGER_TYPE_LONG
:
493 if (IDL_TYPE_INTEGER(type
).f_signed
)
494 fputs("int", state
->file
);
496 fputs("long", state
->file
);
499 case IDL_INTEGER_TYPE_LONGLONG
:
500 if (IDL_TYPE_INTEGER(type
).f_signed
)
501 fputs("long", state
->file
);
503 fputs("double", state
->file
);
507 g_error(" Unknown integer type: %d\n",
508 IDL_TYPE_INTEGER(type
).f_type
);
517 case IDLN_TYPE_WIDE_CHAR
:
518 fputs("char", state
->file
);
521 case IDLN_TYPE_WIDE_STRING
:
522 case IDLN_TYPE_STRING
:
523 fputs("String", state
->file
);
526 case IDLN_TYPE_BOOLEAN
:
527 fputs("boolean", state
->file
);
530 case IDLN_TYPE_OCTET
:
531 if (param
&& IDL_tree_property_get(IDL_PARAM_DCL(param
).simple_declarator
, "array"))
532 fputs("byte", state
->file
);
534 fputs("short", state
->file
);
537 case IDLN_TYPE_FLOAT
:
538 switch(IDL_TYPE_FLOAT(type
).f_type
) {
540 case IDL_FLOAT_TYPE_FLOAT
:
541 fputs("float", state
->file
);
544 case IDL_FLOAT_TYPE_DOUBLE
:
545 fputs("double", state
->file
);
549 g_error(" Unknown floating point typ: %d\n",
550 IDL_NODE_TYPE(type
));
557 if (!(up
= IDL_NODE_UP(type
))) {
558 IDL_tree_error(state
->tree
,
559 "ERROR: orphan ident %s in param list\n",
560 IDL_IDENT(state
->tree
).str
);
563 switch (IDL_NODE_TYPE(up
)) {
564 case IDLN_FORWARD_DCL
:
565 case IDLN_INTERFACE
: {
569 /* might get here via the goto, so re-check type */
570 if (IDL_NODE_TYPE(up
) == IDLN_INTERFACE
)
571 className
= IDL_IDENT(IDL_INTERFACE(up
).ident
).str
;
572 else if (IDL_NODE_TYPE(up
) == IDLN_FORWARD_DCL
)
573 className
= IDL_IDENT(IDL_FORWARD_DCL(up
).ident
).str
;
575 className
= IDL_IDENT(IDL_NATIVE(up
).ident
).str
;
578 if (IDL_NODE_TYPE(state
->tree
) == IDLN_PARAM_DCL
) {
579 IDL_tree simple
= IDL_PARAM_DCL(state
->tree
).simple_declarator
;
580 iid_is
= IDL_tree_property_get(simple
, "iid_is");
584 fputs("nsISupports", state
->file
);
587 * In JavaXPCOM, we handle weak references internally; no need
588 * for the |nsIWeakReference| interface. So just return
591 if (strcmp(className
, "nsIWeakReference") == 0) {
592 fputs("nsISupports", state
->file
);
594 #ifdef HANDLE_NON_IDL_IFACES
595 char *nonidl
= g_hash_table_lookup(NONIDLS(state
), className
);
597 fputs("nsISupports", state
->file
);
601 fprintf(state
->file
, "%s", className
);
610 /* jband - adding goto for iid_is when type is native */
612 if (IDL_NODE_TYPE(param
) == IDLN_PARAM_DCL
&&
613 IDL_tree_property_get(IDL_PARAM_DCL(param
).simple_declarator
,
621 ident
= IDL_IDENT(type
).str
;
622 if (IDL_tree_property_get(type
, "nsid")) {
623 fputs("String", state
->file
);
624 } else if (IDL_tree_property_get(type
, "domstring")) {
625 fputs("String", state
->file
);
626 } else if (IDL_tree_property_get(type
, "astring")) {
627 fputs("String", state
->file
);
628 } else if (IDL_tree_property_get(type
, "utf8string")) {
629 fputs("String", state
->file
);
630 } else if (IDL_tree_property_get(type
, "cstring")) {
631 fputs("String", state
->file
);
633 const char* user_type
= IDL_NATIVE(IDL_NODE_UP(type
)).user_type
;
635 g_hash_table_lookup(TYPEDEFS(state
), user_type
);
639 IDL_tree orig_tree
= state
->tree
;
641 state
->tree
= real_type
;
642 rc
= xpcom_to_java_type(state
, param
);
644 state
->tree
= orig_tree
;
647 if (strcmp(user_type
, "PRInt8") == 0) {
648 fputs("byte", state
->file
);
649 } else if (strcmp(user_type
, "PRInt16") == 0 ||
650 strcmp(user_type
, "PRUint8") == 0) {
651 fputs("short", state
->file
);
652 } else if (strcmp(user_type
, "PRInt32") == 0 ||
653 strcmp(user_type
, "int") == 0 ||
654 strcmp(user_type
, "PRUint16") == 0) {
655 fputs("int", state
->file
);
656 } else if (strcmp(user_type
, "PRInt64") == 0 ||
657 strcmp(user_type
, "PRUint32") == 0) {
658 fputs("long", state
->file
);
659 } else if (strcmp(user_type
, "PRUint64") == 0) {
660 fputs("double", state
->file
);
661 } else if (strcmp(user_type
, "PRBool") == 0) {
662 fputs("boolean", state
->file
);
663 } else if (strcmp(user_type
, "char") == 0 ||
664 strcmp(user_type
, "const char") == 0 ||
665 strcmp(user_type
, "unsigned char") == 0) {
666 if (IDL_tree_property_get(type
, "ptr")) {
667 fputs("byte[]", state
->file
);
669 fputs("char", state
->file
);
671 } else if (strcmp(user_type
, "nsIID") == 0) {
672 fputs("String", state
->file
);
673 } else if (strcmp(user_type
, "nsString") == 0 ||
674 strcmp(user_type
, "nsAString") == 0 ||
675 strcmp(user_type
, "nsACString") == 0) {
676 fputs("String", state
->file
);
678 fputs("long", state
->file
);
685 if (IDL_NODE_TYPE(IDL_NODE_UP(up
)) == IDLN_TYPE_DCL
) {
686 /* restart with the underlying type */
688 IDL_tree orig_tree
= state
->tree
;
689 state
->tree
= IDL_TYPE_DCL(IDL_NODE_UP(up
)).type_spec
;
690 rc
= xpcom_to_java_type(state
, param
);
691 state
->tree
= orig_tree
;
694 IDL_tree_error(state
->tree
,
695 "can't handle %s ident in param list\n",
703 IDL_tree_error(state
->tree
, "can't handle %s in param list\n",
705 /* XXX is this safe to use on Win now? */
706 IDL_NODE_TYPE_NAME(IDL_NODE_UP(type
))
719 xpcom_to_java_param(TreeState
*state
)
721 IDL_tree param
= state
->tree
;
722 state
->tree
= IDL_PARAM_DCL(param
).param_type_spec
;
725 * Put in type of parameter
728 if (!xpcom_to_java_type(state
, param
)) {
733 * If the parameter is out or inout, make it a Java array of the
737 if (IDL_PARAM_DCL(param
).attr
!= IDL_PARAM_IN
) {
738 fputs("[]", state
->file
);
742 * If the parameter is an array make it a Java array
744 if (IDL_tree_property_get(IDL_PARAM_DCL(param
).simple_declarator
, "array"))
745 fputs("[]", state
->file
);
748 * Put in name of parameter
750 fputc(' ', state
->file
);
751 fputs(subscriptIdentifier(state
,
752 IDL_IDENT(IDL_PARAM_DCL(param
).simple_declarator
).str
),
760 type_declaration(TreeState
*state
)
763 * Unlike C, Java has no type declaration directive.
764 * Instead, we record the mapping, and look up the actual type
767 IDL_tree type
= IDL_TYPE_DCL(state
->tree
).type_spec
;
768 IDL_tree dcls
= IDL_TYPE_DCL(state
->tree
).dcls
;
770 /* XXX: check for illegal types */
772 g_hash_table_insert(TYPEDEFS(state
),
773 IDL_IDENT(IDL_LIST(dcls
).data
).str
,
779 #ifdef OUTPUT_SWT_NOSCRIPT_METHODS
781 print_noscript_method(TreeState
*state
)
783 IDL_tree iface
= IDL_NODE_UP(IDL_NODE_UP(state
->tree
));
784 char *className
= IDL_IDENT(IDL_INTERFACE(iface
).ident
).str
;
785 if (strcmp(className
, "nsIBaseWindow") == 0 ||
786 strcmp(className
, "nsIEmbeddingSiteWindow") == 0)
793 method_declaration(TreeState
*state
)
795 const char* array
= NULL
;
796 struct _IDL_OP_DCL
*method
= &IDL_OP_DCL(state
->tree
);
797 gboolean method_notxpcom
=
798 (IDL_tree_property_get(method
->ident
, "notxpcom") != NULL
);
799 gboolean method_noscript
=
800 (IDL_tree_property_get(method
->ident
, "noscript") != NULL
);
801 IDL_tree iterator
= NULL
;
802 IDL_tree retval_param
= NULL
;
804 g_strdup_printf("%c%s",
805 tolower(IDL_IDENT(method
->ident
).str
[0]),
806 IDL_IDENT(method
->ident
).str
+ 1);
807 GSList
*doc_comments
= IDL_IDENT(method
->ident
).comments
;
809 if (!verify_method_declaration(state
->tree
))
812 #ifdef OUTPUT_SWT_NOSCRIPT_METHODS
815 if (method_noscript
&& !print_noscript_method(state
))
818 /* do not write nonscriptable methods */
819 if (method_notxpcom
|| method_noscript
) {
824 #ifdef CREATE_NSIXPCSECURITYMANAGER
825 /* Since this interface is non-scriptable, we treat all of its methods
826 * as if they were [noscript] */
828 IDL_tree iface
= IDL_NODE_UP(IDL_NODE_UP(state
->tree
));
829 char *className
= IDL_IDENT(IDL_INTERFACE(iface
).ident
).str
;
830 if (strcmp(className
, "nsIXPCSecurityManager") == 0)
836 * Add deprecated tags if the interface is deprecated
838 if (IDL_tree_property_get(method
->ident
, "deprecated")) {
839 doc_comments
= add_deprecated(doc_comments
);
842 if (doc_comments
!= NULL
) {
843 write_indent(state
->file
);
844 printlist(state
->file
, doc_comments
);
849 * Unlike C++ headers, Java interfaces return the declared
850 * return value; an exception indicates XPCOM method failure.
852 write_indent(state
->file
);
853 if (method
->op_type_spec
) {
854 state
->tree
= method
->op_type_spec
;
855 if (!xpcom_to_java_type(state
, NULL
)) {
859 /* Check for retval attribute */
860 for (iterator
= method
->parameter_dcls
; iterator
!= NULL
;
861 iterator
= IDL_LIST(iterator
).next
) {
863 IDL_tree original_tree
= state
->tree
;
864 IDL_tree simple_decl
;
866 state
->tree
= IDL_LIST(iterator
).data
;
867 simple_decl
= IDL_PARAM_DCL(state
->tree
).simple_declarator
;
869 if (IDL_tree_property_get(simple_decl
, "retval")) {
872 retval_param
= iterator
;
873 array
= IDL_tree_property_get(simple_decl
, "array");
876 * Put in type of parameter
879 state
->tree
= IDL_PARAM_DCL(state
->tree
).param_type_spec
;
880 if (!xpcom_to_java_type(state
, param
)) {
885 fputs("[]", state
->file
);
889 state
->tree
= original_tree
;
892 if (retval_param
== NULL
) {
893 fputs("void", state
->file
);
900 fprintf(state
->file
, " %s(", subscriptIdentifier(state
, method_name
));
905 for (iterator
= method
->parameter_dcls
; iterator
!= NULL
;
906 iterator
= IDL_LIST(iterator
).next
) {
909 if (iterator
== retval_param
) {
913 if (iterator
!= method
->parameter_dcls
) {
914 fputs(", ", state
->file
);
917 state
->tree
= IDL_LIST(iterator
).data
;
919 if (!xpcom_to_java_param(state
)) {
924 fputs(")", state
->file
);
926 #ifdef HANDLE_EXCEPTIONS
927 if (method
->raises_expr
) {
928 IDL_tree iter
= method
->raises_expr
;
929 IDL_tree dataNode
= IDL_LIST(iter
).data
;
931 fputs(" throws ", state
->file
);
932 fputs(IDL_IDENT(dataNode
).str
, state
->file
);
933 iter
= IDL_LIST(iter
).next
;
936 dataNode
= IDL_LIST(iter
).data
;
937 fprintf(state
->file
, ", %s", IDL_IDENT(dataNode
).str
);
938 iter
= IDL_LIST(iter
).next
;
943 fputs(";\n\n", state
->file
);
950 constant_declaration(TreeState
*state
)
952 struct _IDL_CONST_DCL
*declaration
= &IDL_CONST_DCL(state
->tree
);
953 const char *name
= IDL_IDENT(declaration
->ident
).str
;
954 GSList
*doc_comments
= IDL_IDENT(declaration
->ident
).comments
;
958 const char* type_str
;
963 if (!verify_const_declaration(state
->tree
))
966 /* Could be a typedef; try to map it to the real type. */
967 real_type
= find_underlying_type(declaration
->const_type
);
968 real_type
= real_type
? real_type
: declaration
->const_type
;
970 /* Consts must be in an interface */
971 if (!IDL_NODE_UP(IDL_NODE_UP(state
->tree
)) ||
972 IDL_NODE_TYPE(IDL_NODE_UP(IDL_NODE_UP(state
->tree
))) !=
975 XPIDL_WARNING((state
->tree
, IDL_WARNING1
,
976 "A constant \"%s\" was declared outside an interface."
977 " It was ignored.", name
));
983 * The C++ header XPIDL module only allows for shorts and longs (ints)
984 * to be constants, so we will follow the same convention
989 success
= (IDLN_TYPE_INTEGER
== IDL_NODE_TYPE(real_type
));
992 gboolean is_signed
= IDL_TYPE_INTEGER(real_type
).f_signed
;
993 format
= is_signed
? "%" IDL_LL
"d" : "%" IDL_LL
"u";
995 switch(IDL_TYPE_INTEGER(real_type
).f_type
) {
996 case IDL_INTEGER_TYPE_SHORT
:
1003 case IDL_INTEGER_TYPE_LONG
:
1013 /* Whoops, it's some other kind of number */
1018 IDL_tree_error(state
->tree
,
1019 "const declaration \'%s\' must be of type short or long",
1025 XPIDL_WARNING((state
->tree
, IDL_WARNING1
,
1026 "A constant \"%s\" was not of type short or long."
1027 " It was ignored.", name
));
1031 if (doc_comments
!= NULL
) {
1032 write_indent(state
->file
);
1033 printlist(state
->file
, doc_comments
);
1036 write_indent(state
->file
);
1037 fprintf(state
->file
, "%s %s = ", type_str
,
1038 subscriptIdentifier(state
, (char*) name
));
1039 fprintf(state
->file
, format
, IDL_INTEGER(declaration
->const_exp
).value
);
1040 fprintf(state
->file
, "%s;\n\n", is_long
? "L" : "");
1046 #define ATTR_IDENT(tree) (IDL_IDENT(IDL_LIST(IDL_ATTR_DCL((tree)).simple_declarations).data))
1047 #define ATTR_PROPS(tree) (IDL_LIST(IDL_ATTR_DCL((tree)).simple_declarations).data)
1048 #define ATTR_TYPE_DECL(tree) (IDL_ATTR_DCL((tree)).param_type_spec)
1052 attribute_declaration(TreeState
*state
)
1054 char *attribute_name
;
1055 GSList
*doc_comments
;
1058 if (!verify_attribute_declaration(state
->tree
))
1061 attribute_name
= ATTR_IDENT(state
->tree
).str
;
1062 read_only
= IDL_ATTR_DCL(state
->tree
).f_readonly
;
1064 #ifdef OUTPUT_SWT_NOSCRIPT_METHODS
1065 if (IDL_tree_property_get(ATTR_PROPS(state
->tree
), "notxpcom"))
1067 if (IDL_tree_property_get(ATTR_PROPS(state
->tree
), "noscript") &&
1068 !print_noscript_method(state
))
1071 if (IDL_tree_property_get(ATTR_PROPS(state
->tree
), "notxpcom") ||
1072 IDL_tree_property_get(ATTR_PROPS(state
->tree
), "noscript"))
1077 IDL_IDENT(IDL_LIST(IDL_ATTR_DCL
1078 (state
->tree
).simple_declarations
).data
).comments
;
1081 * Add deprecated tags if the interface is deprecated
1083 if (IDL_tree_property_get(ATTR_PROPS(state
->tree
), "deprecated")) {
1084 doc_comments
= add_deprecated(doc_comments
);
1087 if (doc_comments
!= NULL
) {
1088 write_indent(state
->file
);
1089 printlist(state
->file
, doc_comments
);
1093 * Write the proper Java return value for the get operation
1095 write_indent(state
->file
);
1096 state
->tree
= ATTR_TYPE_DECL(state
->tree
);
1097 if (!xpcom_to_java_type(state
, NULL
)) {
1102 * Write the name of the accessor ("get") method.
1104 fprintf(state
->file
, " get%c%s();\n\n",
1105 toupper(attribute_name
[0]), attribute_name
+ 1);
1108 if (doc_comments
!= NULL
) {
1109 write_indent(state
->file
);
1110 printlist(state
->file
, doc_comments
);
1114 * Write attribute access method name and return type
1116 write_indent(state
->file
);
1117 fprintf(state
->file
, "void set%c%s(",
1118 toupper(attribute_name
[0]),
1122 * Write the proper Java type for the set operation
1124 if (!xpcom_to_java_type(state
, NULL
)) {
1129 * Write the name of the formal parameter.
1131 fprintf(state
->file
, " a%c%s);\n\n", toupper(attribute_name
[0]),
1132 attribute_name
+ 1);
1140 enum_declaration(TreeState
*state
)
1142 XPIDL_WARNING((state
->tree
, IDL_WARNING1
,
1143 "enums not supported, enum \'%s\' ignored",
1144 IDL_IDENT(IDL_TYPE_ENUM(state
->tree
).ident
).str
));
1149 xpidl_java_dispatch(void)
1151 static backend result
;
1152 static nodeHandler table
[IDLN_LAST
];
1153 static gboolean initialized
= FALSE
;
1155 result
.emit_prolog
= java_prolog
;
1156 result
.emit_epilog
= java_epilog
;
1159 table
[IDLN_INTERFACE
] = interface_declaration
;
1160 table
[IDLN_LIST
] = process_list
;
1162 table
[IDLN_OP_DCL
] = method_declaration
;
1163 table
[IDLN_ATTR_DCL
] = attribute_declaration
;
1164 table
[IDLN_CONST_DCL
] = constant_declaration
;
1166 table
[IDLN_TYPE_DCL
] = type_declaration
;
1167 table
[IDLN_FORWARD_DCL
] = forward_declaration
;
1169 table
[IDLN_TYPE_ENUM
] = enum_declaration
;
1174 result
.dispatch_table
= table
;
1178 char* subscriptIdentifier(TreeState
*state
, char *str
)
1181 char *keyword
= g_hash_table_lookup(KEYWORDS(state
), str
);
1183 sstr
= g_strdup_printf("_%s", keyword
);