Browse Source

Fixes for virtual dispatch for multiple inheritance.

+ Fix Itanium vtable layout: derived type's virtual methods come after primary base's but before the rest of the base classes'
+ Wrapper cleanup: move common init code to methods, cache all casted base wrappers right away in preparation for patching base-in-derived vtptrs
+ CppInstancePtr: read native_vtptr when constructed with native ptr-- will need hash lookup to detect managed instances
+ Clean/refactor LazyGeneratedList
pull/1/head
Alex Corrado 14 years ago
parent
commit
6a8bec014e
  1. 2
      src/Mono.VisualC.Interop/ABI/CppAbi.cs
  2. 37
      src/Mono.VisualC.Interop/ABI/Impl/ItaniumTypeInfo.cs
  3. 2
      src/Mono.VisualC.Interop/ABI/Impl/MsvcAbi.cs
  4. 56
      src/Mono.VisualC.Interop/ABI/Impl/MsvcTypeInfo.cs
  5. 8
      src/Mono.VisualC.Interop/CppInstancePtr.cs
  6. 65
      src/Mono.VisualC.Interop/CppTypeInfo.cs
  7. 1
      src/Mono.VisualC.Interop/Makefile.am
  8. 1
      src/Mono.VisualC.Interop/Mono.VisualC.Interop.csproj
  9. 129
      src/Mono.VisualC.Interop/Util/LazyGeneratedList.cs
  10. 374
      src/generator/Templates/CSharp/CSharpClass.cs
  11. 89
      src/generator/Templates/CSharp/CSharpClass.tt

2
src/Mono.VisualC.Interop/ABI/CppAbi.cs

@ -54,7 +54,7 @@ namespace Mono.VisualC.Interop.ABI {
protected static readonly MethodInfo cppip_managedalloc = typeof (CppInstancePtr).GetProperty ("IsManagedAlloc").GetGetMethod (); protected static readonly MethodInfo cppip_managedalloc = typeof (CppInstancePtr).GetProperty ("IsManagedAlloc").GetGetMethod ();
protected static readonly MethodInfo cppip_getmanaged = typeof (CppInstancePtr).GetMethod ("GetManaged", BindingFlags.Static | BindingFlags.NonPublic); protected static readonly MethodInfo cppip_getmanaged = typeof (CppInstancePtr).GetMethod ("GetManaged", BindingFlags.Static | BindingFlags.NonPublic);
protected static readonly ConstructorInfo cppip_fromnative = typeof (CppInstancePtr).GetConstructor (new Type [] { typeof (IntPtr) }); protected static readonly ConstructorInfo cppip_fromnative = typeof (CppInstancePtr).GetConstructor (new Type [] { typeof (IntPtr) });
protected static readonly ConstructorInfo cppip_fromsize = typeof (CppInstancePtr).GetConstructor (new Type [] { typeof (int) }); protected static readonly ConstructorInfo cppip_fromsize = typeof (CppInstancePtr).GetConstructor (BindingFlags.Instance | BindingFlags.NonPublic, null, new Type [] { typeof (int) }, null);
protected static readonly ConstructorInfo cppip_fromsize_managed = typeof (CppInstancePtr).GetConstructor (BindingFlags.Instance | BindingFlags.NonPublic, null, protected static readonly ConstructorInfo cppip_fromsize_managed = typeof (CppInstancePtr).GetConstructor (BindingFlags.Instance | BindingFlags.NonPublic, null,
new Type[] { typeof (int), typeof (object) }, null); new Type[] { typeof (int), typeof (object) }, null);
protected static readonly ConstructorInfo notimplementedexception = typeof (NotImplementedException).GetConstructor (new Type [] { typeof (string) }); protected static readonly ConstructorInfo notimplementedexception = typeof (NotImplementedException).GetConstructor (new Type [] { typeof (string) });

37
src/Mono.VisualC.Interop/ABI/Impl/ItaniumTypeInfo.cs

@ -38,25 +38,38 @@ namespace Mono.VisualC.Interop.ABI {
{ {
} }
protected override void AddBase (CppTypeInfo baseType, bool addVTable)
// When adding a non-primary base class's complete vtable, we need to reserve space for
// the stuff before the address point of the vtptr..
// Includes vbase & vcall offsets (virtual inheritance), offset to top, and RTTI info
public override void AddBase (CppTypeInfo baseType)
{ {
if (TypeComplete)
return;
if (BaseClasses.Count > 0 && baseType.VirtualMethods.Any ()) { // already have a primary base // When adding a non-primary base class's complete vtable, we need to reserve space for
// the stuff before the address point of the vtptr..
// Includes vbase & vcall offsets (virtual inheritance), offset to top, and RTTI info
if (addVTable) {
// FIXME: virtual inheritance // FIXME: virtual inheritance
virtual_methods.Insert (BaseVTableSlots, null); virtual_methods.Add (null);
virtual_methods.Insert (BaseVTableSlots, null); virtual_methods.Add (null);
BaseVTableSlots += 2;
vt_overrides.Add (2);
vt_delegate_types.Add (2);
}
base.AddBase (baseType, addVTable);
}
protected override bool OnVTableDuplicate (ref int iter, PInvokeSignature sig, PInvokeSignature dup)
{
var isOverride = base.OnVTableDuplicate (ref iter, sig, dup);
if (isOverride && sig.Type == MethodType.NativeDtor) {
// also remove that pesky extra dtor
virtual_methods.RemoveAt (iter + 1);
vt_overrides.Remove (1);
vt_delegate_types.Remove (1);
return true;
} }
base.AddBase (baseType); return false;
} }
} }

2
src/Mono.VisualC.Interop/ABI/Impl/MsvcAbi.cs

