Browse Source

Add partial `ref` param support

refactor
josetr 3 years ago
parent
commit
060afd53fc
  1. 3
      src/AST/Assembly.cs
  2. 26
      src/AST/TypeExtensions.cs
  3. 11
      src/Generator/Generators/CSharp/CSharpSources.cs
  4. 17
      tests/CSharp/CSharp.Tests.cs
  5. 17
      tests/CSharp/CSharp.h

3
src/AST/Assembly.cs

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("CppSharp.Generator")]

26
src/AST/TypeExtensions.cs

@ -442,5 +442,31 @@ @@ -442,5 +442,31 @@
{
return array.Size * array.ElementSize;
}
internal static bool IsReferenceToPtrToClass(this Type type)
{
var @ref = type.Desugar().AsLvReference();
if (@ref == null)
return false;
var @ptr = @ref.Pointee.Desugar(false).AsPtr();
if (@ptr == null)
return false;
var @class = @ptr.Pointee;
return @class != null && @class.IsClass();
}
internal static PointerType AsLvReference(this Type type)
{
var reference = type as PointerType;
return reference?.Modifier == PointerType.TypeModifier.LVReference ? reference : null;
}
internal static PointerType AsPtr(this Type type)
{
var ptr = type as PointerType;
return ptr?.Modifier == PointerType.TypeModifier.Pointer ? ptr : null;
}
}
}

11
src/Generator/Generators/CSharp/CSharpSources.cs

@ -3193,6 +3193,17 @@ WriteLines($@" @@ -3193,6 +3193,17 @@ WriteLines($@"
}
WriteLine("{0}({1});", functionName, string.Join(", ", names));
foreach(var param in @params)
{
if (param.Param.IsInOut && param.Param.Type.IsReferenceToPtrToClass())
{
var qualifiedClass = param.Param.Type.Visit(TypePrinter);
WriteLine($"if ({param.Name} != {param.Param.Name}.__Instance)");
WriteLine($"{param.Param.Name} = {qualifiedClass}.__GetOrCreateInstance(__{param.Name}, false);");
}
}
foreach (TextGenerator cleanup in from p in @params
select p.Context.Cleanup)
Write(cleanup);

17
tests/CSharp/CSharp.Tests.cs

@ -1908,4 +1908,21 @@ public unsafe class CSharpTests @@ -1908,4 +1908,21 @@ public unsafe class CSharpTests
Assert.That(CSharpTemplates.FunctionTemplate(6f), Is.EqualTo(6 + 4.1f));
Assert.That(CSharpTemplates.FunctionTemplate(7), Is.EqualTo(7 + 4));
}
[Test]
public void TestPatialRefSupport()
{
var myclass = new ClassWithIntValue();
var backup = myclass;
myclass.Value = 7;
CSharp.CSharp.ModifyCore(ref myclass);
Assert.That(myclass.Value, Is.EqualTo(10));
Assert.That(myclass, Is.SameAs(myclass));
CSharp.CSharp.CreateCore(ref myclass);
Assert.That(myclass.Value, Is.EqualTo(20));
Assert.That(myclass, Is.Not.SameAs(backup));
}
}

17
tests/CSharp/CSharp.h

@ -1535,4 +1535,19 @@ DLL_API int TestFunctionToInstanceMethodRefStruct(FTIStruct* bb, FTIStruct& defa @@ -1535,4 +1535,19 @@ DLL_API int TestFunctionToInstanceMethodRefStruct(FTIStruct* bb, FTIStruct& defa
DLL_API int TestFunctionToInstanceMethodConstStruct(FTIStruct* bb, const FTIStruct defaultValue);
DLL_API int TestFunctionToInstanceMethodConstRefStruct(FTIStruct* bb, const FTIStruct& defaultValue);
class ClassWithoutNativeToManaged { };
class ClassWithoutNativeToManaged { };
struct DLL_API ClassWithIntValue {
int value;
};
DLL_API inline ClassWithIntValue* ModifyCore(CS_IN_OUT ClassWithIntValue*& pClass) {
pClass->value = 10;
return nullptr;
}
DLL_API inline ClassWithIntValue* CreateCore(CS_IN_OUT ClassWithIntValue*& pClass) {
pClass = new ClassWithIntValue();
pClass->value = 20;
return nullptr;
}

Loading…
Cancel
Save