From 02e8a2d7a33af7076c5687cd0c954430fa4f65a5 Mon Sep 17 00:00:00 2001 From: Alex Soto Date: Mon, 11 Jun 2018 10:26:30 -0700 Subject: [PATCH] [generator] Fixes WrapAttribute usage with interface protocols (#3885) (#4210) * [generator] Fixes WrapAttribute usage with interface protocols Fixes xamarin/xamarin-macios#3869 We need to support the scenario where `WrapAttribute` is used to wrap an interface protocol type declaration like: ```csharp [Wrap ("WeakDelegate")] [NullAllowed] ICLSDataStoreDelegate Delegate { get; set; } [NullAllowed, Export ("delegate", ArgumentSemantic.Weak)] NSObject WeakDelegate { get; set; } ``` We generated invalid code for the setter that needed an explicit cast and ended up with a CS0266 compiler error: Bad generated code: ```csharp [CompilerGenerated] public ICLSDataStoreDelegate Delegate { get { return WeakDelegate as ICLSDataStoreDelegate; } set { WeakDelegate = value; } } ``` Good generated code: ```csharp [CompilerGenerated] public ICLSDataStoreDelegate Delegate { get { return WeakDelegate as ICLSDataStoreDelegate; } set { var rvalue = value as NSObject; if (value != null && rvalue == null) throw new ArgumentException ("The object passed of type " + value.GetType () + " does not derive from NSObject"); WeakDelegate = rvalue; } } ``` --- src/generator.cs | 6 ++++-- tests/generator/BGenTests.cs | 3 +++ tests/generator/ghissue3869.cs | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 tests/generator/ghissue3869.cs diff --git a/src/generator.cs b/src/generator.cs index 4532d6e5b1..0e7e6cc4dc 100644 --- a/src/generator.cs +++ b/src/generator.cs @@ -4604,7 +4604,9 @@ public partial class Generator : IMemberGatherer { print ("set {"); indent++; - if (minfo.protocolize){ + var is_protocol_wrapper = UnifiedAPI && IsProtocolInterface (pi.PropertyType, false); + + if (minfo.protocolize || is_protocol_wrapper){ print ("var rvalue = value as NSObject;"); print ("if (value != null && rvalue == null)"); print ("\tthrow new ArgumentException (\"The object passed of type \" + value.GetType () + \" does not derive from NSObject\");"); @@ -4616,7 +4618,7 @@ public partial class Generator : IMemberGatherer { if (IsArrayOfWrappedType (pi.PropertyType)) print ("{0} = NSArray.FromNSObjects (value);", wrap); else - print ("{0} = {1}value;", wrap, minfo.protocolize ? "r" : ""); + print ("{0} = {1}value;", wrap, minfo.protocolize || is_protocol_wrapper ? "r" : ""); } indent--; print ("}"); diff --git a/tests/generator/BGenTests.cs b/tests/generator/BGenTests.cs index 7db8f58729..30b6a08979 100644 --- a/tests/generator/BGenTests.cs +++ b/tests/generator/BGenTests.cs @@ -525,6 +525,9 @@ namespace GeneratorTests [Test] public void Bug57870 () => BuildFile (Profile.iOS, true, true, "bug57870.cs"); + [Test] + public void GHIssue3869 () => BuildFile (Profile.iOS, "ghissue3869.cs"); + [Test] [TestCase ("issue3875.cs", "AProtocol")] [TestCase ("issue3875B.cs", "BProtocol")] diff --git a/tests/generator/ghissue3869.cs b/tests/generator/ghissue3869.cs new file mode 100644 index 0000000000..e0d3bc5133 --- /dev/null +++ b/tests/generator/ghissue3869.cs @@ -0,0 +1,26 @@ +using Foundation; +using ObjCRuntime; + +namespace GHIssue3869 { + interface IFooDelegate { } + + [Protocol, Model] + [BaseType (typeof (NSObject))] + interface FooDelegate { + + [Abstract] + [Export ("doSomethingForIdentifier:parentContext:parentIdentifierPath:")] + NSObject DoSomething (string identifier, NSObject parentContext, string [] parentIdentifierPath); + } + + [BaseType (typeof (NSObject))] + interface Foo { + + [Wrap ("WeakDelegate")] + [NullAllowed] + IFooDelegate Delegate { get; set; } + + [NullAllowed, Export ("delegate", ArgumentSemantic.Weak)] + NSObject WeakDelegate { get; set; } + } +} \ No newline at end of file