Browse Source

Enabled cleaning up in type maps and used it to dispose of used std::string objects.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/681/head
Dimitar Dobrev 9 years ago
parent
commit
4df66454b1
  1. 6
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 26
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 60
      src/Generator/Types/Std/Stdlib.cs
  4. 4
      src/Generator/Types/TypeMap.cs
  5. 12
      tests/CSharp/CSharp.cs
  6. 20
      tests/Common/Common.Tests.cs
  7. 4
      tests/Common/Common.cs

6
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -31,7 +31,7 @@ namespace CppSharp.Generators.CSharp
public TextGenerator ArgumentPrefix { get; private set; } public TextGenerator ArgumentPrefix { get; private set; }
public TextGenerator Cleanup { get; private set; } public TextGenerator Cleanup { get; private set; }
public bool HasFixedBlock { get; set; } public bool HasCodeBlock { get; set; }
} }
public abstract class CSharpMarshalPrinter : MarshalPrinter<CSharpMarshalContext> public abstract class CSharpMarshalPrinter : MarshalPrinter<CSharpMarshalContext>
@ -420,7 +420,7 @@ namespace CppSharp.Generators.CSharp
array.Type, ptr, Context.Parameter.Name); array.Type, ptr, Context.Parameter.Name);
Context.SupportBefore.WriteStartBraceIndent(); Context.SupportBefore.WriteStartBraceIndent();
Context.Return.Write("new global::System.IntPtr({0})", ptr); Context.Return.Write("new global::System.IntPtr({0})", ptr);
Context.HasFixedBlock = true; Context.HasCodeBlock = true;
} }
else else
{ {
@ -495,7 +495,7 @@ namespace CppSharp.Generators.CSharp
var refParamPtr = string.Format("__refParamPtr{0}", Context.ParameterIndex); var refParamPtr = string.Format("__refParamPtr{0}", Context.ParameterIndex);
Context.SupportBefore.WriteLine("fixed ({0} {1} = &{2})", Context.SupportBefore.WriteLine("fixed ({0} {1} = &{2})",
pointer, refParamPtr, Context.Parameter.Name); pointer, refParamPtr, Context.Parameter.Name);
Context.HasFixedBlock = true; Context.HasCodeBlock = true;
Context.SupportBefore.WriteStartBraceIndent(); Context.SupportBefore.WriteStartBraceIndent();
Context.Return.Write(refParamPtr); Context.Return.Write(refParamPtr);
return true; return true;

26
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -955,6 +955,7 @@ namespace CppSharp.Generators.CSharp
ctx.Kind = CSharpMarshalKind.NativeField; ctx.Kind = CSharpMarshalKind.NativeField;
var marshal = new CSharpMarshalManagedToNativePrinter(ctx); var marshal = new CSharpMarshalManagedToNativePrinter(ctx);
ctx.Declaration = field;
var arrayType = field.Type as ArrayType; var arrayType = field.Type as ArrayType;
@ -977,6 +978,9 @@ namespace CppSharp.Generators.CSharp
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore); Write(marshal.Context.SupportBefore);
if (ctx.HasCodeBlock)
PushIndent();
if (marshal.Context.Return.StringBuilder.Length > 0) if (marshal.Context.Return.StringBuilder.Length > 0)
{ {
WriteLine("{0} = {1}{2};", ctx.ReturnVarName, WriteLine("{0} = {1}{2};", ctx.ReturnVarName,
@ -986,7 +990,7 @@ namespace CppSharp.Generators.CSharp
marshal.Context.Return); marshal.Context.Return);
} }
if (arrayType != null && @class.IsValueType) if ((arrayType != null && @class.IsValueType) || ctx.HasCodeBlock)
WriteCloseBraceIndent(); WriteCloseBraceIndent();
WriteCloseBraceIndent(); WriteCloseBraceIndent();
@ -1109,6 +1113,7 @@ namespace CppSharp.Generators.CSharp
{ {
Kind = CSharpMarshalKind.NativeField, Kind = CSharpMarshalKind.NativeField,
ArgName = decl.Name, ArgName = decl.Name,
Declaration = decl,
ReturnVarName = string.Format("{0}{1}{2}", ReturnVarName = string.Format("{0}{1}{2}",
@class.IsValueType @class.IsValueType
? Helpers.InstanceField ? Helpers.InstanceField
@ -1129,6 +1134,9 @@ namespace CppSharp.Generators.CSharp
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore); Write(marshal.Context.SupportBefore);
if (ctx.HasCodeBlock)
PushIndent();
var @return = marshal.Context.Return.ToString(); var @return = marshal.Context.Return.ToString();
if (field.Type.IsPointer()) if (field.Type.IsPointer())
{ {
@ -1139,7 +1147,7 @@ namespace CppSharp.Generators.CSharp
} }
WriteLine("return {0};", @return); WriteLine("return {0};", @return);
if (arrayType != null && @class.IsValueType) if ((arrayType != null && @class.IsValueType) || ctx.HasCodeBlock)
WriteCloseBraceIndent(); WriteCloseBraceIndent();
} }
else if (decl is Variable) else if (decl is Variable)
@ -2744,6 +2752,9 @@ namespace CppSharp.Generators.CSharp
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore); Write(marshal.Context.SupportBefore);
if (ctx.HasCodeBlock)
PushIndent();
// Special case for indexer - needs to dereference if the internal // Special case for indexer - needs to dereference if the internal
// function is a pointer type and the property is not. // function is a pointer type and the property is not.
if (retType.Type.IsAddress() && if (retType.Type.IsAddress() &&
@ -2752,12 +2763,15 @@ namespace CppSharp.Generators.CSharp
WriteLine("return *{0};", marshal.Context.Return); WriteLine("return *{0};", marshal.Context.Return);
else else
WriteLine("return {0};", marshal.Context.Return); WriteLine("return {0};", marshal.Context.Return);
if (ctx.HasCodeBlock)
WriteCloseBraceIndent();
} }
if (needsFixedThis && operatorParam == null) if (needsFixedThis && operatorParam == null)
WriteCloseBraceIndent(); WriteCloseBraceIndent();
var numFixedBlocks = @params.Count(param => param.HasFixedBlock); var numFixedBlocks = @params.Count(param => param.HasUsingBlock);
for(var i = 0; i < numFixedBlocks; ++i) for(var i = 0; i < numFixedBlocks; ++i)
WriteCloseBraceIndent(); WriteCloseBraceIndent();
} }
@ -2838,7 +2852,7 @@ namespace CppSharp.Generators.CSharp
public string Name; public string Name;
public Parameter Param; public Parameter Param;
public CSharpMarshalContext Context; public CSharpMarshalContext Context;
public bool HasFixedBlock; public bool HasUsingBlock;
} }
public List<ParamMarshal> GenerateFunctionParamsMarshal(IEnumerable<Parameter> @params, public List<ParamMarshal> GenerateFunctionParamsMarshal(IEnumerable<Parameter> @params,
@ -2896,7 +2910,7 @@ namespace CppSharp.Generators.CSharp
paramMarshal.Context = ctx; paramMarshal.Context = ctx;
var marshal = new CSharpMarshalManagedToNativePrinter(ctx); var marshal = new CSharpMarshalManagedToNativePrinter(ctx);
param.CSharpMarshalToNative(marshal); param.CSharpMarshalToNative(marshal);
paramMarshal.HasFixedBlock = ctx.HasFixedBlock; paramMarshal.HasUsingBlock = ctx.HasCodeBlock;
if (string.IsNullOrEmpty(marshal.Context.Return)) if (string.IsNullOrEmpty(marshal.Context.Return))
throw new Exception("Cannot marshal argument of function"); throw new Exception("Cannot marshal argument of function");
@ -2904,7 +2918,7 @@ namespace CppSharp.Generators.CSharp
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore); Write(marshal.Context.SupportBefore);
if (paramMarshal.HasFixedBlock) if (paramMarshal.HasUsingBlock)
PushIndent(); PushIndent();
WriteLine("var {0} = {1};", argName, marshal.Context.Return); WriteLine("var {0} = {1};", argName, marshal.Context.Return);

60
src/Generator/Types/Std/Stdlib.cs

@ -57,9 +57,10 @@ namespace CppSharp.Types.Std
return basicString.Visit(typePrinter).Type; return basicString.Visit(typePrinter).Type;
} }
public override void CSharpMarshalToNative(MarshalContext ctx) public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{ {
ClassTemplateSpecialization basicString = GetBasicString(ctx.Parameter.Type); var type = ctx.Parameter.Type.Desugar();
ClassTemplateSpecialization basicString = GetBasicString(type);
var typePrinter = new CSharpTypePrinter(ctx.Driver); var typePrinter = new CSharpTypePrinter(ctx.Driver);
typePrinter.PushContext(CSharpTypePrinterContextKind.Native); typePrinter.PushContext(CSharpTypePrinterContextKind.Native);
if (!ctx.Parameter.Type.Desugar().IsAddress()) if (!ctx.Parameter.Type.Desugar().IsAddress())
@ -67,19 +68,46 @@ namespace CppSharp.Types.Std
typePrinter.PopContext(); typePrinter.PopContext();
var allocator = ctx.Driver.ASTContext.FindClass("allocator", false, true).First( var allocator = ctx.Driver.ASTContext.FindClass("allocator", false, true).First(
a => a.IsSupportedStdType()); a => a.IsSupportedStdType());
ctx.Return.Write("new {0}({1}, new {2}()).{3}", if (type.IsPointer() || (type.IsReference() && ctx.Declaration is Field))
basicString.Visit(typePrinter), ctx.Parameter.Name, {
allocator.Visit(typePrinter), Helpers.InstanceIdentifier); ctx.Return.Write("new {0}({1}, new {2}()).{3}",
basicString.Visit(typePrinter), ctx.Parameter.Name,
allocator.Visit(typePrinter), Helpers.InstanceIdentifier);
}
else
{
string varBasicString = "__basicString" + ctx.ParameterIndex;
ctx.SupportBefore.WriteLine("using (var {0} = new {1}({2}, new {3}()))",
varBasicString, basicString.Visit(typePrinter),
ctx.Parameter.Name, allocator.Visit(typePrinter));
ctx.SupportBefore.WriteStartBraceIndent();
ctx.Return.Write("{0}.{1}", varBasicString, Helpers.InstanceIdentifier);
ctx.HasCodeBlock = true;
}
} }
public override void CSharpMarshalToManaged(MarshalContext ctx) public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{ {
ClassTemplateSpecialization basicString = GetBasicString(ctx.ReturnType.Type); var type = ctx.ReturnType.Type;
ClassTemplateSpecialization basicString = GetBasicString(type);
var c_str = basicString.Methods.First(m => m.OriginalName == "c_str"); var c_str = basicString.Methods.First(m => m.OriginalName == "c_str");
var typePrinter = new CSharpTypePrinter(ctx.Driver); var typePrinter = new CSharpTypePrinter(ctx.Driver);
ctx.Return.Write("{0}.{1}({2}).{3}()", if (type.IsPointer() || ctx.Declaration is Field)
basicString.Visit(typePrinter), Helpers.CreateInstanceIdentifier, {
ctx.ReturnVarName, c_str.Name); ctx.Return.Write("{0}.{1}({2}).{3}()",
basicString.Visit(typePrinter), Helpers.CreateInstanceIdentifier,
ctx.ReturnVarName, c_str.Name);
}
else
{
const string varBasicString = "__basicStringRet";
ctx.SupportBefore.WriteLine("using (var {0} = {1}.{2}({3}))",
varBasicString, basicString.Visit(typePrinter),
Helpers.CreateInstanceIdentifier, ctx.ReturnVarName);
ctx.SupportBefore.WriteStartBraceIndent();
ctx.Return.Write("{0}.{1}()", varBasicString, c_str.Name);
ctx.HasCodeBlock = true;
}
} }
private static ClassTemplateSpecialization GetBasicString(Type type) private static ClassTemplateSpecialization GetBasicString(Type type)
@ -114,12 +142,12 @@ namespace CppSharp.Types.Std
return "string"; return "string";
} }
public override void CSharpMarshalToNative(MarshalContext ctx) public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{ {
ctx.Return.Write("new Std.WString()"); ctx.Return.Write("new Std.WString()");
} }
public override void CSharpMarshalToManaged(MarshalContext ctx) public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{ {
ctx.Return.Write(ctx.ReturnVarName); ctx.Return.Write(ctx.ReturnVarName);
} }
@ -257,12 +285,12 @@ namespace CppSharp.Types.Std
return string.Format("Std.Vector<{0}>", ctx.GetTemplateParameterList()); return string.Format("Std.Vector<{0}>", ctx.GetTemplateParameterList());
} }
public override void CSharpMarshalToNative(MarshalContext ctx) public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{ {
ctx.Return.Write("{0}.Internal", ctx.Parameter.Name); ctx.Return.Write("{0}.Internal", ctx.Parameter.Name);
} }
public override void CSharpMarshalToManaged(MarshalContext ctx) public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{ {
var templateType = Type as TemplateSpecializationType; var templateType = Type as TemplateSpecializationType;
var type = templateType.Arguments[0].Type; var type = templateType.Arguments[0].Type;
@ -382,12 +410,12 @@ namespace CppSharp.Types.Std
return CSharpTypePrinter.IntPtrType; return CSharpTypePrinter.IntPtrType;
} }
public override void CSharpMarshalToNative(MarshalContext ctx) public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{ {
ctx.Return.Write(ctx.Parameter.Name); ctx.Return.Write(ctx.Parameter.Name);
} }
public override void CSharpMarshalToManaged(MarshalContext ctx) public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{ {
ctx.Return.Write(ctx.ReturnVarName); ctx.Return.Write(ctx.ReturnVarName);
} }

