Browse Source

Added much better support for base classes.

pull/1/head
triton 13 years ago
parent
commit
c0fd74f7aa
  1. 37
      src/Generator/Generators/CLI/CLIHeadersTemplate.cs
  2. 78
      src/Generator/Generators/CLI/CLISourcesTemplate.cs

37
src/Generator/Generators/CLI/CLIHeadersTemplate.cs

@ -219,10 +219,24 @@ namespace Cxxi.Generators.CLI
public void GenerateClassConstructors(Class @class, string nativeType) public void GenerateClassConstructors(Class @class, string nativeType)
{ {
// Output a default constructor that takes the native pointer.
PushIndent(); PushIndent();
// Output a default constructor that takes the native pointer.
WriteLine("{0}({1} native);", SafeIdentifier(@class.Name), nativeType); WriteLine("{0}({1} native);", SafeIdentifier(@class.Name), nativeType);
WriteLine("{0}({1} native);", SafeIdentifier(@class.Name), "System::IntPtr"); WriteLine("{0}({1} native);", SafeIdentifier(@class.Name), "System::IntPtr");
foreach (var ctor in @class.Constructors)
{
if (ctor.IsCopyConstructor || ctor.IsMoveConstructor)
continue;
// Default constructors are not supported in .NET value types.
if (ctor.Parameters.Count == 0 && @class.IsValueType)
continue;
GenerateMethod(ctor);
}
PopIndent(); PopIndent();
} }
@ -242,6 +256,23 @@ namespace Cxxi.Generators.CLI
WriteLine("{0} {1};", field.Type, SafeIdentifier(field.Name)); WriteLine("{0} {1};", field.Type, SafeIdentifier(field.Name));
} }
PopIndent(); PopIndent();
// Handle the case of struct (value-type) inheritance by adding the base
// fields to the managed value subtypes.
foreach (var @base in @class.Bases)
{
Class baseClass;
if (!@base.Type.IsTagDecl(out baseClass))
continue;
if (!baseClass.IsValueType || baseClass.Ignore)
{
Console.WriteLine("Ignored base class of value type '{0}'", baseClass.Name);
continue;
}
GenerateClassFields(baseClass);
}
} }
public void GenerateClassMethods(Class @class) public void GenerateClassMethods(Class @class)
@ -254,6 +285,9 @@ namespace Cxxi.Generators.CLI
if (CheckIgnoreMethod(@class, method)) if (CheckIgnoreMethod(@class, method))
continue; continue;
if (method.IsConstructor)
continue;
if (method.IsStatic) if (method.IsStatic)
{ {
staticMethods.Add(method); staticMethods.Add(method);
@ -426,6 +460,7 @@ namespace Cxxi.Generators.CLI
WriteLine(","); WriteLine(",");
} }
PopIndent(); PopIndent();
NewLine(); NewLine();
WriteLine("};"); WriteLine("};");
} }

78
src/Generator/Generators/CLI/CLISourcesTemplate.cs

@ -136,29 +136,64 @@ namespace Cxxi.Generators.CLI
var nativeType = string.Format("::{0}*", @class.OriginalName); var nativeType = string.Format("::{0}*", @class.OriginalName);
WriteLine("{0} native)", isIntPtr ? "System::IntPtr" : nativeType); WriteLine("{0} native)", isIntPtr ? "System::IntPtr" : nativeType);
WriteLine("{");
PushIndent(); var hasBase = GenerateClassConstructorBase(@class);
WriteStartBraceIndent();
if (@class.IsRefType) if (@class.IsRefType)
{ {
Write("NativePtr = "); if (!hasBase)
if (isIntPtr) {
Write("({0})", nativeType); Write("NativePtr = ");
Write("native");
if (isIntPtr) if (isIntPtr)
Write(".ToPointer()"); Write("({0})", nativeType);
WriteLine(";"); Write("native");
if (isIntPtr)
Write(".ToPointer()");
WriteLine(";");
}
} }
else else
{ {
WriteLine("// TODO: Struct marshaling"); WriteLine("// TODO: Struct marshaling");
} }
PopIndent(); WriteCloseBraceIndent();
WriteLine("}");
NewLine(); NewLine();
} }
private void GenerateStructMarshaling(Class @class)
{
foreach (var field in @class.Fields)
{
WriteLine("{0} = {1}");
}
}
private bool GenerateClassConstructorBase(Class @class, Method method = null)
{
var hasBase = @class.HasBase && !@class.Bases[0].Class.Ignore;
if (hasBase && !@class.IsValueType)
{
PushIndent();
Write(": {0}(", @class.Bases[0].Class.Name);
if (method != null)
Write("nullptr");
else
Write("native");
WriteLine(")");
PopIndent();
}
return hasBase;
}
public void GenerateMethod(Method method, Class @class) public void GenerateMethod(Method method, Class @class)
{ {
GenerateDeclarationCommon(method); GenerateDeclarationCommon(method);
@ -172,17 +207,23 @@ namespace Cxxi.Generators.CLI
GenerateMethodParameters(method); GenerateMethodParameters(method);
WriteLine(")"); WriteLine(")");
WriteLine("{");
PushIndent(); if (method.Kind == CXXMethodKind.Constructor)
GenerateClassConstructorBase(@class, method);
WriteStartBraceIndent();
if (@class.IsRefType) if (@class.IsRefType)
{ {
if (method.Kind == CXXMethodKind.Constructor) if (method.Kind == CXXMethodKind.Constructor)
{ {
var @params = GenerateFunctionParamsMarshal(method); if (!@class.IsAbstract)
Write("NativePtr = new ::{0}(", method.QualifiedOriginalName); {
GenerateFunctionParams(method, @params); var @params = GenerateFunctionParamsMarshal(method);
WriteLine(");"); Write("NativePtr = new ::{0}(", method.QualifiedOriginalName);
GenerateFunctionParams(method, @params);
WriteLine(");");
}
} }
else else
{ {
@ -195,8 +236,7 @@ namespace Cxxi.Generators.CLI
GenerateFunctionCall(method, @class); GenerateFunctionCall(method, @class);
} }
PopIndent(); WriteCloseBraceIndent();
WriteLine("}");
} }
public void GenerateFunction(Function function, string className) public void GenerateFunction(Function function, string className)

Loading…
Cancel
Save