diff --git a/src/bgen/Enums.cs b/src/bgen/Enums.cs index 5c1624b1d01..fc5de2230bb 100644 --- a/src/bgen/Enums.cs +++ b/src/bgen/Enums.cs @@ -321,6 +321,23 @@ void GenerateEnum (Type type) print ("return GetValue (str);"); indent--; print ("}"); + + if (BindingTouch.SupportsXmlDocumentation) { + print ($"/// Retrieves the value represented by the backing field value in ."); + print ($"/// The native handle with the name of the constant to retrieve."); + } + + print ("public static {0}? GetNullableValue ({1} handle)", type.Name, NativeHandleType); + print ("{"); + indent++; + print ("using var str = Runtime.GetNSObject<{0}> (handle);", backingFieldTypeName); + print ("if (str is null)"); + indent++; + print ("return null;"); + indent--; + print ("return GetValue (str);"); + indent--; + print ("}"); } if (BindingTouch.SupportsXmlDocumentation) { diff --git a/src/bgen/Generator.cs b/src/bgen/Generator.cs index 9fbd2e73455..37a3910ae06 100644 --- a/src/bgen/Generator.cs +++ b/src/bgen/Generator.cs @@ -500,7 +500,11 @@ string GetFromBindAsWrapper (MemberInformation minfo, out string suffix) throw GetBindAsException ("unbox", retType.Name, originalReturnType.Name, "container", minfo.mi); } } else if (originalReturnType == TypeCache.NSString && IsSmartEnum (retType)) { - append = $"{TypeManager.FormatType (retType.DeclaringType, retType)}Extensions.GetValue ("; + if (isNullable) { + append = $"{TypeManager.FormatType (retType.DeclaringType, retType)}Extensions.GetNullableValue ("; + } else { + append = $"{TypeManager.FormatType (retType.DeclaringType, retType)}Extensions.GetValue ("; + } suffix = ")"; } else if (originalReturnType.IsArray && originalReturnType.GetArrayRank () == 1) { var arrType = originalReturnType.GetElementType (); @@ -2909,14 +2913,8 @@ void GetReturnsWrappers (MethodInfo mi, MemberInformation minfo, Type declaringT var wrapper = GetFromBindAsWrapper (minfo, out suffix); var formattedReturnType = TypeManager.FormatType (minfo.type, mi.ReturnType); if (mi.ReturnType == TypeCache.NSString) { - if (isNullable) { - print ("{0} retvaltmp;", NativeHandleType); - cast_a = "((retvaltmp = "; - cast_b = $") == IntPtr.Zero ? default ({formattedBindAsType}) : ({wrapper}Runtime.GetNSObject<{formattedReturnType}> (retvaltmp, {owns})!){suffix})"; - } else { - cast_a = $"{wrapper}Runtime.GetNSObject<{formattedReturnType}> ("; - cast_b = $", {owns})!{suffix}"; - } + cast_a = $"{wrapper}"; + cast_b = $"{suffix}"; } else { var enumCast = (bindAsType.IsEnum && !minfo.type.IsArray) ? $"({formattedBindAsType}) " : string.Empty; cast_a = $"{enumCast}Runtime.GetNSObject<{formattedReturnType}> ("; diff --git a/src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.Runtime.cs b/src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.Runtime.cs index 3aa53744906..a28852f7eb9 100644 --- a/src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.Runtime.cs +++ b/src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.Runtime.cs @@ -268,7 +268,6 @@ internal static InvocationExpressionSyntax StringFromHandle (ImmutableArray /// Generates a call to the NSArray.ArrayFromHandleFunc with the given arguments. /// diff --git a/src/rgen/Microsoft.Macios.Generator/Emitters/EnumEmitter.cs b/src/rgen/Microsoft.Macios.Generator/Emitters/EnumEmitter.cs index 4970234551e..d1de240035c 100644 --- a/src/rgen/Microsoft.Macios.Generator/Emitters/EnumEmitter.cs +++ b/src/rgen/Microsoft.Macios.Generator/Emitters/EnumEmitter.cs @@ -112,8 +112,23 @@ void EmitExtensionMethods (TabbedWriter classBlock, string symbolN return GetValue (str); "); } + classBlock.WriteLine (); + // get nullable value from a handle, similar to the above but used when the enum could be null (yes, apple + // does have methods that return null for enums) + classBlock.WriteDocumentation (Documentation.SmartEnum.GetValueHandle (symbolName)); + using (var getValueFromHandle = + classBlock.CreateBlock ($"public static {binding.Name}? GetNullableValue (NativeHandle handle)", + true)) { + getValueFromHandle.WriteRaw ( +@"using var str = Runtime.GetNSObject (handle); +if (str is null) + return null; +return GetValue (str); +"); + } classBlock.WriteLine (); + // To ConstantArray classBlock.WriteDocumentation (Documentation.SmartEnum.ToConstantArray (symbolName)); classBlock.WriteRaw ( diff --git a/tests/generator/ExpectedXmlDocs.MacCatalyst.xml b/tests/generator/ExpectedXmlDocs.MacCatalyst.xml index 0c6e3bf8d3d..9ce7b30bd14 100644 --- a/tests/generator/ExpectedXmlDocs.MacCatalyst.xml +++ b/tests/generator/ExpectedXmlDocs.MacCatalyst.xml @@ -39,6 +39,10 @@ Retrieves the value represented by the backing field value in . The native handle with the name of the constant to retrieve. + + Retrieves the value represented by the backing field value in . + The native handle with the name of the constant to retrieve. + Converts an array of enum values into an array of their corresponding constants. The array of enum values to convert. diff --git a/tests/generator/ExpectedXmlDocs.iOS.xml b/tests/generator/ExpectedXmlDocs.iOS.xml index 502a663e13b..dba5cc1b0cf 100644 --- a/tests/generator/ExpectedXmlDocs.iOS.xml +++ b/tests/generator/ExpectedXmlDocs.iOS.xml @@ -39,6 +39,10 @@ Retrieves the value represented by the backing field value in . The native handle with the name of the constant to retrieve. + + Retrieves the value represented by the backing field value in . + The native handle with the name of the constant to retrieve. + Converts an array of enum values into an array of their corresponding constants. The array of enum values to convert. diff --git a/tests/generator/ExpectedXmlDocs.macOS.xml b/tests/generator/ExpectedXmlDocs.macOS.xml index 0c6e3bf8d3d..9ce7b30bd14 100644 --- a/tests/generator/ExpectedXmlDocs.macOS.xml +++ b/tests/generator/ExpectedXmlDocs.macOS.xml @@ -39,6 +39,10 @@ Retrieves the value represented by the backing field value in . The native handle with the name of the constant to retrieve. + + Retrieves the value represented by the backing field value in . + The native handle with the name of the constant to retrieve. + Converts an array of enum values into an array of their corresponding constants. The array of enum values to convert. diff --git a/tests/generator/ExpectedXmlDocs.tvOS.xml b/tests/generator/ExpectedXmlDocs.tvOS.xml index 0c6e3bf8d3d..9ce7b30bd14 100644 --- a/tests/generator/ExpectedXmlDocs.tvOS.xml +++ b/tests/generator/ExpectedXmlDocs.tvOS.xml @@ -39,6 +39,10 @@ Retrieves the value represented by the backing field value in . The native handle with the name of the constant to retrieve. + + Retrieves the value represented by the backing field value in . + The native handle with the name of the constant to retrieve. + Converts an array of enum values into an array of their corresponding constants. The array of enum values to convert. diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedAVCaptureDeviceTypeEnum.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedAVCaptureDeviceTypeEnum.cs index 053fef12920..ee57ea35c70 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedAVCaptureDeviceTypeEnum.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedAVCaptureDeviceTypeEnum.cs @@ -217,6 +217,18 @@ public static AVCaptureDeviceType GetValue (NativeHandle handle) return GetValue (str); } + /// + /// Retrieves the value represented by the backing field value in . + /// + /// The native handle with the name of the constant to retrieve. + public static AVCaptureDeviceType? GetNullableValue (NativeHandle handle) + { + using var str = Runtime.GetNSObject (handle); + if (str is null) + return null; + return GetValue (str); + } + /// /// Converts an array of enum values into an array of their corresponding constants. /// diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedAVCaptureSystemPressureLevel.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedAVCaptureSystemPressureLevel.cs index f4f394fd579..70d777dee19 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedAVCaptureSystemPressureLevel.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedAVCaptureSystemPressureLevel.cs @@ -127,6 +127,18 @@ public static AVCaptureSystemPressureLevel GetValue (NativeHandle handle) return GetValue (str); } + /// + /// Retrieves the value represented by the backing field value in . + /// + /// The native handle with the name of the constant to retrieve. + public static AVCaptureSystemPressureLevel? GetNullableValue (NativeHandle handle) + { + using var str = Runtime.GetNSObject (handle); + if (str is null) + return null; + return GetValue (str); + } + /// /// Converts an array of enum values into an array of their corresponding constants. /// diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedCustomLibraryEnum.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedCustomLibraryEnum.cs index d76d7ca76c8..935a2e6d5b1 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedCustomLibraryEnum.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedCustomLibraryEnum.cs @@ -98,6 +98,18 @@ public static CustomLibraryEnum GetValue (NativeHandle handle) return GetValue (str); } + /// + /// Retrieves the value represented by the backing field value in . + /// + /// The native handle with the name of the constant to retrieve. + public static CustomLibraryEnum? GetNullableValue (NativeHandle handle) + { + using var str = Runtime.GetNSObject (handle); + if (str is null) + return null; + return GetValue (str); + } + /// /// Converts an array of enum values into an array of their corresponding constants. /// diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedCustomLibraryEnumInternal.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedCustomLibraryEnumInternal.cs index 0208d212e14..b1d14378afa 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedCustomLibraryEnumInternal.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedCustomLibraryEnumInternal.cs @@ -98,6 +98,18 @@ public static CustomLibraryEnumInternal GetValue (NativeHandle handle) return GetValue (str); } + /// + /// Retrieves the value represented by the backing field value in . + /// + /// The native handle with the name of the constant to retrieve. + public static CustomLibraryEnumInternal? GetNullableValue (NativeHandle handle) + { + using var str = Runtime.GetNSObject (handle); + if (str is null) + return null; + return GetValue (str); + } + /// /// Converts an array of enum values into an array of their corresponding constants. /// diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedMacOSAVMediaCharacteristics.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedMacOSAVMediaCharacteristics.cs index aeb5497653d..bd92d01bc38 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedMacOSAVMediaCharacteristics.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectedMacOSAVMediaCharacteristics.cs @@ -380,6 +380,18 @@ public static AVMediaCharacteristics GetValue (NativeHandle handle) return GetValue (str); } + /// + /// Retrieves the value represented by the backing field value in . + /// + /// The native handle with the name of the constant to retrieve. + public static AVMediaCharacteristics? GetNullableValue (NativeHandle handle) + { + using var str = Runtime.GetNSObject (handle); + if (str is null) + return null; + return GetValue (str); + } + /// /// Converts an array of enum values into an array of their corresponding constants. /// diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectediOSAVMediaCharacteristics.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectediOSAVMediaCharacteristics.cs index a856c0e0eb5..62388e373a1 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectediOSAVMediaCharacteristics.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/SmartEnum/Data/ExpectediOSAVMediaCharacteristics.cs @@ -399,6 +399,18 @@ public static AVMediaCharacteristics GetValue (NativeHandle handle) return GetValue (str); } + /// + /// Retrieves the value represented by the backing field value in . + /// + /// The native handle with the name of the constant to retrieve. + public static AVMediaCharacteristics? GetNullableValue (NativeHandle handle) + { + using var str = Runtime.GetNSObject (handle); + if (str is null) + return null; + return GetValue (str); + } + /// /// Converts an array of enum values into an array of their corresponding constants. ///