Skip to content

Commit

Permalink
[RGent] Add name and namespace to the codechanges struct. (#21857)
Browse files Browse the repository at this point in the history
We add the name and a collection with the namespaces that contains the
type. This way we do not need to query the symbol when generating code
and we can simply use the data in the structure.

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: GitHub Actions Autoformatter <[email protected]>
  • Loading branch information
3 people authored Dec 27, 2024
1 parent f6d86a2 commit 0bedb2c
Show file tree
Hide file tree
Showing 9 changed files with 260 additions and 76 deletions.
24 changes: 21 additions & 3 deletions src/rgen/Microsoft.Macios.Generator/DataModel/CodeChanges.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ readonly struct CodeChanges {
/// </summary>
public BindingType BindingType { get; } = BindingType.Unknown;

/// <summary>
/// The name of the named type that generated the code change.
/// </summary>
public string Name { get; }

/// <summary>
/// The namespace that contains the named type that generated the code change.
/// </summary>
public ImmutableArray<string> Namespace { get; }

/// <summary>
/// Fully qualified name of the symbol that the code changes are for.
/// </summary>
Expand Down Expand Up @@ -164,10 +174,14 @@ static void GetMembers<T, TR> (TypeDeclarationSyntax baseDeclarationSyntax, Sema
/// Internal constructor added for testing purposes.
/// </summary>
/// <param name="bindingType">The type of binding for the given code changes.</param>
/// <param name="name">The name of the named type that created the code change.</param>
/// <param name="namespace">The namespace that contains the named type.</param>
/// <param name="fullyQualifiedSymbol">The fully qualified name of the symbol.</param>
internal CodeChanges (BindingType bindingType, string fullyQualifiedSymbol)
internal CodeChanges (BindingType bindingType, string name, ImmutableArray<string> @namespace, string fullyQualifiedSymbol)
{
BindingType = bindingType;
Name = name;
Namespace = @namespace;
FullyQualifiedSymbol = fullyQualifiedSymbol;
}

Expand All @@ -178,6 +192,7 @@ internal CodeChanges (BindingType bindingType, string fullyQualifiedSymbol)
/// <param name="semanticModel">The semantic model of the compilation.</param>
CodeChanges (EnumDeclarationSyntax enumDeclaration, SemanticModel semanticModel)
{
(Name, Namespace) = semanticModel.GetNameAndNamespace (enumDeclaration);
BindingType = BindingType.SmartEnum;
FullyQualifiedSymbol = enumDeclaration.GetFullyQualifiedIdentifier ();
Attributes = enumDeclaration.GetAttributeCodeChanges (semanticModel);
Expand Down Expand Up @@ -205,6 +220,7 @@ internal CodeChanges (BindingType bindingType, string fullyQualifiedSymbol)
/// <param name="semanticModel">The semantic model of the compilation.</param>
CodeChanges (ClassDeclarationSyntax classDeclaration, SemanticModel semanticModel)
{
(Name, Namespace) = semanticModel.GetNameAndNamespace (classDeclaration);
BindingType = BindingType.Class;
FullyQualifiedSymbol = classDeclaration.GetFullyQualifiedIdentifier ();
Attributes = classDeclaration.GetAttributeCodeChanges (semanticModel);
Expand All @@ -227,6 +243,7 @@ internal CodeChanges (BindingType bindingType, string fullyQualifiedSymbol)
/// <param name="semanticModel">The semantic model of the compilation.</param>
CodeChanges (InterfaceDeclarationSyntax interfaceDeclaration, SemanticModel semanticModel)
{
(Name, Namespace) = semanticModel.GetNameAndNamespace (interfaceDeclaration);
BindingType = BindingType.Protocol;
FullyQualifiedSymbol = interfaceDeclaration.GetFullyQualifiedIdentifier ();
Attributes = interfaceDeclaration.GetAttributeCodeChanges (semanticModel);
Expand Down Expand Up @@ -261,8 +278,9 @@ internal CodeChanges (BindingType bindingType, string fullyQualifiedSymbol)
public override string ToString ()
{
var sb = new StringBuilder ("Changes: {");
sb.Append ($"BindingType: {BindingType}, ");
sb.Append ($"FullyQualifiedSymbol: {FullyQualifiedSymbol}, ");
sb.Append ($"BindingType: {BindingType}, Name: {Name}, Namespace: [");
sb.AppendJoin (", ", Namespace);
sb.Append ($"], FullyQualifiedSymbol: {FullyQualifiedSymbol}, ");
sb.Append ("Attributes: [");
sb.AppendJoin (", ", Attributes);
sb.Append ("], EnumMembers: [");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ public override bool Equals (CodeChanges x, CodeChanges y)
// - the members are the same
// - the attributes are the same

// this could be a massive or but that makes it less readable
// this could be a massive 'or' but that makes it less readable
if (x.Name != y.Name)
return false;
var namespaceComparer = new ListComparer<string> ();
if (!namespaceComparer.Equals (x.Namespace, y.Namespace))
return false;
if (x.FullyQualifiedSymbol != y.FullyQualifiedSymbol)
return false;
if (x.BindingType != y.BindingType)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Microsoft.Macios.Generator.Extensions;

public static class SemanticModelExtensions {
/// <summary>
/// Returns the name and namespace of the symbol that has been declared in the passed base type declaration
/// syntax node.
/// </summary>
/// <param name="self">The current semantic model.</param>
/// <param name="declaration">The named type declaration syntaxt.</param>
/// <returns>A tuple containing the name and namespace of the type. If they could not be calculated they will
/// be set to be string.Empty.</returns>
public static (string Name, ImmutableArray<string> Namespace) GetNameAndNamespace (this SemanticModel self,
BaseTypeDeclarationSyntax declaration)
{
var symbol = self.GetDeclaredSymbol (declaration);
var name = symbol?.Name ?? string.Empty;
var bucket = ImmutableArray.CreateBuilder<string> ();
var ns = symbol?.ContainingNamespace;
while (ns is not null) {
if (!string.IsNullOrWhiteSpace (ns.Name))
// prepend the namespace so that we can read from top to bottom
bucket.Insert (0, ns.Name);
ns = ns.ContainingNamespace;
}
return (name, bucket.ToImmutableArray ());
}
}
19 changes: 11 additions & 8 deletions src/rgen/Microsoft.Macios.Generator/ListComparer.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Microsoft.Macios.Generator;

public class ListComparer<T> : EqualityComparer<List<T>> {
readonly IComparer<T> comparer;
public class ListComparer<T> : EqualityComparer<IList<T>> {
readonly IComparer<T>? comparer;
readonly IEqualityComparer<T> valueComparer;

public ListComparer (IComparer<T> sortComparer, IEqualityComparer<T>? equalityComparer = null)
public ListComparer (IComparer<T>? sortComparer = null, IEqualityComparer<T>? equalityComparer = null)
{
comparer = sortComparer ?? throw new ArgumentNullException (nameof (sortComparer));
comparer = sortComparer;
valueComparer = equalityComparer ?? EqualityComparer<T>.Default;
}

/// <inheritdoc/>
public override bool Equals (List<T>? x, List<T>? y)
public override bool Equals (IList<T>? x, IList<T>? y)
{
// bases cases for null or diff size
if (x is null && y is null)
Expand All @@ -26,10 +27,12 @@ public override bool Equals (List<T>? x, List<T>? y)

// make copies of the lists and sort them
var xSorted = x.ToArray ();
Array.Sort (xSorted, comparer);
if (comparer is not null)
Array.Sort (xSorted, comparer);

var ySorted = y.ToArray ();
Array.Sort (ySorted, comparer);
if (comparer is not null)
Array.Sort (ySorted, comparer);

for (var i = 0; i < xSorted.Length; i++) {
if (!valueComparer.Equals (xSorted [i], ySorted [i]))
Expand All @@ -39,7 +42,7 @@ public override bool Equals (List<T>? x, List<T>? y)
}

/// <inheritdoc/>
public override int GetHashCode (List<T> obj)
public override int GetHashCode (IList<T> obj)
{
var hash = new HashCode ();
foreach (var element in obj) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public partial class MyClass {
emptyClass,
new CodeChanges (
bindingType: BindingType.Class,
name: "MyClass",
@namespace: ["NS"],
fullyQualifiedSymbol: "NS.MyClass"
) {
Attributes = [
Expand All @@ -57,6 +59,8 @@ public MyClass () {}
singleConstructorClass,
new CodeChanges (
bindingType: BindingType.Class,
name: "MyClass",
@namespace: ["NS"],
fullyQualifiedSymbol: "NS.MyClass"
) {
Attributes = [
Expand Down Expand Up @@ -97,6 +101,8 @@ public MyClass(string inName) {
multiConstructorClass,
new CodeChanges (
bindingType: BindingType.Class,
name: "MyClass",
@namespace: ["NS"],
fullyQualifiedSymbol: "NS.MyClass"
) {
Attributes = [
Expand Down Expand Up @@ -147,6 +153,8 @@ public partial class MyClass {
singlePropertyClass,
new CodeChanges (
bindingType: BindingType.Class,
name: "MyClass",
@namespace: ["NS"],
fullyQualifiedSymbol: "NS.MyClass"
) {
Attributes = [
Expand Down Expand Up @@ -191,6 +199,8 @@ public partial class MyClass {
multiPropertyClassMissingExport,
new CodeChanges (
bindingType: BindingType.Class,
name: "MyClass",
@namespace: ["NS"],
fullyQualifiedSymbol: "NS.MyClass"
) {
Attributes = [
Expand Down Expand Up @@ -236,6 +246,8 @@ public partial class MyClass {
multiPropertyClass,
new CodeChanges (
bindingType: BindingType.Class,
name: "MyClass",
@namespace: ["NS"],
fullyQualifiedSymbol: "NS.MyClass"
) {
Attributes = [
Expand Down Expand Up @@ -294,6 +306,8 @@ public partial class MyClass {
singleMethodClass,
new CodeChanges (
bindingType: BindingType.Class,
name: "MyClass",
@namespace: ["NS"],
fullyQualifiedSymbol: "NS.MyClass"
) {
Attributes = [
Expand Down Expand Up @@ -338,6 +352,8 @@ public void SetSurname (string inSurname) {}
multiMethodClassMissingExport,
new CodeChanges (
bindingType: BindingType.Class,
name: "MyClass",
@namespace: ["NS"],
fullyQualifiedSymbol: "NS.MyClass"
) {
Attributes = [
Expand Down Expand Up @@ -383,6 +399,8 @@ public partial class MyClass {
multiMethodClass,
new CodeChanges (
bindingType: BindingType.Class,
name: "MyClass",
@namespace: ["NS"],
fullyQualifiedSymbol: "NS.MyClass"
) {
Attributes = [
Expand Down Expand Up @@ -442,6 +460,8 @@ public partial class MyClass {
singleEventClass,
new CodeChanges (
bindingType: BindingType.Class,
name: "MyClass",
@namespace: ["NS"],
fullyQualifiedSymbol: "NS.MyClass"
) {
Attributes = [
Expand Down Expand Up @@ -483,6 +503,8 @@ public partial class MyClass {
multiEventClass,
new CodeChanges (
bindingType: BindingType.Class,
name: "MyClass",
@namespace: ["NS"],
fullyQualifiedSymbol: "NS.MyClass"
) {
Attributes = [
Expand Down
Loading

9 comments on commit 0bedb2c

@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.