Skip to content

Commit

Permalink
Merge pull request #1072 from gircore/girmodel-add-copy-free-func
Browse files Browse the repository at this point in the history
  • Loading branch information
badcel authored Jun 30, 2024
2 parents f7d7261 + 295bbca commit 85416e1
Show file tree
Hide file tree
Showing 17 changed files with 157 additions and 55 deletions.
10 changes: 10 additions & 0 deletions src/Generation/Generator/Model/Method.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,14 @@ internal static void SetImplementExplicitly(GirModel.Method method)
ImplementExplicitly.Add(method);
}
}

public static bool IsValidCopyFunction(GirModel.Method method)
{
return !method.Parameters.Any() && method.ReturnType.IsPointer;
}

public static bool IsValidFreeFunction(GirModel.Method method)
{
return !method.Parameters.Any() && method.ReturnType.AnyType.TryPickT0(out var type, out _) && type is GirModel.Void;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,69 @@ public class {ownedHandleTypeName} : {typeName}
}}";
}

private static string RenderCopyFunctions(GirModel.Record record)
{
var unownedHandleTypeName = Model.OpaqueUntypedRecord.GetInternalUnownedHandle(record);
var ownedHandleTypeName = Model.OpaqueUntypedRecord.GetInternalOwnedHandle(record);

return record.CopyFunction is null || !Method.IsValidCopyFunction(record.CopyFunction)
? $"""
public partial {ownedHandleTypeName} OwnedCopy();
public partial {unownedHandleTypeName} UnownedCopy();
"""
: $$"""
[DllImport(ImportResolver.Library, EntryPoint = "{{record.CopyFunction}}")]
protected static extern IntPtr Copy(IntPtr handle);

public {{ownedHandleTypeName}} OwnedCopy()
{
return new {{ownedHandleTypeName}}(Copy(handle));
}

public {{unownedHandleTypeName}} UnownedCopy()
{
return new {{unownedHandleTypeName}}(Copy(handle));
}
""";
}

private static string RenderFromUnowned(GirModel.Record record)
{
var ownedHandleTypeName = Model.OpaqueUntypedRecord.GetInternalOwnedHandle(record);

return record.CopyFunction is null || !Method.IsValidCopyFunction(record.CopyFunction)
? $"""
/// <summary>
/// Create a {ownedHandleTypeName} from a pointer that is assumed unowned.
/// </summary>
/// <param name="ptr">A pointer to a {record.Name} which is not owned by the runtime.</param>
/// <returns>A {ownedHandleTypeName}</returns>
public static partial {ownedHandleTypeName} FromUnowned(IntPtr ptr);
"""
: $$"""
public static {{ownedHandleTypeName}} FromUnowned(IntPtr ptr)
{
return new {{ownedHandleTypeName}}(Copy(ptr));
}
""";
}

private static string RenderReleaseHandle(GirModel.Record record)
{
return record.FreeFunction is null || !Method.IsValidFreeFunction(record.FreeFunction)
? "protected override partial bool ReleaseHandle();"
: $$"""
[DllImport(ImportResolver.Library, EntryPoint = "{{record.FreeFunction}}")]
private static extern void Free(IntPtr handle);

protected override bool ReleaseHandle()
{
Free(handle);
return true;
}
""";
}

