Skip to content

Commit f31acf6

Browse files
mandel-macaqueCopilotGitHub Actions Autoformatter
authored
[RGen] Add the emitter code that generates the get/set invocations for a strong dict. (#23395)
Add the code generation for the getter and setter for all the supported types by the strong dictionary. Added tests to ensure that all code is correctly generated. --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: GitHub Actions Autoformatter <[email protected]>
1 parent 4b05778 commit f31acf6

File tree

12 files changed

+1225
-33
lines changed

12 files changed

+1225
-33
lines changed

src/rgen/Microsoft.Macios.Generator/AttributesNames.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ static class AttributesNames {
8989
if (type == typeof (ObjCBindings.Constructor)) {
9090
return ExportConstructorAttribute;
9191
}
92+
if (type == typeof (ObjCBindings.StrongDictionaryProperty)) {
93+
return ExportStrongDictionaryPropertyAttribute;
94+
}
9295
return null;
9396
}
9497

src/rgen/Microsoft.Macios.Generator/DataModel/Property.Generator.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,31 @@ public bool IsNotification
4545
[MemberNotNullWhen (true, nameof (ExportPropertyData))]
4646
public bool IsProperty => ExportPropertyData is not null;
4747

48+
/// <summary>
49+
/// The data of the export attribute used to mark the value as a strong dictionary property binding.
50+
/// </summary>
51+
public ExportData<ObjCBindings.StrongDictionaryProperty>? ExportStrongPropertyData { get; init; }
52+
53+
/// <summary>
54+
/// True if the property represents a strong dictionary property.
55+
/// </summary>
56+
[MemberNotNullWhen (true, nameof (ExportStrongPropertyData))]
57+
public bool IsStrongDictionaryProperty => ExportStrongPropertyData is not null;
58+
59+
/// <summary>
60+
/// Gets the strong dictionary key for the property, combining the class key and field name when applicable.
61+
/// </summary>
62+
public string? StrongDictionaryKey {
63+
get {
64+
if (!IsStrongDictionaryProperty)
65+
return null;
66+
// return the combination of the class key and the field name
67+
return ExportStrongPropertyData.Value.StrongDictionaryKeyClass is null
68+
? ExportStrongPropertyData.Value.Selector
69+
: $"{ExportStrongPropertyData.Value.StrongDictionaryKeyClass.Value.FullyQualifiedName}.{ExportStrongPropertyData.Value.Selector}";
70+
}
71+
}
72+
4873
/// <summary>
4974
/// Returns if the property was marked as thread safe.
5075
/// </summary>
@@ -238,7 +263,6 @@ public static bool TryCreate (PropertyDeclarationSyntax declaration, RootContext
238263
modifiers: [])
239264
];
240265
}
241-
242266
change = new (
243267
name: memberName,
244268
returnType: new (propertySymbol.Type, context.Compilation),
@@ -250,6 +274,7 @@ public static bool TryCreate (PropertyDeclarationSyntax declaration, RootContext
250274
ForcedType = propertySymbol.GetForceTypeData (),
251275
ExportFieldData = GetFieldInfo (context, propertySymbol),
252276
ExportPropertyData = propertySymbol.GetExportData<ObjCBindings.Property> (),
277+
ExportStrongPropertyData = propertySymbol.GetExportData<ObjCBindings.StrongDictionaryProperty> (),
253278
};
254279
return true;
255280
}

src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ namespace Microsoft.Macios.Generator.DataModel;
134134
/// </summary>
135135
public bool IsTask { get; init; }
136136

137+
/// <summary>
138+
/// True if the type represents a strong dictionary.
139+
/// </summary>
140+
public bool IsStrongDictionary { get; init; }
141+
137142
/// <summary>
138143
/// Returns, if the type is an array, if its elements are a wrapped object from the objc world.
139144
/// </summary>
@@ -144,6 +149,16 @@ namespace Microsoft.Macios.Generator.DataModel;
144149
/// </summary>
145150
public bool ArrayElementIsINativeObject { get; init; }
146151

152+
/// <summary>
153+
/// If the type is an array of enums, it returns the special type of the underlying enum type.
154+
/// </summary>
155+
public SpecialType? ArrayElementEnumUnderlyingType { get; init; }
156+
157+
/// <summary>
158+
/// Returns true if the type is an array of enums.
159+
/// </summary>
160+
public bool ArrayElementTypeIsEnum => ArrayElementEnumUnderlyingType is not null;
161+
147162
readonly bool isNSObject = false;
148163

149164
/// <summary>
@@ -345,6 +360,7 @@ internal TypeInfo (ITypeSymbol symbol)
345360
IsNativeIntegerType = symbol.IsNativeIntegerType;
346361
IsNativeEnum = symbol.HasAttribute (AttributesNames.NativeAttribute);
347362
IsProtocol = symbol.HasAttribute (AttributesNames.ProtocolAttribute);
363+
IsStrongDictionary = symbol.HasAttribute (AttributesNames.StrongDictionaryAttribute);
348364

