Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public RenderableReturnType Convert(GirModel.ReturnType returnType)
{
{ Transfer: Transfer.Full } => Model.TypedRecord.GetFullyQuallifiedOwnedHandle(type),
{ Transfer: Transfer.None } => Model.TypedRecord.GetFullyQuallifiedUnownedHandle(type),
{ Transfer: Transfer.Container } => Model.TypedRecord.GetFullyQuallifiedOwnedHandle(type),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You found a small bug here: this uses the TypedRecord model inside the UntypedRecord parameter converter.

I think in the end at runtime there is no difference as currently both kinds are named the same.

But it's not correct as the naming could change one day.

Can you fix this in a separate PR?

_ => throw new Exception($"Unsupported transfer type {returnType.Transfer} for untyped record {type.Name}")
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ internal class UntypedRecord : ReturnTypeConverter
{
public RenderableReturnType Create(GirModel.ReturnType returnType)
{
if (returnType.Transfer == GirModel.Transfer.Container)
throw new NotSupportedException($"Can't return untyped record {returnType} with transfer mode container");

var typeName = ComplexType.GetFullyQualified((GirModel.Record) returnType.AnyType.AsT0);

return new RenderableReturnType(typeName + Nullable.Render(returnType));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public void Initialize(ReturnTypeToManagedData data, IEnumerable<ParameterToNati
{
{ Transfer: Transfer.Full } => fromVariableName,
{ Transfer: Transfer.None } => $"{fromVariableName}.Copy()",
{ Transfer: Transfer.Container } => fromVariableName,
_ => throw new NotImplementedException($"Unsupported transfer type '{returnType.Transfer}' for untyped record {record.Name}")
};

Expand Down
45 changes: 45 additions & 0 deletions src/Native/GirTestLib/girtest-untyped-record-tester.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
* Test untyped records
*/

static GirTestUntypedRecordTester staticElement1;
static GirTestUntypedRecordTester staticElement2;

/**
* girtest_untyped_record_tester_new_with_a: (constructor)
*
Expand Down Expand Up @@ -99,6 +102,48 @@ void girtest_untyped_record_tester_out_parameter_caller_allocates(int v, GirTest
record->a = v;
}

/**
* girtest_untyped_record_tester_returns_transfer_container:
* Returns: (transfer container) (element-type GirTestUntypedRecordTester)
*/
GirTestUntypedRecordContainerTester*
girtest_untyped_record_tester_returns_transfer_container()
{
GirTestUntypedRecordContainerTester *containerPtr1;
GirTestUntypedRecordContainerTester *containerPtr2;

staticElement1.a = 1;
staticElement2.a = 2;

containerPtr1 = g_slice_new0 (GirTestUntypedRecordContainerTester);
containerPtr2 = g_slice_new0 (GirTestUntypedRecordContainerTester);

containerPtr1->data = &staticElement1;
containerPtr1->next = containerPtr2;

containerPtr2->data = &staticElement2;
containerPtr2->next = NULL;

return containerPtr1;
}

/**
* girtest_untyped_record_tester_get_nth_container_data:
* @container: a #GirTestUntypedRecordContainerTester
* @n: the position of the element
*
* Returns: the element's data, or %NULL if the position
* is off the end of the #GSList
*/
GirTestUntypedRecordTester*
girtest_untyped_record_tester_get_nth_container_data(GirTestUntypedRecordContainerTester* container, guint n)
{
while (n-- > 0 && container)
container = container->next;

return container ? container->data : NULL;
}

/**
* girtest_untyped_record_tester_callback_out_parameter_caller_allocates:
* @callback: (scope call): a function that is called to create a new tester instance
Expand Down
9 changes: 9 additions & 0 deletions src/Native/GirTestLib/girtest-untyped-record-tester.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@
G_BEGIN_DECLS

typedef struct _GirTestUntypedRecordTester GirTestUntypedRecordTester;
typedef struct _GirTestUntypedRecordContainerTester GirTestUntypedRecordContainerTester;

struct _GirTestUntypedRecordTester
{
int a;
};

struct _GirTestUntypedRecordContainerTester
{
GirTestUntypedRecordTester* data;
GirTestUntypedRecordContainerTester *next;
};

/**
* GirTestUntypedRecordCallbackOutParameterCallerAllocates:
* @record:(out caller-allocates): the pointer to the integer value
Expand All @@ -30,6 +37,8 @@ GirTestUntypedRecordTester * girtest_untyped_record_tester_nullable_mirror(GirTe
int girtest_untyped_record_tester_get_a(GirTestUntypedRecordTester* record);
int girtest_untyped_record_tester_get_a_nullable(int fallback, GirTestUntypedRecordTester* record);
void girtest_untyped_record_tester_out_parameter_caller_allocates(int v, GirTestUntypedRecordTester *record);
GirTestUntypedRecordContainerTester* girtest_untyped_record_tester_returns_transfer_container();
GirTestUntypedRecordTester* girtest_untyped_record_tester_get_nth_container_data(GirTestUntypedRecordContainerTester* container, guint n);
GirTestUntypedRecordTester* girtest_untyped_record_tester_callback_out_parameter_caller_allocates(GirTestUntypedRecordCallbackOutParameterCallerAllocates callback);
GirTestUntypedRecordTester* girtest_untyped_record_tester_callback_out_parameter_callee_allocates(GirTestUntypedRecordCallbackOutParameterCalleeAllocates callback);
int girtest_untyped_record_tester_get_a_from_last_element(GirTestUntypedRecordTester* array, int length);
Expand Down
14 changes: 14 additions & 0 deletions src/Tests/Libs/GirTest-0.1.Tests/UntypedRecordTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,20 @@ public void SupportsReturnValueNullableTransferNone()
mirror2.Should().BeNull();
}

[TestMethod]
public void SupportsReturnValueTransferContainer()
{
// Container ownership is transferred to here and then released
UntypedRecordContainerTester container = UntypedRecordTester.ReturnsTransferContainer();

// Elements of container are not owned and copied
UntypedRecordTester element1 = UntypedRecordTester.GetNthContainerData(container, 0);
element1!.A.Should().Be(1);

UntypedRecordTester element2 = UntypedRecordTester.GetNthContainerData(container, 1);
element2!.A.Should().Be(2);
}

[TestMethod]
public void SupportsRecordArrayAsParameter()
{
Expand Down
Loading