private static string StandardHandle(GirModel.Record record)
{
var typeName = Model.OpaqueUntypedRecord.GetInternalHandle(record);
Expand All @@ -136,8 +199,7 @@ public abstract partial class {typeName} : SafeHandle
protected {typeName}(bool ownsHandle) : base(IntPtr.Zero, ownsHandle) {{ }}
public partial {ownedHandleTypeName} OwnedCopy();
public partial {unownedHandleTypeName} UnownedCopy();
{RenderCopyFunctions(record)}
}}
public class {unownedHandleTypeName} : {typeName}
Expand Down Expand Up @@ -178,15 +240,8 @@ public partial class {ownedHandleTypeName} : {typeName}
{{
SetHandle(ptr);
}}
/// <summary>
/// Create a {ownedHandleTypeName} from a pointer that is assumed unowned.
/// </summary>
/// <param name=""ptr"">A pointer to a {record.Name} which is not owned by the runtime.</param>
/// <returns>A {ownedHandleTypeName}</returns>
public static partial {ownedHandleTypeName} FromUnowned(IntPtr ptr);
protected override partial bool ReleaseHandle();
{RenderFromUnowned(record)}
{RenderReleaseHandle(record)}
}}";
}
}
25 changes: 24 additions & 1 deletion src/Generation/Generator/Renderer/Public/OpaqueUntypedRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace {Namespace.GetPublicName(record.Namespace)};
// AUTOGENERATED FILE - DO NOT MODIFY
{PlatformSupportAttribute.Render(record as GirModel.PlatformDependent)}
public sealed partial class {name}
public sealed partial class {name} {RenderIDisposableDefinition(record.FreeFunction)}
{{
public {internalHandleName} Handle {{ get; }}
Expand Down Expand Up @@ -70,6 +70,29 @@ public override int GetHashCode()
{{
return Handle.GetHashCode();
}}
{RenderIDisposableImplementation(record.FreeFunction)}
}}";
}

private static string RenderIDisposableDefinition(GirModel.Method? freeFunc)
{
if (freeFunc is null || !Method.IsValidFreeFunction(freeFunc))
return string.Empty;

return ": IDisposable";
}

private static string RenderIDisposableImplementation(GirModel.Method? freeFunc)
{
if (freeFunc is null || !Method.IsValidFreeFunction(freeFunc))
return string.Empty;

return """
public void Dispose()
{
Handle.Dispose();
}
""";
}
}
6 changes: 6 additions & 0 deletions src/Generation/GirLoader/Input/Record.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,10 @@ public class Record

[XmlAttribute("foreign")]
public bool Foreign;

[XmlAttribute("copy-function")]
public string? CopyFunction { get; set; }

[XmlAttribute("free-function")]
public string? FreeFunction { get; set; }
}
6 changes: 6 additions & 0 deletions src/Generation/GirLoader/Input/Union.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@ public class Union

[XmlAttribute("introspectable")]
public bool Introspectable = true;

[XmlAttribute("copy-function")]
public string? CopyFunction { get; set; }

