Skip to content

Commit

Permalink
Support opaque records
Browse files Browse the repository at this point in the history
  • Loading branch information
badcel committed Aug 6, 2023
1 parent 2a7532c commit f0a9301
Show file tree
Hide file tree
Showing 67 changed files with 589 additions and 125 deletions.
32 changes: 32 additions & 0 deletions src/Generation/Generator/Generator/Internal/OpaqueRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Generator.Model;

namespace Generator.Generator.Internal;

internal class OpaqueRecord : Generator<GirModel.Record>
{
private readonly Publisher _publisher;

public OpaqueRecord(Publisher publisher)
{
_publisher = publisher;
}

public void Generate(GirModel.Record obj)
{
if (!obj.Opaque)
return;

if (obj.TypeFunction is null)
return;

var source = Renderer.Internal.OpaqueRecord.Render(obj);
var codeUnit = new CodeUnit(
Project: Namespace.GetCanonicalName(obj.Namespace),
Name: obj.Name,
Source: source,
IsInternal: true
);

_publisher.Publish(codeUnit);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public RecordDelegates(Publisher publisher)

public void Generate(GirModel.Record record)
{
if (record is { Opaque: true, TypeFunction: not null })
return;

if (!record.Fields.Any(field => field.AnyTypeOrCallback.IsT1))
return;

Expand Down
3 changes: 3 additions & 0 deletions src/Generation/Generator/Generator/Internal/RecordHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public RecordHandle(Publisher publisher)

public void Generate(GirModel.Record record)
{
if (record is { Opaque: true, TypeFunction: not null })
return;

var source = Renderer.Internal.RecordHandle.Render(record);
var codeUnit = new CodeUnit(
Project: Namespace.GetCanonicalName(record.Namespace),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public RecordManagedHandle(Publisher publisher)

public void Generate(GirModel.Record record)
{
if (record is { Opaque: true, TypeFunction: not null })
return;

var source = Renderer.Internal.RecordManagedHandle.Render(record);
var codeUnit = new CodeUnit(
Project: Namespace.GetCanonicalName(record.Namespace),
Expand Down
4 changes: 3 additions & 1 deletion src/Generation/Generator/Generator/Internal/RecordMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ public RecordMethods(Publisher publisher)

public void Generate(GirModel.Record record)
{
if (record is { Opaque: true, TypeFunction: not null })
return;

if (!record.Constructors.Any()
&& !record.Methods.Any()
&& !record.Functions.Any()
&& record.TypeFunction is null)
return;


var source = Renderer.Internal.RecordMethods.Render(record);
var codeUnit = new CodeUnit(
Project: Namespace.GetCanonicalName(record.Namespace),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public RecordOwnedHandle(Publisher publisher)

public void Generate(GirModel.Record record)
{
if (record is { Opaque: true, TypeFunction: not null })
return;

var source = Renderer.Internal.RecordOwnedHandle.Render(record);
var codeUnit = new CodeUnit(
Project: Namespace.GetCanonicalName(record.Namespace),
Expand Down
3 changes: 3 additions & 0 deletions src/Generation/Generator/Generator/Internal/RecordStruct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public RecordStruct(Publisher publisher)

public void Generate(GirModel.Record record)
{
if (record is { Opaque: true, TypeFunction: not null })
return;

var source = Renderer.Internal.RecordStruct.Render(record);
var codeUnit = new CodeUnit(
Project: Namespace.GetCanonicalName(record.Namespace),
Expand Down
32 changes: 32 additions & 0 deletions src/Generation/Generator/Generator/Public/OpaqueRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Generator.Model;

namespace Generator.Generator.Public;

internal class OpaqueRecord : Generator<GirModel.Record>
{
private readonly Publisher _publisher;

public OpaqueRecord(Publisher publisher)
{
_publisher = publisher;
}

public void Generate(GirModel.Record record)
{
if (!record.Opaque)
return;

if (record.TypeFunction is null)
return;

var source = Renderer.Public.OpaqueRecord.Render(record);
var codeUnit = new CodeUnit(
Project: Namespace.GetCanonicalName(record.Namespace),
Name: Record.GetPublicClassName(record),
Source: source,
IsInternal: false
);

_publisher.Publish(codeUnit);
}
}
3 changes: 3 additions & 0 deletions src/Generation/Generator/Generator/Public/RecordClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public RecordClass(Publisher publisher)

public void Generate(GirModel.Record record)
{
if (record is { Opaque: true, TypeFunction: not null })
return;

var source = Renderer.Public.RecordClass.Render(record);
var codeUnit = new CodeUnit(
Project: Namespace.GetCanonicalName(record.Namespace),
Expand Down
16 changes: 16 additions & 0 deletions src/Generation/Generator/Model/OpaqueRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Generator.Model;

internal static class OpaqueRecord
{
public static string GetBoxedHandle(GirModel.Record record)
=> $"GLib.Internal.BoxedHandle<{Namespace.GetInternalName(record.Namespace)}.{Type.GetName(record)}>";

public static string GetOwnedBoxedHandle(GirModel.Record record)
=> $"GLib.Internal.OwnedBoxedHandle<{Namespace.GetInternalName(record.Namespace)}.{Type.GetName(record)}>";

public static string GetInitiallyUnownedBoxedHandle(GirModel.Record record)
=> $"GLib.Internal.InitiallyUnownedBoxedHandle<{Namespace.GetInternalName(record.Namespace)}.{Type.GetName(record)}>";

public static string GetNullBoxedHandle(GirModel.Record record)
=> $"GLib.Internal.BoxedHandle<{Namespace.GetInternalName(record.Namespace)}.{Type.GetName(record)}>.NullHandle";
}
5 changes: 5 additions & 0 deletions src/Generation/Generator/Records.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public static void Generate(IEnumerable<GirModel.Record> records, string path)
var publisher = new Publisher(path);
var generators = new List<Generator<GirModel.Record>>()
{
//Opaque records
new Generator.Internal.OpaqueRecord(publisher),
new Generator.Public.OpaqueRecord(publisher),

//Regular records
new Generator.Internal.RecordDelegates(publisher),
new Generator.Internal.RecordHandle(publisher),
new Generator.Internal.RecordOwnedHandle(publisher),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
using Generator.Model;
using System;
using Generator.Model;

namespace Generator.Renderer.Internal;

internal static class CallbackDelegate
{
public static string Render(GirModel.Callback callback)
{
return $@"
try
{
return $@"
using System;
using System.Runtime.InteropServices;
Expand All @@ -18,5 +21,12 @@ namespace {Namespace.GetInternalName(callback.Namespace)}
public delegate {ReturnTypeRendererCallback.Render(callback.ReturnType)} {callback.Name}({CallbackParameters.Render(callback.Parameters)}{Error.RenderCallback(callback)});
}}";
}
catch (Exception ex)
{
Log.Warning($"Did not generate callback delegatre '{callback.Name}': {ex.Message}");

return string.Empty;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Generator.Renderer.Internal.InstanceParameter;

internal class OpaqueRecord : InstanceParameterConverter
{
public bool Supports(GirModel.Type type)
{
return type is GirModel.Record { Opaque: true, TypeFunction: not null } ;
}

public RenderableInstanceParameter Convert(GirModel.InstanceParameter instanceParameter)
{
var type = (GirModel.Record) instanceParameter.Type;

return new RenderableInstanceParameter(
Name: Model.InstanceParameter.GetName(instanceParameter),
NullableTypeName: Model.OpaqueRecord.GetBoxedHandle(type)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ internal class Record : InstanceParameterConverter
{
public bool Supports(GirModel.Type type)
{
return type is GirModel.Record;
return type is GirModel.Record { Opaque: false } or GirModel.Record { TypeFunction: null } ;
}

public RenderableInstanceParameter Convert(GirModel.InstanceParameter instanceParameter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ internal static class InstanceParameters
{
new InstanceParameter.Class(),
new InstanceParameter.Interface(),
new InstanceParameter.OpaqueRecord(),
new InstanceParameter.Pointer(),
new InstanceParameter.Record(),
new InstanceParameter.Union()
Expand Down
37 changes: 37 additions & 0 deletions src/Generation/Generator/Renderer/Internal/OpaqueRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Generator.Model;

namespace Generator.Renderer.Internal;

internal static class OpaqueRecord
{
public static string Render(GirModel.Record record)
{
return $@"
using System;
using GObject;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
#nullable enable
namespace {Namespace.GetInternalName(record.Namespace)};
// AUTOGENERATED FILE - DO NOT MODIFY
{PlatformSupportAttribute.Render(record as GirModel.PlatformDependent)}
public partial class {record.Name} {RenderNativeGTypeProvider(record)}
{{
{Functions.Render(record.TypeFunction)}
{Functions.Render(record.Functions)}
{Methods.Render(record.Methods)}
{Constructors.Render(record.Constructors)}
}}";
}

private static string RenderNativeGTypeProvider(GirModel.Record record)
{
return record.TypeFunction is not null
? ": GLib.Internal.NativeGTypeProvider"
: string.Empty;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal static class CallbackParameters
new Parameter.Interface(),
new Parameter.InterfaceArray(),
new Parameter.NativeUnsignedIntegerArray(),
new Parameter.OpaqueRecord(),
new Parameter.Pointer(),
new Parameter.PointerAlias(),
new Parameter.PointerArray(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace Generator.Renderer.Internal.Parameter;

internal class OpaqueRecord : ParameterConverter
{
public bool Supports(GirModel.AnyType anyType)
{
return anyType.Is<GirModel.Record>(out var record) && record is { Opaque: true, TypeFunction: not null };
}

public RenderableParameter Convert(GirModel.Parameter parameter)
{
return new RenderableParameter(
Attribute: string.Empty,
Direction: GetDirection(parameter),
NullableTypeName: GetNullableTypeName(parameter),
Name: Model.Parameter.GetName(parameter)
);
}

//Native records are represented as SafeHandles and are not nullable
private static string GetNullableTypeName(GirModel.Parameter parameter)
{
var type = (GirModel.Record) parameter.AnyTypeOrVarArgs.AsT0.AsT0;
return parameter switch
{
{ Direction: GirModel.Direction.In, Transfer: GirModel.Transfer.None } => Model.OpaqueRecord.GetBoxedHandle(type) + Nullable.Render(parameter),
_ => throw new System.Exception($"Can't detect parameter type: CallerAllocates={parameter.CallerAllocates} Direction={parameter.Direction} Transfer={parameter.Transfer}")
};
}

private static string GetDirection(GirModel.Parameter parameter) => parameter switch
{
{ Direction: GirModel.Direction.InOut } => ParameterDirection.In(),
{ Direction: GirModel.Direction.Out, CallerAllocates: true } => ParameterDirection.In(),
{ Direction: GirModel.Direction.Out } => ParameterDirection.Out(),
_ => ParameterDirection.In()
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;

namespace Generator.Renderer.Internal.Parameter;

internal class OpaqueRecordArray : ParameterConverter
{
public bool Supports(GirModel.AnyType anyType)
{
return anyType.IsArray<GirModel.Record>(out var record) && record is { Opaque: true, TypeFunction: not null };
;
}

public RenderableParameter Convert(GirModel.Parameter parameter)
{
if (!parameter.AnyTypeOrVarArgs.AsT0.AsT1.IsPointer)
{
var record = (GirModel.Record) parameter.AnyTypeOrVarArgs.AsT0.AsT1.AnyType.AsT0;
throw new Exception($"Unpointed opaque record array of type {record.Name} not yet supported");
}

return new RenderableParameter(
Attribute: GetAttribute(parameter),
Direction: string.Empty,
NullableTypeName: Model.Type.PointerArray,
Name: Model.Parameter.GetName(parameter)
);
}

private static string GetAttribute(GirModel.Parameter parameter)
{
return parameter.AnyTypeOrVarArgs.AsT0.AsT1.Length switch
{
{ } length => MarshalAs.UnmanagedLpArray(sizeParamIndex: length),
_ => string.Empty,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ internal class Record : ParameterConverter
{
public bool Supports(GirModel.AnyType anyType)
{
return anyType.Is<GirModel.Record>();
return anyType.Is<GirModel.Record>(out var record) && (!record.Opaque || record.TypeFunction is null);
}

public RenderableParameter Convert(GirModel.Parameter parameter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ internal class RecordAlias : ParameterConverter
{
public bool Supports(GirModel.AnyType anyType)
{
return anyType.IsAlias<GirModel.Record>();
return anyType.IsAlias<GirModel.Record>(out var record) && (!record.Opaque || record.TypeFunction is null);;
}

public RenderableParameter Convert(GirModel.Parameter parameter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ internal class RecordArray : ParameterConverter
{
public bool Supports(GirModel.AnyType anyType)
{
return anyType.IsArray<GirModel.Record>();
return anyType.IsArray<GirModel.Record>(out var record) && (!record.Opaque || record.TypeFunction is null);;
}

public RenderableParameter Convert(GirModel.Parameter parameter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ internal class RecordAsPointer : ParameterConverter
{
public bool Supports(GirModel.AnyType anyType)
{
return anyType.Is<GirModel.Record>();
return anyType.Is<GirModel.Record>(out var record) && (!record.Opaque || record.TypeFunction is null);;
}

public RenderableParameter Convert(GirModel.Parameter parameter)
Expand Down
Loading

0 comments on commit f0a9301

Please sign in to comment.