Skip to content

Commit

Permalink
[Rgen] Add properties to the data model in the transformer.
Browse files Browse the repository at this point in the history
Update the transformer code to parse the properties from a binding. This
adds a all properties that the binding has that are either a property or
a field.
  • Loading branch information
mandel-macaque committed Feb 12, 2025
1 parent af7adf4 commit 0583b1e
Show file tree
Hide file tree
Showing 4 changed files with 386 additions and 23 deletions.
23 changes: 0 additions & 23 deletions src/rgen/Microsoft.Macios.Generator/DataModel/Binding.Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,29 +120,6 @@ internal static bool Skip (MethodDeclarationSyntax methodDeclarationSyntax, Sema
return true;
}

delegate bool SkipDelegate<in T> (T declarationSyntax, SemanticModel semanticModel);

delegate bool TryCreateDelegate<in T, TR> (T declaration, RootContext context,
[NotNullWhen (true)] out TR? change)
where T : MemberDeclarationSyntax
where TR : struct;

static void GetMembers<T, TR> (TypeDeclarationSyntax baseDeclarationSyntax, RootContext context,
SkipDelegate<T> skip, TryCreateDelegate<T, TR> tryCreate, out ImmutableArray<TR> members)
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, context.SemanticModel))
continue;
if (tryCreate (declaration, context, out var change))
bucket.Add (change.Value);
}

members = bucket.ToImmutable ();
}

/// <summary>
/// Internal constructor added for testing purposes.
Expand Down
26 changes: 26 additions & 0 deletions src/rgen/Microsoft.Macios.Generator/DataModel/Binding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
// Licensed under the MIT License.
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Macios.Generator.Availability;
using Microsoft.Macios.Generator.Context;

namespace Microsoft.Macios.Generator.DataModel;

Expand Down Expand Up @@ -155,4 +158,27 @@ public ImmutableArray<Method> Methods {
init => methods = value;
}

delegate bool SkipDelegate<in T> (T declarationSyntax, SemanticModel semanticModel);

delegate bool TryCreateDelegate<in T, TR> (T declaration, RootContext context,
[NotNullWhen (true)] out TR? change)
where T : MemberDeclarationSyntax
where TR : struct;

static void GetMembers<T, TR> (TypeDeclarationSyntax baseDeclarationSyntax, RootContext context,
SkipDelegate<T> skip, TryCreateDelegate<T, TR> tryCreate, out ImmutableArray<TR> members)
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, context.SemanticModel))
continue;
if (tryCreate (declaration, context, out var change))
bucket.Add (change.Value);
}

members = bucket.ToImmutable ();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,23 @@ static void GetInterfaceAndProtocols (INamedTypeSymbol symbol, out ImmutableArra
protocols = protocolsBucket.ToImmutable ();
}

/// <summary>
/// Decide if a property should be ignored as a change.
/// </summary>
/// <param name="propertyDeclarationSyntax">The property declaration under test.</param>
/// <param name="semanticModel">The semantic model of the compilation.</param>
/// <returns>True if the property should be ignored. False otherwise.</returns>
internal static bool Skip (PropertyDeclarationSyntax propertyDeclarationSyntax, SemanticModel semanticModel)
{
var propertySymbol = semanticModel.GetDeclaredSymbol (propertyDeclarationSyntax);
if (propertySymbol is null)
// skip if we cannot retrieve the symbol
return true;
var attributes = propertySymbol.GetAttributeData ();
// we will skip properties if they do not have the [Export] attribute or the [Field] attribute
return !attributes.HasExportAttribute () && !attributes.HasFieldAttribute ();
}

/// <summary>
/// Create a new binding based on the interface declaration. Because in the old SDK old the bindings
/// are represented by an interface, this constructor will ensure that the correct binding type is set.
Expand Down Expand Up @@ -213,6 +230,10 @@ internal Binding (InterfaceDeclarationSyntax interfaceDeclarationSyntax, INamedT
hasStaticFlag: HasStaticFlag || BindingInfo.BindingType == BindingType.Category // add static for categories
);
Modifiers = flags.ToClassModifiersArray ();

// loop over the different members and add them to the model
GetMembers<PropertyDeclarationSyntax, Property> (interfaceDeclarationSyntax, context, Skip, Property.TryCreate,
out properties);
}

/// <inheritdoc/>
Expand Down
Loading

0 comments on commit 0583b1e

Please sign in to comment.