@ -49,7 +49,7 @@ namespace Mono.VisualC.Interop.ABI {
protected override CppTypeInfo MakeTypeInfo (IEnumerable<PInvokeSignature> methods) protected override CppTypeInfo MakeTypeInfo (IEnumerable<PInvokeSignature> methods)
{ {
return new MsvcTypeInfo (this, methods.Where (m => IsVirtual (m.OrigMethod)), layout_type, wrapper_type); return new CppTypeInfo (this, methods.Where (m => IsVirtual (m.OrigMethod)), layout_type, wrapper_type);
} }
public override CallingConvention? GetCallingConvention (MethodInfo methodInfo) public override CallingConvention? GetCallingConvention (MethodInfo methodInfo)

56
src/Mono.VisualC.Interop/ABI/Impl/MsvcTypeInfo.cs

@ -1,56 +0,0 @@
// Author:
// Alexander Corrado (alexander.corrado@gmail.com)
// Andreia Gaita (shana@spoiledcat.net)
//
// Copyright (C) 2010 Alexander Corrado
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Reflection;
using Mono.VisualC.Interop.Util;
namespace Mono.VisualC.Interop.ABI {
public class MsvcTypeInfo : CppTypeInfo {
public MsvcTypeInfo (MsvcAbi abi, IEnumerable<PInvokeSignature> virtualMethods, Type nativeLayout, Type wrapperType)
: base (abi, virtualMethods, nativeLayout, wrapperType)
{
}
// AFIK, MSVC places only its first base's virtual methods in the derived class's
// primary vtable. Subsequent base classes (each?) get another vtable pointer
public override void AddBase (CppTypeInfo baseType)
{
if (TypeComplete)
return;
if (BaseClasses.Count == 0)
base.AddBase (baseType, false);
else
base.AddBase (baseType, true);
}
}
}

8
src/Mono.VisualC.Interop/CppInstancePtr.cs

@ -70,6 +70,7 @@ namespace Mono.VisualC.Interop {
} }
// Alloc a new C++ instance // Alloc a new C++ instance
// NOTE: native_vtptr will be set later after native ctor is called
internal CppInstancePtr (int nativeSize, object managedWrapper) internal CppInstancePtr (int nativeSize, object managedWrapper)
{ {
// Under the hood, we're secretly subclassing this C++ class to store a // Under the hood, we're secretly subclassing this C++ class to store a
@ -89,7 +90,7 @@ namespace Mono.VisualC.Interop {
} }
// Alloc a new C++ instance when there is no managed wrapper. // Alloc a new C++ instance when there is no managed wrapper.
public CppInstancePtr (int nativeSize) internal CppInstancePtr (int nativeSize)
{ {
ptr = Marshal.AllocHGlobal (nativeSize); ptr = Marshal.AllocHGlobal (nativeSize);
manage_memory = true; manage_memory = true;
@ -101,6 +102,11 @@ namespace Mono.VisualC.Interop {
if (native == IntPtr.Zero) if (native == IntPtr.Zero)
throw new ArgumentOutOfRangeException ("native cannot be null pointer"); throw new ArgumentOutOfRangeException ("native cannot be null pointer");
// Kludge! CppInstancePtr doesn't know whether this class is virtual or not, but we'll just assume that either
// way it's at least sizeof(void*) and read what would be the vtptr anyway. Supposedly, if it's not virtual,
// the wrappers won't use this field anyway...
native_vtptr = Marshal.ReadIntPtr (native);
ptr = native; ptr = native;
manage_memory = false; manage_memory = false;
} }

65
src/Mono.VisualC.Interop/CppTypeInfo.cs

@ -103,9 +103,9 @@ namespace Mono.VisualC.Interop {
public virtual void AddBase (CppTypeInfo baseType) public virtual void AddBase (CppTypeInfo baseType)
{ {
// by default, if we already have base class(es), this base's virtual methods are not included before the derived class's
// by default, do not add another vtable for this new base class var addVTable = base_classes.Count >= 1;
AddBase (baseType, false); AddBase (baseType, addVTable);
} }
protected virtual void AddBase (CppTypeInfo baseType, bool addVTable) protected virtual void AddBase (CppTypeInfo baseType, bool addVTable)
@ -114,34 +114,38 @@ namespace Mono.VisualC.Interop {
return; return;
base_classes.Add (baseType); base_classes.Add (baseType);
bool addVTablePointer = addVTable || base_classes.Count > 1; bool addVTablePointer = addVTable || base_classes.Count > 1;
int baseVMethodCount = baseType.virtual_methods.Count;
if (addVTable) {
// If we are adding a new vtable, don't skew the offsets of the of this subclass's methods.
// Instead append the new virtual methods to the end.
for (int i = 0; i < baseVMethodCount; i++)
virtual_methods.Add (baseType.virtual_methods [i]);
vt_delegate_types.Add (baseVMethodCount);
vt_overrides.Add (baseVMethodCount);
} else {
if (!addVTable) {
// If we're not adding a new vtable, then all this base class's virtual methods go in primary vtable // If we're not adding a new vtable, then all this base class's virtual methods go in primary vtable
// Skew the offsets of this subclass's vmethods to account for the new base vmethods. // Skew the offsets of this subclass's vmethods to account for the new base vmethods.
int baseVMethodCount = baseType.virtual_methods.Count;
for (int i = 0; i < baseVMethodCount; i++) for (int i = 0; i < baseVMethodCount; i++)
virtual_methods.Insert (BaseVTableSlots + i, baseType.virtual_methods [i]); virtual_methods.Insert (BaseVTableSlots + i, baseType.virtual_methods [i]);
BaseVTableSlots += baseVMethodCount; BaseVTableSlots += baseVMethodCount;
vt_delegate_types.PrependLast (baseType.vt_delegate_types); vt_delegate_types.Add (baseVMethodCount);
//vt_overrides.PrependLast (baseType.vt_overrides);
vt_overrides.Add (baseVMethodCount); vt_overrides.Add (baseVMethodCount);
} else {
// FIXME: Implement this when we get around to msvc again ?
} }
field_offset_padding_without_vtptr += baseType.native_size + field_offset_padding_without_vtptr += baseType.native_size +
(addVTablePointer? baseType.FieldOffsetPadding : baseType.field_offset_padding_without_vtptr); (addVTablePointer? baseType.FieldOffsetPadding : baseType.field_offset_padding_without_vtptr);
} }
public virtual TBase Cast<TBase> (ICppObject instance) public virtual CppInstancePtr Cast (ICppObject instance, Type targetType)
where TBase : ICppObject
{ {
var targetType = typeof (TBase);
var found = false; var found = false;
int offset = 0; int offset = 0;
@ -162,11 +166,7 @@ namespace Mono.VisualC.Interop {
// it is Disposed, even if wrappers created here still exist and are pointing to it. :/ // it is Disposed, even if wrappers created here still exist and are pointing to it. :/
// The casted wrapper created here may be Disposed safely though. // The casted wrapper created here may be Disposed safely though.
// FIXME: On NET_4_0 use IntPtr.Add // FIXME: On NET_4_0 use IntPtr.Add
var cppip = new CppInstancePtr (new IntPtr (instance.Native.Native.ToInt64 () + offset)); return new CppInstancePtr (new IntPtr (instance.Native.Native.ToInt64 () + offset));
// Ugh, this requires boxing of cppip AND some slow reflection.. please cache the result of this!
// FIXME: Perhaps Reflection.Emit all possible base casts and eliminate this beast?
return (TBase)Activator.CreateInstance (targetType, cppip);
} }
public int CountBases (Func<CppTypeInfo, bool> predicate) public int CountBases (Func<CppTypeInfo, bool> predicate)
@ -189,14 +189,10 @@ namespace Mono.VisualC.Interop {
TypeComplete = true; TypeComplete = true;
// Tthis predicate ensures that duplicates are only removed RemoveVTableDuplicates ();
// if declared in different classes (i.e. overridden methods).
// We usually want to allow the same exact virtual methods to appear
// multiple times, in the case of nonvirtual diamond inheritance, for example.
RemoveVTableDuplicates ((pi1, pi2) => !pi1.OrigMethod.Equals (pi2.OrigMethod));
} }
protected virtual void RemoveVTableDuplicates (Func<PInvokeSignature,PInvokeSignature,bool> pred) protected virtual void RemoveVTableDuplicates ()
{ {
// check that any virtual methods overridden in a subclass are only included once // check that any virtual methods overridden in a subclass are only included once
var vsignatures = new Dictionary<MethodSignature,PInvokeSignature> (MethodSignature.EqualityComparer); var vsignatures = new Dictionary<MethodSignature,PInvokeSignature> (MethodSignature.EqualityComparer);
@ -208,14 +204,29 @@ namespace Mono.VisualC.Interop {
PInvokeSignature existing; PInvokeSignature existing;
if (vsignatures.TryGetValue (sig, out existing)) { if (vsignatures.TryGetValue (sig, out existing)) {
if (pred (sig, existing)) OnVTableDuplicate (ref i, sig, existing);
virtual_methods.RemoveAt (i--);
} else { } else {
vsignatures.Add (sig, sig); vsignatures.Add (sig, sig);
} }
} }
} }
protected virtual bool OnVTableDuplicate (ref int iter, PInvokeSignature sig, PInvokeSignature dup)
{
// This predicate ensures that duplicates are only removed
// if declared in different classes (i.e. overridden methods).
// We usually want to allow the same exact virtual methods to appear
// multiple times, in the case of nonvirtual diamond inheritance, for example.
if (!sig.OrigMethod.Equals (dup.OrigMethod)) {
virtual_methods.RemoveAt (iter--);
vt_overrides.Remove (1);
vt_delegate_types.Remove (1);
return true;
}
return false;
}
public virtual T GetAdjustedVirtualCall<T> (CppInstancePtr instance, int derivedVirtualMethodIndex) public virtual T GetAdjustedVirtualCall<T> (CppInstancePtr instance, int derivedVirtualMethodIndex)
where T : class /* Delegate */ where T : class /* Delegate */
{ {

1
src/Mono.VisualC.Interop/Makefile.am

@ -48,7 +48,6 @@ FILES = \
ABI/Impl/ItaniumAbi.cs \ ABI/Impl/ItaniumAbi.cs \
ABI/Impl/ItaniumTypeInfo.cs \ ABI/Impl/ItaniumTypeInfo.cs \
ABI/Impl/MsvcAbi.cs \ ABI/Impl/MsvcAbi.cs \
ABI/Impl/MsvcTypeInfo.cs \
ABI/Impl/VirtualOnlyAbi.cs \ ABI/Impl/VirtualOnlyAbi.cs \
ABI/MethodType.cs \ ABI/MethodType.cs \
ABI/VTable.cs \ ABI/VTable.cs \

1
src/Mono.VisualC.Interop/Mono.VisualC.Interop.csproj

@ -76,7 +76,6 @@
<Compile Include="Util\LazyGeneratedList.cs" /> <Compile Include="Util\LazyGeneratedList.cs" />
<Compile Include="Util\DelegateTypeCache.cs" /> <Compile Include="Util\DelegateTypeCache.cs" />
<Compile Include="Util\ReflectionHelper.cs" /> <Compile Include="Util\ReflectionHelper.cs" />
<Compile Include="ABI\Impl\MsvcTypeInfo.cs" />
<Compile Include="Util\MethodSignature.cs" /> <Compile Include="Util\MethodSignature.cs" />
<Compile Include="CppModifiers.cs" /> <Compile Include="CppModifiers.cs" />
<Compile Include="ABI\Impl\ItaniumTypeInfo.cs" /> <Compile Include="ABI\Impl\ItaniumTypeInfo.cs" />

129
src/Mono.VisualC.Interop/Util/LazyGeneratedList.cs

@ -32,50 +32,19 @@ using System.Collections.Generic;
namespace Mono.VisualC.Interop.Util { namespace Mono.VisualC.Interop.Util {
public class LazyGeneratedList<TItem> : IList<TItem> where TItem : class { public class LazyGeneratedList<TItem> : IList<TItem>
where TItem : class
private class Node<TItem> where TItem : class { {
public LazyGeneratedList<TItem> List { get; set; }
public Node<TItem> Next { get; set; }
public Node (LazyGeneratedList<TItem> list, Node<TItem> next)
{
this.List = list;
this.Next = next;
}
public void AppendNext (Node<TItem> node)
{
if (Next == null)
Next = node;
else
Next.AppendNext (node);
}
public TItem this [int index] {
get {
if (index >= List.Count)
return Next [index - List.Count];
return List [index];
}
}
}
private TItem [] cache; private TItem [] cache;
private Func<int, TItem> generator; private Func<int, TItem> generator;
private Node<TItem> previous; private int count;
private Node<TItem> next;
private int lead, content, follow;
private HashSet<int> removed;
public LazyGeneratedList (int count, Func<int, TItem> generator) public LazyGeneratedList (int count, Func<int, TItem> generator)
{ {
this.cache = new TItem [count]; this.cache = new TItem [count];
this.generator = generator; this.generator = generator;
this.lead = 0; this.count = count;
this.content = count;
this.follow = 0;
this.removed = new HashSet<int> ();
} }
public IEnumerator<TItem> GetEnumerator () public IEnumerator<TItem> GetEnumerator ()
@ -89,86 +58,37 @@ namespace Mono.VisualC.Interop.Util {
} }
public int Count { public int Count {
get { return lead + content + follow; } get { return count; }
} }
public bool IsReadOnly { public bool IsReadOnly {
get { return true; } get { return true; }
} }
public TItem this [int index] { public TItem this [int i] {
get { get {
return ForIndex (index, i => previous [i], i => (cache [i] == null? (cache [i] = generator (i)) : cache [i]), i => next [i]); // access to cache [i] will throw the IndexOutOfRange exception for us
return cache [i] == null? (cache [i] = generator (i)) : cache [i];
} }
set { set {
throw new NotSupportedException ("This IList is read only"); throw new NotSupportedException ("This IList is read only");
} }
} }
private TItem ForIndex (int index, Func<int,TItem> leadAction, Func<int,TItem> contentAction, Func<int,TItem> followAction) public void Add (int count)
{
if (removed.Contains (index))
index++;
if (index < lead) {
if (previous != null && index >= 0)
return leadAction (index);
throw new IndexOutOfRangeException (index.ToString ());
}
int realIndex = index - lead;
if (realIndex >= content) {
int followIndex = realIndex - content;
if (next != null && followIndex < follow)
return followAction (followIndex);
throw new IndexOutOfRangeException (index.ToString ());
}
return contentAction (realIndex);
}
/* Visual aid for the behavior of the following methods:
|<Prepended Range><Generated Range><Appended Range>|
^ ^ ^ ^
PrependFirst PrependLast AppendFirst AppendLast
*/
public void AppendFirst (LazyGeneratedList<TItem> list)
{ {
follow += list.Count; this.count += count;
next = new Node<TItem> (list, next); // flush cache
cache = new TItem [this.count];
} }
public void Remove (int count)
public void AppendLast (LazyGeneratedList<TItem> list)
{ {
var node = new Node<TItem> (list, null); this.count -= count;
if (next == null) // flush cache
next = node; cache = new TItem [this.count];
else
next.AppendNext (node);
follow += list.Count;
} }
public void PrependLast (LazyGeneratedList<TItem> list) // FIXME: Should probably implement these at some point
{
var node = new Node<TItem> (list, null);
if (previous == null)
previous = node;
else
previous.AppendNext (node);
lead += list.Count;
}
public void PrependFirst (LazyGeneratedList<TItem> list)
{
lead += list.Count;
previous = new Node<TItem> (list, previous);
}
// FIXME: Should probably implement these 3 at some point
public bool Contains (TItem item) public bool Contains (TItem item)
{ {
throw new NotImplementedException (); throw new NotImplementedException ();
@ -181,24 +101,13 @@ namespace Mono.VisualC.Interop.Util {
{ {
throw new NotImplementedException (); throw new NotImplementedException ();
} }
public void Insert (int index, TItem item) public void Insert (int index, TItem item)
{ {
throw new NotImplementedException (); throw new NotImplementedException ();
} }
public void RemoveAt (int index) public void RemoveAt (int index)
{ {
while (removed.Contains (index)) throw new NotImplementedException ();
index++;
removed.Add (index);
content--;
}
public void Add (int count)
{
content += count;
Array.Resize (ref cache, content);
} }
public void Add (TItem item) public void Add (TItem item)
{ {

374
src/generator/Templates/CSharp/CSharpClass.cs

@ -19,9 +19,9 @@ namespace Templates {
public partial class CSharpClass : Base { public partial class CSharpClass : Base {
#line 231 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 234 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
private void WriteMethodHeader (Method method, string initBases) private void WriteMethodHeader (Method method, string layoutClass)
{ {
var returnType = GetCSharpType (method.ReturnType); var returnType = GetCSharpType (method.ReturnType);
@ -45,7 +45,7 @@ private void WriteMethodHeader (Method method, string initBases)
Write (")\n"); Write (")\n");
if (method.IsConstructor) if (method.IsConstructor)
WriteLine (initBases); WriteLine (layoutClass);
else else
WriteLine ("{"); WriteLine ("{");
@ -152,206 +152,200 @@ private bool IsByVal (CppType t)
var wrapper = Class.Name; var wrapper = Class.Name;
var iface = "I" + Class.Name; var iface = "I" + Class.Name;
var layout = "_" + Class.Name; var layout = "_" + Class.Name;
var layoutClass = (hasBase? "\t: base (impl.TypeInfo)\n\t\t{" : "{") + "\n\t\t\tLayoutClass ();";
var initBases = "{"; var initBases = (Class.BaseClasses.Count > 1 ? "\tInitBases ();\n\t\t}" : "}");
if (hasBase) {
initBases = "\t: base (impl.TypeInfo) {";
foreach (var nonPrimaryBase in Class.BaseClasses.Skip (1)) {
initBases = string.Format ("{0}\n\t\t\tnew {1} (impl.TypeInfo);", initBases, nonPrimaryBase.Name);
}
}
#line default #line default
#line hidden #line hidden
#line 20 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 14 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("// -------------------------------------------------------------------------\n// Managed wrapper for "); this.Write("// -------------------------------------------------------------------------\n// Managed wrapper for ");
#line default #line default
#line hidden #line hidden
#line 21 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 15 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Class.Name )); this.Write(this.ToStringHelper.ToStringWithCulture( Class.Name ));
#line default #line default
#line hidden #line hidden
#line 21 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 15 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\n// Generated from "); this.Write("\n// Generated from ");
#line default #line default
#line hidden #line hidden
#line 22 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Path.GetFileName (Generator.InputFileName) )); this.Write(this.ToStringHelper.ToStringWithCulture( Path.GetFileName (Generator.InputFileName) ));
#line default #line default
#line hidden #line hidden
#line 22 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" on "); this.Write(" on ");
#line default #line default
#line hidden #line hidden
#line 22 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( DateTime.Now )); this.Write(this.ToStringHelper.ToStringWithCulture( DateTime.Now ));
#line default #line default
#line hidden #line hidden
#line 22 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\n//\n// This file was auto generated. Do not edit.\n// -------------------------------------------------------------------------\n\nusing System;\nusing Mono.VisualC.Interop;\n\nnamespace "); this.Write("\n//\n// This file was auto generated. Do not edit.\n// -------------------------------------------------------------------------\n\nusing System;\nusing Mono.VisualC.Interop;\n\nnamespace ");
#line default #line default
#line hidden #line hidden
#line 30 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 24 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Generator.Namespace )); this.Write(this.ToStringHelper.ToStringWithCulture( Generator.Namespace ));
#line default #line default
#line hidden #line hidden
#line 30 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 24 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" {\n\n\tpublic partial class "); this.Write(" {\n\n\tpublic partial class ");
#line default #line default
#line hidden #line hidden
#line 32 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 26 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); this.Write(this.ToStringHelper.ToStringWithCulture( wrapper ));
#line default #line default
#line hidden #line hidden
#line 32 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 26 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" : "); this.Write(" : ");
#line default #line default
#line hidden #line hidden
#line 32 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 26 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( GetBaseString () )); this.Write(this.ToStringHelper.ToStringWithCulture( GetBaseString () ));
#line default #line default
#line hidden #line hidden
#line 32 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 26 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" {\n\n\t\tprivate static readonly "); this.Write(" {\n\n\t\tprivate static readonly ");
#line default #line default
#line hidden #line hidden
#line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 28 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( iface )); this.Write(this.ToStringHelper.ToStringWithCulture( iface ));
#line default #line default
#line hidden #line hidden
#line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 28 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" impl = Libs."); this.Write(" impl = Libs.");
#line default #line default
#line hidden #line hidden
#line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 28 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Generator.LibBaseName )); this.Write(this.ToStringHelper.ToStringWithCulture( Generator.LibBaseName ));
#line default #line default
#line hidden #line hidden
#line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 28 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(".GetClass<"); this.Write(".GetClass<");
#line default #line default
#line hidden #line hidden
#line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 28 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( iface + "," + layout + "," + wrapper )); this.Write(this.ToStringHelper.ToStringWithCulture( iface + "," + layout + "," + wrapper ));
#line default #line default
#line hidden #line hidden
#line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 28 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("> (\""); this.Write("> (\"");
#line default #line default
#line hidden #line hidden
#line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 28 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Class.Name )); this.Write(this.ToStringHelper.ToStringWithCulture( Class.Name ));
#line default #line default
#line hidden #line hidden
#line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 28 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\");\n"); this.Write("\");\n");
#line default #line default
#line hidden #line hidden
#line 35 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 29 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
if (!hasBase) { if (!hasBase) {
#line default #line default
#line hidden #line hidden
#line 36 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 30 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\tpublic CppInstancePtr Native { get; protected set; }\n"); this.Write("\t\tpublic CppInstancePtr Native { get; protected set; }\n");
#line default #line default
#line hidden #line hidden
#line 37 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 31 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
} }
#line default #line default
#line hidden #line hidden
#line 38 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 32 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\n"); this.Write("\n");
#line default #line default
#line hidden #line hidden
#line 39 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 33 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
/* Interface */ /* Interface */
#line default #line default
#line hidden #line hidden
#line 40 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\tpublic interface "); this.Write("\t\tpublic interface ");
#line default #line default
#line hidden #line hidden
#line 40 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( iface )); this.Write(this.ToStringHelper.ToStringWithCulture( iface ));
#line default #line default
#line hidden #line hidden
#line 40 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" : ICppClassOverridable<"); this.Write(" : ICppClassOverridable<");
#line default #line default
#line hidden #line hidden
#line 40 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); this.Write(this.ToStringHelper.ToStringWithCulture( wrapper ));
#line default #line default
#line hidden #line hidden
#line 40 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("> {\n"); this.Write("> {\n");
#line default #line default
#line hidden #line hidden
#line 41 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 35 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
PushIndent ("\t\t\t"); PushIndent ("\t\t\t");
foreach (var method in Class.Methods) { foreach (var method in Class.Methods) {
Write (CurrentIndent); Write (CurrentIndent);
@ -393,91 +387,91 @@ private bool IsByVal (CppType t)
#line default #line default
#line hidden #line hidden
#line 78 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 72 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\t}\n"); this.Write("\t\t}\n");
#line default #line default
#line hidden #line hidden
#line 79 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 73 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
/* Native layout */ /* Native layout */
#line default #line default
#line hidden #line hidden
#line 80 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 74 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\tprivate struct "); this.Write("\t\tprivate struct ");
#line default #line default
#line hidden #line hidden
#line 80 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 74 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( layout )); this.Write(this.ToStringHelper.ToStringWithCulture( layout ));
#line default #line default
#line hidden #line hidden
#line 80 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 74 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" {\n"); this.Write(" {\n");
#line default #line default
#line hidden #line hidden
#line 81 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 75 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
foreach (var field in Class.Fields) { foreach (var field in Class.Fields) {
#line default #line default
#line hidden #line hidden
#line 82 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\t\tpublic "); this.Write("\t\t\tpublic ");
#line default #line default
#line hidden #line hidden
#line 82 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( GetCSharpType (field.Type) )); this.Write(this.ToStringHelper.ToStringWithCulture( GetCSharpType (field.Type) ));
#line default #line default
#line hidden #line hidden
#line 82 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" "); this.Write(" ");
#line default #line default
#line hidden #line hidden
#line 82 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( field.Name )); this.Write(this.ToStringHelper.ToStringWithCulture( field.Name ));
#line default #line default
#line hidden #line hidden
#line 82 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(";\n"); this.Write(";\n");
#line default #line default
#line hidden #line hidden
#line 83 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 77 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
} }
#line default #line default
#line hidden #line hidden
#line 84 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 78 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\t}\n\n"); this.Write("\t\t}\n\n");
#line default #line default
#line hidden #line hidden
#line 86 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 80 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
/* Native fields */ /* Native fields */
#line default #line default
#line hidden #line hidden
#line 87 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 81 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
PushIndent ("\t\t"); PushIndent ("\t\t");
foreach (var field in Class.Fields.Where (f => f.Access != Access.@private)) { foreach (var field in Class.Fields.Where (f => f.Access != Access.@private)) {
WriteLine ("{0} {1} {2} {{", field.Access, GetCSharpType (field.Type), field.Name); WriteLine ("{0} {1} {2} {{", field.Access, GetCSharpType (field.Type), field.Name);
@ -485,132 +479,155 @@ private bool IsByVal (CppType t)
#line default #line default
#line hidden #line hidden
#line 90 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 84 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\t\tget {\n\t\t\t\treturn impl."); this.Write("\t\t\tget {\n\t\t\t\treturn impl.");
#line default #line default
#line hidden #line hidden
#line 91 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 85 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( field.Name )); this.Write(this.ToStringHelper.ToStringWithCulture( field.Name ));
#line default #line default
#line hidden #line hidden
#line 91 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 85 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" [Native];\n\t\t\t}\n\t\t\tset {\n\t\t\t\timpl."); this.Write(" [Native];\n\t\t\t}\n\t\t\tset {\n\t\t\t\timpl.");
#line default #line default
#line hidden #line hidden
#line 94 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 88 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( field.Name )); this.Write(this.ToStringHelper.ToStringWithCulture( field.Name ));
#line default #line default
#line hidden #line hidden
#line 94 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 88 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" [Native] = value;\n\t\t\t}\n\t\t}\n"); this.Write(" [Native] = value;\n\t\t\t}\n\t\t}\n");
#line default #line default
#line hidden #line hidden
#line 97 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 91 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
} } ClearIndent();
ClearIndent();
#line default #line default
#line hidden #line hidden
#line 99 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 92 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\n"); this.Write("\n");
#line default #line default
#line hidden #line hidden
#line 100 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 93 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
/* Native constructor */ /* Subclass constructor */
#line default #line default
#line hidden #line hidden
#line 101 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 94 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\tpublic "); this.Write("\t\tpublic ");
#line default #line default
#line hidden #line hidden
#line 101 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 94 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); this.Write(this.ToStringHelper.ToStringWithCulture( wrapper ));
#line default #line default
#line hidden #line hidden
#line 101 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 94 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" (CppInstancePtr native)\n\t\t"); this.Write(" (CppTypeInfo subClass)\n\t\t");
#line default
#line hidden
#line 95 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( layoutClass ));
#line default #line default
#line hidden #line hidden
#line 102 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 95 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\n\t\t\tsubClass.AddBase (impl.TypeInfo);\n\t\t");
#line default
#line hidden
#line 97 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( initBases )); this.Write(this.ToStringHelper.ToStringWithCulture( initBases ));
#line default #line default
#line hidden #line hidden
#line 102 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 97 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\n\t\t\tNative = native;\n\t\t}\n\n"); this.Write("\n\n");
#line default #line default
#line hidden #line hidden
#line 106 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 99 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
/* Subclass constructor */ /* Native constructor */
#line default #line default
#line hidden #line hidden
#line 107 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 100 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\tpublic "); this.Write("\t\tpublic ");
#line default #line default
#line hidden #line hidden
#line 107 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 100 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); this.Write(this.ToStringHelper.ToStringWithCulture( wrapper ));
#line default #line default
#line hidden #line hidden
#line 107 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 100 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" (CppTypeInfo subClass)\n\t\t"); this.Write(" (CppInstancePtr native)\n\t\t");
#line default #line default
#line hidden #line hidden
#line 108 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 101 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( layoutClass ));
#line default
#line hidden
#line 101 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\n\t\t\tNative = native;\n\t\t");
#line default
#line hidden
#line 103 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( initBases )); this.Write(this.ToStringHelper.ToStringWithCulture( initBases ));
#line default #line default
#line hidden #line hidden
#line 108 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 103 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\n\t\t\tsubClass.AddBase (impl.TypeInfo);\n\t\t}\n\n"); this.Write("\n\n");
#line default #line default
#line hidden #line hidden
#line 112 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 105 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
/* Wrapper methods */ /* Wrapper methods */
#line default #line default
#line hidden #line hidden
#line 113 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 106 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
PushIndent ("\t\t"); PushIndent ("\t\t");
foreach (var method in Class.Methods.Where (m => m.GenWrapperMethod)) { foreach (var method in Class.Methods.Where (m => m.GenWrapperMethod)) {
WriteMethodHeader (method, initBases); WriteMethodHeader (method, layoutClass);
if (method.IsConstructor) if (method.IsConstructor)
Write ("Native = "); Write ("Native = ");
@ -626,27 +643,32 @@ private bool IsByVal (CppType t)
} }
WriteParameters (method.Parameters, false, false); WriteParameters (method.Parameters, false, false);
Write (");\n");
PopIndent (); PopIndent ();
Write (");\n{0}}}\n\n", CurrentIndent);
if (method.IsConstructor)
WriteLine (initBases);
else
WriteLine ("}");
} }
ClearIndent (); ClearIndent ();
#line default #line default
#line hidden #line hidden
#line 136 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 134 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\n"); this.Write("\n");
#line default #line default
#line hidden #line hidden
#line 137 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 135 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
/* Wrapper properties */ /* Wrapper properties */
#line default #line default
#line hidden #line hidden
#line 138 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 136 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
PushIndent ("\t\t"); PushIndent ("\t\t");
foreach (var prop in Class.Properties) { foreach (var prop in Class.Properties) {
var type = GetCSharpType (prop.Type); var type = GetCSharpType (prop.Type);
@ -694,173 +716,170 @@ private bool IsByVal (CppType t)
#line default #line default
#line hidden #line hidden
#line 181 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 179 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\n"); this.Write("\n\t\tpublic ");
#line default #line default
#line hidden #line hidden
#line 182 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 180 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
/* Make this wrapper castable to non-primary bases */ this.Write(this.ToStringHelper.ToStringWithCulture( hasBase? "override" : "virtual" ));
foreach (var npBase in Class.BaseClasses.Skip (1)) {
var prop = npBase.Name;
var field = prop + "_lazy";
#line default #line default
#line hidden #line hidden
#line 187 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 180 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\t// Non-primary base class implementation for "); this.Write(" void Dispose ()\n\t\t{\n");
#line default #line default
#line hidden #line hidden
#line 187 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 182 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); if (Class.Methods.Any (m => m.IsDestructor && !m.IsArtificial)) {
#line default #line default
#line hidden #line hidden
#line 187 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 183 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(":\n\t\tprivate "); this.Write("\t\t\timpl.Destruct (Native);\n");
#line default #line default
#line hidden #line hidden
#line 188 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 184 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); }
#line default #line default
#line hidden #line hidden
#line 188 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 185 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" "); this.Write("\t\t\tNative.Dispose ();\n\t\t}\n\n\t\tprivate void LayoutClass ()\n\t\t{\n");
#line default #line default
#line hidden #line hidden
#line 188 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 190 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( field )); foreach (var npBase in Class.BaseClasses.Skip (1)) {
#line default #line default
#line hidden #line hidden
#line 188 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 191 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(";\n\t\tpublic "); this.Write("\t\t\tnew ");
#line default #line default
#line hidden #line hidden
#line 189 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 191 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name ));
#line default #line default
#line hidden #line hidden
#line 189 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 191 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" "); this.Write(" (impl.TypeInfo);\n");
#line default #line default
#line hidden #line hidden
#line 189 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 192 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( prop )); }
#line default #line default
#line hidden #line hidden
#line 189 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 193 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" {\n\t\t\tget {\n\t\t\t\tif ("); this.Write("\t\t\timpl.TypeInfo.CompleteType ();\n\t\t}\n\n");
#line default #line default
#line hidden #line hidden
#line 191 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 196 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( field )); /* Make this wrapper castable to non-primary bases */
foreach (var npBase in Class.BaseClasses.Skip (1)) {
#line default #line default
#line hidden #line hidden
#line 191 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 198 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" == null)\n\t\t\t\t\t"); this.Write("\t\t// Non-primary base class implementation for ");
#line default #line default
#line hidden #line hidden
#line 192 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 198 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( field )); this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name ));
#line default #line default
#line hidden #line hidden
#line 192 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 198 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" = impl.TypeInfo.Cast<"); this.Write(":\n\t\tpublic ");
#line default #line default
#line hidden #line hidden
#line 192 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 199 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name ));
#line default #line default
#line hidden #line hidden
#line 192 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 199 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("> (this);\n\t\t\t\treturn "); this.Write(" ");
#line default #line default
#line hidden #line hidden
#line 193 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 199 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( field )); this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name ));
#line default #line default
#line hidden #line hidden
#line 193 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 199 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(";\n\t\t\t}\n\t\t}\n\t\tpublic static implicit operator "); this.Write(" { get; protected set; }\n\t\tpublic static implicit operator ");
#line default #line default
#line hidden #line hidden
#line 196 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 200 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name ));
#line default #line default
#line hidden #line hidden
#line 196 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 200 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("("); this.Write("(");
#line default #line default
#line hidden #line hidden
#line 196 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 200 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); this.Write(this.ToStringHelper.ToStringWithCulture( wrapper ));
#line default #line default
#line hidden #line hidden
#line 196 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 200 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" subClass)\n\t\t{\n\t\t\treturn subClass."); this.Write(" subClass)\n\t\t{\n\t\t\treturn subClass.");
#line default #line default
#line hidden #line hidden
#line 198 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 202 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( prop )); this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name ));
#line default #line default
#line hidden #line hidden
#line 198 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 202 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(";\n\t\t}\n\n"); this.Write(";\n\t\t}\n\n");
#line default #line default
#line hidden #line hidden
#line 201 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 205 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
PushIndent ("\t\t"); PushIndent ("\t\t");
foreach (var method in npBase.Methods) { foreach (var method in npBase.Methods) {
// With the exception of virtual methods that have been overridden, these methods must be called // With the exception of virtual methods that have been overridden, these methods must be called
@ -871,56 +890,93 @@ foreach (var npBase in Class.BaseClasses.Skip (1)) {
WriteMethodHeader (method, initBases); WriteMethodHeader (method, initBases);
Write ("{0}.{1} (", prop, method.FormattedName); Write ("{0}.{1} (", npBase.Name, method.FormattedName);
WriteParameters (method.Parameters, false, false); WriteParameters (method.Parameters, false, false);
PopIndent (); PopIndent ();
Write (");\n{0}}}\n\n", CurrentIndent); Write (");\n{0}}}\n\n", CurrentIndent);
} }
ClearIndent (); ClearIndent ();
} }
if (Class.BaseClasses.Count > 1) {
#line default #line default
#line hidden #line hidden
#line 219 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 224 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\n\t\tpublic "); this.Write("\t\tprivate void InitBases ()\n\t\t{\n");
#line default #line default
#line hidden #line hidden
#line 220 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 226 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( hasBase? "override" : "virtual" )); foreach (var npBase in Class.BaseClasses.Skip (1)) {
#line default #line default
#line hidden #line hidden
#line 220 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 227 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" void Dispose ()\n\t\t{\n"); this.Write("\t\t\t");
#line default #line default
#line hidden #line hidden
#line 222 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 227 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
if (Class.Methods.Any (m => m.IsDestructor && !m.IsArtificial)) { this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name ));
#line default #line default
#line hidden #line hidden
#line 223 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 227 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\t\timpl.Destruct (Native);\n"); this.Write(" = new ");
#line default #line default
#line hidden #line hidden
#line 224 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 227 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name ));
#line default
#line hidden
#line 227 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(" (impl.TypeInfo.Cast (this, typeof (");
#line default
#line hidden
#line 227 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name ));
#line default
#line hidden
#line 227 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write(")));\n");
#line default
#line hidden
#line 228 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
}
#line default
#line hidden
#line 229 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\t}\n");
#line default
#line hidden
#line 230 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
} }
#line default #line default
#line hidden #line hidden
#line 225 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" #line 231 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt"
this.Write("\t\t\tNative.Dispose ();\n\t\t}\n\n\t}\n}\n\n"); this.Write("\t}\n}\n\n");
#line default #line default
#line hidden #line hidden

89
src/generator/Templates/CSharp/CSharpClass.tt

@ -8,14 +8,8 @@
var wrapper = Class.Name; var wrapper = Class.Name;
var iface = "I" + Class.Name; var iface = "I" + Class.Name;
var layout = "_" + Class.Name; var layout = "_" + Class.Name;
var layoutClass = (hasBase? "\t: base (impl.TypeInfo)\n\t\t{" : "{") + "\n\t\t\tLayoutClass ();";
var initBases = "{"; var initBases = (Class.BaseClasses.Count > 1 ? "\tInitBases ();\n\t\t}" : "}");
if (hasBase) {
initBases = "\t: base (impl.TypeInfo) {";
foreach (var nonPrimaryBase in Class.BaseClasses.Skip (1)) {
initBases = string.Format ("{0}\n\t\t\tnew {1} (impl.TypeInfo);", initBases, nonPrimaryBase.Name);
}
}
#> #>
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Managed wrapper for <#= Class.Name #> // Managed wrapper for <#= Class.Name #>
@ -94,26 +88,25 @@ namespace <#= Generator.Namespace #> {
impl.<#= field.Name #> [Native] = value; impl.<#= field.Name #> [Native] = value;
} }
} }
<# } <# } ClearIndent(); #>
ClearIndent(); #>
<# /* Subclass constructor */ #>
public <#= wrapper #> (CppTypeInfo subClass)
<#= layoutClass #>
subClass.AddBase (impl.TypeInfo);
<#= initBases #>
<# /* Native constructor */ #> <# /* Native constructor */ #>
public <#= wrapper #> (CppInstancePtr native) public <#= wrapper #> (CppInstancePtr native)
<#= initBases #> <#= layoutClass #>
Native = native; Native = native;
}
<# /* Subclass constructor */ #>
public <#= wrapper #> (CppTypeInfo subClass)
<#= initBases #> <#= initBases #>
subClass.AddBase (impl.TypeInfo);
}
<# /* Wrapper methods */ #> <# /* Wrapper methods */ #>
<# PushIndent ("\t\t"); <# PushIndent ("\t\t");
foreach (var method in Class.Methods.Where (m => m.GenWrapperMethod)) { foreach (var method in Class.Methods.Where (m => m.GenWrapperMethod)) {
WriteMethodHeader (method, initBases); WriteMethodHeader (method, layoutClass);
if (method.IsConstructor) if (method.IsConstructor)
Write ("Native = "); Write ("Native = ");
@ -129,8 +122,13 @@ namespace <#= Generator.Namespace #> {
} }
WriteParameters (method.Parameters, false, false); WriteParameters (method.Parameters, false, false);
Write (");\n");
PopIndent (); PopIndent ();
Write (");\n{0}}}\n\n", CurrentIndent);
if (method.IsConstructor)
WriteLine (initBases);
else
WriteLine ("}");
} }
ClearIndent (); #> ClearIndent (); #>
@ -179,23 +177,29 @@ namespace <#= Generator.Namespace #> {
} }
ClearIndent (); #> ClearIndent (); #>
public <#= hasBase? "override" : "virtual" #> void Dispose ()
{
<# if (Class.Methods.Any (m => m.IsDestructor && !m.IsArtificial)) { #>
impl.Destruct (Native);
<# } #>
Native.Dispose ();
}
private void LayoutClass ()
{
<# foreach (var npBase in Class.BaseClasses.Skip (1)) { #>
new <#= npBase.Name #> (impl.TypeInfo);
<# } #>
impl.TypeInfo.CompleteType ();
}
<# /* Make this wrapper castable to non-primary bases */ <# /* Make this wrapper castable to non-primary bases */
foreach (var npBase in Class.BaseClasses.Skip (1)) { foreach (var npBase in Class.BaseClasses.Skip (1)) { #>
var prop = npBase.Name;
var field = prop + "_lazy";
#>
// Non-primary base class implementation for <#= npBase.Name #>: // Non-primary base class implementation for <#= npBase.Name #>:
private <#= npBase.Name #> <#= field #>; public <#= npBase.Name #> <#= npBase.Name #> { get; protected set; }
public <#= npBase.Name #> <#= prop #> {
get {
if (<#= field #> == null)
<#= field #> = impl.TypeInfo.Cast<<#= npBase.Name #>> (this);
return <#= field #>;
}
}
public static implicit operator <#= npBase.Name #>(<#= wrapper #> subClass) public static implicit operator <#= npBase.Name #>(<#= wrapper #> subClass)
{ {
return subClass.<#= prop #>; return subClass.<#= npBase.Name #>;
} }
<# PushIndent ("\t\t"); <# PushIndent ("\t\t");
@ -208,28 +212,27 @@ foreach (var npBase in Class.BaseClasses.Skip (1)) {
WriteMethodHeader (method, initBases); WriteMethodHeader (method, initBases);
Write ("{0}.{1} (", prop, method.FormattedName); Write ("{0}.{1} (", npBase.Name, method.FormattedName);
WriteParameters (method.Parameters, false, false); WriteParameters (method.Parameters, false, false);
PopIndent (); PopIndent ();
Write (");\n{0}}}\n\n", CurrentIndent); Write (");\n{0}}}\n\n", CurrentIndent);
} }
ClearIndent (); ClearIndent ();
} #> }
if (Class.BaseClasses.Count > 1) { #>
public <#= hasBase? "override" : "virtual" #> void Dispose () private void InitBases ()
{ {
<# if (Class.Methods.Any (m => m.IsDestructor && !m.IsArtificial)) { #> <# foreach (var npBase in Class.BaseClasses.Skip (1)) { #>
impl.Destruct (Native); <#= npBase.Name #> = new <#= npBase.Name #> (impl.TypeInfo.Cast (this, typeof (<#= npBase.Name #>)));
<# } #> <# } #>
Native.Dispose ();
} }
<# } #>
} }
} }
<#+ <#+
private void WriteMethodHeader (Method method, string initBases) private void WriteMethodHeader (Method method, string layoutClass)
{ {
var returnType = GetCSharpType (method.ReturnType); var returnType = GetCSharpType (method.ReturnType);
@ -253,7 +256,7 @@ private void WriteMethodHeader (Method method, string initBases)
Write (")\n"); Write (")\n");
if (method.IsConstructor) if (method.IsConstructor)
WriteLine (initBases); WriteLine (layoutClass);
else else
WriteLine ("{"); WriteLine ("{");

Loading…
Cancel
Save