4
src/Generator/Types/TypeMap.cs

@ -67,12 +67,12 @@ namespace CppSharp.Types
throw new NotImplementedException(); throw new NotImplementedException();
} }
public virtual void CSharpMarshalToNative(MarshalContext ctx) public virtual void CSharpMarshalToNative(CSharpMarshalContext ctx)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public virtual void CSharpMarshalToManaged(MarshalContext ctx) public virtual void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

12
tests/CSharp/CSharp.cs

@ -29,7 +29,7 @@ namespace CppSharp.Tests
return CSharpSignatureType(ctx).ToString(); return CSharpSignatureType(ctx).ToString();
} }
public override void CSharpMarshalToNative(MarshalContext ctx) public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{ {
if (ctx.Parameter.Type.Desugar().IsAddress()) if (ctx.Parameter.Type.Desugar().IsAddress())
ctx.Return.Write("new global::System.IntPtr(&{0})", ctx.Parameter.Name); ctx.Return.Write("new global::System.IntPtr(&{0})", ctx.Parameter.Name);
@ -37,7 +37,7 @@ namespace CppSharp.Tests
ctx.Return.Write(ctx.Parameter.Name); ctx.Return.Write(ctx.Parameter.Name);
} }
public override void CSharpMarshalToManaged(MarshalContext ctx) public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{ {
if (ctx.ReturnType.Type.Desugar().IsAddress()) if (ctx.ReturnType.Type.Desugar().IsAddress())
{ {
@ -89,13 +89,13 @@ namespace CppSharp.Tests
ctx.GetTemplateParameterList()); ctx.GetTemplateParameterList());
} }
public override void CSharpMarshalToNative(MarshalContext ctx) public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{ {
// pointless, put just so that the generated code compiles // pointless, put just so that the generated code compiles
ctx.Return.Write("new QList.Internal()"); ctx.Return.Write("new QList.Internal()");
} }
public override void CSharpMarshalToManaged(MarshalContext ctx) public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{ {
ctx.Return.Write(ctx.ReturnVarName); ctx.Return.Write(ctx.ReturnVarName);
} }
@ -110,12 +110,12 @@ namespace CppSharp.Tests
return "int"; return "int";
} }
public override void CSharpMarshalToNative(MarshalContext ctx) public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{ {
ctx.Return.Write(ctx.Parameter.Name); ctx.Return.Write(ctx.Parameter.Name);
} }
public override void CSharpMarshalToManaged(MarshalContext ctx) public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{ {
ctx.Return.Write(ctx.ReturnVarName); ctx.Return.Write(ctx.ReturnVarName);
} }

