diff --git a/src/rgen/Microsoft.Macios.Generator/AttributesNames.cs b/src/rgen/Microsoft.Macios.Generator/AttributesNames.cs index f7c9f4bc3dc..a13166cd7ff 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 09f35d640f7..ae4d1a23d05 100644 --- a/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs +++ b/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs @@ -71,6 +71,23 @@ namespace Microsoft.Macios.Generator.DataModel; /// public bool IsVoid => SpecialType == SpecialType.System_Void; + /// + /// True if the type is for an interface. + /// + public bool IsInterface { get; init; } + + /// + /// 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 metadata 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; public bool IsNSObject { @@ -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 cf7d16b940b..05e9ff31ede 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoTests.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoTests.cs @@ -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 de056d3af04..275b5448b5b 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 () @@ -162,12 +163,21 @@ public static TypeInfo ReturnTypeForGeneric (string genericName, bool isNullable isNullable: isNullable ); + public static TypeInfo ReturnTypeForInterface (string interfaceName) + => new ( + name: interfaceName, + isReferenceType: true + ) { + Parents = [], + IsInterface = true, + }; + public static TypeInfo ReturnTypeForStruct (string structName) => new ( name: 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, @@ -184,6 +194,7 @@ public static TypeInfo ReturnTypeForEnum (string enumName, bool isSmartEnum = fa "System.IFormattable", "System.ISpanFormattable" ], + IsNativeEnum = isNativeEnum, EnumUnderlyingType = SpecialType.System_Int32, };