349365
// data that we can get from the symbol without being INamedType
350366
symbol.GetInheritance (
@@ -361,6 +377,7 @@ internal TypeInfo (ITypeSymbol symbol)
361377
FullyQualifiedName = arraySymbol.ElementType.ToDisplayString ();
362378
IsArray = true;
363379
ArrayElementType = arraySymbol.ElementType.SpecialType;
380+
ArrayElementEnumUnderlyingType = arraySymbol.ElementType is INamedTypeSymbol enumType ? enumType.EnumUnderlyingType?.SpecialType : null;
364381
ArrayElementTypeIsWrapped = arraySymbol.ElementType.IsWrapped ();
365382
ArrayElementIsINativeObject = arraySymbol.ElementType.IsINativeObject ();
366383
}
@@ -459,6 +476,8 @@ public bool Equals (TypeInfo other)
459476
return false;
460477
if (IsProtocol != other.IsProtocol)
461478
return false;
479+
if (IsStrongDictionary != other.IsStrongDictionary)
480+
return false;
462481

463482
// compare base classes and interfaces, order does not matter at all
464483
var listComparer = new CollectionComparer<string> ();
@@ -496,6 +515,7 @@ public override int GetHashCode ()
496515
hashCode.Add (IsNativeEnum);
497516
hashCode.Add (Delegate);
498517
hashCode.Add (IsProtocol);
518+
hashCode.Add (IsStrongDictionary);
499519
foreach (var parent in parents) {
500520
hashCode.Add (parent);
501521
}
@@ -764,6 +784,7 @@ public override string ToString ()
764784
sb.Append ($"IsNativeIntegerType: {IsNativeIntegerType}, ");
765785
sb.Append ($"IsNativeEnum: {IsNativeEnum}, ");
766786
sb.Append ($"IsProtocol: {IsProtocol}, ");
787+
sb.Append ($"IsStrongDictionary: {IsStrongDictionary}, ");
767788
sb.Append ($"Delegate: {Delegate?.ToString () ?? "null"}, ");
768789
sb.Append ($"EnumUnderlyingType: '{EnumUnderlyingType?.ToString () ?? "null"}', ");
769790
sb.Append ("Parents: [");

src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.KnownTypes.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,15 @@ static partial class BindingSyntaxFactory {
197197
@namespace: ["CoreMedia"],
198198
@class: "CMSampleBuffer");
199199

200+
// CoreText types
201+
202+
/// <summary>
203+
/// TypeSyntax for CoreText.CTFontDescriptor.
204+
/// </summary>
205+
public static readonly TypeSyntax CTFontDescriptor = StringExtensions.GetIdentifierName (
206+
@namespace: ["CoreText"],
207+
@class: "CTFontDescriptor");
208+
200209
// System types
201210

202211
/// <summary>
@@ -234,5 +243,4 @@ static partial class BindingSyntaxFactory {
234243
@namespace: ["System", "Runtime", "CompilerServices"],
235244
@class: "Unsafe");
236245

237-
238246
}

src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.ObjCRuntime.cs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,24 +1016,29 @@ internal static string GetNSNumberValue (in TypeInfo type)
10161016
{ Name: "nint" } => "NIntValue",
10171017
{ Name: "nuint" } => "NUIntValue",
10181018
{ Name: "nfloat" or "NFloat" } => "NFloatValue",
1019-
{ SpecialType: SpecialType.System_Boolean } => "BooleanValue",
1020-
{ SpecialType: SpecialType.System_Byte } => "ByteValue",
1021-
{ SpecialType: SpecialType.System_Double } => "DoubleValue",
1022-
{ SpecialType: SpecialType.System_Single } => "FloatValue",
1023-
{ SpecialType: SpecialType.System_Int16 } => "Int16Value",
1024-
{ SpecialType: SpecialType.System_Int32 } => "Int32Value",
1025-
{ SpecialType: SpecialType.System_Int64 } => "Int64Value",
1026-
{ SpecialType: SpecialType.System_SByte } => "SByteValue",
1027-
{ SpecialType: SpecialType.System_UInt16 } => "UInt16Value",
1028-
{ SpecialType: SpecialType.System_UInt32 } => "UInt32Value",
1029-
{ SpecialType: SpecialType.System_UInt64 } => "UInt64Value",
1030-
{ SpecialType: SpecialType.System_IntPtr } => "NIntValue",
1031-
{ SpecialType: SpecialType.System_UIntPtr } => "NUIntValue",
1032-
_ => string.Empty,
1019+
_ => GetNSNumberValue (type.SpecialType),
10331020
};
10341021
#pragma warning restore format
10351022
}
10361023

1024+
internal static string GetNSNumberValue (SpecialType type)
1025+
=> type switch {
1026+
SpecialType.System_Boolean => "BooleanValue",
1027+
SpecialType.System_Byte => "ByteValue",
1028+
SpecialType.System_Double => "DoubleValue",
1029+
SpecialType.System_Single => "FloatValue",
1030+
SpecialType.System_Int16 => "Int16Value",
1031+
SpecialType.System_Int32 => "Int32Value",
1032+
SpecialType.System_Int64 => "Int64Value",
1033+
SpecialType.System_SByte => "SByteValue",
1034+
SpecialType.System_UInt16 => "UInt16Value",
1035+
SpecialType.System_UInt32 => "UInt32Value",
1036+
SpecialType.System_UInt64 => "UInt64Value",
1037+
SpecialType.System_IntPtr => "NIntValue",
1038+
SpecialType.System_UIntPtr => "NUIntValue",
1039+
_ => string.Empty,
1040+
};
1041+
10371042
/// <summary>
10381043
/// Generates an if-statement that throws an <see cref="ArgumentNullException"/> if the specified variable is null.
10391044
/// </summary>

0 commit comments

Comments
 (0)