20
tests/Common/Common.Tests.cs

@ -407,11 +407,9 @@ public class CommonTests : GeneratorTestFixture
public void TestVariable() public void TestVariable()
{ {
// Test field property // Test field property
// HACK: disabled until https://github.com/mono/CppSharp/issues/675 is fixed. var @var = new TestVariables();
// It used to work thanks to a hack in Common.cs which is now removed because it caused problems with system types @var.Value = 10;
//var @var = new TestVariables(); Assert.That(TestVariables.VALUE, Is.EqualTo(10));
//@var.Value = 10;
//Assert.That(TestVariables.VALUE, Is.EqualTo(10));
} }
[Test] [Test]
@ -635,6 +633,18 @@ public class CommonTests : GeneratorTestFixture
} }
} }
// ignored until we add automatic compilation for templates
[Test, Ignore]
public void TestStdString()
{
using (var hasStdString = new HasStdString())
{
Assert.That(hasStdString.testStdString("test"), Is.EqualTo("test_test"));
hasStdString.s = "test";
Assert.That(hasStdString.s, Is.EqualTo("test"));
}
}
private class CustomDerivedFromVirtual : AbstractWithVirtualDtor private class CustomDerivedFromVirtual : AbstractWithVirtualDtor
{ {
public override void @abstract() public override void @abstract()

4
tests/Common/Common.cs

@ -32,12 +32,12 @@ namespace CppSharp.Tests
return "ushort"; return "ushort";
} }
public override void CSharpMarshalToManaged(MarshalContext ctx) public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{ {
ctx.Return.Write(ctx.ReturnVarName); ctx.Return.Write(ctx.ReturnVarName);
} }
public override void CSharpMarshalToNative(MarshalContext ctx) public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{ {
ctx.Return.Write("IntPtr.Zero"); ctx.Return.Write("IntPtr.Zero");
} }

Loading…
Cancel
Save