[D] nspace support.
As for C# and Java, this doesn't work for free functions/variables yet. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12534 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
a63cde3827
commit
ce6516fb4c
13 changed files with 757 additions and 164 deletions
|
|
@ -28,6 +28,7 @@
|
||||||
<li><a href="#D_directors">D Directors</a>
|
<li><a href="#D_directors">D Directors</a>
|
||||||
<li><a href="#D_other_features">Other features</a>
|
<li><a href="#D_other_features">Other features</a>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li><a href="#D_nspace">Extended namespace support (<tt>nspace</tt>)</a></li>
|
||||||
<li><a href="#D_native_pointer_support">Native pointer support</a>
|
<li><a href="#D_native_pointer_support">Native pointer support</a>
|
||||||
<li><a href="#D_operator_overloading">Operator overloading</a>
|
<li><a href="#D_operator_overloading">Operator overloading</a>
|
||||||
<li><a href="#D_test_suite">Running the test-suite</a>
|
<li><a href="#D_test_suite">Running the test-suite</a>
|
||||||
|
|
@ -187,6 +188,12 @@
|
||||||
<p>There are two other variants available, <tt>$&dclassname</tt> and <tt>$*dclassname</tt>. The former adds a level of indirection, while the latter removes one. For instance, when wrapping <tt>Foo **</tt>, <tt>$*dclassname</tt> would be replaced by the proxy class name corresponding to <tt>Foo *</tt>.</p>
|
<p>There are two other variants available, <tt>$&dclassname</tt> and <tt>$*dclassname</tt>. The former adds a level of indirection, while the latter removes one. For instance, when wrapping <tt>Foo **</tt>, <tt>$*dclassname</tt> would be replaced by the proxy class name corresponding to <tt>Foo *</tt>.</p>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
|
<dt><tt>$dclazzname</tt> (C#: <tt>$csclazzname</tt>)</dt>
|
||||||
|
<dd>
|
||||||
|
<p>This special variable expands the fully qualified C++ class into the package name, if used by the <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt> feature</a>, and the proxy class name, mangled for use as a function name. For example, <tt>Namespace1::Namespace2::Klass</tt> is expanded into <tt>Namespace1_Namespace2_Klass_</tt>.</p>
|
||||||
|
<p>This special variable might be useful for calling certain functions in the wrapper layer (e.g. upcast wrappers) which are mangled like this.</p>
|
||||||
|
</dd>
|
||||||
|
|
||||||
<dt><tt>$null</tt></dt>
|
<dt><tt>$null</tt></dt>
|
||||||
<dd><p>In code inserted into the generated C/C++ wrapper functions, this variable is replaced by either <tt>0</tt> or nothing at all, depending on whether the function has a return value or not. It can be used to bail out early e.g. in case of errors (<tt>return $null;</tt>).</p></dd>
|
<dd><p>In code inserted into the generated C/C++ wrapper functions, this variable is replaced by either <tt>0</tt> or nothing at all, depending on whether the function has a return value or not. It can be used to bail out early e.g. in case of errors (<tt>return $null;</tt>).</p></dd>
|
||||||
|
|
||||||
|
|
@ -331,7 +338,7 @@ struct A {
|
||||||
<dd><p>Additional code to be emitted to the imports section of the intermediary D module (the <a href="D.html#D_importtype">$importtype</a> macro can be used here). You probably want to use this in conjunction with the <tt>imdmodulecode</tt> pragma.</p></dd>
|
<dd><p>Additional code to be emitted to the imports section of the intermediary D module (the <a href="D.html#D_importtype">$importtype</a> macro can be used here). You probably want to use this in conjunction with the <tt>imdmodulecode</tt> pragma.</p></dd>
|
||||||
|
|
||||||
<dt><tt>%pragma(d) proxydmodulecode</tt></dt>
|
<dt><tt>%pragma(d) proxydmodulecode</tt></dt>
|
||||||
<dd><p>Just like <tt>proxydmodulecode</tt>, the argument is copied to the proxy D module (if SWIG is in <a href="D.html#D_splitproxy">split proxy mode</a>, it is emitted to the main proxy D module only).</p></dd>
|
<dd><p>Just like <tt>proxydmodulecode</tt>, the argument is copied to the proxy D module (if SWIG is in <a href="D.html#D_splitproxy">split proxy mode</a> and/or the <tt>nspace</tt> feature is used, it is emitted to the main proxy D module only).</p></dd>
|
||||||
|
|
||||||
<dt><tt>%pragma(d) globalproxyimports</tt></dt>
|
<dt><tt>%pragma(d) globalproxyimports</tt></dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
|
@ -379,10 +386,13 @@ struct A {
|
||||||
<H2><a name="D_other_features"></a>20.8 Other features</H2>
|
<H2><a name="D_other_features"></a>20.8 Other features</H2>
|
||||||
|
|
||||||
|
|
||||||
<p>The <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt></a> feature of SWIG is not yet supported for D - all class modules are written to the same package, regardless of which C++ namespace they are in.</p>
|
<H3><a name="D_nspace"></a>20.8.1 Extended namespace support (<tt>nspace</tt>)</H3>
|
||||||
|
|
||||||
|
|
||||||
<H3><a name="D_native_pointer_support"></a>20.8.1 Native pointer support</H3>
|
<p>By default, SWIG flattens all C++ namespaces into a single target language namespace, but as for Java and C#, the <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt></a> feature is supported for D. If it is active, C++ namespaces are mapped to D packages/modules. Note, however, that like for the other languages, <em>free</em> variables and functions are not supported yet; currently, they are all allows written to the main proxy D module.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<H3><a name="D_native_pointer_support"></a>20.8.2 Native pointer support</H3>
|
||||||
|
|
||||||
|
|
||||||
<p>Contrary to many of the scripting languages supported by SWIG, D fully supports C-style pointers. The D module thus includes a custom mechanism to wrap C pointers directly as D pointers where applicable, that is, if the type that is pointed to is represented the same in C and D (on the bit-level), dubbed a »primtive type« below.</p>
|
<p>Contrary to many of the scripting languages supported by SWIG, D fully supports C-style pointers. The D module thus includes a custom mechanism to wrap C pointers directly as D pointers where applicable, that is, if the type that is pointed to is represented the same in C and D (on the bit-level), dubbed a »primtive type« below.</p>
|
||||||
|
|
@ -394,7 +404,7 @@ struct A {
|
||||||
<p>To determine if a type should be considered primitive, the <tt>cprimitive</tt> attribute on its <tt>dtype</tt> attribute is used. For example, the <tt>dtype</tt> typemap for <tt>float</tt> has <tt>cprimitive="1"</tt>, so the code from the <tt>nativepointer</tt> attribute is taken into account e.g. for <tt>float **</tt> or the function pointer <tt>float (*)(float *)</tt>.</p>
|
<p>To determine if a type should be considered primitive, the <tt>cprimitive</tt> attribute on its <tt>dtype</tt> attribute is used. For example, the <tt>dtype</tt> typemap for <tt>float</tt> has <tt>cprimitive="1"</tt>, so the code from the <tt>nativepointer</tt> attribute is taken into account e.g. for <tt>float **</tt> or the function pointer <tt>float (*)(float *)</tt>.</p>
|
||||||
|
|
||||||
|
|
||||||
<H3><a name="D_operator_overloading"></a>20.8.2 Operator overloading</H3>
|
<H3><a name="D_operator_overloading"></a>20.8.3 Operator overloading</H3>
|
||||||
|
|
||||||
|
|
||||||
<p>The D module comes with basic operator overloading support for both D1 and D2. There are, however, a few limitations arising from conceptual differences between C++ and D:</p>
|
<p>The D module comes with basic operator overloading support for both D1 and D2. There are, however, a few limitations arising from conceptual differences between C++ and D:</p>
|
||||||
|
|
@ -406,7 +416,7 @@ struct A {
|
||||||
<p>There are also some cases where the operators can be translated to D, but the differences in the implementation details are big enough that a rather involved scheme would be required for automatic wrapping them, which has not been implemented yet. This affects, for example, the array subscript operator, <tt>[]</tt>, in combination with assignments - while <tt>operator []</tt> in C++ simply returns a reference which is then written to, D resorts to a separate <tt>opIndexAssign</tt> method -, or implicit casting (which was introduced in D2 via <tt>alias this</tt>). Despite the lack of automatic support, manually handling these cases should be perfectly possible.</p>
|
<p>There are also some cases where the operators can be translated to D, but the differences in the implementation details are big enough that a rather involved scheme would be required for automatic wrapping them, which has not been implemented yet. This affects, for example, the array subscript operator, <tt>[]</tt>, in combination with assignments - while <tt>operator []</tt> in C++ simply returns a reference which is then written to, D resorts to a separate <tt>opIndexAssign</tt> method -, or implicit casting (which was introduced in D2 via <tt>alias this</tt>). Despite the lack of automatic support, manually handling these cases should be perfectly possible.</p>
|
||||||
|
|
||||||
|
|
||||||
<H3><a name="D_test_suite"></a>20.8.3 Running the test-suite</H3>
|
<H3><a name="D_test_suite"></a>20.8.4 Running the test-suite</H3>
|
||||||
|
|
||||||
|
|
||||||
<p>As with any other language, the SWIG test-suite can be built for D using the <tt>*-d-test-suite</tt> targets of the top-level Makefile. By default, D1 is targeted, to build it with D2, use the optional <tt>D_VERSION</tt> variable, e.g. <tt>make check-d-test-suite D_VERSION=2</tt>.</p>
|
<p>As with any other language, the SWIG test-suite can be built for D using the <tt>*-d-test-suite</tt> targets of the top-level Makefile. By default, D1 is targeted, to build it with D2, use the optional <tt>D_VERSION</tt> variable, e.g. <tt>make check-d-test-suite D_VERSION=2</tt>.</p>
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ public class runme
|
||||||
throw new ApplicationException("Transmission2 wrong");
|
throw new ApplicationException("Transmission2 wrong");
|
||||||
|
|
||||||
// turn feature off / ignoring
|
// turn feature off / ignoring
|
||||||
nspaceNamespace.Outer.nspace ns = new nspaceNamespace.Outer.nspace();
|
nspaceNamespace.Outer.namespce ns = new nspaceNamespace.Outer.namespce();
|
||||||
ns.Dispose();
|
ns.Dispose();
|
||||||
nspaceNamespace.NoNSpacePlease nons = new nspaceNamespace.NoNSpacePlease();
|
nspaceNamespace.NoNSpacePlease nons = new nspaceNamespace.NoNSpacePlease();
|
||||||
nons.Dispose();
|
nons.Dispose();
|
||||||
|
|
|
||||||
|
|
@ -65,13 +65,13 @@ run_testcase = \
|
||||||
cd $*$(VERSIONSUFFIX) && \
|
cd $*$(VERSIONSUFFIX) && \
|
||||||
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \
|
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \
|
||||||
DFLAGS='-of$*_runme' \
|
DFLAGS='-of$*_runme' \
|
||||||
DSRCS='../$(srcdir)/$(TESTPREFIX)$*$(TESTSUFFIX) $*/*.d' d_compile && \
|
DSRCS='../$(srcdir)/$(TESTPREFIX)$*$(TESTSUFFIX) `find $* -name *.d`' d_compile && \
|
||||||
env LD_LIBRARY_PATH=".:$$LD_LIBRARY_PATH" $(RUNTOOL) ./$*_runme; \
|
env LD_LIBRARY_PATH=".:$$LD_LIBRARY_PATH" $(RUNTOOL) ./$*_runme; \
|
||||||
else \
|
else \
|
||||||
cd $*$(VERSIONSUFFIX) && \
|
cd $*$(VERSIONSUFFIX) && \
|
||||||
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \
|
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \
|
||||||
DFLAGS='-c' \
|
DFLAGS='-c' \
|
||||||
DSRCS='$*/*.d' d_compile && cd .. ; \
|
DSRCS='`find $* -name *.d`' d_compile && cd .. ; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Clean: remove testcase directories
|
# Clean: remove testcase directories
|
||||||
|
|
|
||||||
32
Examples/test-suite/d/nspace_extend_runme.1.d
Normal file
32
Examples/test-suite/d/nspace_extend_runme.1.d
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
module nspace_extend_runme;
|
||||||
|
|
||||||
|
static import oi1c = nspace_extend.Outer.Inner1.Color;
|
||||||
|
static import oi2c = nspace_extend.Outer.Inner2.Color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
{
|
||||||
|
// constructors and destructors
|
||||||
|
scope color1 = new oi1c.Color();
|
||||||
|
scope color = new oi1c.Color(color1);
|
||||||
|
|
||||||
|
// class methods
|
||||||
|
color.colorInstanceMethod(20.0);
|
||||||
|
oi1c.Color.colorStaticMethod(20.0);
|
||||||
|
auto created = oi1c.Color.create();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// constructors and destructors
|
||||||
|
scope color2 = new oi2c.Color();
|
||||||
|
scope color = new oi2c.Color(color2);
|
||||||
|
|
||||||
|
// class methods
|
||||||
|
color.colorInstanceMethod(20.0);
|
||||||
|
oi2c.Color.colorStaticMethod(20.0);
|
||||||
|
auto created = oi2c.Color.create();
|
||||||
|
|
||||||
|
// Same class different namespaces
|
||||||
|
auto col1 = new oi1c.Color();
|
||||||
|
auto col2 = oi2c.Color.create();
|
||||||
|
col2.colors(col1, col1, col2, col2, col2);
|
||||||
|
}
|
||||||
|
}
|
||||||
32
Examples/test-suite/d/nspace_extend_runme.2.d
Normal file
32
Examples/test-suite/d/nspace_extend_runme.2.d
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
module nspace_extend_runme;
|
||||||
|
|
||||||
|
static import oi1c = nspace_extend.Outer.Inner1.Color;
|
||||||
|
static import oi2c = nspace_extend.Outer.Inner2.Color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
{
|
||||||
|
// constructors and destructors
|
||||||
|
scope color1 = new oi1c.Color();
|
||||||
|
scope color = new oi1c.Color(color1);
|
||||||
|
|
||||||
|
// class methods
|
||||||
|
color.colorInstanceMethod(20.0);
|
||||||
|
oi1c.Color.colorStaticMethod(20.0);
|
||||||
|
auto created = oi1c.Color.create();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// constructors and destructors
|
||||||
|
scope color2 = new oi2c.Color();
|
||||||
|
scope color = new oi2c.Color(color2);
|
||||||
|
|
||||||
|
// class methods
|
||||||
|
color.colorInstanceMethod(20.0);
|
||||||
|
oi2c.Color.colorStaticMethod(20.0);
|
||||||
|
auto created = oi2c.Color.create();
|
||||||
|
|
||||||
|
// Same class different namespaces
|
||||||
|
auto col1 = new oi1c.Color();
|
||||||
|
auto col2 = oi2c.Color.create();
|
||||||
|
col2.colors(col1, col1, col2, col2, col2);
|
||||||
|
}
|
||||||
|
}
|
||||||
87
Examples/test-suite/d/nspace_runme.1.d
Normal file
87
Examples/test-suite/d/nspace_runme.1.d
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
module nspace_runme;
|
||||||
|
|
||||||
|
import nspace.nspace;
|
||||||
|
static import nspace.NoNSpacePlease;
|
||||||
|
static import nspace.Outer.namespce;
|
||||||
|
static import nspace.Outer.Inner1.Channel;
|
||||||
|
static import oi1c = nspace.Outer.Inner1.Color;
|
||||||
|
static import nspace.Outer.Inner2.Channel;
|
||||||
|
static import nspace.Outer.Inner2.Color;
|
||||||
|
static import nspace.Outer.Inner3.Blue;
|
||||||
|
static import nspace.Outer.Inner4.Blue;
|
||||||
|
static import nspace.Outer.SomeClass;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// constructors and destructors
|
||||||
|
auto color1 = new oi1c.Color();
|
||||||
|
auto color = new oi1c.Color(color1);
|
||||||
|
|
||||||
|
// class methods
|
||||||
|
color.colorInstanceMethod(20.0);
|
||||||
|
oi1c.Color.colorStaticMethod(20.0);
|
||||||
|
auto created = oi1c.Color.create();
|
||||||
|
|
||||||
|
// class enums
|
||||||
|
auto someClass = new nspace.Outer.SomeClass.SomeClass();
|
||||||
|
auto channel = someClass.GetInner1ColorChannel();
|
||||||
|
if (channel != oi1c.Color.Channel.Transmission) {
|
||||||
|
throw new Exception("Transmission wrong");
|
||||||
|
}
|
||||||
|
|
||||||
|
// class anonymous enums
|
||||||
|
int val1 = oi1c.Color.ColorEnumVal1;
|
||||||
|
int val2 = oi1c.Color.ColorEnumVal2;
|
||||||
|
if (val1 != 0 || val2 != 0x22) {
|
||||||
|
throw new Exception("ColorEnumVal wrong");
|
||||||
|
}
|
||||||
|
|
||||||
|
// instance member variables
|
||||||
|
color.instanceMemberVariable = 123;
|
||||||
|
if (color.instanceMemberVariable != 123) {
|
||||||
|
throw new Exception("instance member variable failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// static member variables
|
||||||
|
oi1c.Color.staticMemberVariable = 789;
|
||||||
|
if (oi1c.Color.staticMemberVariable != 789) {
|
||||||
|
throw new Exception("static member variable failed");
|
||||||
|
}
|
||||||
|
if (oi1c.Color.staticConstMemberVariable != 222) {
|
||||||
|
throw new Exception("static const member variable failed");
|
||||||
|
}
|
||||||
|
if (oi1c.Color.staticConstEnumMemberVariable != oi1c.Color.Channel.Transmission) {
|
||||||
|
throw new Exception("static const enum member variable failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check globals in a namespace don't get mangled with the nspace option
|
||||||
|
nspace.nspace.namespaceFunction(color);
|
||||||
|
nspace.nspace.namespaceVar = 111;
|
||||||
|
if (nspace.nspace.namespaceVar != 111) {
|
||||||
|
throw new Exception("global var failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same class different namespaces
|
||||||
|
auto col1 = new oi1c.Color();
|
||||||
|
auto col2 = nspace.Outer.Inner2.Color.Color.create();
|
||||||
|
col2.colors(col1, col1, col2, col2, col2);
|
||||||
|
|
||||||
|
// global enums
|
||||||
|
auto outerChannel1 = someClass.GetInner1Channel();
|
||||||
|
if (outerChannel1 != nspace.Outer.Inner1.Channel.Channel.Transmission1) {
|
||||||
|
throw new Exception("Transmission1 wrong");
|
||||||
|
}
|
||||||
|
auto outerChannel2 = someClass.GetInner2Channel();
|
||||||
|
if (outerChannel2 != nspace.Outer.Inner2.Channel.Channel.Transmission2) {
|
||||||
|
throw new Exception("Transmission2 wrong");
|
||||||
|
}
|
||||||
|
|
||||||
|
// turn feature off / ignoring
|
||||||
|
auto ns = new nspace.Outer.namespce.namespce();
|
||||||
|
auto nons = new nspace.NoNSpacePlease.NoNSpacePlease();
|
||||||
|
|
||||||
|
// Derived class
|
||||||
|
auto blue3 = new nspace.Outer.Inner3.Blue.Blue();
|
||||||
|
blue3.blueInstanceMethod();
|
||||||
|
auto blue4 = new nspace.Outer.Inner4.Blue.Blue();
|
||||||
|
blue4.blueInstanceMethod();
|
||||||
|
}
|
||||||
77
Examples/test-suite/d/nspace_runme.2.d
Normal file
77
Examples/test-suite/d/nspace_runme.2.d
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
module nspace_runme;
|
||||||
|
|
||||||
|
import std.exception;
|
||||||
|
import nspace.nspace;
|
||||||
|
static import nspace.NoNSpacePlease;
|
||||||
|
static import nspace.Outer.namespce;
|
||||||
|
static import nspace.Outer.Inner1.Channel;
|
||||||
|
static import oi1c = nspace.Outer.Inner1.Color;
|
||||||
|
static import nspace.Outer.Inner2.Channel;
|
||||||
|
static import nspace.Outer.Inner2.Color;
|
||||||
|
static import nspace.Outer.Inner3.Blue;
|
||||||
|
static import nspace.Outer.Inner4.Blue;
|
||||||
|
static import nspace.Outer.SomeClass;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// constructors and destructors
|
||||||
|
auto color1 = new oi1c.Color();
|
||||||
|
auto color = new oi1c.Color(color1);
|
||||||
|
|
||||||
|
// class methods
|
||||||
|
color.colorInstanceMethod(20.0);
|
||||||
|
oi1c.Color.colorStaticMethod(20.0);
|
||||||
|
auto created = oi1c.Color.create();
|
||||||
|
|
||||||
|
// class enums
|
||||||
|
auto someClass = new nspace.Outer.SomeClass.SomeClass();
|
||||||
|
auto channel = someClass.GetInner1ColorChannel();
|
||||||
|
enforce(channel == oi1c.Color.Channel.Transmission,
|
||||||
|
"Transmission wrong");
|
||||||
|
|
||||||
|
// class anonymous enums
|
||||||
|
int val1 = oi1c.Color.ColorEnumVal1;
|
||||||
|
int val2 = oi1c.Color.ColorEnumVal2;
|
||||||
|
enforce(val1 == 0 && val2 == 0x22, "ColorEnumVal wrong");
|
||||||
|
|
||||||
|
// instance member variables
|
||||||
|
color.instanceMemberVariable = 123;
|
||||||
|
enforce(color.instanceMemberVariable == 123,
|
||||||
|
"instance member variable failed");
|
||||||
|
|
||||||
|
// static member variables
|
||||||
|
oi1c.Color.staticMemberVariable = 789;
|
||||||
|
enforce(oi1c.Color.staticMemberVariable == 789,
|
||||||
|
"static member variable failed");
|
||||||
|
enforce(oi1c.Color.staticConstMemberVariable == 222,
|
||||||
|
"static const member variable failed");
|
||||||
|
enforce(oi1c.Color.staticConstEnumMemberVariable == oi1c.Color.Channel.Transmission,
|
||||||
|
"static const enum member variable failed");
|
||||||
|
|
||||||
|
// check globals in a namespace don't get mangled with the nspace option
|
||||||
|
nspace.nspace.namespaceFunction(color);
|
||||||
|
nspace.nspace.namespaceVar = 111;
|
||||||
|
enforce(nspace.nspace.namespaceVar == 111, "global var failed");
|
||||||
|
|
||||||
|
// Same class different namespaces
|
||||||
|
auto col1 = new oi1c.Color();
|
||||||
|
auto col2 = nspace.Outer.Inner2.Color.Color.create();
|
||||||
|
col2.colors(col1, col1, col2, col2, col2);
|
||||||
|
|
||||||
|
// global enums
|
||||||
|
auto outerChannel1 = someClass.GetInner1Channel();
|
||||||
|
enforce(outerChannel1 == nspace.Outer.Inner1.Channel.Channel.Transmission1,
|
||||||
|
"Transmission1 wrong");
|
||||||
|
auto outerChannel2 = someClass.GetInner2Channel();
|
||||||
|
enforce(outerChannel2 == nspace.Outer.Inner2.Channel.Channel.Transmission2,
|
||||||
|
"Transmission2 wrong");
|
||||||
|
|
||||||
|
// turn feature off / ignoring
|
||||||
|
auto ns = new nspace.Outer.namespce.namespce();
|
||||||
|
auto nons = new nspace.NoNSpacePlease.NoNSpacePlease();
|
||||||
|
|
||||||
|
// Derived class
|
||||||
|
auto blue3 = new nspace.Outer.Inner3.Blue.Blue();
|
||||||
|
blue3.blueInstanceMethod();
|
||||||
|
auto blue4 = new nspace.Outer.Inner4.Blue.Blue();
|
||||||
|
blue4.blueInstanceMethod();
|
||||||
|
}
|
||||||
|
|
@ -68,7 +68,7 @@ public class nspace_runme {
|
||||||
throw new RuntimeException("Transmission2 wrong");
|
throw new RuntimeException("Transmission2 wrong");
|
||||||
|
|
||||||
// turn feature off / ignoring
|
// turn feature off / ignoring
|
||||||
nspacePackage.Outer.nspace ns = new nspacePackage.Outer.nspace();
|
nspacePackage.Outer.namespce ns = new nspacePackage.Outer.namespce();
|
||||||
nspacePackage.NoNSpacePlease nons = new nspacePackage.NoNSpacePlease();
|
nspacePackage.NoNSpacePlease nons = new nspacePackage.NoNSpacePlease();
|
||||||
|
|
||||||
// Derived class
|
// Derived class
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
%module nspace
|
%module nspace
|
||||||
|
|
||||||
// nspace feature only supported by these languages
|
// nspace feature only supported by these languages
|
||||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
|
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD)
|
||||||
|
|
||||||
%nspace;
|
%nspace;
|
||||||
%nonspace Outer::Inner2::NoNSpacePlease;
|
%nonspace Outer::Inner2::NoNSpacePlease;
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
||||||
namespace Outer {
|
namespace Outer {
|
||||||
class nspace {
|
class namespce {
|
||||||
};
|
};
|
||||||
namespace Inner1 {
|
namespace Inner1 {
|
||||||
enum Channel { Diffuse, Specular = 0x10, Transmission1 };
|
enum Channel { Diffuse, Specular = 0x10, Transmission1 };
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
%module nspace_extend
|
%module nspace_extend
|
||||||
|
|
||||||
// nspace feature only supported by these languages
|
// nspace feature only supported by these languages
|
||||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP)
|
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD)
|
||||||
|
|
||||||
%nspace;
|
%nspace;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ private void* swigCPtr;
|
||||||
private bool swigCMemOwn;
|
private bool swigCMemOwn;
|
||||||
|
|
||||||
public this(void* cObject, bool ownCObject) {
|
public this(void* cObject, bool ownCObject) {
|
||||||
super($imdmodule.$dclassnameSmartPtrUpcast(cObject), ownCObject);
|
super($imdmodule.$dclazznameSmartPtrUpcast(cObject), ownCObject);
|
||||||
swigCPtr = cObject;
|
swigCPtr = cObject;
|
||||||
swigCMemOwn = ownCObject;
|
swigCMemOwn = ownCObject;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ mixin $imdmodule.SwigOperatorDefinitions;
|
||||||
private void* swigCPtr;
|
private void* swigCPtr;
|
||||||
|
|
||||||
public this(void* cObject, bool ownCObject) {
|
public this(void* cObject, bool ownCObject) {
|
||||||
super($imdmodule.$dclassnameUpcast(cObject), ownCObject);
|
super($imdmodule.$dclazznameUpcast(cObject), ownCObject);
|
||||||
swigCPtr = cObject;
|
swigCPtr = cObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,23 +132,37 @@ class D : public Language {
|
||||||
// %pragma(d) globalproxyimports.
|
// %pragma(d) globalproxyimports.
|
||||||
String *global_proxy_imports;
|
String *global_proxy_imports;
|
||||||
|
|
||||||
// Imports written to the proxy D module header from global_proxy_imports
|
// The D code for the main proxy modules. nspace_proxy_dmodules is a hash from
|
||||||
// and, if in split proxy module mode, from D::requireDType().
|
// the namespace name as key to an {"imports", "code"}. If the nspace feature
|
||||||
|
// is not active, only proxy_dmodule_imports and proxy_dmodule_code are used,
|
||||||
|
// which contain the code for the root proxy module.
|
||||||
|
//
|
||||||
|
// These variables should not be accessed directly but rather via the
|
||||||
|
// proxy{Imports, Code}Buffer)() helper functions which return the right
|
||||||
|
// buffer for a given namespace. If not in split proxy mode, they contain the
|
||||||
|
// whole proxy code.
|
||||||
String *proxy_dmodule_imports;
|
String *proxy_dmodule_imports;
|
||||||
|
|
||||||
// The D code for proxy functions/classes which is written to the proxy D
|
|
||||||
// module. If not in split proxy mode, this contains the whole proxy code.
|
|
||||||
String *proxy_dmodule_code;
|
String *proxy_dmodule_code;
|
||||||
|
Hash *nspace_proxy_dmodules;
|
||||||
|
|
||||||
// The D code generated for the currently processed enum.
|
// The D code generated for the currently processed enum.
|
||||||
String *proxy_enum_code;
|
String *proxy_enum_code;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* D data for the current proxy class.
|
* D data for the current proxy class.
|
||||||
|
*
|
||||||
|
* These strings are mainly used to temporarily accumulate code from the
|
||||||
|
* various member handling functions while a single class is processed and are
|
||||||
|
* no longer relevant once that class has been finished, i.e. after
|
||||||
|
* classHandler() has returned.
|
||||||
*/
|
*/
|
||||||
// The name of the current proxy class.
|
// The unqualified name of the current proxy class.
|
||||||
String *proxy_class_name;
|
String *proxy_class_name;
|
||||||
|
|
||||||
|
// The name of the current proxy class, qualified with the name of the
|
||||||
|
// namespace it is in, if any.
|
||||||
|
String *proxy_class_qname;
|
||||||
|
|
||||||
// The import directives for the current proxy class. They are written to the
|
// The import directives for the current proxy class. They are written to the
|
||||||
// same D module the proxy class is written to.
|
// same D module the proxy class is written to.
|
||||||
String *proxy_class_imports;
|
String *proxy_class_imports;
|
||||||
|
|
@ -243,8 +257,10 @@ public:
|
||||||
global_proxy_imports(NULL),
|
global_proxy_imports(NULL),
|
||||||
proxy_dmodule_imports(NULL),
|
proxy_dmodule_imports(NULL),
|
||||||
proxy_dmodule_code(NULL),
|
proxy_dmodule_code(NULL),
|
||||||
|
nspace_proxy_dmodules(NULL),
|
||||||
proxy_enum_code(NULL),
|
proxy_enum_code(NULL),
|
||||||
proxy_class_name(NULL),
|
proxy_class_name(NULL),
|
||||||
|
proxy_class_qname(NULL),
|
||||||
proxy_class_imports(NULL),
|
proxy_class_imports(NULL),
|
||||||
proxy_class_enums_code(NULL),
|
proxy_class_enums_code(NULL),
|
||||||
proxy_class_body_code(NULL),
|
proxy_class_body_code(NULL),
|
||||||
|
|
@ -439,6 +455,7 @@ public:
|
||||||
destructor_call = NewString("");
|
destructor_call = NewString("");
|
||||||
proxy_dmodule_code = NewString("");
|
proxy_dmodule_code = NewString("");
|
||||||
proxy_dmodule_imports = NewString("");
|
proxy_dmodule_imports = NewString("");
|
||||||
|
nspace_proxy_dmodules = NewHash();
|
||||||
im_dmodule_imports = NewString("");
|
im_dmodule_imports = NewString("");
|
||||||
upcasts_code = NewString("");
|
upcasts_code = NewString("");
|
||||||
global_proxy_imports = NewString("");
|
global_proxy_imports = NewString("");
|
||||||
|
|
@ -524,7 +541,7 @@ public:
|
||||||
Close(im_d_file);
|
Close(im_d_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the D proxy module for the wrapped module.
|
// Generate the main D proxy module.
|
||||||
{
|
{
|
||||||
String *filen = NewStringf("%s%s.d", dmodule_directory, proxy_dmodule_name);
|
String *filen = NewStringf("%s%s.d", dmodule_directory, proxy_dmodule_name);
|
||||||
File *proxy_d_file = NewFile(filen, "w", SWIG_output_files());
|
File *proxy_d_file = NewFile(filen, "w", SWIG_output_files());
|
||||||
|
|
@ -557,6 +574,34 @@ public:
|
||||||
Close(proxy_d_file);
|
Close(proxy_d_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate the additional proxy modules for nspace support.
|
||||||
|
for (Iterator it = First(nspace_proxy_dmodules); it.key; it = Next(it)) {
|
||||||
|
String *module_name = createLastNamespaceName(it.key);
|
||||||
|
|
||||||
|
String *filename = NewStringf("%s%s.d", outputDirectory(it.key), module_name);
|
||||||
|
File *file = NewFile(filename, "w", SWIG_output_files());
|
||||||
|
if (!file) {
|
||||||
|
FileErrorDisplay(filename);
|
||||||
|
SWIG_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
Delete(filename);
|
||||||
|
|
||||||
|
emitBanner(file);
|
||||||
|
|
||||||
|
Printf(file, "module %s%s.%s;\n", package, it.key, module_name);
|
||||||
|
Printf(file, "\nstatic import %s;\n", im_dmodule_fq_name);
|
||||||
|
Printv(file, global_proxy_imports, NIL);
|
||||||
|
Printv(file, Getattr(it.item, "imports"), NIL);
|
||||||
|
Printv(file, "\n", NIL);
|
||||||
|
|
||||||
|
String *code = Getattr(it.item, "code");
|
||||||
|
replaceModuleVariables(code);
|
||||||
|
Printv(file, code, NIL);
|
||||||
|
|
||||||
|
Close(file);
|
||||||
|
Delete(module_name);
|
||||||
|
}
|
||||||
|
|
||||||
if (upcasts_code)
|
if (upcasts_code)
|
||||||
Printv(f_wrappers, upcasts_code, NIL);
|
Printv(f_wrappers, upcasts_code, NIL);
|
||||||
|
|
||||||
|
|
@ -613,6 +658,8 @@ public:
|
||||||
proxy_dmodule_code = NULL;
|
proxy_dmodule_code = NULL;
|
||||||
Delete(proxy_dmodule_imports);
|
Delete(proxy_dmodule_imports);
|
||||||
proxy_dmodule_imports = NULL;
|
proxy_dmodule_imports = NULL;
|
||||||
|
Delete(nspace_proxy_dmodules);
|
||||||
|
nspace_proxy_dmodules = NULL;
|
||||||
Delete(im_dmodule_imports);
|
Delete(im_dmodule_imports);
|
||||||
im_dmodule_imports = NULL;
|
im_dmodule_imports = NULL;
|
||||||
Delete(upcasts_code);
|
Delete(upcasts_code);
|
||||||
|
|
@ -709,7 +756,7 @@ public:
|
||||||
Chop(strvalue);
|
Chop(strvalue);
|
||||||
Printf(im_dmodule_imports, "%s\n", strvalue);
|
Printf(im_dmodule_imports, "%s\n", strvalue);
|
||||||
} else if (Strcmp(code, "proxydmodulecode") == 0) {
|
} else if (Strcmp(code, "proxydmodulecode") == 0) {
|
||||||
Printf(proxy_dmodule_code, "%s\n", strvalue);
|
Printf(proxyCodeBuffer(0), "%s\n", strvalue);
|
||||||
} else if (Strcmp(code, "globalproxyimports") == 0) {
|
} else if (Strcmp(code, "globalproxyimports") == 0) {
|
||||||
replaceImportTypeMacros(strvalue);
|
replaceImportTypeMacros(strvalue);
|
||||||
Chop(strvalue);
|
Chop(strvalue);
|
||||||
|
|
@ -798,7 +845,11 @@ public:
|
||||||
if (split_proxy_dmodule && typemap_lookup_type) {
|
if (split_proxy_dmodule && typemap_lookup_type) {
|
||||||
assertClassNameValidity(proxy_class_name);
|
assertClassNameValidity(proxy_class_name);
|
||||||
|
|
||||||
String *filename = NewStringf("%s%s.d", dmodule_directory, symname);
|
String *nspace = Getattr(n, "sym:nspace");
|
||||||
|
String *output_directory = outputDirectory(nspace);
|
||||||
|
String *filename = NewStringf("%s%s.d", output_directory, symname);
|
||||||
|
Delete(output_directory);
|
||||||
|
|
||||||
File *class_file = NewFile(filename, "w", SWIG_output_files());
|
File *class_file = NewFile(filename, "w", SWIG_output_files());
|
||||||
if (!class_file) {
|
if (!class_file) {
|
||||||
FileErrorDisplay(filename);
|
FileErrorDisplay(filename);
|
||||||
|
|
@ -808,7 +859,11 @@ public:
|
||||||
Delete(filename);
|
Delete(filename);
|
||||||
|
|
||||||
emitBanner(class_file);
|
emitBanner(class_file);
|
||||||
Printf(class_file, "module %s%s;\n", package, symname);
|
if (nspace) {
|
||||||
|
Printf(class_file, "module %s%s.%s;\n", package, nspace, symname);
|
||||||
|
} else {
|
||||||
|
Printf(class_file, "module %s%s;\n", package, symname);
|
||||||
|
}
|
||||||
Printv(class_file, imports_trimmed, NIL);
|
Printv(class_file, imports_trimmed, NIL);
|
||||||
|
|
||||||
Printv(class_file, proxy_enum_code, NIL);
|
Printv(class_file, proxy_enum_code, NIL);
|
||||||
|
|
@ -816,8 +871,9 @@ public:
|
||||||
Close(class_file);
|
Close(class_file);
|
||||||
Delete(class_file);
|
Delete(class_file);
|
||||||
} else {
|
} else {
|
||||||
Printv(proxy_dmodule_imports, imports, NIL);
|
String *nspace = Getattr(n, "sym:nspace");
|
||||||
Printv(proxy_dmodule_code, proxy_enum_code, NIL);
|
Printv(proxyImportsBuffer(nspace), imports, NIL);
|
||||||
|
Printv(proxyCodeBuffer(nspace), proxy_enum_code, NIL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -850,14 +906,12 @@ public:
|
||||||
// Note that this is used in enumValue() amongst other places
|
// Note that this is used in enumValue() amongst other places
|
||||||
Setattr(n, "value", tmpValue);
|
Setattr(n, "value", tmpValue);
|
||||||
|
|
||||||
String *proxy_name = Getattr(n, "sym:name");
|
|
||||||
|
|
||||||
// Emit the enum item.
|
// Emit the enum item.
|
||||||
{
|
{
|
||||||
if (!GetFlag(n, "firstenumitem"))
|
if (!GetFlag(n, "firstenumitem"))
|
||||||
Printf(proxy_enum_code, ",\n");
|
Printf(proxy_enum_code, ",\n");
|
||||||
|
|
||||||
Printf(proxy_enum_code, " %s", proxy_name);
|
Printf(proxy_enum_code, " %s", Getattr(n, "sym:name"));
|
||||||
|
|
||||||
// Check for the %dconstvalue feature
|
// Check for the %dconstvalue feature
|
||||||
String *value = Getattr(n, "feature:d:constvalue");
|
String *value = Getattr(n, "feature:d:constvalue");
|
||||||
|
|
@ -886,7 +940,7 @@ public:
|
||||||
|
|
||||||
String *overloaded_name = getOverloadedName(n);
|
String *overloaded_name = getOverloadedName(n);
|
||||||
String *intermediary_function_name =
|
String *intermediary_function_name =
|
||||||
Swig_name_member(NSPACE_TODO,proxy_class_name, overloaded_name);
|
Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
|
||||||
Setattr(n, "imfuncname", intermediary_function_name);
|
Setattr(n, "imfuncname", intermediary_function_name);
|
||||||
|
|
||||||
String *proxy_func_name = Getattr(n, "sym:name");
|
String *proxy_func_name = Getattr(n, "sym:name");
|
||||||
|
|
@ -897,6 +951,7 @@ public:
|
||||||
// If we are in split proxy mode and the function is named like the
|
// If we are in split proxy mode and the function is named like the
|
||||||
// target package, the D compiler is unable to resolve the ambiguity
|
// target package, the D compiler is unable to resolve the ambiguity
|
||||||
// between the package name and an argument-less function call.
|
// between the package name and an argument-less function call.
|
||||||
|
// TODO: This might occur with nspace as well, augment the check.
|
||||||
Swig_warning(WARN_D_NAME_COLLISION, input_file, line_number,
|
Swig_warning(WARN_D_NAME_COLLISION, input_file, line_number,
|
||||||
"%s::%s might collide with the package name, consider using %%rename to resolve the ambiguity.\n",
|
"%s::%s might collide with the package name, consider using %%rename to resolve the ambiguity.\n",
|
||||||
proxy_class_name, proxy_func_name);
|
proxy_class_name, proxy_func_name);
|
||||||
|
|
@ -935,7 +990,7 @@ public:
|
||||||
|
|
||||||
String *overloaded_name = getOverloadedName(n);
|
String *overloaded_name = getOverloadedName(n);
|
||||||
String *intermediary_function_name =
|
String *intermediary_function_name =
|
||||||
Swig_name_member(NSPACE_TODO,proxy_class_name, overloaded_name);
|
Swig_name_member(getNSpace(), proxy_class_name, overloaded_name);
|
||||||
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
|
Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
|
||||||
Setattr(n, "imfuncname", intermediary_function_name);
|
Setattr(n, "imfuncname", intermediary_function_name);
|
||||||
writeProxyClassFunction(n);
|
writeProxyClassFunction(n);
|
||||||
|
|
@ -1006,7 +1061,7 @@ public:
|
||||||
virtual int constructorHandler(Node *n) {
|
virtual int constructorHandler(Node *n) {
|
||||||
Language::constructorHandler(n);
|
Language::constructorHandler(n);
|
||||||
|
|
||||||
// Wrappers not wanted for some methods where the parameters cannot be overloaded in D.
|
// Wrappers not wanted for some methods where the parameters cannot be overloadedprocess in D.
|
||||||
if (Getattr(n, "overload:ignore")) {
|
if (Getattr(n, "overload:ignore")) {
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -1026,7 +1081,7 @@ public:
|
||||||
NewString("");
|
NewString("");
|
||||||
|
|
||||||
String *overloaded_name = getOverloadedName(n);
|
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("");
|
String *imcall = NewString("");
|
||||||
|
|
||||||
const String *methodmods = Getattr(n, "feature:d:methodmodifiers");
|
const String *methodmods = Getattr(n, "feature:d:methodmodifiers");
|
||||||
|
|
@ -1223,7 +1278,7 @@ public:
|
||||||
virtual int destructorHandler(Node *n) {
|
virtual int destructorHandler(Node *n) {
|
||||||
Language::destructorHandler(n);
|
Language::destructorHandler(n);
|
||||||
String *symname = Getattr(n, "sym:name");
|
String *symname = Getattr(n, "sym:name");
|
||||||
Printv(destructor_call, im_dmodule_fq_name, ".", Swig_name_destroy(NSPACE_TODO,symname), "(cast(void*)swigCPtr)", NIL);
|
Printv(destructor_call, im_dmodule_fq_name, ".", Swig_name_destroy(getNSpace(),symname), "(cast(void*)swigCPtr)", NIL);
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1231,19 +1286,27 @@ public:
|
||||||
* D::classHandler()
|
* D::classHandler()
|
||||||
* --------------------------------------------------------------------------- */
|
* --------------------------------------------------------------------------- */
|
||||||
virtual int classHandler(Node *n) {
|
virtual int classHandler(Node *n) {
|
||||||
|
String *nspace = getNSpace();
|
||||||
File *class_file = NULL;
|
File *class_file = NULL;
|
||||||
|
|
||||||
proxy_class_name = Copy(Getattr(n, "sym:name"));
|
proxy_class_name = Copy(Getattr(n, "sym:name"));
|
||||||
|
if (nspace) {
|
||||||
|
proxy_class_qname = NewStringf("%s.%s", nspace, proxy_class_name);
|
||||||
|
} else {
|
||||||
|
proxy_class_qname = Copy(proxy_class_name);
|
||||||
|
}
|
||||||
|
|
||||||
if (!addSymbol(proxy_class_name, n)) {
|
if (!addSymbol(proxy_class_name, n, nspace)) {
|
||||||
return SWIG_ERROR;
|
return SWIG_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
assertClassNameValidity(proxy_class_name);
|
assertClassNameValidity(proxy_class_name);
|
||||||
|
|
||||||
if (split_proxy_dmodule) {
|
if (split_proxy_dmodule) {
|
||||||
String *filename = NewStringf("%s%s.d", dmodule_directory, proxy_class_name);
|
String *output_directory = outputDirectory(nspace);
|
||||||
|
String *filename = NewStringf("%s%s.d", output_directory, proxy_class_name);
|
||||||
class_file = NewFile(filename, "w", SWIG_output_files());
|
class_file = NewFile(filename, "w", SWIG_output_files());
|
||||||
|
Delete(output_directory);
|
||||||
if (!class_file) {
|
if (!class_file) {
|
||||||
FileErrorDisplay(filename);
|
FileErrorDisplay(filename);
|
||||||
SWIG_exit(EXIT_FAILURE);
|
SWIG_exit(EXIT_FAILURE);
|
||||||
|
|
@ -1252,7 +1315,11 @@ public:
|
||||||
Delete(filename);
|
Delete(filename);
|
||||||
|
|
||||||
emitBanner(class_file);
|
emitBanner(class_file);
|
||||||
Printf(class_file, "module %s%s;\n", package, proxy_class_name);
|
if (nspace) {
|
||||||
|
Printf(class_file, "module %s%s.%s;\n", package, nspace, proxy_class_name);
|
||||||
|
} else {
|
||||||
|
Printf(class_file, "module %s%s;\n", package, proxy_class_name);
|
||||||
|
}
|
||||||
Printf(class_file, "\nstatic import %s;\n", im_dmodule_fq_name);
|
Printf(class_file, "\nstatic import %s;\n", im_dmodule_fq_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1264,6 +1331,8 @@ public:
|
||||||
Clear(destructor_call);
|
Clear(destructor_call);
|
||||||
|
|
||||||
|
|
||||||
|
// Traverse the tree for this class, using the *Handler()s to generate code
|
||||||
|
// to the proxy_class_* variables.
|
||||||
Language::classHandler(n);
|
Language::classHandler(n);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1272,6 +1341,10 @@ public:
|
||||||
|
|
||||||
Replaceall(proxy_class_code, "$dclassname", proxy_class_name);
|
Replaceall(proxy_class_code, "$dclassname", proxy_class_name);
|
||||||
|
|
||||||
|
String *dclazzname = Swig_name_member(getNSpace(), proxy_class_name, "");
|
||||||
|
Replaceall(proxy_class_code, "$dclazzname", dclazzname);
|
||||||
|
Delete(dclazzname);
|
||||||
|
|
||||||
if (split_proxy_dmodule) {
|
if (split_proxy_dmodule) {
|
||||||
Printv(class_file, global_proxy_imports, NIL);
|
Printv(class_file, global_proxy_imports, NIL);
|
||||||
Printv(class_file, proxy_class_imports, NIL);
|
Printv(class_file, proxy_class_imports, NIL);
|
||||||
|
|
@ -1282,10 +1355,12 @@ public:
|
||||||
Close(class_file);
|
Close(class_file);
|
||||||
Delete(class_file);
|
Delete(class_file);
|
||||||
} else {
|
} else {
|
||||||
Printv(proxy_dmodule_imports, proxy_class_imports, NIL);
|
Printv(proxyImportsBuffer(getNSpace()), proxy_class_imports, NIL);
|
||||||
Printv(proxy_dmodule_code, proxy_class_code, NIL);
|
Printv(proxyCodeBuffer(getNSpace()), proxy_class_code, NIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Delete(proxy_class_qname);
|
||||||
|
proxy_class_qname = NULL;
|
||||||
Delete(proxy_class_name);
|
Delete(proxy_class_name);
|
||||||
proxy_class_name = NULL;
|
proxy_class_name = NULL;
|
||||||
|
|
||||||
|
|
@ -1402,7 +1477,7 @@ public:
|
||||||
if (wrapping_member_flag) {
|
if (wrapping_member_flag) {
|
||||||
Printv(proxy_class_body_code, constants_code, NIL);
|
Printv(proxy_class_body_code, constants_code, NIL);
|
||||||
} else {
|
} else {
|
||||||
Printv(proxy_dmodule_code, constants_code, NIL);
|
Printv(proxyCodeBuffer(getNSpace()), constants_code, NIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup.
|
// Cleanup.
|
||||||
|
|
@ -1780,10 +1855,18 @@ public:
|
||||||
* D::classDirector()
|
* D::classDirector()
|
||||||
* --------------------------------------------------------------------------- */
|
* --------------------------------------------------------------------------- */
|
||||||
virtual int classDirector(Node *n) {
|
virtual int classDirector(Node *n) {
|
||||||
|
String *nspace = Getattr(n, "sym:nspace");
|
||||||
proxy_class_name = NewString(Getattr(n, "sym:name"));
|
proxy_class_name = NewString(Getattr(n, "sym:name"));
|
||||||
|
if (nspace) {
|
||||||
|
proxy_class_qname = NewStringf("%s.%s", nspace, proxy_class_name);
|
||||||
|
} else {
|
||||||
|
proxy_class_qname = Copy(proxy_class_name);
|
||||||
|
}
|
||||||
|
|
||||||
int success = Language::classDirector(n);
|
int success = Language::classDirector(n);
|
||||||
|
|
||||||
|
Delete(proxy_class_qname);
|
||||||
|
proxy_class_qname = NULL;
|
||||||
Delete(proxy_class_name);
|
Delete(proxy_class_name);
|
||||||
proxy_class_name = NULL;
|
proxy_class_name = NULL;
|
||||||
|
|
||||||
|
|
@ -1874,7 +1957,8 @@ public:
|
||||||
// we're consistent with the sym:overload name in functionWrapper. (?? when
|
// we're consistent with the sym:overload name in functionWrapper. (?? when
|
||||||
// does the overloaded method name get set?)
|
// 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) {
|
if (returntype) {
|
||||||
qualified_return = SwigType_rcaststr(returntype, "c_result");
|
qualified_return = SwigType_rcaststr(returntype, "c_result");
|
||||||
|
|
@ -2507,6 +2591,8 @@ private:
|
||||||
* intermediary D module.
|
* intermediary D module.
|
||||||
*
|
*
|
||||||
* d_name - The name the function in the intermediary D module will get.
|
* d_name - The name the function in the intermediary D module will get.
|
||||||
|
* return type - The return type of the function in the C wrapper.
|
||||||
|
* parameters - The parameter list of the C wrapper function.
|
||||||
* wrapper_function_name - The name of the exported function in the C wrapper
|
* wrapper_function_name - The name of the exported function in the C wrapper
|
||||||
* (usually d_name prefixed by »D_«).
|
* (usually d_name prefixed by »D_«).
|
||||||
* --------------------------------------------------------------------------- */
|
* --------------------------------------------------------------------------- */
|
||||||
|
|
@ -2587,8 +2673,12 @@ private:
|
||||||
|
|
||||||
if (wrapping_member_flag) {
|
if (wrapping_member_flag) {
|
||||||
// Check if this is a setter method for a public member.
|
// Check if this is a setter method for a public member.
|
||||||
setter_flag = (Cmp(Getattr(n, "sym:name"),
|
const String *setter_name = Swig_name_set(getNSpace(),
|
||||||
Swig_name_set(NSPACE_TODO,Swig_name_member(NSPACE_TODO,proxy_class_name, variable_name))) == 0);
|
Swig_name_member(0, proxy_class_name, variable_name));
|
||||||
|
|
||||||
|
if (Cmp(Getattr(n, "sym:name"), setter_name) == 0) {
|
||||||
|
setter_flag = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write function modifiers.
|
// Write function modifiers.
|
||||||
|
|
@ -2769,7 +2859,7 @@ private:
|
||||||
Node *explicit_n = Getattr(n, "explicitcallnode");
|
Node *explicit_n = Getattr(n, "explicitcallnode");
|
||||||
if (explicit_n) {
|
if (explicit_n) {
|
||||||
String *ex_overloaded_name = getOverloadedName(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);
|
String *ex_imcall = Copy(imcall);
|
||||||
Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
|
Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
|
||||||
|
|
@ -3003,7 +3093,7 @@ private:
|
||||||
// The whole function code is now stored in tm (if there was a matching
|
// The whole function code is now stored in tm (if there was a matching
|
||||||
// type map, of course), so simply append it to the code buffer.
|
// type map, of course), so simply append it to the code buffer.
|
||||||
Printf(function_code, "%s\n", tm ? (const String *) tm : empty_string);
|
Printf(function_code, "%s\n", tm ? (const String *) tm : empty_string);
|
||||||
Printv(proxy_dmodule_code, function_code, NIL);
|
Printv(proxyCodeBuffer(getNSpace()), function_code, NIL);
|
||||||
|
|
||||||
Delete(pre_code);
|
Delete(pre_code);
|
||||||
Delete(post_code);
|
Delete(post_code);
|
||||||
|
|
@ -3016,6 +3106,16 @@ private:
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
* D::writeProxyClassAndUpcasts()
|
* D::writeProxyClassAndUpcasts()
|
||||||
|
*
|
||||||
|
* Collects all the code fragments generated by the handler function while
|
||||||
|
* traversing the tree from the proxy_class_* variables and writes the
|
||||||
|
* class definition (including any epilogue code) to proxy_class_code.
|
||||||
|
*
|
||||||
|
* Also writes the upcast function to the wrapper layer when processing a
|
||||||
|
* derived class.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* n – The class node currently processed.
|
||||||
* --------------------------------------------------------------------------- */
|
* --------------------------------------------------------------------------- */
|
||||||
void writeProxyClassAndUpcasts(Node *n) {
|
void writeProxyClassAndUpcasts(Node *n) {
|
||||||
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
|
SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
|
||||||
|
|
@ -3026,7 +3126,8 @@ private:
|
||||||
|
|
||||||
String *c_classname = SwigType_namestr(Getattr(n, "name"));
|
String *c_classname = SwigType_namestr(Getattr(n, "name"));
|
||||||
String *c_baseclass = NULL;
|
String *c_baseclass = NULL;
|
||||||
String *baseclass = NULL;
|
Node *basenode = NULL;
|
||||||
|
String *basename = NULL;
|
||||||
String *c_baseclassname = NULL;
|
String *c_baseclassname = NULL;
|
||||||
|
|
||||||
// Inheritance from pure D classes.
|
// Inheritance from pure D classes.
|
||||||
|
|
@ -3046,9 +3147,10 @@ private:
|
||||||
base = Next(base);
|
base = Next(base);
|
||||||
}
|
}
|
||||||
if (base.item) {
|
if (base.item) {
|
||||||
|
basenode = base.item;
|
||||||
c_baseclassname = Getattr(base.item, "name");
|
c_baseclassname = Getattr(base.item, "name");
|
||||||
baseclass = Copy(getProxyName(c_baseclassname));
|
basename = Copy(getProxyName(c_baseclassname));
|
||||||
if (baseclass)
|
if (basename)
|
||||||
c_baseclass = SwigType_namestr(Getattr(base.item, "name"));
|
c_baseclass = SwigType_namestr(Getattr(base.item, "name"));
|
||||||
base = Next(base);
|
base = Next(base);
|
||||||
/* Warn about multiple inheritance for additional base class(es) */
|
/* Warn about multiple inheritance for additional base class(es) */
|
||||||
|
|
@ -3067,24 +3169,25 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool derived = baseclass && getProxyName(c_baseclassname);
|
bool derived = (basename != NULL);
|
||||||
|
|
||||||
if (derived && purebase_notderived) {
|
if (derived && purebase_notderived) {
|
||||||
pure_baseclass = empty_string;
|
pure_baseclass = empty_string;
|
||||||
}
|
}
|
||||||
const String *wanted_base = baseclass ? baseclass : pure_baseclass;
|
const String *wanted_base = basename ? basename : pure_baseclass;
|
||||||
|
|
||||||
if (purebase_replace) {
|
if (purebase_replace) {
|
||||||
wanted_base = pure_baseclass;
|
wanted_base = pure_baseclass;
|
||||||
derived = false;
|
derived = false;
|
||||||
Delete(baseclass);
|
basenode = NULL;
|
||||||
baseclass = NULL;
|
Delete(basename);
|
||||||
|
basename = NULL;
|
||||||
if (purebase_notderived) {
|
if (purebase_notderived) {
|
||||||
Swig_error(Getfile(n), Getline(n),
|
Swig_error(Getfile(n), Getline(n),
|
||||||
"The dbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n",
|
"The dbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n",
|
||||||
typemap_lookup_type);
|
typemap_lookup_type);
|
||||||
}
|
}
|
||||||
} else if (baseclass && Len(pure_baseclass) > 0) {
|
} else if (basename && Len(pure_baseclass) > 0) {
|
||||||
Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
|
Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
|
||||||
"Warning for %s proxy: Base class %s ignored. Multiple inheritance is not supported in D. "
|
"Warning for %s proxy: Base class %s ignored. Multiple inheritance is not supported in D. "
|
||||||
"Perhaps you need one of the 'replace' or 'notderived' attributes in the dbase typemap?\n", typemap_lookup_type, pure_baseclass);
|
"Perhaps you need one of the 'replace' or 'notderived' attributes in the dbase typemap?\n", typemap_lookup_type, pure_baseclass);
|
||||||
|
|
@ -3101,14 +3204,10 @@ private:
|
||||||
// If this class is derived from a C++ class, we need to have the D class
|
// If this class is derived from a C++ class, we need to have the D class
|
||||||
// generated for it in scope.
|
// generated for it in scope.
|
||||||
if (derived) {
|
if (derived) {
|
||||||
requireDType(baseclass);
|
requireDType(Getattr(basenode, "sym:nspace"), Getattr(basenode, "sym:name"));
|
||||||
|
|
||||||
if (split_proxy_dmodule) {
|
// Fully qualify the baseclass name.
|
||||||
// Fully qualify the baseclass name.
|
Insert(basename, 0, package);
|
||||||
String *module = NewStringf("%s%s.", package, baseclass);
|
|
||||||
Insert(baseclass, 0, module);
|
|
||||||
Delete(module);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write any custom import statements to the proxy module header.
|
// Write any custom import statements to the proxy module header.
|
||||||
|
|
@ -3238,8 +3337,8 @@ private:
|
||||||
// Write the class body and the curly bracket closing the class definition
|
// Write the class body and the curly bracket closing the class definition
|
||||||
// to the proxy module.
|
// to the proxy module.
|
||||||
indentCode(body);
|
indentCode(body);
|
||||||
Replaceall(body, "$dbaseclass", baseclass);
|
Replaceall(body, "$dbaseclass", basename);
|
||||||
Delete(baseclass);
|
Delete(basename);
|
||||||
|
|
||||||
Printv(proxy_class_code, body, "\n}\n", NIL);
|
Printv(proxy_class_code, body, "\n}\n", NIL);
|
||||||
Delete(body);
|
Delete(body);
|
||||||
|
|
@ -3256,9 +3355,8 @@ private:
|
||||||
String* c_class_name, String* c_base_name) {
|
String* c_class_name, String* c_base_name) {
|
||||||
|
|
||||||
String *smartptr = Getattr(n, "feature:smartptr");
|
String *smartptr = Getattr(n, "feature:smartptr");
|
||||||
String *upcast_name = NewString("");
|
String *upcast_name = Swig_name_member(getNSpace(), d_class_name,
|
||||||
Printv(upcast_name, d_class_name,
|
(smartptr != 0 ? "SmartPtrUpcast" : "Upcast"));
|
||||||
(smartptr != 0 ? "SmartPtrUpcast" : "Upcast"), NIL);
|
|
||||||
|
|
||||||
String *upcast_wrapper_name = Swig_name_wrapper(upcast_name);
|
String *upcast_wrapper_name = Swig_name_wrapper(upcast_name);
|
||||||
|
|
||||||
|
|
@ -3338,8 +3436,8 @@ private:
|
||||||
imports_target = NewString("");
|
imports_target = NewString("");
|
||||||
code_target = NewString("");
|
code_target = NewString("");
|
||||||
} else {
|
} else {
|
||||||
imports_target = proxy_dmodule_imports;
|
imports_target = proxyImportsBuffer(0);
|
||||||
code_target = proxy_dmodule_code;
|
code_target = proxyCodeBuffer(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import statements.
|
// Import statements.
|
||||||
|
|
@ -3461,7 +3559,8 @@ private:
|
||||||
|
|
||||||
// Output the director connect method.
|
// Output the director connect method.
|
||||||
String *norm_name = SwigType_namestr(Getattr(n, "name"));
|
String *norm_name = SwigType_namestr(Getattr(n, "name"));
|
||||||
String *connect_name = NewStringf("%s_director_connect", proxy_class_name);
|
String *connect_name = Swig_name_member(getNSpace(),
|
||||||
|
proxy_class_name, "director_connect");
|
||||||
String *sym_name = Getattr(n, "sym:name");
|
String *sym_name = Getattr(n, "sym:name");
|
||||||
Wrapper *code_wrap;
|
Wrapper *code_wrap;
|
||||||
|
|
||||||
|
|
@ -3504,19 +3603,40 @@ private:
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
* D::requireDType()
|
* D::requireDType()
|
||||||
*
|
*
|
||||||
* Adds an import statement for the given module to the header of current
|
* If the given type is not already in scope in the current module, adds an
|
||||||
* module. This is only used for dependencies created in generated code, user-
|
* import statement for it. The name is considered relative to the global root
|
||||||
* (read: typemap-) specified import statements are handeled seperately.
|
* package if one is set.
|
||||||
|
*
|
||||||
|
* This is only used for dependencies created in generated code, user-
|
||||||
|
* (i.e. typemap-) specified import statements are handeled seperately.
|
||||||
* --------------------------------------------------------------------------- */
|
* --------------------------------------------------------------------------- */
|
||||||
void requireDType(const String *dmodule_name) {
|
void requireDType(const String *nspace, const String *symname) {
|
||||||
String *import = createImportStatement(dmodule_name);
|
String *dmodule;
|
||||||
Append(import, "\n");
|
if (nspace) {
|
||||||
if (is_wrapping_class()) {
|
dmodule = NewStringf("%s.", nspace);
|
||||||
addImportStatement(proxy_class_imports, import);
|
|
||||||
} else {
|
} else {
|
||||||
addImportStatement(proxy_dmodule_imports, import);
|
dmodule = NewString("");
|
||||||
}
|
}
|
||||||
Delete(import);
|
|
||||||
|
if (split_proxy_dmodule) {
|
||||||
|
Printv(dmodule, symname, NIL);
|
||||||
|
} else {
|
||||||
|
String *inner = createLastNamespaceName(nspace);
|
||||||
|
Printv(dmodule, inner, NIL);
|
||||||
|
Delete(inner);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inProxyModule(dmodule)) {
|
||||||
|
String *import = createImportStatement(dmodule);
|
||||||
|
Append(import, "\n");
|
||||||
|
if (is_wrapping_class()) {
|
||||||
|
addImportStatement(proxy_class_imports, import);
|
||||||
|
} else {
|
||||||
|
addImportStatement(proxyImportsBuffer(getNSpace()), import);
|
||||||
|
}
|
||||||
|
Delete(import);
|
||||||
|
}
|
||||||
|
Delete(dmodule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
|
|
@ -3550,46 +3670,41 @@ private:
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
* D::createImportStatement()
|
* D::createImportStatement()
|
||||||
*
|
*
|
||||||
* Creates a string containing an import statement for the given module if it
|
* Creates a string containing an import statement for the given module.
|
||||||
* is needed in the currently generated proxy D module (i.e. if it is not the
|
|
||||||
* current module itself).
|
|
||||||
* --------------------------------------------------------------------------- */
|
* --------------------------------------------------------------------------- */
|
||||||
String *createImportStatement(const String *dmodule_name,
|
String *createImportStatement(const String *dmodule_name,
|
||||||
bool static_import = true) const {
|
bool static_import = true) const {
|
||||||
|
|
||||||
if (inProxyModule(dmodule_name)) {
|
if (static_import) {
|
||||||
return NewStringf("");
|
return NewStringf("static import %s%s;", package, dmodule_name);
|
||||||
} else {
|
} else {
|
||||||
if (static_import) {
|
return NewStringf("import %s%s;", package, dmodule_name);
|
||||||
return NewStringf("static import %s%s;", package, dmodule_name);
|
|
||||||
} else {
|
|
||||||
return NewStringf("import %s%s;", package, dmodule_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
* D::inProxyModule()
|
* D::inProxyModule()
|
||||||
*
|
*
|
||||||
* Determines if the specified proxy class is decleared in the currently
|
* Determines if the specified proxy type is declared in the currently
|
||||||
* processed proxy D module.
|
* processed proxy D module.
|
||||||
*
|
*
|
||||||
* This function is used to determine if fully qualified type names have to be
|
* This function is used to determine if fully qualified type names have to be
|
||||||
* used (package, module and type name). This is never the case if the split
|
* used (package, module and type name). If the split proxy mode is not used,
|
||||||
* proxy mode is not used, all proxy types are written to the same module then.
|
* this solely depends on whether the type is in the current namespace or.
|
||||||
* --------------------------------------------------------------------------- */
|
* --------------------------------------------------------------------------- */
|
||||||
bool inProxyModule(const String *type_name) const {
|
bool inProxyModule(const String *type_name) const {
|
||||||
if (!split_proxy_dmodule) {
|
if (!split_proxy_dmodule) {
|
||||||
// If we are not in split proxy module mode, proxy code is always written
|
String *nspace = createOuterNamespaceNames(type_name);
|
||||||
// to the same module.
|
bool result = (getNSpace() || !nspace) && (Strcmp(nspace, getNSpace()) == 0);
|
||||||
return true;
|
Delete(nspace);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Len(proxy_class_name)) {
|
if (!Len(proxy_class_qname)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (Strcmp(proxy_class_name, type_name) == 0);
|
return (Strcmp(proxy_class_qname, type_name) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
|
|
@ -3637,17 +3752,57 @@ private:
|
||||||
* D::assertClassNameValidity()
|
* D::assertClassNameValidity()
|
||||||
* --------------------------------------------------------------------------- */
|
* --------------------------------------------------------------------------- */
|
||||||
void assertClassNameValidity(const String* class_name) const {
|
void assertClassNameValidity(const String* class_name) const {
|
||||||
|
// TODO: With nspace support, there could arise problems also when not in
|
||||||
|
// split proxy mode, warnings for these should be added.
|
||||||
if (split_proxy_dmodule) {
|
if (split_proxy_dmodule) {
|
||||||
if (Cmp(class_name, im_dmodule_name) == 0) {
|
if (Cmp(class_name, im_dmodule_name) == 0) {
|
||||||
Swig_error(input_file, line_number, "Class name cannot be equal to intermediary D module name: %s\n",
|
Swig_error(input_file, line_number,
|
||||||
|
"Class name cannot be equal to intermediary D module name: %s\n",
|
||||||
class_name);
|
class_name);
|
||||||
SWIG_exit(EXIT_FAILURE);
|
SWIG_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Cmp(class_name, proxy_dmodule_name) == 0) {
|
String *nspace = getNSpace();
|
||||||
Swig_error(input_file, line_number, "Class name cannot be equal to proxy D module name: %s\n",
|
if (nspace) {
|
||||||
class_name);
|
// Check the root package/outermost namespace (a class A in module
|
||||||
SWIG_exit(EXIT_FAILURE);
|
// A.B leads to problems if another module A.C is also imported)…
|
||||||
|
if (Len(package) > 0) {
|
||||||
|
String *dotless_package = NewStringWithSize(package, Len(package) - 1);
|
||||||
|
if (Cmp(class_name, dotless_package) == 0) {
|
||||||
|
Swig_error(input_file, line_number,
|
||||||
|
"Class name cannot be the same as the root package it is in: %s\n",
|
||||||
|
class_name);
|
||||||
|
SWIG_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
Delete(dotless_package);
|
||||||
|
} else {
|
||||||
|
String *outer = createFirstNamespaceName(nspace);
|
||||||
|
if (Cmp(class_name, outer) == 0) {
|
||||||
|
Swig_error(input_file, line_number,
|
||||||
|
"Class name cannot be the same as the outermost namespace it is in: %s\n",
|
||||||
|
class_name);
|
||||||
|
SWIG_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
Delete(outer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// … and the innermost one (because of the conflict with the main proxy
|
||||||
|
// module named like the namespace).
|
||||||
|
String *inner = createLastNamespaceName(nspace);
|
||||||
|
if (Cmp(class_name, inner) == 0) {
|
||||||
|
Swig_error(input_file, line_number,
|
||||||
|
"Class name cannot be the same as the innermost namespace it is in: %s\n",
|
||||||
|
class_name);
|
||||||
|
SWIG_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
Delete(inner);
|
||||||
|
} else {
|
||||||
|
if (Cmp(class_name, proxy_dmodule_name) == 0) {
|
||||||
|
Swig_error(input_file, line_number,
|
||||||
|
"Class name cannot be equal to proxy D module name: %s\n",
|
||||||
|
class_name);
|
||||||
|
SWIG_exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3927,48 +4082,69 @@ private:
|
||||||
// import when a type is used in another generated module. If we are not
|
// import when a type is used in another generated module. If we are not
|
||||||
// working in split proxy module mode, this is not relevant and the
|
// working in split proxy module mode, this is not relevant and the
|
||||||
// generated module name is discarded.
|
// generated module name is discarded.
|
||||||
String *import_name;
|
String *type_name;
|
||||||
|
|
||||||
String *qualified_type_name;
|
|
||||||
if (SwigType_isenum(type)) {
|
if (SwigType_isenum(type)) {
|
||||||
// RESEARCH: Make sure that we really cannot get here for anonymous enums.
|
// RESEARCH: Make sure that we really cannot get here for anonymous enums.
|
||||||
Node *n = enumLookup(type);
|
Node *n = enumLookup(type);
|
||||||
const String *symname = Getattr(n, "sym:name");
|
String *enum_name = Getattr(n, "sym:name");
|
||||||
|
|
||||||
// Add in class scope when referencing enum if not a global enum.
|
Node *p = parentNode(n);
|
||||||
const String *parent_name = NULL;
|
if (p && !Strcmp(nodeType(p), "class")) {
|
||||||
String *scopename_prefix = Swig_scopename_prefix(Getattr(n, "name"));
|
// This is a nested enum.
|
||||||
if (scopename_prefix) {
|
String *parent_name = Getattr(p, "sym:name");
|
||||||
parent_name = getProxyName(scopename_prefix);
|
String *nspace = Getattr(p, "sym:nspace");
|
||||||
Delete(scopename_prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parent_name) {
|
|
||||||
qualified_type_name = createQualifiedName(parent_name);
|
|
||||||
Printv(qualified_type_name, ".", symname, NIL);
|
|
||||||
|
|
||||||
// An enum nested in a class is not written to a seperate module (this
|
// An enum nested in a class is not written to a seperate module (this
|
||||||
// would not even be possible in D), so just import the parent.
|
// would not even be possible in D), so just import the parent.
|
||||||
import_name = Copy(parent_name);
|
requireDType(nspace, parent_name);
|
||||||
} else {
|
|
||||||
qualified_type_name = createQualifiedName(symname);
|
|
||||||
|
|
||||||
|
String *module = createModuleName(nspace, parent_name);
|
||||||
|
if (inProxyModule(module)) {
|
||||||
|
type_name = NewStringf("%s.%s", parent_name, enum_name);
|
||||||
|
} else {
|
||||||
|
type_name = NewStringf("%s%s.%s.%s", package, module, parent_name, enum_name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// A non-nested enum is written to a seperate module, import it.
|
// A non-nested enum is written to a seperate module, import it.
|
||||||
import_name = Copy(symname);
|
String *nspace = Getattr(n, "sym:nspace");
|
||||||
|
requireDType(nspace, enum_name);
|
||||||
|
|
||||||
|
String *module = createModuleName(nspace, enum_name);
|
||||||
|
if (inProxyModule(module)) {
|
||||||
|
type_name = Copy(enum_name);
|
||||||
|
} else {
|
||||||
|
type_name = NewStringf("%s%s.%s", package, module, enum_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const String *class_name = getProxyName(type);
|
Node *n = classLookup(type);
|
||||||
if (class_name) {
|
if (n) {
|
||||||
// This is something wrapped as a proxy class (getProxyName() works for
|
String *class_name = Getattr(n, "sym:name");
|
||||||
// pointers to classes too).
|
String *nspace = Getattr(n, "sym:nspace");
|
||||||
qualified_type_name = createQualifiedName(class_name);
|
requireDType(nspace, class_name);
|
||||||
import_name = Copy(class_name);
|
|
||||||
|
String *module = createModuleName(nspace, class_name);
|
||||||
|
if (inProxyModule(module)) {
|
||||||
|
type_name = Copy(class_name);
|
||||||
|
} else {
|
||||||
|
type_name = NewStringf("%s%s.%s", package, module, class_name);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// SWIG does not know anything about the type (after resolving typedefs).
|
// SWIG does not know anything about the type (after resolving typedefs).
|
||||||
// Just mangle the type name string like $descriptor(type) would do.
|
// Just mangle the type name string like $descriptor(type) would do.
|
||||||
String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type));
|
String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type));
|
||||||
qualified_type_name = createQualifiedName(descriptor);
|
requireDType(NULL, descriptor);
|
||||||
import_name = Copy(descriptor);
|
|
||||||
|
String *module = NULL;
|
||||||
|
if (split_proxy_dmodule) {
|
||||||
|
module = Copy(descriptor);
|
||||||
|
}
|
||||||
|
if (inProxyModule(module)) {
|
||||||
|
type_name = Copy(descriptor);
|
||||||
|
} else {
|
||||||
|
type_name = NewStringf("%s%s.%s", package, module, descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
// Add to hash table so that a type wrapper class can be created later.
|
// Add to hash table so that a type wrapper class can be created later.
|
||||||
Setattr(unknown_types, descriptor, type);
|
Setattr(unknown_types, descriptor, type);
|
||||||
|
|
@ -3977,23 +4153,36 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Replaceall(target, variable, qualified_type_name);
|
Replaceall(target, variable, type_name);
|
||||||
Delete(qualified_type_name);
|
Delete(type_name);
|
||||||
|
|
||||||
requireDType(import_name);
|
|
||||||
Delete(import_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
* D::createQualifiedName()
|
* D::createModuleName()
|
||||||
|
*
|
||||||
|
* Returns a string holding the name of the module to import to bring the
|
||||||
|
* given type in scope.
|
||||||
* --------------------------------------------------------------------------- */
|
* --------------------------------------------------------------------------- */
|
||||||
String *createQualifiedName(const String *class_name) const {
|
String *createModuleName(const String *nspace, const String *type_name) const {
|
||||||
if (inProxyModule(class_name)) {
|
String *module;
|
||||||
return Copy(class_name);
|
if (nspace) {
|
||||||
|
module = NewStringf("%s.", nspace);
|
||||||
|
if (split_proxy_dmodule) {
|
||||||
|
Printv(module, type_name, NIL);
|
||||||
|
} else {
|
||||||
|
String *inner = createLastNamespaceName(nspace);
|
||||||
|
Printv(module, inner, NIL);
|
||||||
|
Delete(inner);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return NewStringf("%s%s.%s", package, class_name, class_name);
|
if (split_proxy_dmodule) {
|
||||||
|
module = Copy(type_name);
|
||||||
|
} else {
|
||||||
|
module = proxy_dmodule_name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
* D::replaceModuleVariables()
|
* D::replaceModuleVariables()
|
||||||
|
|
@ -4070,9 +4259,14 @@ private:
|
||||||
String *current_macro = NewStringWithSize(start, (int)(end - start));
|
String *current_macro = NewStringWithSize(start, (int)(end - start));
|
||||||
String *current_param = NewStringWithSize(param_start, (int)(param_end - param_start));
|
String *current_param = NewStringWithSize(param_start, (int)(param_end - param_start));
|
||||||
|
|
||||||
String *import = createImportStatement(current_param, false);
|
|
||||||
Replace(target, current_macro, import, DOH_REPLACE_ANY);
|
if (inProxyModule(current_param)) {
|
||||||
Delete(import);
|
Replace(target, current_macro, "", DOH_REPLACE_ANY);
|
||||||
|
} else {
|
||||||
|
String *import = createImportStatement(current_param, false);
|
||||||
|
Replace(target, current_macro, import, DOH_REPLACE_ANY);
|
||||||
|
Delete(import);
|
||||||
|
}
|
||||||
|
|
||||||
Delete(current_param);
|
Delete(current_param);
|
||||||
Delete(current_macro);
|
Delete(current_macro);
|
||||||
|
|
@ -4107,13 +4301,35 @@ private:
|
||||||
* Returns the D class name if a type corresponds to something wrapped with a
|
* Returns the D class name if a type corresponds to something wrapped with a
|
||||||
* proxy class, NULL otherwise.
|
* proxy class, NULL otherwise.
|
||||||
* --------------------------------------------------------------------------- */
|
* --------------------------------------------------------------------------- */
|
||||||
const String *getProxyName(SwigType *t) {
|
const String *getProxyName(SwigType *t) {
|
||||||
|
String *proxyname = NULL;
|
||||||
Node *n = classLookup(t);
|
Node *n = classLookup(t);
|
||||||
if (n) {
|
if (n) {
|
||||||
return Getattr(n, "sym:name");
|
proxyname = Getattr(n, "proxyname");
|
||||||
} else {
|
if (!proxyname) {
|
||||||
return NULL;
|
String *nspace = Getattr(n, "sym:nspace");
|
||||||
|
String *symname = Getattr(n, "sym:name");
|
||||||
|
|
||||||
|
if (nspace) {
|
||||||
|
proxyname = NewStringf("%s.%s", nspace, symname);
|
||||||
|
} else {
|
||||||
|
proxyname = Copy(symname);
|
||||||
|
}
|
||||||
|
if (split_proxy_dmodule) {
|
||||||
|
Printf(proxyname, ".%s", symname);
|
||||||
|
} else {
|
||||||
|
if (!inProxyModule(proxyname)) {
|
||||||
|
Delete(proxyname);
|
||||||
|
String *inner = createLastNamespaceName(nspace);
|
||||||
|
proxyname = NewStringf("%s.%s.%s", nspace, inner, symname);
|
||||||
|
Delete(inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Setattr(n, "proxyname", proxyname);
|
||||||
|
Delete(proxyname); // Return value still valid because of the ref from n.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return proxyname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
|
|
@ -4324,6 +4540,145 @@ private:
|
||||||
Swig_banner_target_lang(f, " *");
|
Swig_banner_target_lang(f, " *");
|
||||||
Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
|
Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
* D::outputDirectory()
|
||||||
|
*
|
||||||
|
* Returns the directory to write the D modules for the given namespace to and
|
||||||
|
* and creates the subdirectory if it doesn't exist.
|
||||||
|
* --------------------------------------------------------------------------- */
|
||||||
|
String *outputDirectory(String *nspace) {
|
||||||
|
String *output_directory = Copy(dmodule_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
* D::proxyCodeBuffer()
|
||||||
|
*
|
||||||
|
* Returns the buffer to write proxy code for the given namespace to.
|
||||||
|
* --------------------------------------------------------------------------- */
|
||||||
|
String *proxyCodeBuffer(String *nspace) {
|
||||||
|
if (!nspace) {
|
||||||
|
return proxy_dmodule_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hash *hash = Getattr(nspace_proxy_dmodules, nspace);
|
||||||
|
if (!hash) {
|
||||||
|
hash = NewHash();
|
||||||
|
Setattr(hash, "code", NewString(""));
|
||||||
|
Setattr(hash, "imports", NewString(""));
|
||||||
|
Setattr(nspace_proxy_dmodules, nspace, hash);
|
||||||
|
}
|
||||||
|
return Getattr(hash, "code");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
* D::proxyCodeBuffer()
|
||||||
|
*
|
||||||
|
* Returns the buffer to write imports for the proxy code for the given
|
||||||
|
* namespace to.
|
||||||
|
* --------------------------------------------------------------------------- */
|
||||||
|
String *proxyImportsBuffer(String *nspace) {
|
||||||
|
if (!nspace) {
|
||||||
|
return proxy_dmodule_imports;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hash *hash = Getattr(nspace_proxy_dmodules, nspace);
|
||||||
|
if (!hash) {
|
||||||
|
hash = NewHash();
|
||||||
|
Setattr(hash, "code", NewString(""));
|
||||||
|
Setattr(hash, "imports", NewString(""));
|
||||||
|
Setattr(nspace_proxy_dmodules, nspace, hash);
|
||||||
|
}
|
||||||
|
return Getattr(hash, "imports");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
* D::createFirstNamespaceName()
|
||||||
|
*
|
||||||
|
* Returns a new string containing the name of the outermost namespace, e.g.
|
||||||
|
* »A« for the argument »A.B.C«.
|
||||||
|
* --------------------------------------------------------------------------- */
|
||||||
|
String *createFirstNamespaceName(const String *nspace) const {
|
||||||
|
char *tmp = Char(nspace);
|
||||||
|
char *c = tmp;
|
||||||
|
char *co = 0;
|
||||||
|
if (!strstr(c, "."))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
co = c + Len(nspace);
|
||||||
|
|
||||||
|
while (*c && (c != co)) {
|
||||||
|
if ((*c == '.')) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
if (!*c || (c == tmp)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return NewStringWithSize(tmp, (int)(c - tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
* D::createLastNamespaceName()
|
||||||
|
*
|
||||||
|
* Returns a new string containing the name of the innermost namespace, e.g.
|
||||||
|
* »C« for the argument »A.B.C«.
|
||||||
|
* --------------------------------------------------------------------------- */
|
||||||
|
String *createLastNamespaceName(const String *nspace) const {
|
||||||
|
if (!nspace) return NULL;
|
||||||
|
char *c = Char(nspace);
|
||||||
|
char *cc = c;
|
||||||
|
if (!strstr(c, "."))
|
||||||
|
return NewString(nspace);
|
||||||
|
|
||||||
|
while (*c) {
|
||||||
|
if (*c == '.') {
|
||||||
|
cc = c;
|
||||||
|
}
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
return NewString(cc + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
* D::createOuterNamespaceNames()
|
||||||
|
*
|
||||||
|
* Returns a new string containing the name of the outer namespace, e.g.
|
||||||
|
* »A.B« for the argument »A.B.C«.
|
||||||
|
* --------------------------------------------------------------------------- */
|
||||||
|
String *createOuterNamespaceNames(const String *nspace) const {
|
||||||
|
if (!nspace) return NULL;
|
||||||
|
char *tmp = Char(nspace);
|
||||||
|
char *c = tmp;
|
||||||
|
char *cc = c;
|
||||||
|
if (!strstr(c, "."))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (*c) {
|
||||||
|
if (*c == '.') {
|
||||||
|
cc = c;
|
||||||
|
}
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
if (cc == tmp) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return NewStringWithSize(tmp, (int)(cc - tmp));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static Language *new_swig_d() {
|
static Language *new_swig_d() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue