PageRenderTime 64ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/trunk/Source/Modules/java.cxx

#
C++ | 1775 lines | 1293 code | 246 blank | 236 comment | 357 complexity | 54406e4a0cffbaac552ad8efb693c35a MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /* -----------------------------------------------------------------------------
  2. * This file is part of SWIG, which is licensed as a whole under version 3
  3. * (or any later version) of the GNU General Public License. Some additional
  4. * terms also apply to certain portions of SWIG. The full details of the SWIG
  5. * license and copyrights can be found in the LICENSE and COPYRIGHT files
  6. * included with the SWIG source code as distributed by the SWIG developers
  7. * and at http://www.swig.org/legal.html.
  8. *
  9. * java.cxx
  10. *
  11. * Java language module for SWIG.
  12. * ----------------------------------------------------------------------------- */
  13. char cvsroot_java_cxx[] = "$Id: java.cxx 12891 2012-01-06 18:57:25Z wsfulton $";
  14. #include "swigmod.h"
  15. #include <limits.h> // for INT_MAX
  16. #include "cparse.h"
  17. #include <ctype.h>
  18. /* Hash type used for upcalls from C/C++ */
  19. typedef DOH UpcallData;
  20. class JAVA:public Language {
  21. static const char *usage;
  22. const String *empty_string;
  23. const String *public_string;
  24. const String *protected_string;
  25. Hash *swig_types_hash;
  26. File *f_begin;
  27. File *f_runtime;
  28. File *f_runtime_h;
  29. File *f_header;
  30. File *f_wrappers;
  31. File *f_init;
  32. File *f_directors;
  33. File *f_directors_h;
  34. List *filenames_list;
  35. bool proxy_flag; // Flag for generating proxy classes
  36. bool nopgcpp_flag; // Flag for suppressing the premature garbage collection prevention parameter
  37. bool native_function_flag; // Flag for when wrapping a native function
  38. bool enum_constant_flag; // Flag for when wrapping an enum or constant
  39. bool static_flag; // Flag for when wrapping a static functions or member variables
  40. bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable
  41. bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const
  42. bool global_variable_flag; // Flag for when wrapping a global variable
  43. bool old_variable_names; // Flag for old style variable names in the intermediary class
  44. bool member_func_flag; // flag set when wrapping a member function
  45. String *imclass_name; // intermediary class name
  46. String *module_class_name; // module class name
  47. String *constants_interface_name; // constants interface name
  48. String *imclass_class_code; // intermediary class code
  49. String *proxy_class_def;
  50. String *proxy_class_code;
  51. String *module_class_code;
  52. String *proxy_class_name; // proxy class name
  53. String *full_proxy_class_name;// fully qualified proxy class name when using nspace feature, otherwise same as proxy_class_name
  54. String *full_imclass_name; // fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name
  55. String *variable_name; //Name of a variable being wrapped
  56. String *proxy_class_constants_code;
  57. String *module_class_constants_code;
  58. String *enum_code;
  59. String *package; // Optional package name
  60. String *jnipackage; // Package name used in the JNI code
  61. String *package_path; // Package name used internally by JNI (slashes)
  62. String *imclass_imports; //intermediary class imports from %pragma
  63. String *module_imports; //module imports from %pragma
  64. String *imclass_baseclass; //inheritance for intermediary class class from %pragma
  65. String *module_baseclass; //inheritance for module class from %pragma
  66. String *imclass_interfaces; //interfaces for intermediary class class from %pragma
  67. String *module_interfaces; //interfaces for module class from %pragma
  68. String *imclass_class_modifiers; //class modifiers for intermediary class overriden by %pragma
  69. String *module_class_modifiers; //class modifiers for module class overriden by %pragma
  70. String *upcasts_code; //C++ casts for inheritance hierarchies C++ code
  71. String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code
  72. String *imclass_directors; // Intermediate class director code
  73. String *destructor_call; //C++ destructor call if any
  74. String *destructor_throws_clause; //C++ destructor throws clause if any
  75. // Director method stuff:
  76. List *dmethods_seq;
  77. Hash *dmethods_table;
  78. int n_dmethods;
  79. int n_directors;
  80. int first_class_dmethod;
  81. int curr_class_dmethod;
  82. enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum };
  83. public:
  84. /* -----------------------------------------------------------------------------
  85. * JAVA()
  86. * ----------------------------------------------------------------------------- */
  87. JAVA():empty_string(NewString("")),
  88. public_string(NewString("public")),
  89. protected_string(NewString("protected")),
  90. swig_types_hash(NULL),
  91. f_begin(NULL),
  92. f_runtime(NULL),
  93. f_runtime_h(NULL),
  94. f_header(NULL),
  95. f_wrappers(NULL),
  96. f_init(NULL),
  97. f_directors(NULL),
  98. f_directors_h(NULL),
  99. filenames_list(NULL),
  100. proxy_flag(true),
  101. nopgcpp_flag(false),
  102. native_function_flag(false),
  103. enum_constant_flag(false),
  104. static_flag(false),
  105. variable_wrapper_flag(false),
  106. wrapping_member_flag(false),
  107. global_variable_flag(false),
  108. old_variable_names(false),
  109. member_func_flag(false),
  110. imclass_name(NULL),
  111. module_class_name(NULL),
  112. constants_interface_name(NULL),
  113. imclass_class_code(NULL),
  114. proxy_class_def(NULL),
  115. proxy_class_code(NULL),
  116. module_class_code(NULL),
  117. proxy_class_name(NULL),
  118. full_proxy_class_name(NULL),
  119. full_imclass_name(NULL),
  120. variable_name(NULL),
  121. proxy_class_constants_code(NULL),
  122. module_class_constants_code(NULL),
  123. package(NULL),
  124. jnipackage(NULL),
  125. package_path(NULL),
  126. imclass_imports(NULL),
  127. module_imports(NULL),
  128. imclass_baseclass(NULL),
  129. module_baseclass(NULL),
  130. imclass_interfaces(NULL),
  131. module_interfaces(NULL),
  132. imclass_class_modifiers(NULL),
  133. module_class_modifiers(NULL),
  134. upcasts_code(NULL),
  135. imclass_cppcasts_code(NULL),
  136. imclass_directors(NULL),
  137. destructor_call(NULL),
  138. destructor_throws_clause(NULL),
  139. dmethods_seq(NULL),
  140. dmethods_table(NULL),
  141. n_dmethods(0),
  142. n_directors(0) {
  143. /* for now, multiple inheritance in directors is disabled, this
  144. should be easy to implement though */
  145. director_multiple_inheritance = 0;
  146. director_language = 1;
  147. }
  148. /* -----------------------------------------------------------------------------
  149. * getProxyName()
  150. *
  151. * Test to see if a type corresponds to something wrapped with a proxy class.
  152. * Return NULL if not otherwise the proxy class name, fully qualified with
  153. * package name if the nspace feature is used.
  154. * ----------------------------------------------------------------------------- */
  155. String *getProxyName(SwigType *t) {
  156. String *proxyname = NULL;
  157. if (proxy_flag) {
  158. Node *n = classLookup(t);
  159. if (n) {
  160. proxyname = Getattr(n, "proxyname");
  161. if (!proxyname) {
  162. String *nspace = Getattr(n, "sym:nspace");
  163. String *symname = Getattr(n, "sym:name");
  164. if (nspace) {
  165. if (package)
  166. proxyname = NewStringf("%s.%s.%s", package, nspace, symname);
  167. else
  168. proxyname = NewStringf("%s.%s", nspace, symname);
  169. } else {
  170. proxyname = Copy(symname);
  171. }
  172. Setattr(n, "proxyname", proxyname);
  173. Delete(proxyname);
  174. }
  175. }
  176. }
  177. return proxyname;
  178. }
  179. /* -----------------------------------------------------------------------------
  180. * makeValidJniName()
  181. * ----------------------------------------------------------------------------- */
  182. String *makeValidJniName(const String *name) {
  183. String *valid_jni_name = NewString(name);
  184. Replaceall(valid_jni_name, "_", "_1");
  185. return valid_jni_name;
  186. }
  187. /* -----------------------------------------------------------------------------
  188. * directorClassName()
  189. * ----------------------------------------------------------------------------- */
  190. String *directorClassName(Node *n) {
  191. String *dirclassname;
  192. const char *attrib = "director:classname";
  193. if (!(dirclassname = Getattr(n, attrib))) {
  194. String *classname = Getattr(n, "sym:name");
  195. dirclassname = NewStringf("SwigDirector_%s", classname);
  196. Setattr(n, attrib, dirclassname);
  197. }
  198. return dirclassname;
  199. }
  200. /* ------------------------------------------------------------
  201. * main()
  202. * ------------------------------------------------------------ */
  203. virtual void main(int argc, char *argv[]) {
  204. SWIG_library_directory("java");
  205. // Look for certain command line options
  206. for (int i = 1; i < argc; i++) {
  207. if (argv[i]) {
  208. if (strcmp(argv[i], "-package") == 0) {
  209. if (argv[i + 1]) {
  210. package = NewString("");
  211. Printf(package, argv[i + 1]);
  212. if (Len(package) == 0) {
  213. Delete(package);
  214. package = 0;
  215. }
  216. Swig_mark_arg(i);
  217. Swig_mark_arg(i + 1);
  218. i++;
  219. } else {
  220. Swig_arg_error();
  221. }
  222. } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
  223. Printf(stderr, "Deprecated command line option: %s. Proxy classes are now generated by default.\n", argv[i]);
  224. Swig_mark_arg(i);
  225. proxy_flag = true;
  226. } else if ((strcmp(argv[i], "-noproxy") == 0)) {
  227. Swig_mark_arg(i);
  228. proxy_flag = false;
  229. } else if (strcmp(argv[i], "-nopgcpp") == 0) {
  230. Swig_mark_arg(i);
  231. nopgcpp_flag = true;
  232. } else if (strcmp(argv[i], "-oldvarnames") == 0) {
  233. Swig_mark_arg(i);
  234. old_variable_names = true;
  235. } else if (strcmp(argv[i], "-jnic") == 0) {
  236. Swig_mark_arg(i);
  237. Printf(stderr, "Deprecated command line option: -jnic. C JNI calling convention now used when -c++ not specified.\n");
  238. } else if (strcmp(argv[i], "-nofinalize") == 0) {
  239. Swig_mark_arg(i);
  240. Printf(stderr, "Deprecated command line option: -nofinalize. Use the new javafinalize typemap instead.\n");
  241. } else if (strcmp(argv[i], "-jnicpp") == 0) {
  242. Swig_mark_arg(i);
  243. Printf(stderr, "Deprecated command line option: -jnicpp. C++ JNI calling convention now used when -c++ specified.\n");
  244. } else if (strcmp(argv[i], "-help") == 0) {
  245. Printf(stdout, "%s\n", usage);
  246. }
  247. }
  248. }
  249. // Add a symbol to the parser for conditional compilation
  250. Preprocessor_define("SWIGJAVA 1", 0);
  251. // Add typemap definitions
  252. SWIG_typemap_lang("java");
  253. SWIG_config_file("java.swg");
  254. allow_overloading();
  255. }
  256. /* ---------------------------------------------------------------------
  257. * top()
  258. * --------------------------------------------------------------------- */
  259. virtual int top(Node *n) {
  260. // Get any options set in the module directive
  261. Node *optionsnode = Getattr(Getattr(n, "module"), "options");
  262. if (optionsnode) {
  263. if (Getattr(optionsnode, "jniclassname"))
  264. imclass_name = Copy(Getattr(optionsnode, "jniclassname"));
  265. /* check if directors are enabled for this module. note: this
  266. * is a "master" switch, without which no director code will be
  267. * emitted. %feature("director") statements are also required
  268. * to enable directors for individual classes or methods.
  269. *
  270. * use %module(directors="1") modulename at the start of the
  271. * interface file to enable director generation.
  272. */
  273. if (Getattr(optionsnode, "directors")) {
  274. allow_directors();
  275. }
  276. if (Getattr(optionsnode, "dirprot")) {
  277. allow_dirprot();
  278. }
  279. allow_allprotected(GetFlag(optionsnode, "allprotected"));
  280. }
  281. /* Initialize all of the output files */
  282. String *outfile = Getattr(n, "outfile");
  283. String *outfile_h = Getattr(n, "outfile_h");
  284. if (!outfile) {
  285. Printf(stderr, "Unable to determine outfile\n");
  286. SWIG_exit(EXIT_FAILURE);
  287. }
  288. f_begin = NewFile(outfile, "w", SWIG_output_files());
  289. if (!f_begin) {
  290. FileErrorDisplay(outfile);
  291. SWIG_exit(EXIT_FAILURE);
  292. }
  293. if (directorsEnabled()) {
  294. if (!outfile_h) {
  295. Printf(stderr, "Unable to determine outfile_h\n");
  296. SWIG_exit(EXIT_FAILURE);
  297. }
  298. f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
  299. if (!f_runtime_h) {
  300. FileErrorDisplay(outfile_h);
  301. SWIG_exit(EXIT_FAILURE);
  302. }
  303. }
  304. f_runtime = NewString("");
  305. f_init = NewString("");
  306. f_header = NewString("");
  307. f_wrappers = NewString("");
  308. f_directors_h = NewString("");
  309. f_directors = NewString("");
  310. /* Register file targets with the SWIG file handler */
  311. Swig_register_filebyname("begin", f_begin);
  312. Swig_register_filebyname("header", f_header);
  313. Swig_register_filebyname("wrapper", f_wrappers);
  314. Swig_register_filebyname("runtime", f_runtime);
  315. Swig_register_filebyname("init", f_init);
  316. Swig_register_filebyname("director", f_directors);
  317. Swig_register_filebyname("director_h", f_directors_h);
  318. swig_types_hash = NewHash();
  319. filenames_list = NewList();
  320. // Make the intermediary class and module class names. The intermediary class name can be set in the module directive.
  321. if (!imclass_name) {
  322. imclass_name = NewStringf("%sJNI", Getattr(n, "name"));
  323. module_class_name = Copy(Getattr(n, "name"));
  324. } else {
  325. // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution
  326. if (Cmp(imclass_name, Getattr(n, "name")) == 0)
  327. module_class_name = NewStringf("%sModule", Getattr(n, "name"));
  328. else
  329. module_class_name = Copy(Getattr(n, "name"));
  330. }
  331. constants_interface_name = NewStringf("%sConstants", module_class_name);
  332. // module class and intermediary classes are always created
  333. addSymbol(imclass_name, n);
  334. addSymbol(module_class_name, n);
  335. imclass_class_code = NewString("");
  336. proxy_class_def = NewString("");
  337. proxy_class_code = NewString("");
  338. module_class_constants_code = NewString("");
  339. imclass_baseclass = NewString("");
  340. imclass_interfaces = NewString("");
  341. imclass_class_modifiers = NewString("");
  342. module_class_code = NewString("");
  343. module_baseclass = NewString("");
  344. module_interfaces = NewString("");
  345. module_imports = NewString("");
  346. module_class_modifiers = NewString("");
  347. imclass_imports = NewString("");
  348. imclass_cppcasts_code = NewString("");
  349. imclass_directors = NewString("");
  350. upcasts_code = NewString("");
  351. dmethods_seq = NewList();
  352. dmethods_table = NewHash();
  353. n_dmethods = 0;
  354. n_directors = 0;
  355. jnipackage = NewString("");
  356. package_path = NewString("");
  357. Swig_banner(f_begin);
  358. Printf(f_runtime, "\n#define SWIGJAVA\n");
  359. if (directorsEnabled()) {
  360. Printf(f_runtime, "#define SWIG_DIRECTORS\n");
  361. /* Emit initial director header and director code: */
  362. Swig_banner(f_directors_h);
  363. Printf(f_directors_h, "\n");
  364. Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_class_name);
  365. Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_class_name);
  366. Printf(f_directors, "\n\n");
  367. Printf(f_directors, "/* ---------------------------------------------------\n");
  368. Printf(f_directors, " * C++ director class methods\n");
  369. Printf(f_directors, " * --------------------------------------------------- */\n\n");
  370. if (outfile_h)
  371. Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h));
  372. }
  373. Printf(f_runtime, "\n");
  374. String *wrapper_name = NewString("");
  375. if (package) {
  376. String *jniname = makeValidJniName(package);
  377. Printv(jnipackage, jniname, NIL);
  378. Delete(jniname);
  379. Replaceall(jnipackage, ".", "_");
  380. Append(jnipackage, "_");
  381. Printv(package_path, package, NIL);
  382. Replaceall(package_path, ".", "/");
  383. }
  384. String *jniname = makeValidJniName(imclass_name);
  385. Printf(wrapper_name, "Java_%s%s_%%f", jnipackage, jniname);
  386. Delete(jniname);
  387. Swig_name_register("wrapper", Char(wrapper_name));
  388. if (old_variable_names) {
  389. Swig_name_register("set", "set_%n%v");
  390. Swig_name_register("get", "get_%n%v");
  391. }
  392. Delete(wrapper_name);
  393. Printf(f_wrappers, "\n#ifdef __cplusplus\n");
  394. Printf(f_wrappers, "extern \"C\" {\n");
  395. Printf(f_wrappers, "#endif\n\n");
  396. /* Emit code */
  397. Language::top(n);
  398. if (directorsEnabled()) {
  399. // Insert director runtime into the f_runtime file (make it occur before %header section)
  400. Swig_insert_file("director.swg", f_runtime);
  401. }
  402. // Generate the intermediary class
  403. {
  404. String *filen = NewStringf("%s%s.java", SWIG_output_directory(), imclass_name);
  405. File *f_im = NewFile(filen, "w", SWIG_output_files());
  406. if (!f_im) {
  407. FileErrorDisplay(filen);
  408. SWIG_exit(EXIT_FAILURE);
  409. }
  410. Append(filenames_list, Copy(filen));
  411. Delete(filen);
  412. filen = NULL;
  413. // Start writing out the intermediary class file
  414. emitBanner(f_im);
  415. if (package)
  416. Printf(f_im, "package %s;\n", package);
  417. if (imclass_imports)
  418. Printf(f_im, "%s\n", imclass_imports);
  419. if (Len(imclass_class_modifiers) > 0)
  420. Printf(f_im, "%s ", imclass_class_modifiers);
  421. Printf(f_im, "%s ", imclass_name);
  422. if (imclass_baseclass && *Char(imclass_baseclass))
  423. Printf(f_im, "extends %s ", imclass_baseclass);
  424. if (Len(imclass_interfaces) > 0)
  425. Printv(f_im, "implements ", imclass_interfaces, " ", NIL);
  426. Printf(f_im, "{\n");
  427. // Add the intermediary class methods
  428. Replaceall(imclass_class_code, "$module", module_class_name);
  429. Replaceall(imclass_class_code, "$imclassname", imclass_name);
  430. Printv(f_im, imclass_class_code, NIL);
  431. Printv(f_im, imclass_cppcasts_code, NIL);
  432. if (Len(imclass_directors) > 0)
  433. Printv(f_im, "\n", imclass_directors, NIL);
  434. if (n_dmethods > 0) {
  435. Putc('\n', f_im);
  436. Printf(f_im, " private final static native void swig_module_init();\n");
  437. Printf(f_im, " static {\n");
  438. Printf(f_im, " swig_module_init();\n");
  439. Printf(f_im, " }\n");
  440. }
  441. // Finish off the class
  442. Printf(f_im, "}\n");
  443. Close(f_im);
  444. }
  445. // Generate the Java module class
  446. {
  447. String *filen = NewStringf("%s%s.java", SWIG_output_directory(), module_class_name);
  448. File *f_module = NewFile(filen, "w", SWIG_output_files());
  449. if (!f_module) {
  450. FileErrorDisplay(filen);
  451. SWIG_exit(EXIT_FAILURE);
  452. }
  453. Append(filenames_list, Copy(filen));
  454. Delete(filen);
  455. filen = NULL;
  456. // Start writing out the module class file
  457. emitBanner(f_module);
  458. if (package)
  459. Printf(f_module, "package %s;\n", package);
  460. if (module_imports)
  461. Printf(f_module, "%s\n", module_imports);
  462. if (Len(module_class_modifiers) > 0)
  463. Printf(f_module, "%s ", module_class_modifiers);
  464. Printf(f_module, "%s ", module_class_name);
  465. if (module_baseclass && *Char(module_baseclass))
  466. Printf(f_module, "extends %s ", module_baseclass);
  467. if (Len(module_interfaces) > 0) {
  468. if (Len(module_class_constants_code) != 0)
  469. Printv(f_module, "implements ", constants_interface_name, ", ", module_interfaces, " ", NIL);
  470. else
  471. Printv(f_module, "implements ", module_interfaces, " ", NIL);
  472. } else {
  473. if (Len(module_class_constants_code) != 0)
  474. Printv(f_module, "implements ", constants_interface_name, " ", NIL);
  475. }
  476. Printf(f_module, "{\n");
  477. Replaceall(module_class_code, "$module", module_class_name);
  478. Replaceall(module_class_constants_code, "$module", module_class_name);
  479. Replaceall(module_class_code, "$imclassname", imclass_name);
  480. Replaceall(module_class_constants_code, "$imclassname", imclass_name);
  481. // Add the wrapper methods
  482. Printv(f_module, module_class_code, NIL);
  483. // Finish off the class
  484. Printf(f_module, "}\n");
  485. Close(f_module);
  486. }
  487. // Generate the Java constants interface
  488. if (Len(module_class_constants_code) != 0) {
  489. String *filen = NewStringf("%s%s.java", SWIG_output_directory(), constants_interface_name);
  490. File *f_module = NewFile(filen, "w", SWIG_output_files());
  491. if (!f_module) {
  492. FileErrorDisplay(filen);
  493. SWIG_exit(EXIT_FAILURE);
  494. }
  495. Append(filenames_list, Copy(filen));
  496. Delete(filen);
  497. filen = NULL;
  498. // Start writing out the Java constants interface file
  499. emitBanner(f_module);
  500. if (package)
  501. Printf(f_module, "package %s;\n", package);
  502. if (module_imports)
  503. Printf(f_module, "%s\n", module_imports);
  504. Printf(f_module, "public interface %s {\n", constants_interface_name);
  505. // Write out all the global constants
  506. Printv(f_module, module_class_constants_code, NIL);
  507. // Finish off the Java interface
  508. Printf(f_module, "}\n");
  509. Close(f_module);
  510. }
  511. if (upcasts_code)
  512. Printv(f_wrappers, upcasts_code, NIL);
  513. emitDirectorUpcalls();
  514. Printf(f_wrappers, "#ifdef __cplusplus\n");
  515. Printf(f_wrappers, "}\n");
  516. Printf(f_wrappers, "#endif\n");
  517. // Output a Java type wrapper class for each SWIG type
  518. for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) {
  519. emitTypeWrapperClass(swig_type.key, swig_type.item);
  520. }
  521. // Check for overwriting file problems on filesystems that are case insensitive
  522. Iterator it1;
  523. Iterator it2;
  524. for (it1 = First(filenames_list); it1.item; it1 = Next(it1)) {
  525. String *item1_lower = Swig_string_lower(it1.item);
  526. for (it2 = Next(it1); it2.item; it2 = Next(it2)) {
  527. String *item2_lower = Swig_string_lower(it2.item);
  528. if (it1.item && it2.item) {
  529. if (Strcmp(item1_lower, item2_lower) == 0) {
  530. Swig_warning(WARN_LANG_PORTABILITY_FILENAME, input_file, line_number,
  531. "Portability warning: File %s will be overwritten by %s on case insensitive filesystems such as "
  532. "Windows' FAT32 and NTFS unless the class/module name is renamed\n", it1.item, it2.item);
  533. }
  534. }
  535. Delete(item2_lower);
  536. }
  537. Delete(item1_lower);
  538. }
  539. Delete(swig_types_hash);
  540. swig_types_hash = NULL;
  541. Delete(filenames_list);
  542. filenames_list = NULL;
  543. Delete(imclass_name);
  544. imclass_name = NULL;
  545. Delete(imclass_class_code);
  546. imclass_class_code = NULL;
  547. Delete(proxy_class_def);
  548. proxy_class_def = NULL;
  549. Delete(proxy_class_code);
  550. proxy_class_code = NULL;
  551. Delete(module_class_constants_code);
  552. module_class_constants_code = NULL;
  553. Delete(imclass_baseclass);
  554. imclass_baseclass = NULL;
  555. Delete(imclass_interfaces);
  556. imclass_interfaces = NULL;
  557. Delete(imclass_class_modifiers);
  558. imclass_class_modifiers = NULL;
  559. Delete(module_class_name);
  560. module_class_name = NULL;
  561. Delete(constants_interface_name);
  562. constants_interface_name = NULL;
  563. Delete(module_class_code);
  564. module_class_code = NULL;
  565. Delete(module_baseclass);
  566. module_baseclass = NULL;
  567. Delete(module_interfaces);
  568. module_interfaces = NULL;
  569. Delete(module_imports);
  570. module_imports = NULL;
  571. Delete(module_class_modifiers);
  572. module_class_modifiers = NULL;
  573. Delete(imclass_imports);
  574. imclass_imports = NULL;
  575. Delete(imclass_cppcasts_code);
  576. imclass_cppcasts_code = NULL;
  577. Delete(imclass_directors);
  578. imclass_directors = NULL;
  579. Delete(upcasts_code);
  580. upcasts_code = NULL;
  581. Delete(package);
  582. package = NULL;
  583. Delete(jnipackage);
  584. jnipackage = NULL;
  585. Delete(package_path);
  586. package_path = NULL;
  587. Delete(dmethods_seq);
  588. dmethods_seq = NULL;
  589. Delete(dmethods_table);
  590. dmethods_table = NULL;
  591. n_dmethods = 0;
  592. /* Close all of the files */
  593. Dump(f_header, f_runtime);
  594. if (directorsEnabled()) {
  595. Dump(f_directors, f_runtime);
  596. Dump(f_directors_h, f_runtime_h);
  597. Printf(f_runtime_h, "\n");
  598. Printf(f_runtime_h, "#endif\n");
  599. Close(f_runtime_h);
  600. Delete(f_runtime_h);
  601. f_runtime_h = NULL;
  602. Delete(f_directors);
  603. f_directors = NULL;
  604. Delete(f_directors_h);
  605. f_directors_h = NULL;
  606. }
  607. Dump(f_wrappers, f_runtime);
  608. Wrapper_pretty_print(f_init, f_runtime);
  609. Delete(f_header);
  610. Delete(f_wrappers);
  611. Delete(f_init);
  612. Dump(f_runtime, f_begin);
  613. Delete(f_runtime);
  614. Close(f_begin);
  615. Delete(f_begin);
  616. return SWIG_OK;
  617. }
  618. /* -----------------------------------------------------------------------------
  619. * emitBanner()
  620. * ----------------------------------------------------------------------------- */
  621. void emitBanner(File *f) {
  622. Printf(f, "/* ----------------------------------------------------------------------------\n");
  623. Swig_banner_target_lang(f, " *");
  624. Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
  625. }
  626. /*-----------------------------------------------------------------------
  627. * Add new director upcall signature
  628. *----------------------------------------------------------------------*/
  629. UpcallData *addUpcallMethod(String *imclass_method, String *class_method, String *imclass_desc, String *class_desc, String *decl) {
  630. UpcallData *udata;
  631. String *imclass_methodidx;
  632. String *class_methodidx;
  633. Hash *new_udata;
  634. String *key = NewStringf("%s|%s", imclass_method, decl);
  635. ++curr_class_dmethod;
  636. /* Do we know about this director class already? */
  637. if ((udata = Getattr(dmethods_table, key))) {
  638. Delete(key);
  639. return Getattr(udata, "methodoff");
  640. }
  641. imclass_methodidx = NewStringf("%d", n_dmethods);
  642. class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod);
  643. n_dmethods++;
  644. new_udata = NewHash();
  645. Append(dmethods_seq, new_udata);
  646. Setattr(dmethods_table, key, new_udata);
  647. Setattr(new_udata, "method", Copy(class_method));
  648. Setattr(new_udata, "fdesc", Copy(class_desc));
  649. Setattr(new_udata, "imclass_method", Copy(imclass_method));
  650. Setattr(new_udata, "imclass_fdesc", Copy(imclass_desc));
  651. Setattr(new_udata, "imclass_methodidx", imclass_methodidx);
  652. Setattr(new_udata, "class_methodidx", class_methodidx);
  653. Setattr(new_udata, "decl", Copy(decl));
  654. Delete(key);
  655. return new_udata;
  656. }
  657. /*-----------------------------------------------------------------------
  658. * Get director upcall signature
  659. *----------------------------------------------------------------------*/
  660. UpcallData *getUpcallMethodData(String *director_class, String *decl) {
  661. String *key = NewStringf("%s|%s", director_class, decl);
  662. UpcallData *udata = Getattr(dmethods_table, key);
  663. Delete(key);
  664. return udata;
  665. }
  666. /* ----------------------------------------------------------------------
  667. * nativeWrapper()
  668. * ---------------------------------------------------------------------- */
  669. virtual int nativeWrapper(Node *n) {
  670. String *wrapname = Getattr(n, "wrap:name");
  671. if (!addSymbol(wrapname, n, imclass_name))
  672. return SWIG_ERROR;
  673. if (Getattr(n, "type")) {
  674. Swig_save("nativeWrapper", n, "name", NIL);
  675. Setattr(n, "name", wrapname);
  676. native_function_flag = true;
  677. functionWrapper(n);
  678. Swig_restore(n);
  679. native_function_flag = false;
  680. } else {
  681. Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name"));
  682. }
  683. return SWIG_OK;
  684. }
  685. /* ----------------------------------------------------------------------
  686. * functionWrapper()
  687. * ---------------------------------------------------------------------- */
  688. virtual int functionWrapper(Node *n) {
  689. String *symname = Getattr(n, "sym:name");
  690. SwigType *t = Getattr(n, "type");
  691. ParmList *l = Getattr(n, "parms");
  692. String *tm;
  693. Parm *p;
  694. int i;
  695. String *c_return_type = NewString("");
  696. String *im_return_type = NewString("");
  697. String *cleanup = NewString("");
  698. String *outarg = NewString("");
  699. String *body = NewString("");
  700. int num_arguments = 0;
  701. int gencomma = 0;
  702. bool is_void_return;
  703. String *overloaded_name = getOverloadedName(n);
  704. String *nondir_args = NewString("");
  705. bool is_destructor = (Cmp(Getattr(n, "nodeType"), "destructor") == 0);
  706. if (!Getattr(n, "sym:overloaded")) {
  707. if (!addSymbol(Getattr(n, "sym:name"), n, imclass_name))
  708. return SWIG_ERROR;
  709. }
  710. /*
  711. The rest of this function deals with generating the intermediary class wrapper function (that wraps
  712. a c/c++ function) and generating the JNI c code. Each Java wrapper function has a
  713. matching JNI c function call.
  714. */
  715. // A new wrapper function object
  716. Wrapper *f = NewWrapper();
  717. // Make a wrapper name for this function
  718. String *jniname = makeValidJniName(overloaded_name);
  719. String *wname = Swig_name_wrapper(jniname);
  720. Delete(jniname);
  721. /* Attach the non-standard typemaps to the parameter list. */
  722. Swig_typemap_attach_parms("jni", l, f);
  723. Swig_typemap_attach_parms("jtype", l, f);
  724. Swig_typemap_attach_parms("jstype", l, f);
  725. /* Get return types */
  726. if ((tm = Swig_typemap_lookup("jni", n, "", 0))) {
  727. Printf(c_return_type, "%s", tm);
  728. } else {
  729. Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(t, 0));
  730. }
  731. if ((tm = Swig_typemap_lookup("jtype", n, "", 0))) {
  732. Printf(im_return_type, "%s", tm);
  733. } else {
  734. Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(t, 0));
  735. }
  736. is_void_return = (Cmp(c_return_type, "void") == 0);
  737. if (!is_void_return)
  738. Wrapper_add_localv(f, "jresult", c_return_type, "jresult = 0", NIL);
  739. Printv(f->def, "SWIGEXPORT ", c_return_type, " JNICALL ", wname, "(JNIEnv *jenv, jclass jcls", NIL);
  740. // Usually these function parameters are unused - The code below ensures
  741. // that compilers do not issue such a warning if configured to do so.
  742. Printv(f->code, " (void)jenv;\n", NIL);
  743. Printv(f->code, " (void)jcls;\n", NIL);
  744. // Emit all of the local variables for holding arguments.
  745. emit_parameter_variables(l, f);
  746. /* Attach the standard typemaps */
  747. emit_attach_parmmaps(l, f);
  748. // Parameter overloading
  749. Setattr(n, "wrap:parms", l);
  750. Setattr(n, "wrap:name", wname);
  751. // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java
  752. if (Getattr(n, "sym:overloaded")) {
  753. // Emit warnings for the few cases that can't be overloaded in Java and give up on generating wrapper
  754. Swig_overload_check(n);
  755. if (Getattr(n, "overload:ignore"))
  756. return SWIG_OK;
  757. }
  758. Printf(imclass_class_code, " public final static native %s %s(", im_return_type, overloaded_name);
  759. num_arguments = emit_num_arguments(l);
  760. // Now walk the function parameter list and generate code to get arguments
  761. for (i = 0, p = l; i < num_arguments; i++) {
  762. while (checkAttribute(p, "tmap:in:numinputs", "0")) {
  763. p = Getattr(p, "tmap:in:next");
  764. }
  765. SwigType *pt = Getattr(p, "type");
  766. String *ln = Getattr(p, "lname");
  767. String *im_param_type = NewString("");
  768. String *c_param_type = NewString("");
  769. String *arg = NewString("");
  770. Printf(arg, "j%s", ln);
  771. /* Get the JNI C types of the parameter */
  772. if ((tm = Getattr(p, "tmap:jni"))) {
  773. Printv(c_param_type, tm, NIL);
  774. } else {
  775. Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(pt, 0));
  776. }
  777. /* Get the intermediary class parameter types of the parameter */
  778. if ((tm = Getattr(p, "tmap:jtype"))) {
  779. Printv(im_param_type, tm, NIL);
  780. } else {
  781. Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(pt, 0));
  782. }
  783. /* Add parameter to intermediary class method */
  784. if (gencomma)
  785. Printf(imclass_class_code, ", ");
  786. Printf(imclass_class_code, "%s %s", im_param_type, arg);
  787. // Add parameter to C function
  788. Printv(f->def, ", ", c_param_type, " ", arg, NIL);
  789. ++gencomma;
  790. // Premature garbage collection prevention parameter
  791. if (!is_destructor) {
  792. String *pgc_parameter = prematureGarbageCollectionPreventionParameter(pt, p);
  793. if (pgc_parameter) {
  794. Printf(imclass_class_code, ", %s %s_", pgc_parameter, arg);
  795. Printf(f->def, ", jobject %s_", arg);
  796. Printf(f->code, " (void)%s_;\n", arg);
  797. }
  798. }
  799. // Get typemap for this argument
  800. if ((tm = Getattr(p, "tmap:in"))) {
  801. addThrows(n, "tmap:in", p);
  802. Replaceall(tm, "$source", arg); /* deprecated */
  803. Replaceall(tm, "$target", ln); /* deprecated */
  804. Replaceall(tm, "$arg", arg); /* deprecated? */
  805. Replaceall(tm, "$input", arg);
  806. Setattr(p, "emit:input", arg);
  807. Printf(nondir_args, "%s\n", tm);
  808. p = Getattr(p, "tmap:in:next");
  809. } else {
  810. Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
  811. p = nextSibling(p);
  812. }
  813. Delete(im_param_type);
  814. Delete(c_param_type);
  815. Delete(arg);
  816. }
  817. Printv(f->code, nondir_args, NIL);
  818. Delete(nondir_args);
  819. /* Insert constraint checking code */
  820. for (p = l; p;) {
  821. if ((tm = Getattr(p, "tmap:check"))) {
  822. addThrows(n, "tmap:check", p);
  823. Replaceall(tm, "$target", Getattr(p, "lname")); /* deprecated */
  824. Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
  825. Replaceall(tm, "$input", Getattr(p, "emit:input"));
  826. Printv(f->code, tm, "\n", NIL);
  827. p = Getattr(p, "tmap:check:next");
  828. } else {
  829. p = nextSibling(p);
  830. }
  831. }
  832. /* Insert cleanup code */
  833. for (p = l; p;) {
  834. if ((tm = Getattr(p, "tmap:freearg"))) {
  835. addThrows(n, "tmap:freearg", p);
  836. Replaceall(tm, "$source", Getattr(p, "emit:input")); /* deprecated */
  837. Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
  838. Replaceall(tm, "$input", Getattr(p, "emit:input"));
  839. Printv(cleanup, tm, "\n", NIL);
  840. p = Getattr(p, "tmap:freearg:next");
  841. } else {
  842. p = nextSibling(p);
  843. }
  844. }
  845. /* Insert argument output code */
  846. for (p = l; p;) {
  847. if ((tm = Getattr(p, "tmap:argout"))) {
  848. addThrows(n, "tmap:argout", p);
  849. Replaceall(tm, "$source", Getattr(p, "emit:input")); /* deprecated */
  850. Replaceall(tm, "$target", Getattr(p, "lname")); /* deprecated */
  851. Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */
  852. Replaceall(tm, "$result", "jresult");
  853. Replaceall(tm, "$input", Getattr(p, "emit:input"));
  854. Printv(outarg, tm, "\n", NIL);
  855. p = Getattr(p, "tmap:argout:next");
  856. } else {
  857. p = nextSibling(p);
  858. }
  859. }
  860. // Get any Java exception classes in the throws typemap
  861. ParmList *throw_parm_list = NULL;
  862. if ((throw_parm_list = Getattr(n, "catchlist"))) {
  863. Swig_typemap_attach_parms("throws", throw_parm_list, f);
  864. for (p = throw_parm_list; p; p = nextSibling(p)) {
  865. if ((tm = Getattr(p, "tmap:throws"))) {
  866. addThrows(n, "tmap:throws", p);
  867. }
  868. }
  869. }
  870. if (!native_function_flag) {
  871. if (Cmp(nodeType(n), "constant") == 0) {
  872. // Wrapping a constant hack
  873. Swig_save("functionWrapper", n, "wrap:action", NIL);
  874. // below based on Swig_VargetToFunction()
  875. SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n));
  876. Setattr(n, "wrap:action", NewStringf("%s = (%s)(%s);", Swig_cresult_name(), SwigType_lstr(ty, 0), Getattr(n, "value")));
  877. }
  878. // Now write code to make the function call
  879. Swig_director_emit_dynamic_cast(n, f);
  880. String *actioncode = emit_action(n);
  881. // Handle exception classes specified in the "except" feature's "throws" attribute
  882. addThrows(n, "feature:except", n);
  883. if (Cmp(nodeType(n), "constant") == 0)
  884. Swig_restore(n);
  885. /* Return value if necessary */
  886. if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
  887. addThrows(n, "tmap:out", n);
  888. Replaceall(tm, "$source", Swig_cresult_name()); /* deprecated */
  889. Replaceall(tm, "$target", "jresult"); /* deprecated */
  890. Replaceall(tm, "$result", "jresult");
  891. if (GetFlag(n, "feature:new"))
  892. Replaceall(tm, "$owner", "1");
  893. else
  894. Replaceall(tm, "$owner", "0");
  895. Printf(f->code, "%s", tm);
  896. if (Len(tm))
  897. Printf(f->code, "\n");
  898. } else {
  899. Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name"));
  900. }
  901. emit_return_variable(n, t, f);
  902. }
  903. /* Output argument output code */
  904. Printv(f->code, outarg, NIL);
  905. /* Output cleanup code */
  906. Printv(f->code, cleanup, NIL);
  907. /* Look to see if there is any newfree cleanup code */
  908. if (GetFlag(n, "feature:new")) {
  909. if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
  910. addThrows(n, "tmap:newfree", n);
  911. Replaceall(tm, "$source", Swig_cresult_name()); /* deprecated */
  912. Printf(f->code, "%s\n", tm);
  913. }
  914. }
  915. /* See if there is any return cleanup code */
  916. if (!native_function_flag) {
  917. if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
  918. addThrows(n, "tmap:ret", n);
  919. Replaceall(tm, "$source", Swig_cresult_name()); /* deprecated */
  920. Printf(f->code, "%s\n", tm);
  921. }
  922. }
  923. /* Finish C function and intermediary class function definitions */
  924. Printf(imclass_class_code, ")");
  925. generateThrowsClause(n, imclass_class_code);
  926. Printf(imclass_class_code, ";\n");
  927. Printf(f->def, ") {");
  928. if (!is_void_return)
  929. Printv(f->code, " return jresult;\n", NIL);
  930. Printf(f->code, "}\n");
  931. /* Substitute the cleanup code */
  932. Replaceall(f->code, "$cleanup", cleanup);
  933. /* Substitute the function name */
  934. Replaceall(f->code, "$symname", symname);
  935. /* Contract macro modification */
  936. Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ");
  937. if (!is_void_return)
  938. Replaceall(f->code, "$null", "0");
  939. else
  940. Replaceall(f->code, "$null", "");
  941. /* Dump the function out */
  942. if (!native_function_flag)
  943. Wrapper_print(f, f_wrappers);
  944. if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
  945. moduleClassFunctionHandler(n);
  946. }
  947. /*
  948. * Generate the proxy class getters/setters for public member variables.
  949. * Not for enums and constants.
  950. */
  951. if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
  952. // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name
  953. bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) != 0;
  954. String *getter_setter_name = NewString("");
  955. if (!getter_flag)
  956. Printf(getter_setter_name, "set");
  957. else
  958. Printf(getter_setter_name, "get");
  959. Putc(toupper((int) *Char(variable_name)), getter_setter_name);
  960. Printf(getter_setter_name, "%s", Char(variable_name) + 1);
  961. Setattr(n, "proxyfuncname", getter_setter_name);
  962. Setattr(n, "imfuncname", symname);
  963. proxyClassFunctionHandler(n);
  964. Delete(getter_setter_name);
  965. }
  966. Delete(c_return_type);
  967. Delete(im_return_type);
  968. Delete(cleanup);
  969. Delete(outarg);
  970. Delete(body);
  971. Delete(overloaded_name);
  972. DelWrapper(f);
  973. return SWIG_OK;
  974. }
  975. /* -----------------------------------------------------------------------
  976. * variableWrapper()
  977. * ----------------------------------------------------------------------- */
  978. virtual int variableWrapper(Node *n) {
  979. variable_wrapper_flag = true;
  980. Language::variableWrapper(n); /* Default to functions */
  981. variable_wrapper_flag = false;
  982. return SWIG_OK;
  983. }
  984. /* -----------------------------------------------------------------------
  985. * globalvariableHandler()
  986. * ------------------------------------------------------------------------ */
  987. virtual int globalvariableHandler(Node *n) {
  988. variable_name = Getattr(n, "sym:name");
  989. global_variable_flag = true;
  990. int ret = Language::globalvariableHandler(n);
  991. global_variable_flag = false;
  992. return ret;
  993. }
  994. /* ----------------------------------------------------------------------
  995. * enumDeclaration()
  996. *
  997. * C/C++ enums can be mapped in one of 4 ways, depending on the java:enum feature specified:
  998. * 1) Simple enums - simple constant within the proxy class or module class
  999. * 2) Typeunsafe enums - simple constant in a Java class (class named after the c++ enum name)
  1000. * 3) Typesafe enum - typesafe enum pattern (class named after the c++ enum name)
  1001. * 4) Proper enums - proper Java enum
  1002. * Anonymous enums always default to 1)
  1003. * ---------------------------------------------------------------------- */
  1004. virtual int enumDeclaration(Node *n) {
  1005. if (!ImportMode) {
  1006. if (getCurrentClass() && (cplus_mode != PUBLIC))
  1007. return SWIG_NOWRAP;
  1008. String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call
  1009. if (proxy_flag && !is_wrapping_class()) {
  1010. // Global enums / enums in a namespace
  1011. assert(!full_imclass_name);
  1012. if (!nspace) {
  1013. full_imclass_name = NewStringf("%s", imclass_name);
  1014. } else {
  1015. if (package) {
  1016. full_imclass_name = NewStringf("%s.%s", package, imclass_name);
  1017. } else {
  1018. String *name = Getattr(n, "name") ? Getattr(n, "name") : NewString("<unnamed>");
  1019. Swig_error(Getfile(n), Getline(n), "The nspace feature used on '%s' is not supported unless a package is specified with -package - Java does not support types declared in a named package accessing types declared in an unnamed package.\n", name);
  1020. SWIG_exit(EXIT_FAILURE);
  1021. }
  1022. }
  1023. }
  1024. enum_code = NewString("");
  1025. String *symname = Getattr(n, "sym:name");
  1026. String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code;
  1027. EnumFeature enum_feature = decodeEnumFeature(n);
  1028. String *typemap_lookup_type = Getattr(n, "name");
  1029. if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
  1030. // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
  1031. String *scope = 0;
  1032. if (nspace || proxy_class_name) {
  1033. scope = NewString("");
  1034. if (nspace)
  1035. Printf(scope, "%s", nspace);
  1036. if (proxy_class_name)
  1037. Printv(scope, nspace ? "." : "", proxy_class_name, NIL);
  1038. }
  1039. if (!addSymbol(symname, n, scope))
  1040. return SWIG_ERROR;
  1041. // Pure Java baseclass and interfaces
  1042. const String *pure_baseclass = typemapLookup(n, "javabase", typemap_lookup_type, WARN_NONE);
  1043. const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
  1044. // Emit the enum
  1045. Printv(enum_code, typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers (enum modifiers really)
  1046. " ", symname, *Char(pure_baseclass) ? // Bases
  1047. " extends " : "", pure_baseclass, *Char(pure_interfaces) ? // Interfaces
  1048. " implements " : "", pure_interfaces, " {\n", NIL);
  1049. if (proxy_flag && is_wrapping_class())
  1050. Replaceall(enum_code, "$static ", "static ");
  1051. else
  1052. Replaceall(enum_code, "$static ", "");
  1053. Delete(scope);
  1054. } else {
  1055. // Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
  1056. if (symname && !Getattr(n, "unnamedinstance"))
  1057. Printf(constants_code, " // %s \n", symname);
  1058. }
  1059. // Emit each enum item
  1060. Language::enumDeclaration(n);
  1061. if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
  1062. // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
  1063. // Finish the enum declaration
  1064. // Typemaps are used to generate the enum definition in a similar manner to proxy classes.
  1065. Printv(enum_code, (enum_feature == ProperEnum) ? ";\n" : "", typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class
  1066. typemapLookup(n, "javacode", typemap_lookup_type, WARN_NONE), // extra Java code
  1067. "}", NIL);
  1068. Replaceall(enum_code, "$javaclassname", symname);
  1069. // Substitute $enumvalues - intended usage is for typesafe enums
  1070. if (Getattr(n, "enumvalues"))
  1071. Replaceall(enum_code, "$enumvalues", Getattr(n, "enumvalues"));
  1072. else
  1073. Replaceall(enum_code, "$enumvalues", "");
  1074. if (proxy_flag && is_wrapping_class()) {
  1075. // Enums defined within the C++ class are defined within the proxy class
  1076. // Add extra indentation
  1077. Replaceall(enum_code, "\n", "\n ");
  1078. Replaceall(enum_code, " \n", "\n");
  1079. Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL);
  1080. } else {
  1081. // Global enums are defined in their own file
  1082. String *output_directory = outputDirectory(nspace);
  1083. String *filen = NewStringf("%s%s.java", output_directory, symname);
  1084. File *f_enum = NewFile(filen, "w", SWIG_output_files());
  1085. if (!f_enum) {
  1086. FileErrorDisplay(filen);
  1087. SWIG_exit(EXIT_FAILURE);
  1088. }
  1089. Append(filenames_list, Copy(filen));
  1090. Delete(filen);
  1091. filen = NULL;
  1092. // Start writing out the enum file
  1093. emitBanner(f_enum);
  1094. if (package || nspace) {
  1095. Printf(f_enum, "package ");
  1096. if (package)
  1097. Printv(f_enum, package, nspace ? "." : "", NIL);
  1098. if (nspace)
  1099. Printv(f_enum, nspace, NIL);
  1100. Printf(f_enum, ";\n");
  1101. }
  1102. Printv(f_enum, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE), // Import statements
  1103. "\n", enum_code, "\n", NIL);
  1104. Printf(f_enum, "\n");
  1105. Close(f_enum);
  1106. Delete(output_directory);
  1107. }
  1108. } else {
  1109. // Wrap C++ enum with simple constant
  1110. Printf(enum_code, "\n");
  1111. if (proxy_flag && is_wrapping_class())
  1112. Printv(proxy_class_constants_code, enum_code, NIL);
  1113. else
  1114. Printv(module_class_constants_code, enum_code, NIL);
  1115. }
  1116. Delete(enum_code);
  1117. enum_code = NULL;
  1118. if (proxy_flag && !is_wrapping_class()) {
  1119. Delete(full_imclass_name);
  1120. full_imclass_name = 0;
  1121. }
  1122. }
  1123. return SWIG_OK;
  1124. }
  1125. /* ----------------------------------------------------------------------
  1126. * enumvalueDeclaration()
  1127. * ---------------------------------------------------------------------- */
  1128. virtual int enumvalueDeclaration(Node *n) {
  1129. if (getCurrentClass() && (cplus_mode != PUBLIC))
  1130. return SWIG_NOWRAP;
  1131. Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
  1132. String *symname = Getattr(n, "sym:name");
  1133. String *value = Getattr(n, "value");
  1134. String *name = Getattr(n, "name");
  1135. Node *parent = parentNode(n);
  1136. int unnamedinstance = GetFlag(parent, "unnamedinstance");
  1137. String *parent_name = Getattr(parent, "name");
  1138. String *nspace = getNSpace();
  1139. String *tmpValue;
  1140. // Strange hack from parent method
  1141. if (value)
  1142. tmpValue = NewString(value);
  1143. else
  1144. tmpValue = NewString(name);
  1145. // Note that this is used in enumValue() amongst other places
  1146. Setattr(n, "value", tmpValue);
  1147. // Deal with enum values that are not int
  1148. int swigtype = SwigType_type(Getattr(n, "type"));
  1149. if (swigtype == T_BOOL) {
  1150. const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
  1151. Setattr(n, "enumvalue", val);
  1152. } else if (swigtype == T_CHAR) {
  1153. String *val = NewStringf("'%s'", Getattr(n, "enumvalue"));
  1154. Setattr(n, "enumvalue", val);
  1155. Delete(val);
  1156. }
  1157. {
  1158. EnumFeature enum_feature = decodeEnumFeature(parent);
  1159. // Add to language symbol table
  1160. String *scope = 0;
  1161. if (unnamedinstance || !parent_name || enum_feature == SimpleEnum) {
  1162. if (proxy_class_name) {
  1163. scope = NewString("");
  1164. if (nspace)
  1165. Printf(scope, "%s.", nspace);
  1166. Printf(scope, "%s", proxy_class_name);
  1167. } else {
  1168. scope = Copy(constants_interface_name);
  1169. }
  1170. } else {
  1171. scope = NewString("");
  1172. if (nspace)
  1173. Printf(scope, "%s.", nspace);
  1174. if (proxy_class_name)
  1175. Printf(scope, "%s.", proxy_class_name);
  1176. Printf(scope, "%s",Getattr(parent, "sym:name"));
  1177. }
  1178. if (!addSymbol(name, n, scope))
  1179. return SWIG_ERROR;
  1180. if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) {
  1181. // Wrap (non-anonymous) C/C++ enum with a proper Java enum
  1182. // Emit the enum item.
  1183. if (!GetFlag(n, "firstenumitem"))
  1184. Printf(enum_code, ",\n");
  1185. Printf(enum_code, " %s", symname);
  1186. if (Getattr(n, "enumvalue")) {
  1187. String *value = enumValue(n);
  1188. Printf(enum_code, "(%s)", value);
  1189. Delete(value);
  1190. }
  1191. } else {
  1192. // Wrap C/C++ enums with constant integers or use the typesafe enum pattern
  1193. SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum ");
  1194. Setattr(n, "type", typemap_lookup_type);
  1195. const String *tm = typemapLookup(n, "jstype", typemap_lookup_type, WARN_JAVA_TYPEMAP_JSTYPE_UNDEF);
  1196. String *return_type = Copy(tm);
  1197. substituteClassname(typemap_lookup_type, return_type);
  1198. const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
  1199. methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
  1200. if ((enum_feature == TypesafeEnum) && parent_name && !unnamedinstance) {
  1201. // Wrap (non-anonymous) enum using the typesafe enum pattern
  1202. if (Getattr(n, "enumvalue")) {
  1203. String *value = enumValue(n);
  1204. Printf(enum_code, " %s final static %s %s = new %s(\"%s\", %s);\n", methodmods, return_type, symname, return_type, symname, value);
  1205. Delete(value);
  1206. } else {
  1207. Printf(enum_code, " %s final static %s %s = new %s(\"%s\");\n", methodmods, return_type, symname, return_type, symname);
  1208. }
  1209. } else {
  1210. // Simple integer constants
  1211. // Note these are always generated for anonymous enums, no matter what enum_feature is specified
  1212. // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later
  1213. String *value = enumValue(n);
  1214. Printf(enum_code, " %s final static %s %s = %s;\n", methodmods, return_type, symname, value);
  1215. Delete(value);
  1216. }
  1217. Delete(return_type);
  1218. }
  1219. // Add the enum value to the comma separated list being constructed in the enum declaration.
  1220. String *enumvalues = Getattr(parent, "enumvalues");
  1221. if (!enumvalues)
  1222. Setattr(parent, "enumvalues", Copy(symname));
  1223. else
  1224. Printv(enumvalues, ", ", symname, NIL);
  1225. Delete(scope);
  1226. }
  1227. Delete(tmpValue);
  1228. Swig_restore(n);
  1229. return SWIG_OK;
  1230. }
  1231. /* -----------------------------------------------------------------------
  1232. * constantWrapper()
  1233. * Used for wrapping constants - #define or %constant.
  1234. * Also for inline initialised const static primitive type member variables (short, int, double, enums etc).
  1235. * Java static final variables are generated for these.
  1236. * If the %javaconst(1) feature is used then the C constant value is used to initialise the Java final variable.
  1237. * If not, a JNI method is generated to get the C constant value for initialisation of the Java final variable.
  1238. * However, if the %javaconstvalue feature is used, it overrides all other ways to generate the initialisation.
  1239. * Also note that this method might be called for wrapping enum items (when the enum is using %javaconst(0)).
  1240. * ------------------------------------------------------------------------ */
  1241. virtual int constantWrapper(Node *n) {
  1242. String *symname = Getattr(n, "sym:name");
  1243. SwigType *t = Getattr(n, "type");
  1244. ParmList *l = Getattr(n, "parms");
  1245. String *tm;
  1246. String *return_type = NewString("");
  1247. String *constants_code = NewString("");
  1248. Swig_save("constantWrapper", n, "value", NIL);
  1249. bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
  1250. const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname;
  1251. if (!is_enum_item) {
  1252. String *scope = 0;
  1253. if (proxy_class_name) {
  1254. String *nspace = getNSpace();
  1255. scope = NewString("");
  1256. if (nspace)
  1257. Printf(scope, "%s.", nspace);
  1258. Printf(scope, "%s", proxy_class_name);
  1259. } else {
  1260. scope = Copy(constants_interface_name);
  1261. }
  1262. if (!addSymbol(itemname, n, scope))
  1263. return SWIG_ERROR;
  1264. Delete(scope);
  1265. }
  1266. // The %javaconst feature determines how the constant value is obtained
  1267. int const_feature_flag = GetFlag(n, "feature:java:const");
  1268. /* Adjust the enum type for the Swig_typemap_lookup.
  1269. * We want the same jstype typemap for all the enum items so we use the enum type (parent node). */
  1270. if (is_enum_item) {
  1271. t = Getattr(parentNode(n), "enumtype");
  1272. Setattr(n, "type", t);
  1273. }
  1274. /* Attach the non-standard typemaps to the parameter list. */
  1275. Swig_typemap_attach_parms("jstype", l, NULL);
  1276. /* Get Java return types */
  1277. bool classname_substituted_flag = false;
  1278. if ((tm = Swig_typemap_lookup("jstype", n, "", 0))) {
  1279. classname_substituted_flag = substituteClassname(t, tm);
  1280. Printf(return_type, "%s", tm);
  1281. } else {
  1282. Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0));
  1283. }
  1284. // Add the stripped quotes back in
  1285. String *new_value = NewString("");
  1286. if (SwigType_type(t) == T_STRING) {
  1287. Printf(new_value, "\"%s\"", Copy(Getattr(n, "value")));
  1288. Setattr(n, "value", new_value);
  1289. } else if (SwigType_type(t) == T_CHAR) {
  1290. Printf(new_value, "\'%s\'", Copy(Getattr(n, "value")));
  1291. Setattr(n, "value", new_value);
  1292. }
  1293. const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
  1294. methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
  1295. Printf(constants_code, " %s final static %s %s = ", methodmods, return_type, itemname);
  1296. // Check for the %javaconstvalue feature
  1297. String *value = Getattr(n, "feature:java:constvalue");
  1298. if (value) {
  1299. Printf(constants_code, "%s;\n", value);
  1300. } else if (!const_feature_flag) {
  1301. // Default enum and constant handling will work with any type of C constant and initialises the Java variable from C through a JNI call.
  1302. if (classname_substituted_flag) {
  1303. if (SwigType_isenum(t)) {
  1304. // This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
  1305. Printf(constants_code, "%s.swigToEnum(%s.%s());\n", return_type, full_imclass_name, Swig_name_get(getNSpace(), symname));
  1306. } else {
  1307. // This handles function pointers using the %constant directive
  1308. Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
  1309. }
  1310. } else {
  1311. Printf(constants_code, "%s.%s();\n", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
  1312. }
  1313. // Each constant and enum value is wrapped with a separate JNI function call
  1314. SetFlag(n, "feature:immutable");
  1315. enum_constant_flag = true;
  1316. variableWrapper(n);
  1317. enum_constant_flag = false;
  1318. } else {
  1319. // Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code
  1320. if (Getattr(n, "wrappedasconstant")) {
  1321. if (SwigType_type(t) == T_CHAR)
  1322. Printf(constants_code, "\'%s\';\n", Getattr(n, "staticmembervariableHandler:value"));
  1323. else
  1324. Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
  1325. } else {
  1326. Printf(constants_code, "%s;\n", Getattr(n, "value"));
  1327. }
  1328. }
  1329. // Emit the generated code to appropriate place
  1330. // Enums only emit the intermediate and JNI methods, so no proxy or module class wrapper methods needed
  1331. if (!is_enum_item) {
  1332. if (proxy_flag && wrapping_member_flag)
  1333. Printv(proxy_class_constants_code, constants_code, NIL);
  1334. else
  1335. Printv(module_class_constants_code, constants_code, NIL);
  1336. }
  1337. // Cleanup
  1338. Swig_restore(n);
  1339. Delete(new_value);
  1340. Delete(return_type);
  1341. Delete(constants_code);
  1342. return SWIG_OK;
  1343. }
  1344. /* -----------------------------------------------------------------------------
  1345. * insertDirective()
  1346. * ----------------------------------------------------------------------------- */
  1347. virtual int insertDirective(Node *n) {
  1348. String *code = Getattr(n, "code");
  1349. Replaceall(code, "$module", module_class_name);
  1350. Replaceall(code, "$imclassname", imclass_name);
  1351. return Language::insertDirective(n);
  1352. }
  1353. /* -----------------------------------------------------------------------------
  1354. * pragmaDirective()
  1355. *
  1356. * Valid Pragmas:
  1357. * jniclassbase - base (extends) for the intermediary class
  1358. * jniclassclassmodifiers - class modifiers for the intermediary class
  1359. * jniclasscode - text (java code) is copied verbatim to the intermediary class
  1360. * jniclassimports - import statements for the intermediary class
  1361. * jniclassinterfaces - interface (implements) for the intermediary class
  1362. *
  1363. * modulebase - base (extends) for the module class
  1364. * moduleclassmodifiers - class modifiers for the module class
  1365. * modulecode - text (java code) is copied verbatim to the module class
  1366. * moduleimports - import statements for the module class
  1367. * moduleinterfaces - interface (implements) for the module class
  1368. *
  1369. * ----------------------------------------------------------------------------- */
  1370. virtual int pragmaDirective(Node *n) {
  1371. if (!ImportMode) {
  1372. String *lang = Getattr(n, "lang");
  1373. String *code = Getattr(n, "name");
  1374. String *value = Getattr(n, "value");
  1375. if (Strcmp(lang, "java") == 0) {
  1376. String *strvalue = NewString(value);
  1377. Replaceall(strvalue, "\\\"", "\"");
  1378. if (Strcmp(code, "jniclassbase") == 0) {
  1379. Delete(imclass_baseclass);
  1380. imclass_baseclass = Copy(strvalue);
  1381. } else if (Strcmp(code, "jniclassclassmodifiers") == 0) {
  1382. Delete(imclass_class_modifiers);
  1383. imclass_class_modifiers = Copy(strvalue);
  1384. } else if (Strcmp(code, "jniclasscode") == 0) {
  1385. Printf(imclass_class_code, "%s\n", strvalue);
  1386. } else if (Strcmp(code, "jniclassimports") == 0) {
  1387. Delete(imclass_imports);
  1388. imclass_imports = Copy(strvalue);
  1389. } else if (Strcmp(code, "jniclassinterfaces") == 0) {
  1390. Delete(imclass_interfaces);
  1391. imclass_interfaces = Copy(strvalue);
  1392. } else if (Strcmp(code, "modulebase") == 0) {
  1393. Delete(module_baseclass);
  1394. module_baseclass = Copy(strvalue);
  1395. } else if (Strcmp(code, "moduleclassmodifiers") == 0) {
  1396. Delete(module_class_modifiers);
  1397. module_class_modifiers = Copy(strvalue);
  1398. } else if (Strcmp(code, "modulecode") == 0) {
  1399. Printf(module_class_code, "%s\n", strvalue);
  1400. } else if (Strcmp(code, "moduleimports") == 0) {
  1401. Delete(module_imports);
  1402. module_imports = Copy(strvalue);
  1403. } else if (Strcmp(code, "moduleinterfaces") == 0) {
  1404. Delete(module_interfaces);
  1405. module_interfaces = Copy(strvalue);
  1406. } else if (Strcmp(code, "moduleimport") == 0) {
  1407. Swig_error(input_file, line_number, "Deprecated pragma. Please use the moduleimports pragma.\n");
  1408. } else if (Strcmp(code, "moduleinterface") == 0) {
  1409. Swig_error(input_file, line_number, "Deprecated pragma. Please use the moduleinterfaces pragma.\n");
  1410. } else if (Strcmp(code, "modulemethodmodifiers") == 0) {
  1411. Swig_error(input_file, line_number, "Deprecated pragma. Please use %%javamethodmodifiers.\n");
  1412. } else if (Strcmp(code, "allshadowimport") == 0) {
  1413. Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaimports).\n");
  1414. } else if (Strcmp(code, "allshadowcode") == 0) {
  1415. Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javacode).\n");
  1416. } else if (Strcmp(code, "allshadowbase") == 0) {
  1417. Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javabase).\n");
  1418. } else if (Strcmp(code, "allshadowinterface") == 0) {
  1419. Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javainterfaces).\n");
  1420. } else if (Strcmp(code, "allshadowclassmodifiers") == 0) {
  1421. Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n");
  1422. } else if (proxy_flag) {
  1423. if (Strcmp(code, "shadowcode") == 0) {
  1424. Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javacode).\n");
  1425. } else if (Strcmp(code, "shadowimport") == 0) {
  1426. Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaimports).\n");
  1427. } else if (Strcmp(code, "shadowbase") == 0) {
  1428. Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javabase).\n");
  1429. } else if (Strcmp(code, "shadowinterface") == 0) {
  1430. Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javainterfaces).\n");
  1431. } else if (Strcmp(code, "shadowclassmodifiers") == 0) {
  1432. Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n");
  1433. } else {
  1434. Swig_error(input_file, line_number, "Unrecognized pragma.\n");
  1435. }
  1436. } else {
  1437. Swig_error(input_file, line_number, "Unrecognized pragma.\n");
  1438. }
  1439. Delete(strvalue);
  1440. }
  1441. }
  1442. return Language::pragmaDirective(n);
  1443. }
  1444. /* -----------------------------------------------------------------------------
  1445. * emitProxyClassDefAndCPPCasts()
  1446. * ----------------------------------------------------------------------------- */
  1447. void emitProxyClassDefAndCPPCasts(Node *n) {
  1448. String *c_classname = SwigType_namestr(Getattr(n, "name"));
  1449. String *c_baseclass = NULL;
  1450. String *baseclass = NULL;
  1451. String *c_baseclassname = NULL;
  1452. SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
  1453. bool feature_director = Swig_directorclass(n) ? true : false;
  1454. // Inheritance from pure Java classes
  1455. Node *attributes = NewHash();
  1456. const String *pure_baseclass = typemapLookup(n, "javabase", typemap_lookup_type, WARN_NONE, attributes);
  1457. bool purebase_replace = GetFlag(attributes, "tmap:javabase:replace") ? true : false;
  1458. bool purebase_notderived = GetFlag(attributes, "tmap:javabase:notderived") ? true : false;
  1459. Delete(attributes);
  1460. // C++ inheritance
  1461. if (!purebase_replace) {
  1462. List *baselist = Getattr(n, "bases");
  1463. if (baselist) {
  1464. Iterator base = First(baselist);
  1465. while (base.item && GetFlag(base.item, "feature:ignore")) {
  1466. base = Next(base);
  1467. }
  1468. if (base.item) {
  1469. c_baseclassname = Getattr(base.item, "name");
  1470. baseclass = Copy(getProxyName(c_baseclassname));
  1471. if (baseclass)
  1472. c_baseclass = SwigType_namestr(Getattr(base.item, "name"));
  1473. base = Next(base);
  1474. /* Warn about multiple inheritance for additional base class(es) */
  1475. while (base.item) {
  1476. if (GetFlag(base.item, "feature:ignore")) {
  1477. base = Next(base);
  1478. continue;
  1479. }
  1480. String *proxyclassname = Getattr(n, "classtypeobj");
  1481. String *baseclassname = Getattr(base.item, "name");
  1482. Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
  1483. "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname));
  1484. base = Next(base);
  1485. }
  1486. }
  1487. }
  1488. }
  1489. bool derived = baseclass && getProxyName(c_baseclassname);
  1490. if (derived && purebase_notderived)
  1491. pure_baseclass = empty_string;
  1492. const String *wanted_base = baseclass ? baseclass : pure_baseclass;
  1493. if (purebase_replace) {
  1494. wanted_base = pure_baseclass;
  1495. derived = false;
  1496. Delete(baseclass);
  1497. baseclass = NULL;
  1498. if (purebase_notderived)
  1499. Swig_error(Getfile(n), Getline(n), "The javabase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
  1500. } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) {
  1501. Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
  1502. "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java. "
  1503. "Perhaps you need one of the 'replace' or 'notderived' attributes in the csbase typemap?\n", typemap_lookup_type, pure_baseclass);
  1504. }
  1505. // Pure Java interfaces
  1506. const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
  1507. // Start writing the proxy class
  1508. Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE), // Import statements
  1509. "\n", typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers
  1510. " $javaclassname", // Class name and bases
  1511. (*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(pure_interfaces) ? // Pure Java interfaces
  1512. " implements " : "", pure_interfaces, " {", derived ? typemapLookup(n, "javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class
  1513. typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class
  1514. NIL);
  1515. // C++ destructor is wrapped by the delete method
  1516. // Note that the method name is specified in a typemap attribute called methodname
  1517. String *destruct = NewString("");
  1518. const String *tm = NULL;
  1519. attributes = NewHash();
  1520. String *destruct_methodname = NULL;
  1521. String *destruct_methodmodifiers = NULL;
  1522. if (derived) {
  1523. tm = typemapLookup(n, "javadestruct_derived", typemap_lookup_type, WARN_NONE, attributes);
  1524. destruct_methodname = Getattr(attributes, "tmap:javadestruct_derived:methodname");
  1525. destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct_derived:methodmodifiers");
  1526. } else {
  1527. tm = typemapLookup(n, "javadestruct", typemap_lookup_type, WARN_NONE, attributes);
  1528. destruct_methodname = Getattr(attributes, "tmap:javadestruct:methodname");
  1529. destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct:methodmodifiers");