From 47d119cd8c6fd9f8696f5db4463a873de9deed3a Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Saenz Date: Fri, 17 Jan 2025 11:07:34 -0500 Subject: [PATCH 1/3] [Rgen] Add more information about the type in the TypeInfo struct. We want to be able to know if a symbol is: * An Interface * An enumerator with a native attribute. * If the interger used a C# keyword to be created. --- .../AttributesNames.cs | 1 + .../DataModel/TypeInfo.cs | 29 +++++++++ .../DataModel/TypeInfoTests.cs | 65 ++++++++++++++++++- .../TestDataFactory.cs | 13 +++- 4 files changed, 105 insertions(+), 3 deletions(-) diff --git a/src/rgen/Microsoft.Macios.Generator/AttributesNames.cs b/src/rgen/Microsoft.Macios.Generator/AttributesNames.cs index f7c9f4bc3dc2..a13166cd7ff8 100644 --- a/src/rgen/Microsoft.Macios.Generator/AttributesNames.cs +++ b/src/rgen/Microsoft.Macios.Generator/AttributesNames.cs @@ -22,6 +22,7 @@ static class AttributesNames { public const string SupportedOSPlatformAttribute = "System.Runtime.Versioning.SupportedOSPlatformAttribute"; public const string UnsupportedOSPlatformAttribute = "System.Runtime.Versioning.UnsupportedOSPlatformAttribute"; public const string ObsoletedOSPlatformAttribute = "System.Runtime.Versioning.ObsoletedOSPlatformAttribute"; + public const string NativeEnumAttribute = "ObjCRuntime.NativeAttribute"; public static readonly string [] BindingTypes = [ BindingAttribute, diff --git a/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs b/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs index 09f35d640f79..9c66556f36da 100644 --- a/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs +++ b/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs @@ -70,6 +70,23 @@ namespace Microsoft.Macios.Generator.DataModel; /// Returns if the return type is void. /// public bool IsVoid => SpecialType == SpecialType.System_Void; + + /// + /// True if the type is for an iterface. + /// + public bool IsInterface { get; init; } + + /// + /// True if the type represents an interger that was built using one of the keywords, like byte, int, nint etc. + /// + /// This can be used to decide if we should use the name of the matadata name to cast the value. + /// + public bool IsNativeIntegerType { get; init; } + + /// + /// True if an enumerator was marked with the NativeAttribute. + /// + public bool IsNativeEnum { get; init; } readonly bool isNSObject = false; @@ -131,6 +148,9 @@ symbol is IArrayTypeSymbol arrayTypeSymbol IsSmartEnum = symbol.IsSmartEnum (); IsArray = symbol is IArrayTypeSymbol; IsReferenceType = symbol.IsReferenceType; + IsInterface = symbol.TypeKind == TypeKind.Interface; + IsNativeIntegerType = symbol.IsNativeIntegerType; + IsNativeEnum = symbol.HasAttribute (AttributesNames.NativeEnumAttribute); // data that we can get from the symbol without being INamedType symbol.GetInheritance ( @@ -182,6 +202,12 @@ public bool Equals (TypeInfo other) return false; if (EnumUnderlyingType != other.EnumUnderlyingType) return false; + if (IsInterface != other.IsInterface) + return false; + if (IsNativeIntegerType != other.IsNativeIntegerType) + return false; + if (IsNativeEnum != other.IsNativeEnum) + return false; // compare base classes and interfaces, order does not matter at all var listComparer = new CollectionComparer (); @@ -230,6 +256,9 @@ public override string ToString () sb.Append ($"IsVoid : {IsVoid}, "); sb.Append ($"IsNSObject : {IsNSObject}, "); sb.Append ($"IsNativeObject: {IsINativeObject}, "); + sb.Append ($"IsInterface: {IsInterface}, "); + sb.Append ($"IsNativeIntegerType: {IsNativeIntegerType}, "); + sb.Append ($"IsNativeEnum: {IsNativeEnum}, "); sb.Append ($"EnumUnderlyingType: '{EnumUnderlyingType?.ToString () ?? "null"}', "); sb.Append ("Parents: ["); sb.AppendJoin (", ", parents); diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoTests.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoTests.cs index cf7d16b940b0..c7cdc69e8a79 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoTests.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoTests.cs @@ -68,7 +68,7 @@ public int MyMethod () {} parameters: [] ) ]; - + const string nullableIntMethodNoParams = @" using System; @@ -93,7 +93,7 @@ public class MyClass { parameters: [] ) ]; - + const string intArrayMethodNoParams = @" using System; @@ -322,6 +322,67 @@ public class MyClass { parameters: [] ) ]; + + const string interfaceMethod = @" +using System; +using System.Collections.Generic; + +namespace NS { + public interface IInterface {} + + public class MyClass { + public IInterface MyMethod () {} + } +} +"; + yield return [ + interfaceMethod, + new Method ( + type: "NS.MyClass", + name: "MyMethod", + returnType: ReturnTypeForInterface ("NS.IInterface"), + symbolAvailability: new (), + exportMethodData: new (), + attributes: [], + modifiers: [ + SyntaxFactory.Token (SyntaxKind.PublicKeyword), + ], + parameters: [] + ) + ]; + + const string nativeEnumMethod = @" +using System; +using ObjCRuntime; +using System.Collections.Generic; + +namespace NS { + [Native] + public enum MyEnum : int { + One, + Two + } + + public class MyClass { + public MyEnum MyMethod () {} + } +} +"; + yield return [ + nativeEnumMethod, + new Method ( + type: "NS.MyClass", + name: "MyMethod", + returnType: ReturnTypeForEnum("NS.MyEnum", isNativeEnum: true), + symbolAvailability: new (), + exportMethodData: new (), + attributes: [], + modifiers: [ + SyntaxFactory.Token (SyntaxKind.PublicKeyword), + ], + parameters: [] + ) + ]; } IEnumerator IEnumerable.GetEnumerator () => GetEnumerator (); diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs index f64d79ad80e8..4b10d914b020 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs @@ -125,6 +125,7 @@ public static TypeInfo ReturnTypeForIntPtr (bool isNullable = false) "System.Runtime.Serialization.ISerializable" ], MetadataName = "IntPtr", + IsNativeIntegerType = !isNullable, }; public static TypeInfo ReturnTypeForBool () @@ -157,6 +158,15 @@ public static TypeInfo ReturnTypeForClass (string className) ) { Parents = ["object"] }; + + public static TypeInfo ReturnTypeForInterface (string interfaceName) + => new ( + name: interfaceName, + isReferenceType: true + ) { + Parents = [], + IsInterface = true, + }; public static TypeInfo ReturnTypeForStruct (string structName) => new ( @@ -165,7 +175,7 @@ public static TypeInfo ReturnTypeForStruct (string structName) Parents = ["System.ValueType", "object"] }; - public static TypeInfo ReturnTypeForEnum (string enumName, bool isSmartEnum = false) + public static TypeInfo ReturnTypeForEnum (string enumName, bool isSmartEnum = false, bool isNativeEnum = false) => new ( name: enumName, isBlittable: true, @@ -182,6 +192,7 @@ public static TypeInfo ReturnTypeForEnum (string enumName, bool isSmartEnum = fa "System.IFormattable", "System.ISpanFormattable" ], + IsNativeEnum = isNativeEnum, EnumUnderlyingType = SpecialType.System_Int32, }; From 6b11e005a9b2edf955574e8759dbc24283c9a753 Mon Sep 17 00:00:00 2001 From: GitHub Actions Autoformatter Date: Fri, 17 Jan 2025 16:13:17 +0000 Subject: [PATCH 2/3] Auto-format source code --- src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs | 6 +++--- .../DataModel/TypeInfoTests.cs | 8 ++++---- .../Microsoft.Macios.Generator.Tests/TestDataFactory.cs | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs b/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs index 9c66556f36da..3ae8aa7dda7f 100644 --- a/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs +++ b/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs @@ -70,19 +70,19 @@ namespace Microsoft.Macios.Generator.DataModel; /// Returns if the return type is void. /// public bool IsVoid => SpecialType == SpecialType.System_Void; - + /// /// True if the type is for an iterface. /// public bool IsInterface { get; init; } - + /// /// True if the type represents an interger that was built using one of the keywords, like byte, int, nint etc. /// /// This can be used to decide if we should use the name of the matadata name to cast the value. /// public bool IsNativeIntegerType { get; init; } - + /// /// True if an enumerator was marked with the NativeAttribute. /// diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoTests.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoTests.cs index c7cdc69e8a79..05e9ff31edec 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoTests.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoTests.cs @@ -68,7 +68,7 @@ public int MyMethod () {} parameters: [] ) ]; - + const string nullableIntMethodNoParams = @" using System; @@ -93,7 +93,7 @@ public class MyClass { parameters: [] ) ]; - + const string intArrayMethodNoParams = @" using System; @@ -350,7 +350,7 @@ public IInterface MyMethod () {} parameters: [] ) ]; - + const string nativeEnumMethod = @" using System; using ObjCRuntime; @@ -373,7 +373,7 @@ public MyEnum MyMethod () {} new Method ( type: "NS.MyClass", name: "MyMethod", - returnType: ReturnTypeForEnum("NS.MyEnum", isNativeEnum: true), + returnType: ReturnTypeForEnum ("NS.MyEnum", isNativeEnum: true), symbolAvailability: new (), exportMethodData: new (), attributes: [], diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs index 4b10d914b020..32a897f16582 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs @@ -158,7 +158,7 @@ public static TypeInfo ReturnTypeForClass (string className) ) { Parents = ["object"] }; - + public static TypeInfo ReturnTypeForInterface (string interfaceName) => new ( name: interfaceName, From c6fe088ac1bb086c36cc256c6354a82bbbf506d5 Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Fri, 17 Jan 2025 11:14:50 -0500 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs b/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs index 3ae8aa7dda7f..ae4d1a23d05e 100644 --- a/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs +++ b/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs @@ -72,14 +72,14 @@ namespace Microsoft.Macios.Generator.DataModel; public bool IsVoid => SpecialType == SpecialType.System_Void; /// - /// True if the type is for an iterface. + /// True if the type is for an interface. /// public bool IsInterface { get; init; } /// - /// True if the type represents an interger that was built using one of the keywords, like byte, int, nint etc. + /// True if the type represents an integer that was built using one of the keywords, like byte, int, nint etc. /// - /// This can be used to decide if we should use the name of the matadata name to cast the value. + /// This can be used to decide if we should use the name of the metadata name to cast the value. /// public bool IsNativeIntegerType { get; init; }