Skip to content

Commit

Permalink
TypedRecord: Add field access
Browse files Browse the repository at this point in the history
  • Loading branch information
badcel committed Jan 6, 2024
1 parent 1ea670b commit 8992974
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,7 @@ private static string RenderFieldGetter(GirModel.Record record, GirModel.Field f
if (IsClosed || IsInvalid)
throw new InvalidOperationException(""Handle is closed or invalid"");
var data = Unsafe.AsRef<{dataName}>((void*)handle);
return data.{renderableField.Name};
return Unsafe.AsRef<{dataName}>((void*)handle).{renderableField.Name};
}}";
}

Expand All @@ -266,8 +265,7 @@ private static string RenderFieldSetter(GirModel.Record record, GirModel.Field f
if (IsClosed || IsInvalid)
throw new InvalidOperationException(""Handle is closed or invalid"");
var data = Unsafe.AsRef<{dataName}>((void*)handle);
data.{renderableField.Name} = value;
Unsafe.AsRef<{dataName}>((void*)handle).{renderableField.Name} = value;
}}";
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace Generator.Renderer.Public.Field;

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

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

private static string GetNullableTypeName(GirModel.Field field)
{
var type = (GirModel.Bitfield) field.AnyTypeOrCallback.AsT0.AsT0;
return field.IsPointer
? Model.Type.Pointer
: Model.ComplexType.GetFullyQualified(type);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace Generator.Renderer.Public.Field;

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

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

private static string GetNullableTypeName(GirModel.Field field)
{
var type = (GirModel.Enumeration) field.AnyTypeOrCallback.AsT0.AsT0;
return field.IsPointer
? Model.Type.Pointer
: Model.ComplexType.GetFullyQualified(type);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace Generator.Renderer.Public.Field;

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

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

private static string GetNullableTypeName(GirModel.Field field)
{
return field.IsPointer
? Model.Type.Pointer
: Model.Type.GetName(field.AnyTypeOrCallback.AsT0.AsT0);
}
}
19 changes: 19 additions & 0 deletions src/Generation/Generator/Renderer/Public/Field/Converter/String.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Generator.Model;

namespace Generator.Renderer.Public.Field;

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

public RenderableField Convert(GirModel.Field field)
{
return new RenderableField(
Name: Model.Field.GetName(field),
NullableTypeName: Type.GetName(field.AnyTypeOrCallback.AsT0.AsT0)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Generator.Renderer.Public.Field;

public interface FieldConverter
{
bool Supports(GirModel.Field field);
RenderableField Convert(GirModel.Field field);
}
23 changes: 23 additions & 0 deletions src/Generation/Generator/Renderer/Public/Field/Fields.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Collections.Generic;

namespace Generator.Renderer.Public;

internal static class Fields
{
private static readonly List<Field.FieldConverter> Converters = new()
{
new Field.Bitfield(),
new Field.Enumeration(),
new Field.PrimitiveValueType(),
new Field.String(),
};

public static Field.RenderableField GetRenderableField(GirModel.Field field)
{
foreach (var converter in Converters)
if (converter.Supports(field))
return converter.Convert(field);

throw new System.Exception($"Internal field \"{field.Name}\" of type {field.AnyTypeOrCallback} can not be rendered");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Generator.Renderer.Public.Field;

public record RenderableField(string Name, string NullableTypeName);
35 changes: 35 additions & 0 deletions src/Generation/Generator/Renderer/Public/TypedRecord.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Text;
using Generator.Model;

namespace Generator.Renderer.Public;
Expand Down Expand Up @@ -49,6 +50,10 @@ public partial class {name}
{FunctionRenderer.Render(record.TypeFunction)}
{record.Fields
.Select(f => RenderField(record, f))
.Join(Environment.NewLine)}
{record.Functions
.Select(FunctionRenderer.Render)
.Join(Environment.NewLine)}
Expand All @@ -59,4 +64,34 @@ public partial class {name}
.Join(Environment.NewLine)}
}}";
}

private static string RenderField(GirModel.Record record, GirModel.Field field)
{
try
{
var renderableField = Fields.GetRenderableField(field);

if (field is { IsReadable: false, IsWritable: false } || field.IsPrivate)
return string.Empty;

var result = new StringBuilder();

result.AppendLine($"public {renderableField.NullableTypeName} {renderableField.Name} {{");

if (field.IsReadable)
result.AppendLine($"get => Handle.Get{renderableField.Name}();");

if (field.IsWritable)
result.AppendLine($"set => Handle.Set{renderableField.Name}(value);");

result.AppendLine("}");

return result.ToString();
}
catch (Exception ex)
{
Log.Warning($"Did not render typed record {record.Name} field {field.Name}: {ex.Message}");
return string.Empty;
}
}
}
11 changes: 11 additions & 0 deletions src/Tests/Libs/GirTest-0.1.Tests/TypedRecordTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,15 @@ void Callback(out TypedRecordTester? recordTester)
var result = TypedRecordTester.RunCallbackCreateNullableFullOwnershipTransferOut(Callback);
result!.Handle.DangerousGetHandle().Should().Be(instance.Handle.DangerousGetHandle());
}

[TestMethod]
public void SupportsPrimitiveValueTypeField()
{
var instance = TypedRecordTester.New();
instance.RefCount.Should().Be(1);
instance.RefCount = 2;
instance.RefCount.Should().Be(2);
instance.RefCount = 1;
instance.RefCount.Should().Be(1);
}
}

0 comments on commit 8992974

Please sign in to comment.