From 312c1355d9ec5aa07fe7b5c791747b9f1f024ee7 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 16 Mar 2026 21:01:39 +0100 Subject: [PATCH 1/2] [sharpie] Fix platform type mapping for types inside generic type arguments The PlatformTypeMappingMassager did not recurse into child nodes (such as type arguments inside Action<> or Func<>) because the VisitMemberType and VisitSimpleType overrides did not call their base implementations. This meant that types like NSURLResponse inside Action were never mapped to their .NET equivalents (NSUrlResponse). Fix by calling base.VisitMemberType/VisitSimpleType before processing the type itself, so children (type arguments) are mapped first. Added a test case with a block parameter containing mapped types. Fixes https://github.com/dotnet/macios/issues/24892 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/sharpie/Tests/Massagers/PlatformTypeMapping.h | 1 + .../sharpie/Tests/Massagers/PlatformTypeMapping.iphoneos.cs | 5 +++++ tests/sharpie/Tests/Massagers/PlatformTypeMapping.macosx.cs | 5 +++++ .../Sharpie.Bind/Massagers/PlatformTypeMappingMassager.cs | 4 ++++ 4 files changed, 15 insertions(+) diff --git a/tests/sharpie/Tests/Massagers/PlatformTypeMapping.h b/tests/sharpie/Tests/Massagers/PlatformTypeMapping.h index 4ab1a8a53daf..ef789bba8c0c 100644 --- a/tests/sharpie/Tests/Massagers/PlatformTypeMapping.h +++ b/tests/sharpie/Tests/Massagers/PlatformTypeMapping.h @@ -9,4 +9,5 @@ @interface WebFetcher : NSObject @property (nonatomic, readonly, copy) NSURL *url; -(NSURLResponse *)getResponseForUrl:(NSURL *)url withCredential:(NSURLCredential *)credential; +-(void)loadDataWithUrl:(NSURL *)url completionHandler:(void (^)(NSData *, NSURLResponse *))handler; @end diff --git a/tests/sharpie/Tests/Massagers/PlatformTypeMapping.iphoneos.cs b/tests/sharpie/Tests/Massagers/PlatformTypeMapping.iphoneos.cs index bd219fe54ae0..33be4e000f76 100644 --- a/tests/sharpie/Tests/Massagers/PlatformTypeMapping.iphoneos.cs +++ b/tests/sharpie/Tests/Massagers/PlatformTypeMapping.iphoneos.cs @@ -1,3 +1,4 @@ +using System; using Foundation; using ObjCRuntime; @@ -11,4 +12,8 @@ interface WebFetcher : INSUrlConnectionDelegate { // -(NSURLResponse *)getResponseForUrl:(NSURL *)url withCredential:(NSURLCredential *)credential; [Export ("getResponseForUrl:withCredential:")] NSUrlResponse GetResponseForUrl (NSUrl url, NSUrlCredential credential); + + // -(void)loadDataWithUrl:(NSURL *)url completionHandler:(void (^)(NSData *, NSURLResponse *))handler; + [Export ("loadDataWithUrl:completionHandler:")] + void LoadDataWithUrl (NSUrl url, Action handler); } diff --git a/tests/sharpie/Tests/Massagers/PlatformTypeMapping.macosx.cs b/tests/sharpie/Tests/Massagers/PlatformTypeMapping.macosx.cs index bd219fe54ae0..33be4e000f76 100644 --- a/tests/sharpie/Tests/Massagers/PlatformTypeMapping.macosx.cs +++ b/tests/sharpie/Tests/Massagers/PlatformTypeMapping.macosx.cs @@ -1,3 +1,4 @@ +using System; using Foundation; using ObjCRuntime; @@ -11,4 +12,8 @@ interface WebFetcher : INSUrlConnectionDelegate { // -(NSURLResponse *)getResponseForUrl:(NSURL *)url withCredential:(NSURLCredential *)credential; [Export ("getResponseForUrl:withCredential:")] NSUrlResponse GetResponseForUrl (NSUrl url, NSUrlCredential credential); + + // -(void)loadDataWithUrl:(NSURL *)url completionHandler:(void (^)(NSData *, NSURLResponse *))handler; + [Export ("loadDataWithUrl:completionHandler:")] + void LoadDataWithUrl (NSUrl url, Action handler); } diff --git a/tools/sharpie/Sharpie.Bind/Massagers/PlatformTypeMappingMassager.cs b/tools/sharpie/Sharpie.Bind/Massagers/PlatformTypeMappingMassager.cs index 4a357a14f14c..3d36915ccdc2 100644 --- a/tools/sharpie/Sharpie.Bind/Massagers/PlatformTypeMappingMassager.cs +++ b/tools/sharpie/Sharpie.Bind/Massagers/PlatformTypeMappingMassager.cs @@ -207,11 +207,15 @@ public override void VisitTypeOfExpression (TypeOfExpression typeOfExpression) public override void VisitMemberType (MemberType memberType) { + // Visit children first so that type arguments (e.g. inside Action) + // are mapped before the parent type is processed. + base.VisitMemberType (memberType); VisitType (memberType, memberType.MemberName); } public override void VisitSimpleType (SimpleType simpleType) { + base.VisitSimpleType (simpleType); VisitType (simpleType, simpleType.Identifier); } From 33b540c8e7e893e71d3fa19614c9652145fa5243 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 17 Mar 2026 15:40:13 +0100 Subject: [PATCH 2/2] [sharpie] Update ObjCGenerics test expectations for type argument mapping The PlatformTypeMappingMassager now correctly recurses into generic type arguments, which means protocol names like NSSecureCoding inside generic constraints (e.g. NSObject) are now properly mapped to their .NET equivalents (INSSecureCoding). Update the expected test output to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/sharpie/Tests/ObjCGenerics.iphoneos.cs | 6 +++--- tests/sharpie/Tests/ObjCGenerics.macosx.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/sharpie/Tests/ObjCGenerics.iphoneos.cs b/tests/sharpie/Tests/ObjCGenerics.iphoneos.cs index a11273618fde..68ed305d6555 100644 --- a/tests/sharpie/Tests/ObjCGenerics.iphoneos.cs +++ b/tests/sharpie/Tests/ObjCGenerics.iphoneos.cs @@ -6,16 +6,16 @@ interface CNLabeledValue : INSCopying, INSSecureCoding { // @property (readonly, copy, nonatomic) ValueType ValueTypeProperty; [Export ("ValueTypeProperty", ArgumentSemantic.Copy)] - NSObject ValueTypeProperty { get; } + NSObject ValueTypeProperty { get; } // -(ValueType _Nullable)getValueTypeMethod; [NullAllowed, Export ("getValueTypeMethod")] [Verify (MethodToProperty)] - NSObject ValueTypeMethod { get; } + NSObject ValueTypeMethod { get; } // -(void)setValueTypeMethod:(ValueType _Nullable)obj; [Export ("setValueTypeMethod:")] - void SetValueTypeMethod ([NullAllowed] NSObject obj); + void SetValueTypeMethod ([NullAllowed] NSObject obj); } // @protocol A diff --git a/tests/sharpie/Tests/ObjCGenerics.macosx.cs b/tests/sharpie/Tests/ObjCGenerics.macosx.cs index a11273618fde..68ed305d6555 100644 --- a/tests/sharpie/Tests/ObjCGenerics.macosx.cs +++ b/tests/sharpie/Tests/ObjCGenerics.macosx.cs @@ -6,16 +6,16 @@ interface CNLabeledValue : INSCopying, INSSecureCoding { // @property (readonly, copy, nonatomic) ValueType ValueTypeProperty; [Export ("ValueTypeProperty", ArgumentSemantic.Copy)] - NSObject ValueTypeProperty { get; } + NSObject ValueTypeProperty { get; } // -(ValueType _Nullable)getValueTypeMethod; [NullAllowed, Export ("getValueTypeMethod")] [Verify (MethodToProperty)] - NSObject ValueTypeMethod { get; } + NSObject ValueTypeMethod { get; } // -(void)setValueTypeMethod:(ValueType _Nullable)obj; [Export ("setValueTypeMethod:")] - void SetValueTypeMethod ([NullAllowed] NSObject obj); + void SetValueTypeMethod ([NullAllowed] NSObject obj); } // @protocol A