[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;
	}
}

```
This commit is contained in:
Alex Soto 2018-06-11 10:26:30 -07:00 коммит произвёл GitHub
Родитель 45ae4c53ce
Коммит 02e8a2d7a3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 33 добавлений и 2 удалений

Просмотреть файл

@ -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 ("}");

Просмотреть файл

@ -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")]

Просмотреть файл

@ -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; }
}
}