Browse Source

Add blocks for ctor, dtor, and finalizer bodies. Add constructor that takes a bool from the caller to indicate if the callee should own the pointer passed to it or not

pull/1320/head
Build Agent 6 years ago committed by João Matos
parent
commit
010099021c
  1. 1
      src/Generator/Generators/CLI/CLIHeaders.cs
  2. 10
      src/Generator/Generators/CLI/CLIMarshal.cs
  3. 48
      src/Generator/Generators/CLI/CLISources.cs
  4. 3
      src/Generator/Utils/BlockGenerator.cs

1
src/Generator/Generators/CLI/CLIHeaders.cs

@ -376,6 +376,7 @@ namespace CppSharp.Generators.CLI
// Output a default constructor that takes the native pointer. // Output a default constructor that takes the native pointer.
WriteLine("{0}({1} native);", @class.Name, nativeType); WriteLine("{0}({1} native);", @class.Name, nativeType);
WriteLine("{0}({1} native, bool ownNativeInstance);", @class.Name, nativeType);
WriteLine("static {0}^ {1}(::System::IntPtr native);", WriteLine("static {0}^ {1}(::System::IntPtr native);",
@class.Name, Helpers.CreateInstanceIdentifier); @class.Name, Helpers.CreateInstanceIdentifier);

10
src/Generator/Generators/CLI/CLIMarshal.cs

