[generator] Skip protocols that aren't available on the current platform. (#12208)

That way we can do this in api definitions:

    [BaseType (typeof (NSObject))]
    interface MyType : MyProtocol { }

    [Protocol]
    [NoMacCatalyst]
    interface MyProtocol {}

instead of this:

    [BaseType (typeof (NSObject))]
    interface MyType
    #if __MACOS__
        : MyProtocol
    #endif
    {
    }

    [Protocol]
    [NoMacCatalyst]
    interface MyProtocol {}

for a type that implements a protocol on macOS, but not on Mac Catalyst.
This commit is contained in:
Rolf Bjarne Kvinge 2021-07-28 09:35:41 +02:00 коммит произвёл GitHub
Родитель 0bd4d1b101
Коммит c202ba4a93
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 35 добавлений и 0 удалений

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

@ -4742,6 +4742,9 @@ public partial class Generator : IMemberGatherer {
foreach (var method in source.GatherMethods (BindingFlags.Public | BindingFlags.Instance, this))
yield return method;
foreach (var parent in source.GetInterfaces ()){
// skip interfaces that aren't available on the current platform
if (parent.IsUnavailable (this))
continue;
// skip case where the interface implemented comes from an already built assembly (e.g. monotouch.dll)
// e.g. Dispose won't have an [Export] since it's present to satisfy System.IDisposable
if (parent.FullName != "System.IDisposable") {
@ -4757,6 +4760,9 @@ public partial class Generator : IMemberGatherer {
foreach (var prop in source.GatherProperties (this))
yield return prop;
foreach (var parent in source.GetInterfaces ()){
// skip interfaces that aren't available on the current platform
if (parent.IsUnavailable (this))
continue;
// skip case where the interface implemented comes from an already built assembly (e.g. monotouch.dll)
// e.g. the Handle property won't have an [Export] since it's present to satisfyINativeObject
if (parent.Name != "INativeObject") {
@ -6522,6 +6528,10 @@ public partial class Generator : IMemberGatherer {
continue;
}
// skip protocols that aren't available on the current platform
if (protocolType.IsUnavailable (this))
continue;
// A protocol this class implements. We need to implement the corresponding interface for the protocol.
string pname = protocolType.Name;
// the extra 'I' is only required for the bindings being built, if it comes from something already

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

@ -633,6 +633,17 @@ namespace GeneratorTests
[Test]
public void StrongDictsNativeEnums () => BuildFile (Profile.iOS, "strong-dict-native-enum.cs");
[Test]
public void IgnoreUnavailableProtocol ()
{
var bgen = BuildFile (Profile.iOS, "tests/ignore-unavailable-protocol.cs");
var myClass = bgen.ApiAssembly.MainModule.GetType ("NS", "MyClass");
var myProtocol = bgen.ApiAssembly.MainModule.GetType ("NS", "IMyProtocol");
var myClassInterfaces = myClass.Interfaces.Select (v => v.InterfaceType.Name).ToArray ();
Assert.That (myClassInterfaces, Does.Not.Contain ("IMyProtocol"), "IMyProtocol");
Assert.IsNull (myProtocol, "MyProtocol null");
}
[Test]
public void VSTS970507 ()
{

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

@ -0,0 +1,14 @@
using System;
using Foundation;
using ObjCRuntime;
namespace NS {
[Unavailable (PlatformName.iOS, ObjCRuntime.PlatformArchitecture.All)]
[Protocol]
interface MyProtocol {
}
[BaseType (typeof (NSObject))]
interface MyClass : MyProtocol {
}
}