Skip to content

Commit

Permalink
Support boxed records
Browse files Browse the repository at this point in the history
  • Loading branch information
badcel committed Nov 16, 2023
1 parent 321d359 commit 7d44153
Show file tree
Hide file tree
Showing 63 changed files with 1,790 additions and 191 deletions.
29 changes: 29 additions & 0 deletions src/Generation/Generator/Generator/Internal/TypedRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Generator.Model;

namespace Generator.Generator.Internal;

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

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

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

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

_publisher.Publish(codeUnit);
}
}
29 changes: 29 additions & 0 deletions src/Generation/Generator/Generator/Internal/TypedRecordData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Generator.Model;

namespace Generator.Generator.Internal;

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

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

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

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

_publisher.Publish(codeUnit);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Linq;
using Generator.Model;

namespace Generator.Generator.Internal;

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

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

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

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

var source = Renderer.Internal.TypedRecordDelegates.Render(record);
var codeUnit = new CodeUnit(
Project: Namespace.GetCanonicalName(record.Namespace),
Name: $"{Model.TypedRecord.GetDataName(record)}.Delegates",
Source: source,
IsInternal: true
);

_publisher.Publish(codeUnit);
}
}
29 changes: 29 additions & 0 deletions src/Generation/Generator/Generator/Internal/TypedRecordHandle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Generator.Model;

namespace Generator.Generator.Internal;

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

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

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

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

_publisher.Publish(codeUnit);
}
}
29 changes: 29 additions & 0 deletions src/Generation/Generator/Generator/Public/TypedRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Generator.Model;

namespace Generator.Generator.Public;

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

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

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

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

_publisher.Publish(codeUnit);
}
}
12 changes: 10 additions & 2 deletions src/Generation/Generator/Model/Record.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ internal static partial class Record
{
public static bool IsStandard(GirModel.Record record)
{
return !IsOpaqueTyped(record) && !IsOpaqueUntyped(record);
return !IsOpaqueTyped(record) && !IsOpaqueUntyped(record) && !IsTyped(record);
}

public static bool IsOpaqueTyped(GirModel.Record record)
Expand All @@ -21,7 +21,15 @@ public static bool IsOpaqueUntyped(GirModel.Record record)
//untyped.
return record is { Opaque: true, TypeFunction: null or { CIdentifier: "intern" } };
}


public static bool IsTyped(GirModel.Record record)
{
//Even if there is a TypeFunction it does not mean that it actually is
//a typed / boxed record. There is a magic keyword "intern" which means this
//record is actually fundamental and does not have a type function.
return record is { Opaque: false, TypeFunction.CIdentifier: not "intern" };
}

public static string GetFullyQualifiedInternalStructName(GirModel.Record record)
=> Namespace.GetInternalName(record.Namespace) + "." + GetInternalStructName(record);

Expand Down
80 changes: 80 additions & 0 deletions src/Generation/Generator/Model/TypedRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System.Linq;

namespace Generator.Model;

internal static class TypedRecord
{
public static string GetPublicClassName(GirModel.Record record)
=> record.Name;

public static string GetFullyQualifiedPublicClassName(GirModel.Record record)
=> Namespace.GetPublicName(record.Namespace) + "." + GetPublicClassName(record);

public static string GetFullyQualifiedInternalClassName(GirModel.Record record)
=> Namespace.GetInternalName(record.Namespace) + "." + record.Name;

public static string GetInternalHandle(GirModel.Record record)
=> $"{Type.GetName(record)}Handle";

public static string GetInternalOwnedHandle(GirModel.Record record)
=> $"{Type.GetName(record)}OwnedHandle";

public static string GetInternalUnownedHandle(GirModel.Record record)
=> $"{Type.GetName(record)}UnownedHandle";

public static string GetFullyQuallifiedHandle(GirModel.Record record)
=> $"{Namespace.GetInternalName(record.Namespace)}.{GetInternalHandle(record)}";

public static string GetFullyQuallifiedOwnedHandle(GirModel.Record record)
=> $"{Namespace.GetInternalName(record.Namespace)}.{GetInternalOwnedHandle(record)}";

public static string GetFullyQuallifiedUnownedHandle(GirModel.Record record)
=> $"{Namespace.GetInternalName(record.Namespace)}.{GetInternalUnownedHandle(record)}";

public static string GetFullyQuallifiedNullHandle(GirModel.Record record)
=> $"{Namespace.GetInternalName(record.Namespace)}.{GetInternalUnownedHandle(record)}.NullHandle";

public static string GetDataName(GirModel.Record record)
=> $"{Type.GetName(record)}Data";

public static string GetFullyQuallifiedDataName(GirModel.Record record)
=> $"{Namespace.GetInternalName(record.Namespace)}.{GetDataName(record)}";

public static string GetInternalArrayHandle(GirModel.Record record)
{
var prefix = $"{Type.GetName(record)}Array";
if (record.Namespace.Records.Select(x => x.Name).Contains(prefix))
prefix += "2";

return $"{prefix}Handle";
}

public static string GetFullyQuallifiedArrayHandle(GirModel.Record record)
=> $"{Namespace.GetInternalName(record.Namespace)}.{GetInternalArrayHandle(record)}";

public static string GetInternalArrayOwnedHandle(GirModel.Record record)
{
var prefix = $"{Type.GetName(record)}Array";
if (record.Namespace.Records.Select(x => x.Name).Contains(prefix))
prefix += "2";

return $"{prefix}OwnedHandle";
}

public static string GetFullyQuallifiedArrayOwnedHandle(GirModel.Record record)
=> $"{Namespace.GetInternalName(record.Namespace)}.{GetInternalArrayOwnedHandle(record)}";

public static string GetInternalArrayUnownedHandle(GirModel.Record record)
{
var prefix = $"{Type.GetName(record)}Array";
if (record.Namespace.Records.Select(x => x.Name).Contains(prefix))
prefix += "2";
return $"{prefix}UnownedHandle";
}

public static string GetFullyQuallifiedArrayUnownedHandle(GirModel.Record record)
=> $"{Namespace.GetInternalName(record.Namespace)}.{GetInternalArrayUnownedHandle(record)}";

public static string GetFullyQuallifiedArrayNullHandle(GirModel.Record record)
=> $"{Namespace.GetInternalName(record.Namespace)}.{GetInternalArrayUnownedHandle(record)}.NullHandle";
}
7 changes: 7 additions & 0 deletions src/Generation/Generator/Records.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ public static void Generate(IEnumerable<GirModel.Record> records, string path)
new Generator.Internal.OpaqueUntypedRecordHandle(publisher),
new Generator.Public.OpaqueUntypedRecord(publisher),

