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

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

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

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

@ -57,9 +57,10 @@ namespace CppSharp.Types.Std @@ -57,9 +57,10 @@ namespace CppSharp.Types.Std
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);
typePrinter.PushContext(CSharpTypePrinterContextKind.Native);
if (!ctx.Parameter.Type.Desugar().IsAddress())
@ -67,19 +68,46 @@ namespace CppSharp.Types.Std @@ -67,19 +68,46 @@ namespace CppSharp.Types.Std
typePrinter.PopContext();
var allocator = ctx.Driver.ASTContext.FindClass("allocator", false, true).First(
a => a.IsSupportedStdType());
ctx.Return.Write("new {0}({1}, new {2}()).{3}",
basicString.Visit(typePrinter), ctx.Parameter.Name,
allocator.Visit(typePrinter), Helpers.InstanceIdentifier);
if (type.IsPointer() || (type.IsReference() && ctx.Declaration is Field))
{
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 typePrinter = new CSharpTypePrinter(ctx.Driver);
ctx.Return.Write("{0}.{1}({2}).{3}()",
basicString.Visit(typePrinter), Helpers.CreateInstanceIdentifier,
ctx.ReturnVarName, c_str.Name);
if (type.IsPointer() || ctx.Declaration is Field)
{
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)
@ -114,12 +142,12 @@ namespace CppSharp.Types.Std @@ -114,12 +142,12 @@ namespace CppSharp.Types.Std
return "string";
}
public override void CSharpMarshalToNative(MarshalContext ctx)
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{
ctx.Return.Write("new Std.WString()");
}
public override void CSharpMarshalToManaged(MarshalContext ctx)
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{
ctx.Return.Write(ctx.ReturnVarName);
}
@ -257,12 +285,12 @@ namespace CppSharp.Types.Std @@ -257,12 +285,12 @@ namespace CppSharp.Types.Std
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);
}
public override void CSharpMarshalToManaged(MarshalContext ctx)
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{
var templateType = Type as TemplateSpecializationType;
var type = templateType.Arguments[0].Type;
@ -382,12 +410,12 @@ namespace CppSharp.Types.Std @@ -382,12 +410,12 @@ namespace CppSharp.Types.Std
return CSharpTypePrinter.IntPtrType;
}
public override void CSharpMarshalToNative(MarshalContext ctx)
public override void CSharpMarshalToNative(CSharpMarshalContext ctx)
{
ctx.Return.Write(ctx.Parameter.Name);
}
public override void CSharpMarshalToManaged(MarshalContext ctx)
public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
{
ctx.Return.Write(ctx.ReturnVarName);
}

4
src/Generator/Types/TypeMap.cs

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

12
tests/CSharp/CSharp.cs

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

20
tests/Common/Common.Tests.cs

@ -407,11 +407,9 @@ public class CommonTests : GeneratorTestFixture @@ -407,11 +407,9 @@ public class CommonTests : GeneratorTestFixture
public void TestVariable()
{
// Test field property
// HACK: disabled until https://github.com/mono/CppSharp/issues/675 is fixed.
// It used to work thanks to a hack in Common.cs which is now removed because it caused problems with system types
//var @var = new TestVariables();
//@var.Value = 10;
//Assert.That(TestVariables.VALUE, Is.EqualTo(10));
var @var = new TestVariables();
@var.Value = 10;
Assert.That(TestVariables.VALUE, Is.EqualTo(10));
}
[Test]
@ -635,6 +633,18 @@ public class CommonTests : GeneratorTestFixture @@ -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
{
public override void @abstract()

4
tests/Common/Common.cs

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

Loading…
Cancel
Save