Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support opaque untyped records #942

Merged
merged 2 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/Generation/Generator/Generator/Internal/OpaqueUntypedRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Generator.Model;

namespace Generator.Generator.Internal;

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

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

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

var source = Renderer.Internal.OpaqueUntypedRecord.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
@@ -0,0 +1,29 @@
using Generator.Model;

namespace Generator.Generator.Internal;

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

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

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

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

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

namespace Generator.Generator.Public;

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

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

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

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

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

internal static class OpaqueUntypedRecord
{
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 GetFullyQuallifiedInternalHandle(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";
}
9 changes: 8 additions & 1 deletion 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);
return !IsOpaqueTyped(record) && !IsOpaqueUntyped(record);
}

public static bool IsOpaqueTyped(GirModel.Record record)
Expand All @@ -15,6 +15,13 @@ public static bool IsOpaqueTyped(GirModel.Record record)
return record is { Opaque: true, TypeFunction.CIdentifier: not "intern" };
}

public static bool IsOpaqueUntyped(GirModel.Record record)
{
//A CIdentifier "intern" means that this type is fundamental and can be treated as
//untyped.
return record is { Opaque: true, TypeFunction: null or { CIdentifier: "intern" } };
}

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

Expand Down
5 changes: 5 additions & 0 deletions src/Generation/Generator/Records.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ public static void Generate(IEnumerable<GirModel.Record> records, string path)
new Generator.Internal.OpaqueTypedRecordHandle(publisher),
new Generator.Public.OpaqueTypedRecord(publisher),

//Opaque untyped records
new Generator.Internal.OpaqueUntypedRecord(publisher),
new Generator.Internal.OpaqueUntypedRecordHandle(publisher),
new Generator.Public.OpaqueUntypedRecord(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,28 @@
namespace Generator.Renderer.Internal.InstanceParameter;

internal class OpaqueUntypedRecord : InstanceParameterConverter
{
public bool Supports(GirModel.Type type)
{
return type is GirModel.Record r && Model.Record.IsOpaqueUntyped(r);
}

public RenderableInstanceParameter Convert(GirModel.InstanceParameter instanceParameter)
{
return new RenderableInstanceParameter(
Name: Model.InstanceParameter.GetName(instanceParameter),
NullableTypeName: GetNullableTypeName(instanceParameter)
);
}

private static string GetNullableTypeName(GirModel.InstanceParameter instanceParameter)
{
var type = (GirModel.Record) instanceParameter.Type;
return instanceParameter switch
{
{ Direction: GirModel.Direction.In, Transfer: GirModel.Transfer.None } => Model.OpaqueUntypedRecord.GetFullyQuallifiedInternalHandle(type),
{ Direction: GirModel.Direction.In, Transfer: GirModel.Transfer.Full } => Model.OpaqueUntypedRecord.GetFullyQuallifiedUnownedHandle(type),
_ => throw new System.Exception($"Can't detect opaque untyped record instance parameter type {instanceParameter.Name}: CallerAllocates={instanceParameter.CallerAllocates} Direction={instanceParameter.Direction} Transfer={instanceParameter.Transfer}")
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ internal static class InstanceParameters
new InstanceParameter.Class(),
new InstanceParameter.Interface(),
new InstanceParameter.OpaqueTypedRecord(),
new InstanceParameter.OpaqueUntypedRecord(),
new InstanceParameter.Pointer(),
new InstanceParameter.Record(),
new InstanceParameter.Union()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class {unownedHandleTypeName} : {typeName}
/// <summary>
/// Creates a new instance of {ownedHandleTypeName}. Assumes that the given pointer is unowned by the runtime.
/// </summary>
internal {unownedHandleTypeName}(IntPtr ptr) : base(false)
public {unownedHandleTypeName}(IntPtr ptr) : base(false)
{{
SetHandle(ptr);
}}
Expand All @@ -76,7 +76,7 @@ public class {ownedHandleTypeName} : {typeName}
/// <summary>
/// Creates a new instance of {ownedHandleTypeName}. Assumes that the given pointer is owned by the runtime.
/// </summary>
internal {ownedHandleTypeName}(IntPtr ptr) : base(true)
public {ownedHandleTypeName}(IntPtr ptr) : base(true)
{{
SetHandle(ptr);
}}
Expand Down
29 changes: 29 additions & 0 deletions src/Generation/Generator/Renderer/Internal/OpaqueUntypedRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Generator.Model;

namespace Generator.Renderer.Internal;

internal static class OpaqueUntypedRecord
{
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}
{{
{Constructors.Render(record.Constructors)}
{Functions.Render(record.Functions)}
{Methods.Render(record.Methods)}
}}";
}
}
Loading