@ -275,15 +275,19 @@ namespace CppSharp.Generators.CLI
instance += Context.ReturnVarName; instance += Context.ReturnVarName;
var needsCopy = Context.MarshalKind != MarshalKind.NativeField; var needsCopy = Context.MarshalKind != MarshalKind.NativeField;
bool ownNativeInstance = false;
if (@class.IsRefType && needsCopy) if (@class.IsRefType && needsCopy)
{ {
var name = Generator.GeneratedIdentifier(Context.ReturnVarName); var name = Generator.GeneratedIdentifier(Context.ReturnVarName);
Context.Before.WriteLine("auto {0} = new ::{1}({2});", name, Context.Before.WriteLine("auto {0} = new ::{1}({2});", name,
@class.QualifiedOriginalName, Context.ReturnVarName); @class.QualifiedOriginalName, Context.ReturnVarName);
instance = name; instance = name;
ownNativeInstance = true;
} }
WriteClassInstance(@class, instance); WriteClassInstance(@class, instance, ownNativeInstance);
return true; return true;
} }
@ -295,7 +299,7 @@ namespace CppSharp.Generators.CLI
return decl.QualifiedName; return decl.QualifiedName;
} }
public void WriteClassInstance(Class @class, string instance) public void WriteClassInstance(Class @class, string instance, bool ownNativeInstance = false)
{ {
if (@class.IsRefType) if (@class.IsRefType)
Context.Return.Write("({0} == nullptr) ? nullptr : gcnew ", Context.Return.Write("({0} == nullptr) ? nullptr : gcnew ",
@ -303,7 +307,7 @@ namespace CppSharp.Generators.CLI
Context.Return.Write("{0}(", QualifiedIdentifier(@class)); Context.Return.Write("{0}(", QualifiedIdentifier(@class));
Context.Return.Write("(::{0}*)", @class.QualifiedOriginalName); Context.Return.Write("(::{0}*)", @class.QualifiedOriginalName);
Context.Return.Write("{0})", instance); Context.Return.Write("{0}{1})", instance, ownNativeInstance ? ", true" : "");
} }
public override bool VisitFieldDecl(Field field) public override bool VisitFieldDecl(Field field)

48
src/Generator/Generators/CLI/CLISources.cs

@ -250,6 +250,8 @@ namespace CppSharp.Generators.CLI
WriteLine("{0}::~{1}()", QualifiedIdentifier(@class), @class.Name); WriteLine("{0}::~{1}()", QualifiedIdentifier(@class), @class.Name);
WriteOpenBraceAndIndent(); WriteOpenBraceAndIndent();
PushBlock(BlockKind.DestructorBody, @class);
if (CLIGenerator.ShouldGenerateClassNativeField(@class)) if (CLIGenerator.ShouldGenerateClassNativeField(@class))
{ {
WriteLine("delete NativePtr;"); WriteLine("delete NativePtr;");
@ -264,6 +266,8 @@ namespace CppSharp.Generators.CLI
UnindentAndWriteCloseBrace(); UnindentAndWriteCloseBrace();
} }
PopBlock();
UnindentAndWriteCloseBrace(); UnindentAndWriteCloseBrace();
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
@ -276,9 +280,13 @@ namespace CppSharp.Generators.CLI
WriteLine("{0}::!{1}()", QualifiedIdentifier(@class), @class.Name); WriteLine("{0}::!{1}()", QualifiedIdentifier(@class), @class.Name);
WriteOpenBraceAndIndent(); WriteOpenBraceAndIndent();
PushBlock(BlockKind.FinalizerBody, @class);
if (CLIGenerator.ShouldGenerateClassNativeField(@class)) if (CLIGenerator.ShouldGenerateClassNativeField(@class))
WriteLine("delete NativePtr;"); WriteLine("delete NativePtr;");
PopBlock();
UnindentAndWriteCloseBrace(); UnindentAndWriteCloseBrace();
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
@ -618,16 +626,16 @@ namespace CppSharp.Generators.CLI
GeneratePropertySetter(variable, @class, variable.Name, variable.Type); GeneratePropertySetter(variable, @class, variable.Name, variable.Type);
} }
private void GenerateClassConstructor(Class @class) private void GenerateClassConstructor(Class @class, bool withOwnNativeInstanceParam = false)
{ {
string qualifiedIdentifier = QualifiedIdentifier(@class); string qualifiedIdentifier = QualifiedIdentifier(@class);
Write("{0}::{1}(", qualifiedIdentifier, @class.Name); Write("{0}::{1}(", qualifiedIdentifier, @class.Name);
var nativeType = string.Format("::{0}*", @class.QualifiedOriginalName); var nativeType = string.Format("::{0}*", @class.QualifiedOriginalName);
WriteLine("{0} native)", nativeType); WriteLine(!withOwnNativeInstanceParam ? "{0} native)" : "{0} native, const bool ownNativeInstance)", nativeType);
var hasBase = GenerateClassConstructorBase(@class); var hasBase = GenerateClassConstructorBase(@class, null, withOwnNativeInstanceParam);
if (CLIGenerator.ShouldGenerateClassNativeField(@class)) if (CLIGenerator.ShouldGenerateClassNativeField(@class))
{ {
@ -635,11 +643,13 @@ namespace CppSharp.Generators.CLI
Write(hasBase ? "," : ":"); Write(hasBase ? "," : ":");
Unindent(); Unindent();
WriteLine(" {0}(false)", Helpers.OwnsNativeInstanceIdentifier); WriteLine(!withOwnNativeInstanceParam ? " {0}(false)" : " {0}(ownNativeInstance)", Helpers.OwnsNativeInstanceIdentifier);
} }
WriteOpenBraceAndIndent(); WriteOpenBraceAndIndent();
PushBlock(BlockKind.ConstructorBody, @class);
const string nativePtr = "native"; const string nativePtr = "native";
if (@class.IsRefType) if (@class.IsRefType)
@ -654,16 +664,24 @@ namespace CppSharp.Generators.CLI
GenerateStructMarshaling(@class, nativePtr + "->"); GenerateStructMarshaling(@class, nativePtr + "->");
} }
PopBlock();
UnindentAndWriteCloseBrace(); UnindentAndWriteCloseBrace();
NewLine();
WriteLine("{0}^ {0}::{1}(::System::IntPtr native)", qualifiedIdentifier, Helpers.CreateInstanceIdentifier);
WriteOpenBraceAndIndent(); if (!withOwnNativeInstanceParam)
{
NewLine();
WriteLine("{0}^ {0}::{1}(::System::IntPtr native)", qualifiedIdentifier, Helpers.CreateInstanceIdentifier);
WriteLine("return gcnew ::{0}(({1}) native.ToPointer());", qualifiedIdentifier, nativeType); WriteOpenBraceAndIndent();
UnindentAndWriteCloseBrace(); WriteLine("return gcnew ::{0}(({1}) native.ToPointer());", qualifiedIdentifier, nativeType);
NewLine();
UnindentAndWriteCloseBrace();
NewLine();
GenerateClassConstructor(@class, true);
}
} }
private void GenerateStructMarshaling(Class @class, string nativeVar) private void GenerateStructMarshaling(Class @class, string nativeVar)
@ -701,7 +719,7 @@ namespace CppSharp.Generators.CLI
} }
} }
private bool GenerateClassConstructorBase(Class @class, Method method = null) private bool GenerateClassConstructorBase(Class @class, Method method = null, bool withOwnNativeInstanceParam = false)
{ {
var hasBase = @class.HasBase && @class.Bases[0].IsClass && @class.Bases[0].Class.IsGenerated; var hasBase = @class.HasBase && @class.Bases[0].IsClass && @class.Bases[0].Class.IsGenerated;
if (!hasBase) if (!hasBase)
@ -720,7 +738,7 @@ namespace CppSharp.Generators.CLI
var nativeTypeName = baseClass.Visit(cppTypePrinter); var nativeTypeName = baseClass.Visit(cppTypePrinter);
Write("({0}*)", nativeTypeName); Write("({0}*)", nativeTypeName);
WriteLine("{0})", method != null ? "nullptr" : "native"); WriteLine("{0}{1})", method != null ? "nullptr" : "native", !withOwnNativeInstanceParam ? "" : ", ownNativeInstance");
Unindent(); Unindent();
} }
@ -754,7 +772,11 @@ namespace CppSharp.Generators.CLI
PushBlock(BlockKind.MethodBody, method); PushBlock(BlockKind.MethodBody, method);
if (method.IsConstructor && @class.IsRefType) if (method.IsConstructor && @class.IsRefType)
{
PushBlock(BlockKind.ConstructorBody, @class);
WriteLine("{0} = true;", Helpers.OwnsNativeInstanceIdentifier); WriteLine("{0} = true;", Helpers.OwnsNativeInstanceIdentifier);
}
if (method.IsProxy) if (method.IsProxy)
goto SkipImpl; goto SkipImpl;
@ -770,6 +792,8 @@ namespace CppSharp.Generators.CLI
GenerateFunctionParams(@params); GenerateFunctionParams(@params);
WriteLine(");"); WriteLine(");");
} }
PopBlock();
} }
else else
{ {

3
src/Generator/Utils/BlockGenerator.cs

@ -50,6 +50,9 @@ namespace CppSharp
Destructor, Destructor,
AccessSpecifier, AccessSpecifier,
Fields, Fields,
ConstructorBody,
DestructorBody,
FinalizerBody
} }
[DebuggerDisplay("{Kind} | {Object}")] [DebuggerDisplay("{Kind} | {Object}")]

Loading…
Cancel
Save