//Typed records
new Generator.Internal.TypedRecord(publisher),
new Generator.Internal.TypedRecordDelegates(publisher),
new Generator.Internal.TypedRecordHandle(publisher),
new Generator.Internal.TypedRecordData(publisher),
new Generator.Public.TypedRecord(publisher),

//Regular records
new Generator.Internal.RecordDelegates(publisher),
new Generator.Internal.RecordHandle(publisher),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Generator.Renderer.Internal.Field;

internal class OpaqueTypedRecord : FieldConverter
{
public bool Supports(GirModel.Field field)
{
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.Is<GirModel.Record>(out var record) && Model.Record.IsOpaqueTyped(record);
}

public RenderableField Convert(GirModel.Field field)
{
return new RenderableField(
Name: Model.Field.GetName(field),
Attribute: null,
NullableTypeName: Model.Type.Pointer
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Generator.Renderer.Internal.Field;

internal class OpaqueUntypedRecord : FieldConverter
{
public bool Supports(GirModel.Field field)
{
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.Is<GirModel.Record>(out var record) && Model.Record.IsOpaqueUntyped(record);
}

public RenderableField Convert(GirModel.Field field)
{
return new RenderableField(
Name: Model.Field.GetName(field),
Attribute: null,
NullableTypeName: Model.Type.Pointer
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ internal class Record : FieldConverter
{
public bool Supports(GirModel.Field field)
{
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.Is<GirModel.Record>();
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.Is<GirModel.Record>(out var record) && Model.Record.IsStandard(record);
}

public RenderableField Convert(GirModel.Field field)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ internal class RecordArray : FieldConverter
{
public bool Supports(GirModel.Field field)
{
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.IsArray<GirModel.Record>();
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.IsArray<GirModel.Record>(out var record) && Model.Record.IsStandard(record);;
}

public RenderableField Convert(GirModel.Field field)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Generator.Model;

namespace Generator.Renderer.Internal.Field;

internal class TypedRecord : FieldConverter
{
public bool Supports(GirModel.Field field)
{
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.Is<GirModel.Record>(out var record) && Model.Record.IsTyped(record);
}

public RenderableField Convert(GirModel.Field field)
{
return new RenderableField(
Name: Model.Field.GetName(field),
Attribute: null,
NullableTypeName: GetNullableTypeName(field)
);
}

private static string GetNullableTypeName(GirModel.Field field)
{
var type = (GirModel.Record) field.AnyTypeOrCallback.AsT0.AsT0;
return field.IsPointer
? Type.Pointer
: Model.Record.GetFullyQualifiedInternalStructName(type);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace Generator.Renderer.Internal.Field;

internal class TypedRecordArray : FieldConverter
{
public bool Supports(GirModel.Field field)
{
return field.AnyTypeOrCallback.TryPickT0(out var anyType, out _) && anyType.IsArray<GirModel.Record>(out var record) && Model.Record.IsTyped(record);;
}

public RenderableField Convert(GirModel.Field field)
{
return new RenderableField(
Name: Model.Field.GetName(field),
Attribute: GetAttribute(field),
NullableTypeName: GetNullableTypeName(field)
);
}

private static string? GetAttribute(GirModel.Field field)
{
var arrayType = field.AnyTypeOrCallback.AsT0.AsT1;
return arrayType.FixedSize is not null
? MarshalAs.UnmanagedByValArray(sizeConst: arrayType.FixedSize.Value)
: null;
}

private static string GetNullableTypeName(GirModel.Field field)
{
var arrayType = field.AnyTypeOrCallback.AsT0.AsT1;
var type = (GirModel.Record) arrayType.AnyType.AsT0;
return Model.Record.GetFullyQualifiedInternalStructName(type) + "[]";
}
}
Loading

0 comments on commit 7d44153

Please sign in to comment.