Skip to content

Commit

Permalink
Modified GetProxies test to have an original return type of NSArray<N…
Browse files Browse the repository at this point in the history
…SNumber>, added logic to handle binding of NSArrays with NSNumbers and Class-types
  • Loading branch information
dustin-wojciechowski committed Feb 5, 2024
1 parent aaa56b6 commit 11b99e8
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/bgen/Caches/TypeCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public class TypeCache {
public Type CGVector { get; }
public Type DispatchQueue { get; }
public Type DispatchData { get; }
public Type NSArray { get; }
public Type NSNumber { get; }
public Type NSRange { get; }
public Type NSString { get; }
Expand Down Expand Up @@ -219,6 +220,7 @@ public TypeCache (MetadataLoadContext universe, Frameworks frameworks, PlatformN
CGVector = Lookup (platformAssembly, "CoreGraphics", "CGVector");
DispatchQueue = Lookup (platformAssembly, "CoreFoundation", "DispatchQueue");
DispatchData = Lookup (platformAssembly, "CoreFoundation", "DispatchData");
NSArray = Lookup (bindThirdPartyLibrary ? platformAssembly : apiAssembly, "Foundation", "NSArray");
NSNumber = Lookup (bindThirdPartyLibrary ? platformAssembly : apiAssembly, "Foundation", "NSNumber");
NSRange = Lookup (platformAssembly, "Foundation", "NSRange");
NSString = Lookup (platformAssembly, "Foundation", "NSString");
Expand Down
57 changes: 56 additions & 1 deletion src/bgen/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -520,11 +520,50 @@ string GetFromBindAsWrapper (MemberInformation minfo, out string suffix)
append = string.Format ("ptr => {{\n\tusing (var val = Runtime.GetNSObject<NSValue> (ptr)!) {{\n\t\treturn val{0};\n\t}}\n}}", valueFetcher);
} else
throw new BindingException (1048, true, arrIsNullable ? arrRetType.Name + "?[]" : retType.Name);
} else
} else if (originalReturnType.BaseType == TypeCache.NSArray) {
if (originalReturnType.GenericTypeArguments.Length > 0) {
var arrType = originalReturnType.GenericTypeArguments [0];
append = GenerateNSArrayElementConverterText (retType, arrType, minfo, out suffix);
}
else
throw new BindingException (1048, true, retType.Name);
}
else
throw new BindingException (1048, true, retType.Name);
return append;
}

public string GenerateNSArrayElementConverterText (Type retType, Type arrType, MemberInformation minfo, out string suffix)
{
string append = "";
suffix = string.Empty;
var nullableElementType = TypeManager.GetUnderlyingNullableType (retType.GetElementType ());
var arrIsNullable = nullableElementType is not null;
var arrRetType = arrIsNullable ? nullableElementType : retType.GetElementType ();
string valueFetcher = "";

if (arrType == TypeCache.NSNumber && !arrIsNullable) {
if (TypeManager.NSNumberReturnMap.TryGetValue (arrRetType, out valueFetcher) || arrRetType.IsEnum) {
var getterStr = string.Format ("{0}{1}", arrIsNullable ? "?" : string.Empty, arrRetType.IsEnum ? ".Int32Value" : valueFetcher);
append = string.Format ("ptr => {{\n\tusing (var num = Runtime.GetNSObject<NSNumber> (ptr)!) {{\n\t\treturn ({1}) num{0};\n\t}}\n}}", getterStr, TypeManager.FormatType (arrRetType.DeclaringType, arrRetType));
} else
throw GetBindAsException ("unbox", retType.Name, arrType.Name, "array", minfo.mi);
} else if (arrType == TypeCache.NSValue && !arrIsNullable) {
if (arrRetType.Name == "RectangleF" || arrRetType.Name == "SizeF" || arrRetType.Name == "PointF")
valueFetcher = $"{(arrIsNullable ? "?" : string.Empty)}.{arrRetType.Name}Value";
else if (!TypeManager.NSValueReturnMap.TryGetValue (arrRetType, out valueFetcher))
throw GetBindAsException ("unbox", retType.Name, arrType.Name, "array", minfo.mi);
append = string.Format ("ptr => {{\n\tusing (var val = Runtime.GetNSObject<NSValue> (ptr)!) {{\n\t\treturn val{0};\n\t}}\n}}", valueFetcher);
} else if (arrType == TypeCache.NSString && !arrIsNullable) {
append = $"ptr => {{\n\tusing (var str = Runtime.GetNSObject<NSString> (ptr)!) {{\n\t\treturn {TypeManager.FormatType (arrRetType.DeclaringType, arrRetType)}Extensions.GetValue (str);\n\t}}\n}}";
} else if (arrType.IsClass) {
append = string.Format ("createObject => new {0} (createObject, owns: false)", arrType);
} else
throw new BindingException (1048, true, arrIsNullable ? arrRetType.Name + "?[]" : retType.Name);

return append;
}

public bool HasForcedAttribute (ICustomAttributeProvider cu, out string owns)
{
var att = AttributeManager.GetCustomAttribute<ForcedTypeAttribute> (cu);
Expand Down Expand Up @@ -2873,6 +2912,22 @@ void GetReturnsWrappers (MethodInfo mi, MemberInformation minfo, Type declaringT
cast_a = $"{wrapper}Runtime.GetNSObject<{formattedReturnType}> (";
cast_b = $")!{suffix}";
}
} else if (mi.ReturnType.BaseType == TypeCache.NSArray) {
if (minfo is not null && minfo.is_bindAs) {
var bindAttrType = GetBindAsAttribute (minfo.mi).Type;
if (!bindAttrType.IsArray) {
throw new BindingException (1071, true, minfo.mi.DeclaringType.FullName, minfo.mi.Name);
}

var bindAsT = bindAttrType.GetElementType ();
print ("{0} retvalarrtmp;", NativeHandleType);
cast_a = "((retvalarrtmp = ";
cast_b = ") == IntPtr.Zero ? null! : (";
cast_b +=
$"NSArray.ArrayFromHandleFunc <{TypeManager.FormatType (bindAsT.DeclaringType, bindAsT)}> (retvalarrtmp, {GetFromBindAsWrapper (minfo, out suffix)})" +
suffix;
cast_b += "))";
}
} else {
var enumCast = (bindAsType.IsEnum && !minfo.type.IsArray) ? $"({formattedBindAsType}) " : string.Empty;
print ("{0} retvaltmp;", NativeHandleType);
Expand Down
8 changes: 7 additions & 1 deletion tests/generator/ghissue6994.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Foundation;
using ObjCRuntime;
using CoreMedia;
using Network;

namespace GHIssue6994 {

Expand Down Expand Up @@ -30,8 +31,13 @@ interface Foo {
[Export ("addProxies:")]
void AddProxies (IntPtr [] proxies);

[return: BindAs (typeof (int[]))]
[Export ("getProxies")]
IntPtr [] GetProxies ();
NSArray<NSNumber> GetProxies ();

[return: BindAs (typeof (NWProxyConfig[]))]
[Export ("getConfigs")]
NSArray<NWProxyConfig> GetConfigs ();

[Export ("initWithRegion:")]
IntPtr Constructor (MTLRegion [] regions);
Expand Down

0 comments on commit 11b99e8

Please sign in to comment.