Skip to content

Commit

Permalink
[Rgen] Add support to parse StrongDictionary in the transformer. (#22204
Browse files Browse the repository at this point in the history
)

Allow to parse StrongDictionaries in the transformer. These bindings are
special because we do not filter out properties that are missing the
Export/Field attributes.

---------

Co-authored-by: GitHub Actions Autoformatter <[email protected]>
  • Loading branch information
mandel-macaque and GitHub Actions Autoformatter authored Feb 18, 2025
1 parent 1cfb15b commit c09216f
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/rgen/Microsoft.Macios.Generator/DataModel/BindingType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ enum BindingType : ulong {
/// </summary>
SmartEnum,
/// <summary>
/// Binding type for a dictionary with strong value.
/// </summary>
StrongDictionary,
/// <summary>
/// Binding type for a core image filter.
/// </summary>
CoreImageFilter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ static BindingType GetBindingType (Dictionary<string, List<AttributeData>> attri
bindingType = BindingType.Category;
} else if (attributes.HasCoreImageFilterAttribute ()) {
bindingType = BindingType.CoreImageFilter;
} else if (attributes.HasStrongDictionaryAttribute ()) {
bindingType = BindingType.StrongDictionary;
} else if (baseTypeAttribute is not null) {
bindingType = BindingType.Class;
} else {
Expand Down Expand Up @@ -146,6 +148,8 @@ static string GetBaseClass (BindingInfo bindingInfo)
BindingType.Category => "object",
// protocols do not have a base class, if anything, they implement other protocols
BindingType.Protocol => string.Empty,
// strong dictionary inherit from a dictionary container, we do not support inheritance in the old SDK
BindingType.StrongDictionary => "Foundation.DictionaryContainer",
// for unknown types, use the default
_ => "object"
};
Expand Down Expand Up @@ -248,8 +252,15 @@ internal Binding (InterfaceDeclarationSyntax interfaceDeclarationSyntax, INamedT
Modifiers = flags.ToClassModifiersArray ();

// loop over the different members and add them to the model
GetMembers<PropertyDeclarationSyntax, Property> (interfaceDeclarationSyntax, context, Skip, Property.TryCreate,
out properties);
if (BindingInfo.BindingType == BindingType.StrongDictionary) {
// strong dictionaries are a little different, we will get all the properties with no filter since the
// properties from a strong dictionary do not have any attribute
GetMembers<PropertyDeclarationSyntax, Property> (interfaceDeclarationSyntax, context, static (_, _) => false, Property.TryCreate,
out properties);
} else {
GetMembers<PropertyDeclarationSyntax, Property> (interfaceDeclarationSyntax, context, Skip, Property.TryCreate,
out properties);
}
// methods are a little diff, in the old SDK style, both methods and constructors are methods, we will get
// all exported methods and then filter accordingly
GetMembers<MethodDeclarationSyntax, Method> (interfaceDeclarationSyntax, context, Skip, Method.TryCreate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.Macios.Transformer.DataModel;
using Xamarin.Tests;
using Xamarin.Utils;
using static Microsoft.Macios.Generator.Tests.TestDataFactory;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

namespace Microsoft.Macios.Transformer.Tests.DataModel;
Expand Down Expand Up @@ -383,6 +384,72 @@ interface MyCIAccordionFoldTransition : CIAccordionFoldTransitionProtocol {
Token (SyntaxKind.PartialKeyword)]
}
];

const string strongDictionary = @"
using System;
using Foundation;
using CoreImage;
using ObjCRuntime;
namespace Test;
[StrongDictionary (""CMHevcTemporalLevelInfoKeys"")]
interface MyCMHevcTemporalLevelInfoSettings {
int TemporalLevel { get; set; }
}
";

yield return [
(Source: strongDictionary, Path: path),
new Binding (
symbolName: "MyCMHevcTemporalLevelInfoSettings",
@namespace: ["Test"],
fullyQualifiedSymbol: "Test.MyCMHevcTemporalLevelInfoSettings",
info: new BindingInfo (null, BindingType.StrongDictionary),
symbolAvailability: availabilityBuilder.ToImmutable (),
attributes: new ()
) {
Base = "Foundation.DictionaryContainer",
UsingDirectives = new HashSet<string> {
"System",
"Foundation",
"CoreImage",
"ObjCRuntime"
},
Interfaces = [],
Protocols = [],
Modifiers = [
Token (SyntaxKind.PublicKeyword),
Token (SyntaxKind.PartialKeyword)
],
Properties = [
new (
name: "TemporalLevel",
returnType: ReturnTypeForInt (),
symbolAvailability: availabilityBuilder.ToImmutable (),
attributes: new (),
accessors: [
new Accessor (
accessorKind: AccessorKind.Getter,
symbolAvailability: availabilityBuilder.ToImmutable (),
attributes: new ()),
new Accessor (
accessorKind: AccessorKind.Setter,
symbolAvailability: availabilityBuilder.ToImmutable (),
attributes: new ())
]
) {
Modifiers = [
Token (SyntaxKind.PublicKeyword),
Token (SyntaxKind.VirtualKeyword),
Token (SyntaxKind.PartialKeyword)
],
ExportPropertyData = null, // we want to explicitly set this to null
}
]
}
];
}

IEnumerator IEnumerable.GetEnumerator () => GetEnumerator ();
Expand Down

0 comments on commit c09216f

Please sign in to comment.