[XmlAttribute("free-function")]
public string? FreeFunction { get; set; }
}
2 changes: 2 additions & 0 deletions src/Generation/GirLoader/Output/Record.GirModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace GirLoader.Output;
public partial class Record : GirModel.Record
{
GirModel.Function? GirModel.Record.TypeFunction => GetTypeFunction;
GirModel.Method? GirModel.Record.CopyFunction => CopyFunction;
GirModel.Method? GirModel.Record.FreeFunction => FreeFunction;
IEnumerable<GirModel.Function> GirModel.Record.Functions => Functions;
IEnumerable<GirModel.Method> GirModel.Record.Methods => Methods;
IEnumerable<GirModel.Constructor> GirModel.Record.Constructors => Constructors;
Expand Down
7 changes: 6 additions & 1 deletion src/Generation/GirLoader/Output/Record.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ public partial class Record : ComplexType, ShadowableProvider
public bool Foreign { get; }
public bool Opaque { get; }
public bool Pointer { get; }
public Method? CopyFunction { get; }
public Method? FreeFunction { get; }

public Record(Repository repository, string? cType, string name, TypeReference? gLibClassStructFor, IEnumerable<Method> methods, IEnumerable<Function> functions, Function? getTypeFunction, IEnumerable<Field> fields, bool disguised, IEnumerable<Constructor> constructors, bool introspectable, bool foreign, bool opaque, bool pointer) : base(repository, cType, name)
public Record(Repository repository, string? cType, string name, TypeReference? gLibClassStructFor, IEnumerable<Method> methods, IEnumerable<Function> functions, Function? getTypeFunction, IEnumerable<Field> fields, bool disguised, IEnumerable<Constructor> constructors, bool introspectable, bool foreign, bool opaque, bool pointer, Method? copyFunction, Method? freeFunction) : base(repository, cType, name)
{
GLibClassStructFor = gLibClassStructFor;
GetTypeFunction = getTypeFunction;
Expand All @@ -34,6 +36,9 @@ public Record(Repository repository, string? cType, string name, TypeReference?
Opaque = opaque;
Pointer = pointer;

CopyFunction = copyFunction;
FreeFunction = freeFunction;

this._constructors = constructors.ToList();
this._methods = methods.ToList();
this._functions = functions.ToList();
Expand Down
9 changes: 7 additions & 2 deletions src/Generation/GirLoader/Output/RecordFactory.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;

namespace GirLoader.Output;

Expand Down Expand Up @@ -30,12 +31,14 @@ public Record Create(Input.Record record, Repository repository)
_ => null
};

var methods = _methodFactory.Create(record.Methods);

var newRecord = new Record(
repository: repository,
cType: record.CType,
name: record.Name,
gLibClassStructFor: GetGLibClassStructFor(record.GLibIsGTypeStructFor, repository.Namespace),
methods: _methodFactory.Create(record.Methods),
methods: methods,
functions: _functionFactory.Create(record.Functions, repository),
getTypeFunction: getTypeFunction,
fields: _fieldFactory.Create(record.Fields, repository),
Expand All @@ -44,7 +47,9 @@ public Record Create(Input.Record record, Repository repository)
introspectable: record.Introspectable,
foreign: record.Foreign,
opaque: record.Opaque,
pointer: record.Pointer
pointer: record.Pointer,
copyFunction: methods.FirstOrDefault(x => x.Identifier == record.CopyFunction),
freeFunction: methods.FirstOrDefault(x => x.Identifier == record.FreeFunction)
);

if (getTypeFunction is not null)
Expand Down
2 changes: 2 additions & 0 deletions src/Generation/GirLoader/Output/Union.GirModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace GirLoader.Output;
public partial class Union : GirModel.Union
{
GirModel.Function? GirModel.Union.TypeFunction => GetTypeFunction;
GirModel.Method? GirModel.Union.CopyFunction => CopyFunction;
GirModel.Method? GirModel.Union.FreeFunction => FreeFunction;
IEnumerable<GirModel.Function> GirModel.Union.Functions => Functions;
IEnumerable<GirModel.Method> GirModel.Union.Methods => Methods;
IEnumerable<GirModel.Constructor> GirModel.Union.Constructors => Constructors;
Expand Down
7 changes: 6 additions & 1 deletion src/Generation/GirLoader/Output/Union.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ public partial class Union : ComplexType
public IEnumerable<Constructor> Constructors => _constructors;
public IEnumerable<Function> Functions => _functions;
public bool Introspectable { get; }
public Method? CopyFunction { get; }
public Method? FreeFunction { get; }

public Union(Repository repository, string? cType, string name, IEnumerable<Method> methods, IEnumerable<Function> functions, Function? getTypeFunction, IEnumerable<Field> fields, bool disguised, IEnumerable<Constructor> constructors, bool introspectable) : base(repository, cType, name)
public Union(Repository repository, string? cType, string name, IEnumerable<Method> methods, IEnumerable<Function> functions, Function? getTypeFunction, IEnumerable<Field> fields, bool disguised, IEnumerable<Constructor> constructors, bool introspectable, Method? copyFunction, Method? freeFunction) : base(repository, cType, name)
{
GetTypeFunction = getTypeFunction;
Disguised = disguised;
Introspectable = introspectable;

CopyFunction = copyFunction;
FreeFunction = freeFunction;

this._constructors = constructors.ToList();
this._methods = methods.ToList();
this._functions = functions.ToList();
Expand Down
9 changes: 7 additions & 2 deletions src/Generation/GirLoader/Output/UnionFactory.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using OneOf.Types;

namespace GirLoader.Output;
Expand Down Expand Up @@ -29,17 +30,21 @@ public Union Create(Input.Union union, Repository repository)
_ => null
};

var methods = _methodFactory.Create(union.Methods);

var newUnion = new Union(
repository: repository,
cType: union.CType,
name: union.Name,
methods: _methodFactory.Create(union.Methods),
methods: methods,
functions: _functionFactory.Create(union.Functions, repository),
getTypeFunction: getTypeFunction,
fields: _fieldFactory.Create(union.Fields, repository),
disguised: union.Disguised,
constructors: _constructorFactory.Create(union.Constructors),
introspectable: union.Introspectable
introspectable: union.Introspectable,
copyFunction: methods.FirstOrDefault(x => x.Identifier == union.CopyFunction),
freeFunction: methods.FirstOrDefault(x => x.Identifier == union.FreeFunction)
);

if (getTypeFunction is not null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public partial class Record : GirModel.Record
GirModel.Namespace ComplexType.Namespace => _record.Namespace;
string ComplexType.Name => _record.Name;
GirModel.Function? GirModel.Record.TypeFunction => _record.TypeFunction;
GirModel.Method? GirModel.Record.CopyFunction => _record.CopyFunction;
GirModel.Method? GirModel.Record.FreeFunction => _record.FreeFunction;
IEnumerable<GirModel.Function> GirModel.Record.Functions => _record.Functions;
IEnumerable<Method> GirModel.Record.Methods => _record.Methods;
IEnumerable<Constructor> GirModel.Record.Constructors => _record.Constructors;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public partial class Union : GirModel.Union
GirModel.Namespace ComplexType.Namespace => _union.Namespace;
string ComplexType.Name => _union.Name;
GirModel.Function? GirModel.Union.TypeFunction => _union.TypeFunction;
GirModel.Method? GirModel.Union.CopyFunction => _union.CopyFunction;
GirModel.Method? GirModel.Union.FreeFunction => _union.FreeFunction;
IEnumerable<GirModel.Function> GirModel.Union.Functions => _union.Functions;
IEnumerable<Method> GirModel.Union.Methods => _union.Methods;
IEnumerable<Constructor> GirModel.Union.Constructors => _union.Constructors;
Expand Down
2 changes: 2 additions & 0 deletions src/Generation/GirModel/Record.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace GirModel;
public interface Record : ComplexType
{
Function? TypeFunction { get; }
Method? CopyFunction { get; }
Method? FreeFunction { get; }
IEnumerable<Function> Functions { get; }
IEnumerable<Method> Methods { get; }
IEnumerable<Constructor> Constructors { get; }
Expand Down
2 changes: 2 additions & 0 deletions src/Generation/GirModel/Union.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace GirModel;
public interface Union : ComplexType
{
Function? TypeFunction { get; }
Method? CopyFunction { get; }
Method? FreeFunction { get; }
IEnumerable<Function> Functions { get; }
IEnumerable<Method> Methods { get; }
IEnumerable<Constructor> Constructors { get; }
Expand Down
37 changes: 0 additions & 37 deletions src/Libs/GirTest-0.1/Internal/OpaqueUntypedRecordTesterHandle.cs

This file was deleted.

7 changes: 7 additions & 0 deletions src/Tests/Libs/GirTest-0.1.Tests/OpaqueUntypedRecordTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ namespace GirTest.Tests;
[TestClass, TestCategory("BindingTest")]
public class OpaqueUntypedRecordTest : Test
{
[TestMethod]
public void ImplementsIDisposable()
{
var recordTester = OpaqueUntypedRecordTester.New();
recordTester.Dispose();
}

[TestMethod]
public void SupportsConstructorTransferFull()
{
Expand Down

0 comments on commit 85416e1

Please sign in to comment.