summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2010-03-06 19:11:32 +0000
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2010-03-06 19:11:32 +0000
commitb6b99bb1486d9709378bd37333c4c930affe5ad3 (patch)
tree7181e4cd4ab7d3a290f7a9e65528d1a27f17e995
parent51d433ee0ab0f677bbf20b4321369b82e3c91f02 (diff)
downloadswig-b6b99bb1486d9709378bd37333c4c930affe5ad3.tar.gz
Add nspace feature for C# and add documentation on nspace
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11920 626c5289-ae23-0410-ae9c-e8d60b6d4f22
-rw-r--r--CHANGES.current3
-rw-r--r--Doc/Manual/CSharp.html5
-rw-r--r--Doc/Manual/Contents.html9
-rw-r--r--Doc/Manual/Java.html13
-rw-r--r--Doc/Manual/SWIGPlus.html96
-rw-r--r--Examples/test-suite/csharp/Makefile.in4
-rw-r--r--Examples/test-suite/csharp/nspace_runme.cs60
-rw-r--r--Lib/swig.swg5
-rw-r--r--Source/Modules/csharp.cxx259
9 files changed, 369 insertions, 85 deletions
diff --git a/CHANGES.current b/CHANGES.current
index ec0473bee..1e9704783 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -1,6 +1,9 @@
Version 2.0.0 (in progress)
============================
+2010-03-06: wsfulton
+ [C#] Added the nspace feature for C#. Documentation for the nspace feature is now available.
+
2010-03-04: wsfulton
Added the nspace feature. This adds some improved namespace support. Currently only Java
is supported for target languages, where C++ namespaces are automatically translated into
diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html
index 324be63ec..3281bc268 100644
--- a/Doc/Manual/CSharp.html
+++ b/Doc/Manual/CSharp.html
@@ -103,6 +103,11 @@ Note that by default, the generated C# classes have no namespace and the module
</li>
<li>
+The <a href="SWIGPlus.html#SWIGPlus_nspace">nspace feature</a> is also supported as described in this general section with a C# example.
+Unlike Java which requires the use of the -package option when using the <tt>nspace</tt> feature, the -namespace option is not mandatory for C#.
+</li>
+
+<li>
The <tt>-dllimport &lt;name&gt;</tt> commandline option specifies the name of the DLL for the <tt>DllImport</tt> attribute for every PInvoke method. If this commandline option is not given, the <tt>DllImport</tt> DLL name is the same as the module name. This option is useful for when one wants to invoke SWIG multiple times on different modules, yet compile all the resulting code into a single DLL.
</li>
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index 0cda0b8f4..266d8210c 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -229,7 +229,10 @@
<li><a href="SWIGPlus.html#SWIGPlus_nn28">Wrapping overloaded operators</a>
<li><a href="SWIGPlus.html#SWIGPlus_class_extension">Class extension</a>
<li><a href="SWIGPlus.html#SWIGPlus_nn30">Templates</a>
-<li><a href="SWIGPlus.html#SWIGPlus_nn31">Namespaces</a>
+<li><a href="SWIGPlus.html#SWIGPlus_namespaces">Namespaces</a>
+<ul>
+<li><a href="SWIGPlus.html#SWIGPlus_nspace">The nspace feature for namespaces</a>
+</ul>
<li><a href="SWIGPlus.html#SWIGPlus_renaming_templated_types_namespaces">Renaming templated types in namespaces</a>
<li><a href="SWIGPlus.html#SWIGPlus_exception_specifications">Exception specifications</a>
<li><a href="SWIGPlus.html#SWIGPlus_catches">Exception handling with %catches</a>
@@ -237,7 +240,7 @@
<li><a href="SWIGPlus.html#SWIGPlus_nn34">Smart pointers and operator-&gt;()</a>
<li><a href="SWIGPlus.html#SWIGPlus_nn35">Using declarations and inheritance</a>
<li><a href="SWIGPlus.html#SWIGPlus_nested_classes">Nested classes</a>
-<li><a href="SWIGPlus.html#SWIGPlus_nn37">A brief rant about const-correctness</a>
+<li><a href="SWIGPlus.html#SWIGPlus_const">A brief rant about const-correctness</a>
<li><a href="SWIGPlus.html#SWIGPlus_nn42">Where to go for more information</a>
</ul>
</div>
@@ -349,7 +352,7 @@
<li><a href="Typemaps.html#Typemaps_typedef_reductions">Typedef reductions</a>
<li><a href="Typemaps.html#Typemaps_nn19">Default typemaps</a>
<li><a href="Typemaps.html#Typemaps_mixed_default">Mixed default typemaps</a>
-<li><a href="Typemaps.html#Typemaps_nn20">Multi-arguments typemaps</a>
+<li><a href="Typemaps.html#Typemaps_multi_argument_typemaps_patterns">Multi-arguments typemaps</a>
<li><a href="Typemaps.html#Typemaps_debugging_search">Debugging typemap pattern matching</a>
</ul>
<li><a href="Typemaps.html#Typemaps_nn21">Code generation rules</a>
diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html
index 7869c5269..7ae802998 100644
--- a/Doc/Manual/Java.html
+++ b/Doc/Manual/Java.html
@@ -1852,7 +1852,9 @@ Further details on default arguments and how to restore this approach are given
<p>
-SWIG is aware of C++ namespaces, but namespace names do not appear in
+SWIG is aware of named C++ namespaces and they can be mapped to Java packages, however,
+the default wrapping flattens the namespaces, effectively ignoring them.
+So by default, the namespace names do not appear in
the module nor do namespaces result in a module that is broken up into
submodules or packages. For example, if you have a file like this,
</p>
@@ -1908,6 +1910,15 @@ symbols separate, consider wrapping them as separate SWIG modules.
Each SWIG module can be placed into a separate package.
</p>
+<p>
+The default behaviour described above can be improved via the <a href="SWIGPlus.html#SWIGPlus_nspace">nspace feature</a>.
+Note that it only works for classes, structs, unions and enums declared within a named C++ namespace.
+When the nspace feature is used, the C++ namespaces are converted into Java packages of the same name.
+Proxy classes are thus declared within a package and this proxy makes numerous calls to the JNI intermediary class which is declared in the unnamed package by default.
+As Java does not support types declared in a named package accessing types declared in an unnamed package, the <tt>-package</tt> commandline option described earlier must be used to provide a parent package.
+So if SWIG is run using the <tt>-package com.myco</tt> option, a wrapped class, <tt>MyWorld::Material::Color</tt>, can then be accessed as <tt>com.myco.MyWorld.Material.Color</tt>.
+</p>
+
<H3><a name="templates"></a>21.3.14 C++ templates</H3>
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index d1498224f..bcded9166 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -48,7 +48,10 @@
<li><a href="#SWIGPlus_nn28">Wrapping overloaded operators</a>
<li><a href="#SWIGPlus_class_extension">Class extension</a>
<li><a href="#SWIGPlus_nn30">Templates</a>
-<li><a href="#SWIGPlus_nn31">Namespaces</a>
+<li><a href="#SWIGPlus_namespaces">Namespaces</a>
+<ul>
+<li><a href="#SWIGPlus_nspace">The nspace feature for namespaces</a>
+</ul>
<li><a href="#SWIGPlus_renaming_templated_types_namespaces">Renaming templated types in namespaces</a>
<li><a href="#SWIGPlus_exception_specifications">Exception specifications</a>
<li><a href="#SWIGPlus_catches">Exception handling with %catches</a>
@@ -3647,12 +3650,16 @@ as the class name. For example:
Similar changes apply to typemaps and other customization features.
</p>
-<H2><a name="SWIGPlus_nn31"></a>6.19 Namespaces</H2>
+<H2><a name="SWIGPlus_namespaces"></a>6.19 Namespaces</H2>
<p>
-Support for C++ namespaces is a relatively late addition to SWIG,
-first appearing in SWIG-1.3.12. Before describing the implementation,
+Support for C++ namespaces is comprehensive, but by default simple, however,
+some target languages can turn on more advanced namespace support via the
+<a href="#SWIGPlus_nspace">nspace feature</a>, described later.
+Code within unnamed namespaces is ignored as there is no external
+access to symbols declared within the unnamed namespace.
+Before detailing the default implementation for named namespaces,
it is worth noting that the semantics of C++ namespaces is extremely
non-trivial--especially with regard to the C++ type system and class
machinery. At a most basic level, namespaces are sometimes used to
@@ -4092,6 +4099,87 @@ with any namespace awareness. In the future, language modules may or may not p
more advanced namespace support.
</p>
+<H3><a name="SWIGPlus_nspace"></a>6.19.1 The nspace feature for namespaces</H3>
+
+
+<p>
+Some target languages provide support for the <tt>nspace</tt> <a href="Customization.html#features">feature</a>.
+The feature can be applied to any class, struct, union or enum declared within a named namespace.
+The feature wraps the type within the target language specific concept of a namespace,
+for example, a Java package or C# namespace.
+Please see the language specific sections to see if the target language you are interested in supports the nspace feature.
+</p>
+
+<p>
+The feature is demonstrated below for C# using the following example:
+</p>
+
+<div class="code">
+<pre>
+%feature("nspace") MyWorld::Material::Color;
+%nspace MyWorld::Wrapping::Color; // %nspace is a macro for %feature("nspace")
+
+namespace MyWorld {
+ namespace Material {
+ class Color {
+ ...
+ };
+ }
+ namespace Wrapping {
+ class Color {
+ ...
+ };
+ }
+}
+</pre>
+</div>
+
+<p>
+Without the <tt>nspace</tt> feature directives above or <tt>%rename</tt>, you would get the following warning resulting in just one of the <tt>Color</tt> classes being available for use from the target language:
+</p>
+
+<div class="shell">
+<pre>
+example.i:9: Error: 'Color' is multiply defined in the generated target language module.
+example.i:5: Error: Previous declaration of 'Color'
+</pre>
+</div>
+
+<p>
+With the <tt>nspace</tt> feature the two <tt>Color</tt> classes are wrapped into the equivalent C# namespaces.
+A fully qualified constructor call of each these two types in C# is then:
+</p>
+
+<div class="targetlang">
+<pre>
+MyWorld.Material.Color materialColor = new MyWorld.Material.Color();
+MyWorld.Wrapping.Color wrappingColor = new MyWorld.Wrapping.Color();
+</pre>
+</div>
+
+<p>
+Note that the <tt>nspace</tt> feature does not apply to variables and functions simply declared in a namespace. For example, the following symbols cannot co-exist in the target language without renaming. This may change in a future version.
+</p>
+
+<div class="code">
+<pre>
+namespace MyWorld {
+ namespace Material {
+ int quantity;
+ void dispatch();
+ }
+ namespace Wrapping {
+ int quantity;
+ void dispatch();
+ }
+}
+</pre>
+</div>
+
+<p>
+<b>Compatibility Note:</b> The nspace feature was first introduced in SWIG-2.0.0.
+</p>
+
<H2><a name="SWIGPlus_renaming_templated_types_namespaces"></a>6.20 Renaming templated types in namespaces</H2>
diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in
index 1545eb30d..0f44b3335 100644
--- a/Examples/test-suite/csharp/Makefile.in
+++ b/Examples/test-suite/csharp/Makefile.in
@@ -70,13 +70,13 @@ run_testcase = \
$(MAKE) -f $*/$(top_builddir)/$(EXAMPLES)/Makefile \
CSHARPFLAGS='-nologo $(CSHARPFLAGSSPECIAL) -out:$*_runme.exe' \
CSHARPSRCS='`$(CSHARPCYGPATH_W) $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX)` \
- $*$(CSHARPPATHSEPARATOR)*.cs' csharp_compile && \
+ `find $* -name "*.cs"`' csharp_compile && \
env LD_LIBRARY_PATH="$*:$$LD_LIBRARY_PATH" PATH="$*:$$PATH" SHLIB_PATH="$*:$$SHLIB_PATH" $(RUNTOOL) $(INTERPRETER) $*_runme.exe; \
else \
cd $* && \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \
CSHARPFLAGS='-nologo $(CSHARPFLAGSSPECIAL) -t:module -out:$*.netmodule' \
- CSHARPSRCS='*.cs' csharp_compile && cd .. ; \
+ CSHARPSRCS='`find . -name "*.cs"`' csharp_compile && cd .. ; \
fi
# Clean: remove testcase directories
diff --git a/Examples/test-suite/csharp/nspace_runme.cs b/Examples/test-suite/csharp/nspace_runme.cs
new file mode 100644
index 000000000..91baf6a0f
--- /dev/null
+++ b/Examples/test-suite/csharp/nspace_runme.cs
@@ -0,0 +1,60 @@
+using System;
+
+public class runme
+{
+ static void Main()
+ {
+ // constructors and destructors
+ nspaceNamespace.Outer.Inner1.Color color1 = new nspaceNamespace.Outer.Inner1.Color();
+ nspaceNamespace.Outer.Inner1.Color color = new nspaceNamespace.Outer.Inner1.Color(color1);
+ color1.Dispose();
+ color1 = null;
+
+ // class methods
+ color.colorInstanceMethod(20.0);
+ nspaceNamespace.Outer.Inner1.Color.colorStaticMethod(20.0);
+ nspaceNamespace.Outer.Inner1.Color created = nspaceNamespace.Outer.Inner1.Color.create();
+ created.Dispose();
+
+ // class enums
+ nspaceNamespace.Outer.SomeClass someClass = new nspaceNamespace.Outer.SomeClass();
+ nspaceNamespace.Outer.Inner1.Color.Channel channel = someClass.GetInner1ColorChannel();
+ if (channel != nspaceNamespace.Outer.Inner1.Color.Channel.Transmission)
+ throw new ApplicationException("Transmission wrong");
+
+ // static member variables
+ nspaceNamespace.Outer.Inner1.Color.staticMemberVariable = 789;
+ if (nspaceNamespace.Outer.Inner1.Color.staticMemberVariable != 789)
+ throw new ApplicationException("static member variable failed");
+
+ // instance member variables
+ color.instanceMemberVariable = 123;
+ if (color.instanceMemberVariable != 123)
+ throw new ApplicationException("instance member variable failed");
+
+ // check globals in a namespace don't get mangled with the nspaceNamespace option
+ nspaceNamespace.nspace.namespaceFunction(color);
+ nspaceNamespace.nspace.namespaceVar = 111;
+ if (nspaceNamespace.nspace.namespaceVar != 111)
+ throw new ApplicationException("global var failed");
+
+ // Same class different namespaces
+ nspaceNamespace.Outer.Inner1.Color col1 = new nspaceNamespace.Outer.Inner1.Color();
+ nspaceNamespace.Outer.Inner2.Color col2 = nspaceNamespace.Outer.Inner2.Color.create();
+ col2.colors(col1, col1, col2, col2, col2);
+
+ // global enums
+ nspaceNamespace.Outer.Inner1.Channel outerChannel1 = someClass.GetInner1Channel();
+ if (outerChannel1 != nspaceNamespace.Outer.Inner1.Channel.Transmission1)
+ throw new ApplicationException("Transmission1 wrong");
+ nspaceNamespace.Outer.Inner2.Channel outerChannel2 = someClass.GetInner2Channel();
+ if (outerChannel2 != nspaceNamespace.Outer.Inner2.Channel.Transmission2)
+ throw new ApplicationException("Transmission2 wrong");
+
+ // turn feature off / ignoring
+ nspaceNamespace.Outer.nspace ns = new nspaceNamespace.Outer.nspace();
+ ns.Dispose();
+ nspaceNamespace.NoNSpacePlease nons = new nspaceNamespace.NoNSpacePlease();
+ nons.Dispose();
+ }
+}
diff --git a/Lib/swig.swg b/Lib/swig.swg
index af7fa6a30..ec903533c 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -156,6 +156,11 @@
#define %nonaturalvar %feature("naturalvar","0")
#define %clearnaturalvar %feature("naturalvar","")
+/* nspace directives */
+#define %nspace %feature("nspace")
+#define %nonspace %feature("nspace","0")
+#define %clearnspace %feature("nspace","")
+
/* valuewrapper directives */
#define %valuewrapper %feature("valuewrapper")
#define %clearvaluewrapper %feature("valuewrapper","")
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
index 6d3d09ea4..0dbed4d1e 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -54,7 +54,9 @@ class CSHARP:public Language {
String *proxy_class_def;
String *proxy_class_code;
String *module_class_code;
- String *proxy_class_name;
+ String *proxy_class_name; // proxy class name
+ String *full_proxy_class_name;// fully qualified proxy class name when using nspace feature, otherwise same as proxy_class_name
+ String *full_imclass_name; // fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name
String *variable_name; //Name of a variable being wrapped
String *proxy_class_constants_code;
String *module_class_constants_code;
@@ -125,6 +127,8 @@ public:
proxy_class_code(NULL),
module_class_code(NULL),
proxy_class_name(NULL),
+ full_proxy_class_name(NULL),
+ full_imclass_name(NULL),
variable_name(NULL),
proxy_class_constants_code(NULL),
module_class_constants_code(NULL),
@@ -163,18 +167,34 @@ public:
* getProxyName()
*
* Test to see if a type corresponds to something wrapped with a proxy class.
- * Return NULL if not otherwise the proxy class name
+ * Return NULL if not otherwise the proxy class name, fully qualified with
+ * a namespace if the nspace feature is used.
* ----------------------------------------------------------------------------- */
String *getProxyName(SwigType *t) {
- if (proxy_flag) {
- Node *n = classLookup(t);
- if (n) {
- return Getattr(n, "sym:name");
- }
- }
- return NULL;
- }
+ String *proxyname = NULL;
+ if (proxy_flag) {
+ Node *n = classLookup(t);
+ if (n) {
+ proxyname = Getattr(n, "proxyname");
+ if (!proxyname) {
+ String *nspace = Getattr(n, "sym:nspace");
+ String *symname = Getattr(n, "sym:name");
+ if (nspace) {
+ if (Len(namespce) > 0)
+ proxyname = NewStringf("%s.%s.%s", namespce, nspace, symname);
+ else
+ proxyname = NewStringf("%s.%s", nspace, symname);
+ } else {
+ proxyname = Copy(symname);
+ }
+ Setattr(n, "proxyname", proxyname);
+ Delete(proxyname);
+ }
+ }
+ }
+ return proxyname;
+ }
/* -----------------------------------------------------------------------------
* directorClassName()
@@ -419,7 +439,7 @@ public:
// Start writing out the intermediary class file
emitBanner(f_im);
- addOpenNamespace(namespce, f_im);
+ addOpenNamespace(namespce, 0, f_im);
if (imclass_imports)
Printf(f_im, "%s\n", imclass_imports);
@@ -443,7 +463,7 @@ public:
// Finish off the class
Printf(f_im, "}\n");
- addCloseNamespace(namespce, f_im);
+ addCloseNamespace(namespce, 0, f_im);
Close(f_im);
}
@@ -463,7 +483,7 @@ public:
// Start writing out the module class file
emitBanner(f_module);
- addOpenNamespace(namespce, f_module);
+ addOpenNamespace(namespce, 0, f_module);
if (module_imports)
Printf(f_module, "%s\n", module_imports);
@@ -495,7 +515,7 @@ public:
// Finish off the class
Printf(f_module, "}\n");
- addCloseNamespace(namespce, f_module);
+ addCloseNamespace(namespce, 0, f_module);
Close(f_module);
}
@@ -1033,7 +1053,7 @@ public:
*/
if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
// Capitalize the first letter in the variable in the getter/setter function name
- bool getter_flag = Cmp(symname, Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, proxy_class_name, variable_name))) != 0;
+ bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) != 0;
String *getter_setter_name = NewString("");
if (!getter_flag)
@@ -1106,6 +1126,22 @@ public:
if (getCurrentClass() && (cplus_mode != PUBLIC))
return SWIG_NOWRAP;
+ if (proxy_flag && !is_wrapping_class()) {
+ // Global enums / enums in a namespace
+ String *nspace = Getattr(n, "sym:nspace");
+ assert(!full_imclass_name);
+
+ if (!nspace) {
+ full_imclass_name = NewStringf("%s", imclass_name);
+ } else {
+ if (Len(namespce) > 0) {
+ full_imclass_name = NewStringf("%s.%s", namespce, imclass_name);
+ } else {
+ full_imclass_name = NewStringf("%s", imclass_name);
+ }
+ }
+ }
+
enum_code = NewString("");
String *symname = Getattr(n, "sym:name");
String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code;
@@ -1163,7 +1199,9 @@ public:
Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL);
} else {
// Global enums are defined in their own file
- String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), symname);
+ String *nspace = Getattr(n, "sym:nspace");
+ String *output_directory = outputDirectory(nspace);
+ String *filen = NewStringf("%s%s.cs", output_directory, symname);
File *f_enum = NewFile(filen, "w", SWIG_output_files());
if (!f_enum) {
FileErrorDisplay(filen);
@@ -1176,14 +1214,14 @@ public:
// Start writing out the enum file
emitBanner(f_enum);
- addOpenNamespace(namespce, f_enum);
+ addOpenNamespace(namespce, nspace, f_enum);
Printv(f_enum, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements
"\n", enum_code, "\n", NIL);
- addCloseNamespace(namespce, f_enum);
-
+ addCloseNamespace(namespce, nspace, f_enum);
Close(f_enum);
+ Delete(output_directory);
}
} else {
// Wrap C++ enum with simple constant
@@ -1196,6 +1234,11 @@ public:
Delete(enum_code);
enum_code = NULL;
+
+ if (proxy_flag && !is_wrapping_class()) {
+ Delete(full_imclass_name);
+ full_imclass_name = 0;
+ }
}
return SWIG_OK;
}
@@ -1381,13 +1424,13 @@ public:
if (classname_substituted_flag) {
if (SwigType_isenum(t)) {
// This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on)
- Printf(constants_code, "(%s)%s.%s();\n", return_type, imclass_name, Swig_name_get(NSPACE_TODO, symname));
+ Printf(constants_code, "(%s)%s.%s();\n", return_type, imclass_name, Swig_name_get(getNSpace(), symname));
} else {
// This handles function pointers using the %constant directive
- Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, imclass_name, Swig_name_get(NSPACE_TODO, symname));
+ Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, imclass_name, Swig_name_get(getNSpace(), symname));
}
} else
- Printf(constants_code, "%s.%s();\n", imclass_name, Swig_name_get(NSPACE_TODO, symname));
+ Printf(constants_code, "%s.%s();\n", imclass_name, Swig_name_get(getNSpace(), symname));
// Each constant and enum value is wrapped with a separate PInvoke function call
SetFlag(n, "feature:immutable");
@@ -1641,7 +1684,8 @@ public:
Printf(proxy_class_code, " if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s))\n", method, methid);
Printf(proxy_class_code, " swigDelegate%s = new SwigDelegate%s_%s(SwigDirector%s);\n", methid, proxy_class_name, methid, overname);
}
- Printf(proxy_class_code, " %s.%s_director_connect(swigCPtr", imclass_name, proxy_class_name);
+ String *director_connect_method_name = Swig_name_member(getNSpace(), proxy_class_name, "director_connect");
+ Printf(proxy_class_code, " %s.%s(swigCPtr", imclass_name, director_connect_method_name);
for (i = first_class_dmethod; i < curr_class_dmethod; ++i) {
UpcallData *udata = Getitem(dmethods_seq, i);
String *methid = Getattr(udata, "class_methodidx");
@@ -1703,6 +1747,7 @@ public:
director_method_types = NULL;
Delete(director_connect_parms);
director_connect_parms = NULL;
+ Delete(director_connect_method_name);
}
Delete(attributes);
@@ -1719,8 +1764,8 @@ public:
Replaceall(proxy_class_def, "$module", module_class_name);
Replaceall(proxy_class_code, "$module", module_class_name);
- Replaceall(proxy_class_def, "$imclassname", imclass_name);
- Replaceall(proxy_class_code, "$imclassname", imclass_name);
+ Replaceall(proxy_class_def, "$imclassname", full_imclass_name);
+ Replaceall(proxy_class_code, "$imclassname", full_imclass_name);
Replaceall(proxy_class_def, "$dllimport", dllimport);
Replaceall(proxy_class_code, "$dllimport", dllimport);
@@ -1749,24 +1794,38 @@ public:
virtual int classHandler(Node *n) {
+ String *nspace = getNSpace();
File *f_proxy = NULL;
if (proxy_flag) {
proxy_class_name = NewString(Getattr(n, "sym:name"));
- if (!addSymbol(proxy_class_name, n))
- return SWIG_ERROR;
+ if (!nspace) {
+ full_proxy_class_name = NewStringf("%s", proxy_class_name);
+ full_imclass_name = NewStringf("%s", imclass_name);
+ if (Cmp(proxy_class_name, imclass_name) == 0) {
+ Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
+ SWIG_exit(EXIT_FAILURE);
+ }
- if (Cmp(proxy_class_name, imclass_name) == 0) {
- Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
- SWIG_exit(EXIT_FAILURE);
+ if (Cmp(proxy_class_name, module_class_name) == 0) {
+ Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ } else {
+ if (Len(namespce) > 0) {
+ full_proxy_class_name = NewStringf("%s.%s.%s", namespce, nspace, proxy_class_name);
+ full_imclass_name = NewStringf("%s.%s", namespce, imclass_name);
+ } else {
+ full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name);
+ full_imclass_name = NewStringf("%s", imclass_name);
+ }
}
- if (Cmp(proxy_class_name, module_class_name) == 0) {
- Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
- SWIG_exit(EXIT_FAILURE);
- }
+ if (!addSymbol(proxy_class_name, n, nspace))
+ return SWIG_ERROR;
- String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), proxy_class_name);
+ String *output_directory = outputDirectory(nspace);
+ String *filen = NewStringf("%s%s.cs", output_directory, proxy_class_name);
f_proxy = NewFile(filen, "w", SWIG_output_files());
if (!f_proxy) {
FileErrorDisplay(filen);
@@ -1779,7 +1838,7 @@ public:
// Start writing out the proxy class file
emitBanner(f_proxy);
- addOpenNamespace(namespce, f_proxy);
+ addOpenNamespace(namespce, nspace, f_proxy);
Clear(proxy_class_def);
Clear(proxy_class_code);
@@ -1797,9 +1856,9 @@ public:
Replaceall(proxy_class_def, "$module", module_class_name);
Replaceall(proxy_class_code, "$module", module_class_name);
Replaceall(proxy_class_constants_code, "$module", module_class_name);
- Replaceall(proxy_class_def, "$imclassname", imclass_name);
- Replaceall(proxy_class_code, "$imclassname", imclass_name);
- Replaceall(proxy_class_constants_code, "$imclassname", imclass_name);
+ Replaceall(proxy_class_def, "$imclassname", full_imclass_name);
+ Replaceall(proxy_class_code, "$imclassname", full_imclass_name);
+ Replaceall(proxy_class_constants_code, "$imclassname", full_imclass_name);
Replaceall(proxy_class_def, "$dllimport", dllimport);
Replaceall(proxy_class_code, "$dllimport", dllimport);
Replaceall(proxy_class_constants_code, "$dllimport", dllimport);
@@ -1811,7 +1870,7 @@ public:
Printv(f_proxy, proxy_class_constants_code, NIL);
Printf(f_proxy, "}\n");
- addCloseNamespace(namespce, f_proxy);
+ addCloseNamespace(namespce, nspace, f_proxy);
Close(f_proxy);
f_proxy = NULL;
@@ -1844,6 +1903,10 @@ public:
Delete(proxy_class_name);
proxy_class_name = NULL;
+ Delete(full_proxy_class_name);
+ full_proxy_class_name = NULL;
+ Delete(full_imclass_name);
+ full_imclass_name = NULL;
Delete(destructor_call);
destructor_call = NULL;
Delete(proxy_class_constants_code);
@@ -1862,7 +1925,7 @@ public:
if (proxy_flag) {
String *overloaded_name = getOverloadedName(n);
- String *intermediary_function_name = Swig_name_member(NSPACE_TODO, proxy_class_name, overloaded_name);
+ String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
Setattr(n, "imfuncname", intermediary_function_name);
proxyClassFunctionHandler(n);
@@ -1882,7 +1945,7 @@ public:
if (proxy_flag) {
String *overloaded_name = getOverloadedName(n);
- String *intermediary_function_name = Swig_name_member(NSPACE_TODO, proxy_class_name, overloaded_name);
+ String *intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
Setattr(n, "imfuncname", intermediary_function_name);
proxyClassFunctionHandler(n);
@@ -1962,7 +2025,7 @@ public:
if (wrapping_member_flag && !enum_constant_flag) {
// Properties
- setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, proxy_class_name, variable_name))) == 0);
+ setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) == 0);
if (setter_flag)
Swig_typemap_attach_parms("csvarin", l, NULL);
}
@@ -2005,7 +2068,7 @@ public:
Printf(function_code, "static ");
Printf(function_code, "%s %s(", return_type, proxy_function_name);
- Printv(imcall, imclass_name, ".$imfuncname(", NIL);
+ Printv(imcall, full_imclass_name, ".$imfuncname(", NIL);
if (!static_flag)
Printf(imcall, "swigCPtr");
@@ -2132,7 +2195,7 @@ public:
Node *explicit_n = Getattr(n, "explicitcallnode");
if (explicit_n) {
String *ex_overloaded_name = getOverloadedName(explicit_n);
- String *ex_intermediary_function_name = Swig_name_member(NSPACE_TODO, proxy_class_name, ex_overloaded_name);
+ String *ex_intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, ex_overloaded_name);
String *ex_imcall = Copy(imcall);
Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
@@ -2250,7 +2313,7 @@ public:
if (proxy_flag) {
String *overloaded_name = getOverloadedName(n);
- String *mangled_overname = Swig_name_construct(NSPACE_TODO, overloaded_name);
+ String *mangled_overname = Swig_name_construct(getNSpace(), overloaded_name);
String *imcall = NewString("");
const String *csattributes = Getattr(n, "feature:cs:attributes");
@@ -2270,7 +2333,7 @@ public:
Printf(function_code, " %s %s(", methodmods, proxy_class_name);
Printf(helper_code, " static private %s SwigConstruct%s(", im_return_type, proxy_class_name);
- Printv(imcall, imclass_name, ".", mangled_overname, "(", NIL);
+ Printv(imcall, full_imclass_name, ".", mangled_overname, "(", NIL);
/* Attach the non-standard typemaps to the parameter list */
Swig_typemap_attach_parms("in", l, NULL);
@@ -2451,7 +2514,7 @@ public:
String *symname = Getattr(n, "sym:name");
if (proxy_flag) {
- Printv(destructor_call, imclass_name, ".", Swig_name_destroy(NSPACE_TODO, symname), "(swigCPtr)", NIL);
+ Printv(destructor_call, full_imclass_name, ".", Swig_name_destroy(getNSpace(), symname), "(swigCPtr)", NIL);
}
return SWIG_OK;
}
@@ -2577,7 +2640,7 @@ public:
if (proxy_flag && global_variable_flag) {
// Capitalize the first letter in the variable to create the getter/setter function name
func_name = NewString("");
- setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(NSPACE_TODO, variable_name)) == 0);
+ setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), variable_name)) == 0);
if (setter_flag)
Printf(func_name, "set");
else
@@ -2848,10 +2911,10 @@ public:
// Strange hack to change the name
Setattr(n, "name", Getattr(n, "value")); /* for wrapping of enums in a namespace when emit_action is used */
constantWrapper(n);
- value = NewStringf("%s.%s()", imclass_name, Swig_name_get(NSPACE_TODO, symname));
+ value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname));
} else {
memberconstantHandler(n);
- value = NewStringf("%s.%s()", imclass_name, Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, proxy_class_name, symname)));
+ value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), Swig_name_member(getNSpace(), proxy_class_name, symname)));
}
}
}
@@ -2863,26 +2926,41 @@ public:
* ----------------------------------------------------------------------------- */
String *getEnumName(SwigType *t) {
- Node *enum_name = NULL;
+ Node *enumname = NULL;
Node *n = enumLookup(t);
if (n) {
- String *symname = Getattr(n, "sym:name");
- if (symname) {
- // Add in class scope when referencing enum if not a global enum
- String *scopename_prefix = Swig_scopename_prefix(Getattr(n, "name"));
- String *proxyname = 0;
- if (scopename_prefix) {
- proxyname = getProxyName(scopename_prefix);
+ enumname = Getattr(n, "enumname");
+ if (!enumname) {
+ String *symname = Getattr(n, "sym:name");
+ if (symname) {
+ // Add in class scope when referencing enum if not a global enum
+ String *scopename_prefix = Swig_scopename_prefix(Getattr(n, "name"));
+ String *proxyname = 0;
+ if (scopename_prefix) {
+ proxyname = getProxyName(scopename_prefix);
+ }
+ if (proxyname) {
+ enumname = NewStringf("%s.%s", proxyname, symname);
+ } else {
+ // global enum or enum in a namespace
+ String *nspace = Getattr(n, "sym:nspace");
+ if (nspace) {
+ if (Len(namespce) > 0)
+ enumname = NewStringf("%s.%s.%s", namespce, nspace, symname);
+ else
+ enumname = NewStringf("%s.%s", nspace, symname);
+ } else {
+ enumname = Copy(symname);
+ }
+ }
+ Setattr(n, "enumname", enumname);
+ Delete(enumname);
+ Delete(scopename_prefix);
}
- if (proxyname)
- enum_name = NewStringf("%s.%s", proxyname, symname);
- else
- enum_name = NewStringf("%s", symname);
- Delete(scopename_prefix);
}
}
- return enum_name;
+ return enumname;
}
/* -----------------------------------------------------------------------------
@@ -3019,7 +3097,7 @@ public:
// Start writing out the type wrapper class file
emitBanner(f_swigtype);
- addOpenNamespace(namespce, f_swigtype);
+ addOpenNamespace(namespce, 0, f_swigtype);
// Pure C# baseclass and interfaces
const String *pure_baseclass = typemapLookup(n, "csbase", type, WARN_NONE);
@@ -3048,7 +3126,7 @@ public:
Printv(f_swigtype, swigtype, NIL);
- addCloseNamespace(namespce, f_swigtype);
+ addCloseNamespace(namespce, 0, f_swigtype);
Close(f_swigtype);
Delete(swigtype);
@@ -3123,22 +3201,53 @@ public:
* addOpenNamespace()
* ----------------------------------------------------------------------------- */
- void addOpenNamespace(String *namspace, File *file) {
- if (namspace)
- if (Len(namspace) > 0)
- Printf(file, "namespace %s {\n", namspace);
+ void addOpenNamespace(const String *namspace, const String *nspace, File *file) {
+ if (namspace) {
+ if (Len(namspace) > 0 || nspace) {
+ Printf(file, "namespace ");
+ if (Len(namspace) > 0)
+ Printv(file, namspace, nspace ? "." : "", NIL);
+ if (nspace)
+ Printv(file, nspace, NIL);
+ Printf(file, " {\n");
+ }
+ }
}
/* -----------------------------------------------------------------------------
* addCloseNamespace()
* ----------------------------------------------------------------------------- */
- void addCloseNamespace(String *namspace, File *file) {
+ void addCloseNamespace(const String *namspace, const String *nspace, File *file) {
if (namspace)
- if (Len(namspace) > 0)
+ if (Len(namspace) > 0 || nspace)
Printf(file, "\n}\n");
}
+ /* -----------------------------------------------------------------------------
+ * outputDirectory()
+ *
+ * Return the directory to use for generating Java classes/enums and create the
+ * subdirectory (does not create if language specific outdir does not exist).
+ * ----------------------------------------------------------------------------- */
+
+ String *outputDirectory(String *nspace) {
+ String *output_directory = Copy(SWIG_output_directory());
+ if (nspace) {
+ String *nspace_subdirectory = Copy(nspace);
+ Replaceall(nspace_subdirectory, ".", SWIG_FILE_DELIMITER);
+ String *newdir_error = Swig_new_subdirectory(output_directory, nspace_subdirectory);
+ if (newdir_error) {
+ Printf(stderr, "%s\n", newdir_error);
+ Delete(newdir_error);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0);
+ Delete(nspace_subdirectory);
+ }
+ return output_directory;
+ }
+
/*----------------------------------------------------------------------
* Start of director methods
*--------------------------------------------------------------------*/
@@ -3189,7 +3298,7 @@ public:
// Output the director connect method:
String *norm_name = SwigType_namestr(Getattr(n, "name"));
- String *swig_director_connect = NewStringf("%s_director_connect", proxy_class_name);
+ String *swig_director_connect = Swig_name_member(getNSpace(), proxy_class_name, "director_connect");
String *sym_name = Getattr(n, "sym:name");
Wrapper *code_wrap;
@@ -3279,7 +3388,7 @@ public:
// we're consistent with the sym:overload name in functionWrapper. (?? when
// does the overloaded method name get set?)
- imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(NSPACE_TODO, classname, overloaded_name));
+ imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), classname, overloaded_name));
if (returntype) {