From 4af3d21dd2dcd6b37c6a2a79c36994f7db01bdc8 Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Fri, 20 Dec 2024 17:09:15 -0500 Subject: [PATCH] [Rgen] Add the platform availability as part of the enum field changes struct. (#21843) This way we keep track of the different changes of the availability not only from the current enum value but from any possible changes in the parent containers. This can be the enum itself or a class in case we have a nested enum declaration. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: GitHub Actions Autoformatter --- .../Availability/SymbolAvailability.cs | 4 +- .../DataModel/CodeChanges.cs | 15 +++--- .../DataModel/EnumMember.cs | 20 +++++-- .../DataModel/CodeChangesComparerTests.cs | 6 +-- .../CodeChangesEqualityComparerTests.cs | 6 +-- .../DataModel/EnumMemberCodeChangesTests.cs | 52 +++++++++++++------ .../EnumMembersEqualityComparerTests.cs | 17 +++--- 7 files changed, 80 insertions(+), 40 deletions(-) diff --git a/src/rgen/Microsoft.Macios.Generator/Availability/SymbolAvailability.cs b/src/rgen/Microsoft.Macios.Generator/Availability/SymbolAvailability.cs index 25bc3d47831d..f7ae1876dcde 100644 --- a/src/rgen/Microsoft.Macios.Generator/Availability/SymbolAvailability.cs +++ b/src/rgen/Microsoft.Macios.Generator/Availability/SymbolAvailability.cs @@ -11,7 +11,9 @@ namespace Microsoft.Macios.Generator.Availability; static readonly HashSet supportedPlatforms = [ApplePlatform.iOS, ApplePlatform.TVOS, ApplePlatform.MacOSX, ApplePlatform.MacCatalyst]; - readonly SortedDictionary availabilities; + readonly SortedDictionary availabilities = new (); + + public SymbolAvailability () { } SymbolAvailability (Dictionary platforms) { diff --git a/src/rgen/Microsoft.Macios.Generator/DataModel/CodeChanges.cs b/src/rgen/Microsoft.Macios.Generator/DataModel/CodeChanges.cs index 55d85fc0a9c8..d5ec30561dda 100644 --- a/src/rgen/Microsoft.Macios.Generator/DataModel/CodeChanges.cs +++ b/src/rgen/Microsoft.Macios.Generator/DataModel/CodeChanges.cs @@ -183,13 +183,16 @@ internal CodeChanges (BindingType bindingType, string fullyQualifiedSymbol) Attributes = enumDeclaration.GetAttributeCodeChanges (semanticModel); var bucket = ImmutableArray.CreateBuilder (); // loop over the fields and add those that contain a FieldAttribute - var enumValueDeclaration = enumDeclaration.Members.OfType (); - foreach (var val in enumValueDeclaration) { - if (Skip (val, semanticModel)) + var enumValueDeclarations = enumDeclaration.Members.OfType (); + foreach (var declaration in enumValueDeclarations) { + if (Skip (declaration, semanticModel)) continue; - var memberName = val.Identifier.ToFullString ().Trim (); - var attributes = val.GetAttributeCodeChanges (semanticModel); - bucket.Add (new (memberName, attributes)); + if (semanticModel.GetDeclaredSymbol (declaration) is not ISymbol symbol) { + continue; + } + var memberName = declaration.Identifier.ToFullString ().Trim (); + var attributes = declaration.GetAttributeCodeChanges (semanticModel); + bucket.Add (new (memberName, symbol.GetSupportedPlatforms (), attributes)); } EnumMembers = bucket.ToImmutable (); diff --git a/src/rgen/Microsoft.Macios.Generator/DataModel/EnumMember.cs b/src/rgen/Microsoft.Macios.Generator/DataModel/EnumMember.cs index a7da4a7a251b..7b8ec773172e 100644 --- a/src/rgen/Microsoft.Macios.Generator/DataModel/EnumMember.cs +++ b/src/rgen/Microsoft.Macios.Generator/DataModel/EnumMember.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; using System.Linq; +using Microsoft.Macios.Generator.Availability; namespace Microsoft.Macios.Generator.DataModel; @@ -9,12 +10,16 @@ namespace Microsoft.Macios.Generator.DataModel; /// reflected in the generated code. /// readonly struct EnumMember : IEquatable { - /// /// Get the name of the member. /// public string Name { get; } + /// + /// The platform availability of the enum value. + /// + public SymbolAvailability SymbolAvailability { get; } + /// /// Get the attributes added to the member. /// @@ -24,10 +29,13 @@ namespace Microsoft.Macios.Generator.DataModel; /// Create a new change that happened on a member. /// /// The name of the changed member. + /// The symbol availability of the member. /// The list of attribute changes in the member. - public EnumMember (string name, ImmutableArray attributes) + public EnumMember (string name, SymbolAvailability symbolAvailability, + ImmutableArray attributes) { Name = name; + SymbolAvailability = symbolAvailability; Attributes = attributes; } @@ -35,13 +43,17 @@ public EnumMember (string name, ImmutableArray attributes) /// Create a new change that happened on a member. /// /// The name of the changed member. - public EnumMember (string name) : this (name, []) { } + public EnumMember (string name) : this (name, new SymbolAvailability (), ImmutableArray.Empty) + { + } /// public bool Equals (EnumMember other) { if (Name != other.Name) return false; + if (SymbolAvailability != other.SymbolAvailability) + return false; var attrComparer = new AttributesEqualityComparer (); return attrComparer.Equals (Attributes, other.Attributes); } @@ -55,7 +67,7 @@ public override bool Equals (object? obj) /// public override int GetHashCode () { - return HashCode.Combine (Name, Attributes); + return HashCode.Combine (Name, SymbolAvailability, Attributes); } public static bool operator == (EnumMember x, EnumMember y) diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/CodeChangesComparerTests.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/CodeChangesComparerTests.cs index 439415a37dc4..6b82162d8ce0 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/CodeChangesComparerTests.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/CodeChangesComparerTests.cs @@ -61,7 +61,7 @@ public void CompareDifferentMembersLength () var changes1 = new CodeChanges (BindingType.SmartEnum, "name"); var changes2 = new CodeChanges (BindingType.SmartEnum, "name") { EnumMembers = [ - new EnumMember ("name", []) + new EnumMember ("name", new (), []) ], }; Assert.False (comparer.Equals (changes1, changes2)); @@ -72,12 +72,12 @@ public void CompareDifferentMembers () { var changes1 = new CodeChanges (BindingType.SmartEnum, "name") { EnumMembers = [ - new EnumMember ("name", []) + new EnumMember ("name", new (), []) ], }; var changes2 = new CodeChanges (BindingType.SmartEnum, "name") { EnumMembers = [ - new EnumMember ("name2", []) + new EnumMember ("name2", new (), []) ], }; Assert.False (comparer.Equals (changes1, changes2)); diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/CodeChangesEqualityComparerTests.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/CodeChangesEqualityComparerTests.cs index 66686d90d764..16ddb972484a 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/CodeChangesEqualityComparerTests.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/CodeChangesEqualityComparerTests.cs @@ -61,7 +61,7 @@ public void CompareDifferentMembersLength () var changes1 = new CodeChanges (BindingType.SmartEnum, "name"); var changes2 = new CodeChanges (BindingType.SmartEnum, "name") { EnumMembers = [ - new EnumMember ("name", []) + new EnumMember ("name", new (), []) ], }; Assert.False (equalityComparer.Equals (changes1, changes2)); @@ -72,12 +72,12 @@ public void CompareDifferentMembers () { var changes1 = new CodeChanges (BindingType.SmartEnum, "name") { EnumMembers = [ - new EnumMember ("name", []) + new EnumMember ("name", new (), []) ], }; var changes2 = new CodeChanges (BindingType.SmartEnum, "name") { EnumMembers = [ - new EnumMember ("name2", []) + new EnumMember ("name2", new (), []) ], }; Assert.False (equalityComparer.Equals (changes1, changes2)); diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/EnumMemberCodeChangesTests.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/EnumMemberCodeChangesTests.cs index 61d981cb4520..21fa21a8c9af 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/EnumMemberCodeChangesTests.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/EnumMemberCodeChangesTests.cs @@ -1,3 +1,5 @@ +using Microsoft.Macios.Generator.Attributes; +using Microsoft.Macios.Generator.Availability; using Microsoft.Macios.Generator.DataModel; using Xunit; @@ -7,8 +9,8 @@ public class EnumMemberCodeChangesTests { [Fact] public void EqualsNoParams () { - var memberCodeChange1 = new EnumMember ("name", []); - var memberCodeChange2 = new EnumMember ("name", []); + var memberCodeChange1 = new EnumMember ("name", new (), []); + var memberCodeChange2 = new EnumMember ("name", new (), []); Assert.True (memberCodeChange1.Equals (memberCodeChange2)); Assert.True (memberCodeChange1 == memberCodeChange2); Assert.False (memberCodeChange1 != memberCodeChange2); @@ -17,10 +19,10 @@ public void EqualsNoParams () [Fact] public void EqualsWithArgumentParams () { - var memberCodeChange1 = new EnumMember ("name", [ + var memberCodeChange1 = new EnumMember ("name", new (), [ new AttributeCodeChange ("name", ["arg1", "arg2"]) ]); - var memberCodeChange2 = new EnumMember ("name", [ + var memberCodeChange2 = new EnumMember ("name", new (), [ new AttributeCodeChange ("name", ["arg1", "arg2"]) ]); Assert.True (memberCodeChange1.Equals (memberCodeChange2)); @@ -31,20 +33,20 @@ public void EqualsWithArgumentParams () [Fact] public void NotEqualsDifferentName () { - var memberCodeChange1 = new EnumMember ("name", []); - var memberCodeChange2 = new EnumMember ("name2", []); + var memberCodeChange1 = new EnumMember ("name", new (), []); + var memberCodeChange2 = new EnumMember ("name2", new (), []); Assert.False (memberCodeChange1.Equals (memberCodeChange2)); Assert.False (memberCodeChange1 == memberCodeChange2); Assert.True (memberCodeChange1 != memberCodeChange2); } [Fact] - public void NotEqualsDiffenretAttributeNames () + public void NotEqualsDifferentAttributeNames () { - var memberCodeChange1 = new EnumMember ("name", [ + var memberCodeChange1 = new EnumMember ("name", new (), [ new AttributeCodeChange ("name", ["arg1", "arg2"]) ]); - var memberCodeChange2 = new EnumMember ("name", [ + var memberCodeChange2 = new EnumMember ("name", new (), [ new AttributeCodeChange ("name2", ["arg1", "arg2"]) ]); Assert.False (memberCodeChange1.Equals (memberCodeChange2)); @@ -55,10 +57,10 @@ public void NotEqualsDiffenretAttributeNames () [Fact] public void NotEqualsDifferentAttributeParams () { - var memberCodeChange1 = new EnumMember ("name", [ + var memberCodeChange1 = new EnumMember ("name", new (), [ new AttributeCodeChange ("name", ["arg1", "arg2"]) ]); - var memberCodeChange2 = new EnumMember ("name", [ + var memberCodeChange2 = new EnumMember ("name", new (), [ new AttributeCodeChange ("name", ["arg1", "arg3"]) ]); Assert.False (memberCodeChange1.Equals (memberCodeChange2)); @@ -69,10 +71,10 @@ public void NotEqualsDifferentAttributeParams () [Fact] public void NotEqualsDifferentAttributeParamsOrder () { - var memberCodeChange1 = new EnumMember ("name", [ + var memberCodeChange1 = new EnumMember ("name", new (), [ new AttributeCodeChange ("name", ["arg1", "arg2"]) ]); - var memberCodeChange2 = new EnumMember ("name", [ + var memberCodeChange2 = new EnumMember ("name", new (), [ new AttributeCodeChange ("name", ["arg2", "arg1"]) ]); Assert.False (memberCodeChange1.Equals (memberCodeChange2)); @@ -83,12 +85,32 @@ public void NotEqualsDifferentAttributeParamsOrder () [Fact] public void NotEqualsDifferentAttributesCount () { + var memberCodeChange1 = new EnumMember ("name", new (), [ + new AttributeCodeChange ("name", ["arg1", "arg2"]), + new AttributeCodeChange ("name2", []) + ]); + var memberCodeChange2 = new EnumMember ("name", new (), [ + new AttributeCodeChange ("name", ["arg2", "arg1"]) + ]); + Assert.False (memberCodeChange1.Equals (memberCodeChange2)); + Assert.False (memberCodeChange1 == memberCodeChange2); + Assert.True (memberCodeChange1 != memberCodeChange2); + } + + [Fact] + public void NotEqualsDifferentPlatformAvailability () + { + var builder = SymbolAvailability.CreateBuilder (); + builder.Add (new SupportedOSPlatformData ("ios")); + builder.Add (new SupportedOSPlatformData ("tvos")); + builder.Add (new UnsupportedOSPlatformData ("tvos")); + var availability = builder.ToImmutable (); - var memberCodeChange1 = new EnumMember ("name", [ + var memberCodeChange1 = new EnumMember ("name", availability, [ new AttributeCodeChange ("name", ["arg1", "arg2"]), new AttributeCodeChange ("name2", []) ]); - var memberCodeChange2 = new EnumMember ("name", [ + var memberCodeChange2 = new EnumMember ("name", new (), [ new AttributeCodeChange ("name", ["arg2", "arg1"]) ]); Assert.False (memberCodeChange1.Equals (memberCodeChange2)); diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/EnumMembersEqualityComparerTests.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/EnumMembersEqualityComparerTests.cs index ecbfb05dab80..274b2ee62ebd 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/EnumMembersEqualityComparerTests.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/EnumMembersEqualityComparerTests.cs @@ -1,4 +1,5 @@ using System.Collections.Immutable; +using Microsoft.Macios.Generator.Availability; using Microsoft.Macios.Generator.DataModel; using Xunit; @@ -16,32 +17,32 @@ public EnumMembersEqualityComparerTests () [Fact] public void NotEqualsDiffLength () { - ImmutableArray x = [new ("name", []), new ("name1")]; - ImmutableArray y = [new ("name", [])]; + ImmutableArray x = [new ("name", new (), []), new ("name1")]; + ImmutableArray y = [new ("name", new (), [])]; Assert.False (comparer.Equals (x, y)); } [Fact] public void NotEqualsDiffAttributes () { - ImmutableArray x = [new ("name", []), new ("name1")]; - ImmutableArray y = [new ("name1", []), new ("name1")]; + ImmutableArray x = [new ("name", new (), []), new ("name1")]; + ImmutableArray y = [new ("name1", new (), []), new ("name1")]; Assert.False (comparer.Equals (x, y)); } [Fact] public void EqualsSameOrder () { - ImmutableArray x = [new ("name", []), new ("name1")]; - ImmutableArray y = [new ("name", []), new ("name1")]; + ImmutableArray x = [new ("name", new SymbolAvailability (), []), new ("name1")]; + ImmutableArray y = [new ("name", new SymbolAvailability (), []), new ("name1")]; Assert.True (comparer.Equals (x, y)); } [Fact] public void EqualsDiffOrder () { - ImmutableArray x = [new ("name1", []), new ("name")]; - ImmutableArray y = [new ("name", []), new ("name1")]; + ImmutableArray x = [new ("name1", new (), []), new ("name")]; + ImmutableArray y = [new ("name", new (), []), new ("name1")]; Assert.True (comparer.Equals (x, y)); } }