From 09f2d6772f520b0f9efee5d57e941026cf819a4f Mon Sep 17 00:00:00 2001 From: badcel <1218031+badcel@users.noreply.github.com> Date: Wed, 24 Apr 2024 19:09:04 +0200 Subject: [PATCH] Untyped records: Implement IEquality via pointer comparison --- ...rdEqualsMethodCollidesWithGeneratedCode.cs | 5 ++++- .../Renderer/Internal/UntypedRecordHandle.cs | 21 +++++++++++++++++++ .../Renderer/Public/UntypedRecord.cs | 21 +++++++++++++++++++ .../girtest-untyped-record-tester.c | 14 +++++++++++++ .../girtest-untyped-record-tester.h | 1 + .../GirTest-0.1.Tests/UntypedRecordTest.cs | 9 ++++++++ 6 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/Generation/Generator/Fixer/Record/RecordEqualsMethodCollidesWithGeneratedCode.cs b/src/Generation/Generator/Fixer/Record/RecordEqualsMethodCollidesWithGeneratedCode.cs index 93541d991..45e6c8b19 100644 --- a/src/Generation/Generator/Fixer/Record/RecordEqualsMethodCollidesWithGeneratedCode.cs +++ b/src/Generation/Generator/Fixer/Record/RecordEqualsMethodCollidesWithGeneratedCode.cs @@ -6,7 +6,10 @@ internal class RecordEqualsMethodCollidesWithGeneratedCode : Fixer RenderField(record, x)).Join(Environment.NewLine)} + + public bool Equals({typeName}? other) + {{ + if (ReferenceEquals(null, other)) + return false; + + if (ReferenceEquals(this, other)) + return true; + + return handle.Equals(other.handle); + }} + + public override bool Equals(object? obj) + {{ + return ReferenceEquals(this, obj) || obj is {typeName} other && Equals(other); + }} + + public override int GetHashCode() + {{ + return handle.GetHashCode(); + }} }} public class {unownedHandleTypeName} : {typeName} diff --git a/src/Generation/Generator/Renderer/Public/UntypedRecord.cs b/src/Generation/Generator/Renderer/Public/UntypedRecord.cs index 6349c58cd..c28ed4add 100644 --- a/src/Generation/Generator/Renderer/Public/UntypedRecord.cs +++ b/src/Generation/Generator/Renderer/Public/UntypedRecord.cs @@ -54,6 +54,27 @@ public sealed partial class {name} .Where(Method.IsEnabled) .Select(MethodRenderer.Render) .Join(Environment.NewLine)} + + public bool Equals({name}? other) + {{ + if (ReferenceEquals(null, other)) + return false; + + if (ReferenceEquals(this, other)) + return true; + + return Handle.Equals(other.Handle); + }} + + public override bool Equals(object? obj) + {{ + return ReferenceEquals(this, obj) || obj is {name} other && Equals(other); + }} + + public override int GetHashCode() + {{ + return Handle.GetHashCode(); + }} }}"; } diff --git a/src/Native/GirTestLib/girtest-untyped-record-tester.c b/src/Native/GirTestLib/girtest-untyped-record-tester.c index 213e25f62..0b322937f 100644 --- a/src/Native/GirTestLib/girtest-untyped-record-tester.c +++ b/src/Native/GirTestLib/girtest-untyped-record-tester.c @@ -157,4 +157,18 @@ int girtest_untyped_record_tester_get_a_from_last_element_pointer(GirTestUntyped { GirTestUntypedRecordTester** result = array += (length-1); return (*result)->a; +} + +/** + * girtest_untyped_record_tester_equals: + * @self: An instance + * @other: Another instance + * + * Compare the data of the given instances. + * + * Returns: if the given instances contain the same data. + **/ +gboolean girtest_untyped_record_tester_equals(GirTestUntypedRecordTester *self, GirTestUntypedRecordTester *other) +{ + return self->a == other->a; } \ No newline at end of file diff --git a/src/Native/GirTestLib/girtest-untyped-record-tester.h b/src/Native/GirTestLib/girtest-untyped-record-tester.h index 0dfcea1d8..171bbb843 100644 --- a/src/Native/GirTestLib/girtest-untyped-record-tester.h +++ b/src/Native/GirTestLib/girtest-untyped-record-tester.h @@ -34,4 +34,5 @@ GirTestUntypedRecordTester* girtest_untyped_record_tester_callback_out_parameter 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); int girtest_untyped_record_tester_get_a_from_last_element_pointer(GirTestUntypedRecordTester** array, int length); +gboolean girtest_untyped_record_tester_equals(GirTestUntypedRecordTester *self, GirTestUntypedRecordTester *other); G_END_DECLS \ No newline at end of file diff --git a/src/Tests/Libs/GirTest-0.1.Tests/UntypedRecordTest.cs b/src/Tests/Libs/GirTest-0.1.Tests/UntypedRecordTest.cs index f44c86c95..1004c8147 100644 --- a/src/Tests/Libs/GirTest-0.1.Tests/UntypedRecordTest.cs +++ b/src/Tests/Libs/GirTest-0.1.Tests/UntypedRecordTest.cs @@ -124,4 +124,13 @@ public void IsSealed() { typeof(UntypedRecordTester).IsSealed.Should().BeTrue(); } + + [TestMethod] + public void HasNativeEqualsMethod() + { + var instance1 = new UntypedRecordTester(); + var instance2 = new UntypedRecordTester(); + + instance1.NativeEquals(instance2).Should().BeTrue(); + } }