C#, D, Java methodmodifiers on destructors

Add support so that the %csmethodmodifiers, %dmethodmodifiers,
%javamethodmodifiers can modify the method modifiers for the destructor wrappers
in the proxy class: dispose, Dispose, delete. With this feature, it is now possible
to make a C# proxy class sealed, eg when wrapping a class X, the virtual method modifiers
can be removed using:

  %typemap(csclassmodifiers) X "public sealed class"
  %csmethodmodifiers X::~X "public /*virtual*/";
This commit is contained in:
William S Fulton 2018-05-11 18:09:51 +01:00
commit ee17f8d04f
9 changed files with 210 additions and 13 deletions

View file

@ -44,7 +44,8 @@
<li><a href="#CSharp_date_marshalling">Date marshalling using the csin typemap and associated attributes</a>
<li><a href="#CSharp_date_properties">A date example demonstrating marshalling of C# properties</a>
<li><a href="#CSharp_date_pre_post_directors">Date example demonstrating the 'pre' and 'post' typemap attributes for directors</a>
<li><a href="#CSharp_partial_classes">Turning wrapped classes into partial classes</a>
<li><a href="#CSharp_partial_classes">Turning proxy classes into partial classes</a>
<li><a href="#CSharp_sealed_proxy_class">Turning proxy classes into sealed classes</a>
<li><a href="#CSharp_extending_proxy_class">Extending proxy classes with additional C# code</a>
<li><a href="#CSharp_enum_underlying_type">Underlying type for enums</a>
</ul>
@ -2515,7 +2516,7 @@ Pay special attention to the memory management issues, using these attributes.
</p>
<H3><a name="CSharp_partial_classes">20.8.6 Turning wrapped classes into partial classes</a></H3>
<H3><a name="CSharp_partial_classes">20.8.6 Turning proxy classes into partial classes</a></H3>
<p>
@ -2615,7 +2616,97 @@ demonstrating that the class contains methods calling both unmanaged code - <tt>
The following example is an alternative approach to adding managed code to the generated proxy class.
</p>
<H3><a name="CSharp_extending_proxy_class">20.8.7 Extending proxy classes with additional C# code</a></H3>
<H3><a name="CSharp_sealed_proxy_class">20.8.7 Turning proxy classes into sealed classes</a></H3>
<p>
The technique in the previous section can be used to make the proxy class a sealed class.
Consider a C++ class <tt>NotABaseClass</tt> that you don't want to be derived from in C#:
</p>
<div class="code">
<pre>
struct NotABaseClass {
NotABaseClass();
~NotABaseClass();
};
</pre>
</div>
<p>
The default C# proxy class method generated with Dispose method is:
</p>
<div class="code">
<pre>
public class NotABaseClass : global::System.IDisposable {
...
public virtual void Dispose() {
...
}
}
</pre>
</div>
<p>
The <tt>csclassmodifiers</tt> typemap can be used to modify the class modifiers and
the <tt>csmethodmodifiers</tt> feature can be used on the destructor to modify the proxy's <tt>Dispose</tt> method:
</p>
<div class="code">
<pre>
%typemap(csclassmodifiers) NotABaseClass "public sealed class"
%csmethodmodifiers NotABaseClass::~NotABaseClass "public /*virtual*/";
</pre>
</div>
<p>
The relevant generated code is thus:
</p>
<div class="code">
<pre>
public sealed class NotABaseClass : global::System.IDisposable {
...
public /*virtual*/ void Dispose() {
...
}
}
</pre>
</div>
<p>
Any attempt to derive from the <tt>NotABaseClass</tt> in C# will result in a C# compiler error, for example:
</p>
<div class="code">
<pre>
public class Derived : NotABaseClass {
};
</pre>
</div>
<div class="shell">
<pre>
runme.cs(6,14): error CS0509: `Derived': cannot derive from sealed type `NotABaseClass'
</pre>
</div>
<p>
Finally, if you get a warning about use of 'protected' in the generated base class:
</p>
<div class="shell">
<pre>
NotABaseClass.cs(14,18): warning CS0628: `NotABaseClass.swigCMemOwn': new protected member declared in sealed class
</pre>
</div>
<p>
Either suppress the warning or modify the generated code by copying and tweaking the default
'csbody' typemap code in csharp.swg by modifying swigCMemOwn to not be protected.
</p>
<H3><a name="CSharp_extending_proxy_class">20.8.8 Extending proxy classes with additional C# code</a></H3>
<p>
@ -2654,7 +2745,7 @@ public class ExtendMe : global::System.IDisposable {
</pre>
</div>
<H3><a name="CSharp_enum_underlying_type">20.8.8 Underlying type for enums</a></H3>
<H3><a name="CSharp_enum_underlying_type">20.8.9 Underlying type for enums</a></H3>
<P>