Skip to content

Instantly share code, notes, and snippets.

@mandel-macaque
Created November 27, 2024 17:26
Show Gist options
  • Save mandel-macaque/d15c894397d0e0a9ff4caf8f27153140 to your computer and use it in GitHub Desktop.
Save mandel-macaque/d15c894397d0e0a9ff4caf8f27153140 to your computer and use it in GitHub Desktop.
diff --git a/src/rgen/Microsoft.Macios.Generator/DataModel/CodeChanges.cs b/src/rgen/Microsoft.Macios.Generator/DataModel/CodeChanges.cs
index dc16fb990..1f0a40a96 100644
--- a/src/rgen/Microsoft.Macios.Generator/DataModel/CodeChanges.cs
+++ b/src/rgen/Microsoft.Macios.Generator/DataModel/CodeChanges.cs
@@ -1,4 +1,6 @@
+using System;
using System.Collections.Immutable;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
@@ -110,6 +112,7 @@ readonly struct CodeChanges {
if (methodDeclarationSyntax.Modifiers.Any (SyntaxKind.PartialKeyword)) {
return !methodDeclarationSyntax.HasAttribute (semanticModel, AttributesNames.ExportMethodAttribute);
}
+
return true;
}
@@ -145,12 +148,34 @@ readonly struct CodeChanges {
continue;
var memberName = val.Identifier.ToFullString ().Trim ();
var attributes = val.GetAttributeCodeChanges (semanticModel);
- bucket.Add (new (memberName, attributes));
+ bucket.Add (new(memberName, attributes));
}
EnumMembers = bucket.ToImmutable ();
}
+ delegate bool SkipDelegate<T> (T declarationSyntax, SemanticModel semanticModel);
+
+ delegate bool TryCreateDelegate<in T, TR> (T declaration, SemanticModel semanticModel,
+ [NotNullWhen (true)] out TR? change)
+ where T : MemberDeclarationSyntax
+ where TR : struct;
+
+ ImmutableArray<TR> GetMembers<T, TR> (TypeDeclarationSyntax baseDeclarationSyntax, SemanticModel semanticModel,
+ SkipDelegate<T> skip, TryCreateDelegate<T, TR> tryCreate) where T : MemberDeclarationSyntax where TR : struct
+ {
+ var bucket = ImmutableArray.CreateBuilder<TR> ();
+ var declarations = baseDeclarationSyntax.Members.OfType<T> ();
+ foreach (var declaration in declarations) {
+ if (skip (declaration, semanticModel))
+ continue;
+ if (tryCreate (declaration, semanticModel, out var change))
+ bucket.Add (change.Value);
+ }
+
+ return bucket.ToImmutable ();
+ }
+
/// <summary>
/// Creates a new instance of the <see cref="CodeChanges"/> struct for a given class declaration.
/// </summary>
@@ -161,50 +186,11 @@ readonly struct CodeChanges {
FullyQualifiedSymbol = classDeclaration.GetFullyQualifiedIdentifier ();
SymbolDeclaration = classDeclaration;
EnumMembers = []; // always empty since classes dot not have enum values
- Attributes = [];
-
- var properties = ImmutableArray.CreateBuilder<Property> ();
- var propertyDeclarations = classDeclaration.Members.OfType<PropertyDeclarationSyntax> ();
- foreach (var declaration in propertyDeclarations) {
- if (Skip (declaration, semanticModel))
- continue;
- if (Property.TryCreate (declaration, semanticModel, out var change))
- properties.Add (change.Value);
- }
-
- Properties = properties.ToImmutable ();
-
- var constructors = ImmutableArray.CreateBuilder<Constructor> ();
- var constructorDeclarations = classDeclaration.Members.OfType<ConstructorDeclarationSyntax> ();
- foreach (var declaration in constructorDeclarations) {
- if (Skip (declaration, semanticModel))
- continue;
- if (Constructor.TryCreate (declaration, semanticModel, out var change))
- constructors.Add (change.Value);
- }
-
- Constructors = constructors.ToImmutable ();
-
- var events = ImmutableArray.CreateBuilder<Event> ();
- var eventDeclarations = classDeclaration.Members.OfType<EventDeclarationSyntax> ();
- foreach (var declaration in eventDeclarations) {
- if (Skip (declaration, semanticModel))
- continue;
- if (Event.TryCreate (declaration, semanticModel, out var change))
- events.Add (change.Value);
- }
-
- Events = events.ToImmutable ();
-
- var methods = ImmutableArray.CreateBuilder<Method> ();
- var methodDeclarations = classDeclaration.Members.OfType<MethodDeclarationSyntax> ();
- foreach (MethodDeclarationSyntax declaration in methodDeclarations) {
- if (Skip (declaration, semanticModel))
- continue;
- if (Method.TryCreate (declaration, semanticModel, out var change))
- methods.Add (change.Value);
- }
- Methods = methods.ToImmutable ();
+ Attributes = classDeclaration.GetAttributeCodeChanges (semanticModel);
+ Constructors = GetMembers<ConstructorDeclarationSyntax, Constructor> (classDeclaration, semanticModel, Skip, Constructor.TryCreate);
+ Properties = GetMembers<PropertyDeclarationSyntax, Property> (classDeclaration, semanticModel, Skip, Property.TryCreate);
+ Events = GetMembers<EventDeclarationSyntax, Event> (classDeclaration, semanticModel, Skip, Event.TryCreate);
+ Methods = GetMembers<MethodDeclarationSyntax, Method> (classDeclaration, semanticModel, Skip, Method.TryCreate);
}
/// <summary>
@@ -216,9 +202,11 @@ readonly struct CodeChanges {
{
FullyQualifiedSymbol = interfaceDeclaration.GetFullyQualifiedIdentifier ();
SymbolDeclaration = interfaceDeclaration;
- // TODO: to be implemented once we add protocol support
- EnumMembers = [];
- Attributes = [];
+ Attributes = interfaceDeclaration.GetAttributeCodeChanges (semanticModel);
+ Constructors = []; // interfaces do not list constructors
+ Properties = GetMembers<PropertyDeclarationSyntax, Property> (interfaceDeclaration, semanticModel, Skip, Property.TryCreate);
+ Events = GetMembers<EventDeclarationSyntax, Event> (interfaceDeclaration, semanticModel, Skip, Event.TryCreate);
+ Methods = GetMembers<MethodDeclarationSyntax, Method> (interfaceDeclaration, semanticModel, Skip, Method.TryCreate);
}
/// <summary>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment