Skip to content

Commit

Permalink
[RGen] Add the platform availability as part of the constructor data …
Browse files Browse the repository at this point in the history
…model (#21847)

This way, when we start generating the code we do not need to calculate
the changes and this structure will take into account any changes in the
class availability.

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: GitHub Actions Autoformatter <[email protected]>
  • Loading branch information
3 people authored Dec 23, 2024
1 parent 4af3d21 commit 5c76b9a
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 10 deletions.
29 changes: 28 additions & 1 deletion src/rgen/Microsoft.Macios.Generator/DataModel/Constructor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,45 @@
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Macios.Generator.Availability;
using Microsoft.Macios.Generator.Extensions;

namespace Microsoft.Macios.Generator.DataModel;

readonly struct Constructor : IEquatable<Constructor> {
/// <summary>
/// Type name that owns the constructor.
/// </summary>
public string Type { get; }

/// <summary>
/// The platform availability of the enum value.
/// </summary>
public SymbolAvailability SymbolAvailability { get; }

/// <summary>
/// Get the attributes added to the constructor.
/// </summary>
public ImmutableArray<AttributeCodeChange> Attributes { get; } = [];

/// <summary>
/// Modifiers list.
/// </summary>
public ImmutableArray<SyntaxToken> Modifiers { get; } = [];

/// <summary>
/// Parameters list.
/// </summary>
public ImmutableArray<Parameter> Parameters { get; } = [];

public Constructor (string type, ImmutableArray<AttributeCodeChange> attributes,
public Constructor (string type,
SymbolAvailability symbolAvailability,
ImmutableArray<AttributeCodeChange> attributes,
ImmutableArray<SyntaxToken> modifiers,
ImmutableArray<Parameter> parameters)
{
Type = type;
SymbolAvailability = symbolAvailability;
Attributes = attributes;
Modifiers = modifiers;
Parameters = parameters;
Expand Down Expand Up @@ -54,6 +76,7 @@ public static bool TryCreate (ConstructorDeclarationSyntax declaration, Semantic

change = new (
type: constructor.ContainingSymbol.ToDisplayString ().Trim (), // we want the full name
symbolAvailability: constructor.GetSupportedPlatforms (),
attributes: attributes,
modifiers: [.. declaration.Modifiers],
parameters: parametersBucket.ToImmutable ());
Expand All @@ -65,6 +88,9 @@ public bool Equals (Constructor other)
{
if (Type != other.Type)
return false;
if (SymbolAvailability != other.SymbolAvailability)
return false;

var attrsComparer = new AttributesEqualityComparer ();
if (!attrsComparer.Equals (Attributes, other.Attributes))
return false;
Expand All @@ -87,6 +113,7 @@ public override int GetHashCode ()
{
var hashCode = new HashCode ();
hashCode.Add (Type);
hashCode.Add (SymbolAvailability);
foreach (var modifier in Modifiers) {
hashCode.Add (modifier);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public int Compare (Constructor x, Constructor y)
if (attributesLengthCompare != 0)
return attributesLengthCompare;

// sort by the attributes
// Sort by the attributes, this covers the need to sort by the os availability since that
// information comes from the attributes. There is no need to sort twice by the same data
var attributeComparer = new AttributeComparer ();
var xAttributes = x.Attributes.Order (attributeComparer).ToArray ();
var yAttributes = y.Attributes.Order (attributeComparer).ToArray ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public MyClass () {}
Constructors = [
new (
type: "NS.MyClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword)
Expand Down Expand Up @@ -104,6 +105,7 @@ public MyClass(string inName) {
Constructors = [
new (
type: "NS.MyClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword)
Expand All @@ -112,6 +114,7 @@ public MyClass(string inName) {
),
new (
type: "NS.MyClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ public void CompareDifferentConstructorLength ()
]),
],
Constructors = [
new ("MyClass", [], [], [])
new ("MyClass", new (), [], [], [])
],
};
Assert.False (equalityComparer.Equals (changes1, changes2));
Expand Down Expand Up @@ -397,7 +397,7 @@ public void CompareDifferentConstructors ()
]),
],
Constructors = [
new ("MyClass", [], [], [])
new ("MyClass", new (), [], [], [])
],
};
var changes2 = new CodeChanges (BindingType.SmartEnum, "name") {
Expand Down Expand Up @@ -438,6 +438,7 @@ public void CompareDifferentConstructors ()
],
Constructors = [
new ("MyClass",
symbolAvailability: new (),
attributes: [],
modifiers: [],
parameters: [
Expand Down Expand Up @@ -488,8 +489,9 @@ public void CompareSameConstructors ()
]),
],
Constructors = [
new Constructor ("MyClass", [], [], []),
new Constructor ("MyClass", new (), [], [], []),
new ("MyClass",
symbolAvailability: new (),
attributes: [],
modifiers: [],
parameters: [
Expand Down Expand Up @@ -534,8 +536,9 @@ public void CompareSameConstructors ()
]),
],
Constructors = [
new Constructor ("MyClass", [], [], []),
new Constructor ("MyClass", new (), [], [], []),
new ("MyClass",
symbolAvailability: new (),
attributes: [],
modifiers: [],
parameters: [
Expand Down Expand Up @@ -587,12 +590,13 @@ public void CompareSameConstructorsDiffOrder ()
],
Constructors = [
new ("MyClass",
symbolAvailability: new (),
attributes: [],
modifiers: [],
parameters: [
new (0, "string", "name"),
]),
new ("MyClass", [], [], []),
new ("MyClass", new (), [], [], []),
],
};
var changes2 = new CodeChanges (BindingType.SmartEnum, "name") {
Expand Down Expand Up @@ -632,8 +636,9 @@ public void CompareSameConstructorsDiffOrder ()
]),
],
Constructors = [
new ("MyClass", [], [], []),
new ("MyClass", new (), [], [], []),
new ("MyClass",
symbolAvailability: new (),
attributes: [],
modifiers: [],
parameters: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ public class ConstructorComparerTests {
[Fact]
public void CompareDiffType ()
{
var x = new Constructor ("MyClass", [], [], []);
var y = new Constructor ("MyClass2", [], [], []);
var x = new Constructor ("MyClass", new (), [], [], []);
var y = new Constructor ("MyClass2", new (), [], [], []);
Assert.Equal (String.Compare (x.Type, y.Type, StringComparison.Ordinal), comparer.Compare (x, y));
}

Expand All @@ -21,12 +21,14 @@ public void CompareModifierDiffLength ()
{
var x = new Constructor ("MyClass",
attributes: [],
symbolAvailability: new (),
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
SyntaxFactory.Token (SyntaxKind.PartialKeyword),
],
parameters: []);
var y = new Constructor ("MyClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
Expand All @@ -39,12 +41,14 @@ public void CompareModifierDiffLength ()
public void CompareDiffModifier ()
{
var x = new Constructor ("MyClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PartialKeyword),
],
parameters: []);
var y = new Constructor ("MyClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
Expand All @@ -58,6 +62,7 @@ public void CompareDiffModifier ()
public void CompareAttrsDiffLength ()
{
var x = new Constructor ("MyClass",
symbolAvailability: new (),
attributes: [
new ("FirstAttr"),
new ("SecondAttr", ["first"]),
Expand All @@ -68,6 +73,7 @@ public void CompareAttrsDiffLength ()
],
parameters: []);
var y = new Constructor ("MyClass",
symbolAvailability: new (),
attributes: [
new ("FirstAttr"),
],
Expand All @@ -83,6 +89,7 @@ public void CompareAttrsDiffLength ()
public void CompareDiffAttrs ()
{
var x = new Constructor ("MyClass",
symbolAvailability: new (),
attributes: [
new ("FirstAttr"),
],
Expand All @@ -92,6 +99,7 @@ public void CompareDiffAttrs ()
],
parameters: []);
var y = new Constructor ("MyClass",
symbolAvailability: new (),
attributes: [
new ("SecondAttr", ["first"]),
],
Expand All @@ -109,6 +117,7 @@ public void CompareParameterDiffLength ()
{

var x = new Constructor ("MyClass",
symbolAvailability: new (),
attributes: [
new ("FirstAttr"),
],
Expand All @@ -120,6 +129,7 @@ public void CompareParameterDiffLength ()
new (0, "string", "name"),
]);
var y = new Constructor ("MyClass",
symbolAvailability: new (),
attributes: [
new ("FirstAttr"),
],
Expand All @@ -138,6 +148,7 @@ public void CompareParameterDiffLength ()
public void CompareDiffParameters ()
{
var x = new Constructor ("MyClass",
symbolAvailability: new (),
attributes: [
new ("FirstAttr"),
],
Expand All @@ -149,6 +160,7 @@ public void CompareDiffParameters ()
new (0, "string", "name"),
]);
var y = new Constructor ("MyClass",
symbolAvailability: new (),
attributes: [
new ("FirstAttr"),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Linq;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Macios.Generator.Attributes;
using Microsoft.Macios.Generator.Availability;
using Microsoft.Macios.Generator.DataModel;
using Xamarin.Tests;
using Xamarin.Utils;
Expand Down Expand Up @@ -31,6 +33,7 @@ public TestClass () {
emptyConstructor,
new Constructor (
type: "NS.TestClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
Expand All @@ -55,6 +58,7 @@ public TestClass (string inName) {
singleParameter,
new Constructor (
type: "NS.TestClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
Expand Down Expand Up @@ -84,6 +88,7 @@ public TestClass (string inName, int inAge) {
multiParameter,
new Constructor (
type: "NS.TestClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
Expand Down Expand Up @@ -114,6 +119,7 @@ public TestClass (string? inName, int inAge) {
nullableParameter,
new Constructor (
type: "NS.TestClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
Expand Down Expand Up @@ -147,6 +153,7 @@ public TestClass (string? inName, int inAge, params string[] inSurnames) {
paramsCollectionParameter,
new Constructor (
type: "NS.TestClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
Expand Down Expand Up @@ -176,6 +183,7 @@ public TestClass (string? inName = null) {
optionalParameter,
new Constructor (
type: "NS.TestClass",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
Expand Down Expand Up @@ -203,6 +211,7 @@ public TestClass (T? inName = null) {
genericParameter,
new Constructor (
type: "NS.TestClass<T>",
symbolAvailability: new (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
Expand All @@ -212,6 +221,41 @@ public TestClass (T? inName = null) {
]
)
];

const string availabilityPresent = @"
using System.Runtime.Versioning;
using System;
namespace NS {
[SupportedOSPlatform (""ios"")]
[SupportedOSPlatform (""tvos"")]
public class TestClass {
string name;
public TestClass (string? inName = null) {
name = inName ?? string.Empty;
}
}
}
";
var builder = SymbolAvailability.CreateBuilder ();
builder.Add (new SupportedOSPlatformData ("ios"));
builder.Add (new SupportedOSPlatformData ("tvos"));

yield return [
availabilityPresent,
new Constructor (
type: "NS.TestClass",
symbolAvailability: builder.ToImmutable (),
attributes: [],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
],
parameters: [
new (0, "string?", "inName") { IsNullable = true, IsOptional = true, },
]
)
];

}

IEnumerator IEnumerable.GetEnumerator ()
Expand Down
Loading

10 comments on commit 5c76b9a

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

Please sign in to comment.