diff --git a/src/bgen/Generator.cs b/src/bgen/Generator.cs index bf32f444af7e..30e546003dd7 100644 --- a/src/bgen/Generator.cs +++ b/src/bgen/Generator.cs @@ -167,7 +167,22 @@ public bool IsNSObject (Type type) return false; } - return type.IsInterface; + // If any of the interfaces this type implements is an NSObject, + // then this type is also an NSObject + var ifaces = type.GetInterfaces (); + foreach (var iface in ifaces) + if (IsNSObject (iface)) + return true; + + if (type.IsInterface) { + var bta = ReflectionExtensions.GetBaseTypeAttribute (type, this); + if (bta?.BaseType is not null) + return IsNSObject (bta.BaseType); + + return false; + } + + return false; } public string PrimitiveType (Type t, bool formatted = false) @@ -604,8 +619,10 @@ public TrampolineInfo MakeTrampoline (Type t) invoke.AppendFormat (" Runtime.GetINativeObject<{1}> ({0}, false)!", safe_name, pi.ParameterType); } else if (isForced) { invoke.AppendFormat (" Runtime.GetINativeObject<{1}> ({0}, true, {2})!", safe_name, TypeManager.RenderType (pi.ParameterType), isForcedOwns); - } else { + } else if (IsNSObject (pi.ParameterType)) { invoke.AppendFormat (" Runtime.GetNSObject<{1}> ({0})!", safe_name, TypeManager.RenderType (pi.ParameterType)); + } else { + invoke.AppendFormat (" Runtime.GetINativeObject<{1}> ({0}, false)!", safe_name, TypeManager.RenderType (pi.ParameterType)); } continue; } diff --git a/tests/generator/BGenTests.cs b/tests/generator/BGenTests.cs index 556946c22d7f..ffd40b0ed3b5 100644 --- a/tests/generator/BGenTests.cs +++ b/tests/generator/BGenTests.cs @@ -404,6 +404,20 @@ public void Bug35176 () Assert.AreEqual (expectedAttributes, renderedAttributes, "Introduced attributes"); } + [Test] + [TestCase (Profile.iOS)] + public void INativeObjectsInBlocks (Profile profile) + { + var bgen = new BGenTool (); + bgen.Profile = profile; + bgen.Defines = BGenTool.GetDefaultDefines (bgen.Profile); + bgen.AddTestApiDefinition ("tests/inativeobjects-in-blocks.cs"); + bgen.AddExtraSourcesRelativeToGeneratorDirectory ("tests/inativeobjects-in-blocks-sources.cs"); + bgen.CreateTemporaryBinding (); + bgen.AssertExecute ("build"); + bgen.AssertNoWarnings (); + } + [Test] public void Bug36457 () { diff --git a/tests/generator/BGenTool.cs b/tests/generator/BGenTool.cs index 681ba2003b54..1bbf9ea39719 100644 --- a/tests/generator/BGenTool.cs +++ b/tests/generator/BGenTool.cs @@ -26,6 +26,7 @@ class BGenTool : Tool { public List ApiDefinitions = new List (); public List Sources = new List (); + public List ExtraSources = new List (); public List References = new List (); #if NET public List? CompileCommand = null; @@ -71,6 +72,16 @@ public void AddTestApiDefinition (string filename) ApiDefinitions.Add (Path.Combine (Configuration.SourceRoot, "tests", "generator", filename)); } + public void AddExtraSourcesRelativeToGeneratorDirectory (string pathRelativeToGeneratorDirectory) + { + ExtraSources.Add (GetFullPathRelativeToGeneratorDirectory (pathRelativeToGeneratorDirectory)); + } + + public string GetFullPathRelativeToGeneratorDirectory (string pathRelativeToGeneratorDirectory) + { + return Path.Combine (Configuration.SourceRoot, "tests", "generator", pathRelativeToGeneratorDirectory); + } + public AssemblyDefinition ApiAssembly { get { return LoadAssembly (); @@ -169,6 +180,9 @@ string [] BuildArgumentArray () foreach (var s in Sources) sb.Add ($"-s={s}"); + foreach (var x in ExtraSources) + sb.Add ($"-x={x}"); + if (ReferenceBclByDefault) { if (tf is null) { // do nothing diff --git a/tests/generator/tests/inativeobjects-in-blocks-sources.cs b/tests/generator/tests/inativeobjects-in-blocks-sources.cs new file mode 100644 index 000000000000..c2ce8653b981 --- /dev/null +++ b/tests/generator/tests/inativeobjects-in-blocks-sources.cs @@ -0,0 +1,9 @@ +using System; + +using CoreFoundation; +using Foundation; +using ObjCRuntime; + +namespace NS { + public partial class DispatchData2 : NativeObject { } +} diff --git a/tests/generator/tests/inativeobjects-in-blocks.cs b/tests/generator/tests/inativeobjects-in-blocks.cs new file mode 100644 index 000000000000..3a340ef89997 --- /dev/null +++ b/tests/generator/tests/inativeobjects-in-blocks.cs @@ -0,0 +1,21 @@ +using System; + +using CoreFoundation; +using Foundation; +using ObjCRuntime; + +namespace NS { + + [Partial] + interface DispatchData2 { + } + + delegate void DispatchB (DispatchData2 data); + delegate void DispatchA (DispatchData2 data, [BlockCallback] DispatchB dispatch); + + [BaseType (typeof (NSObject))] + interface INativeObjectInBlocks { + [Export ("someProperty")] + DispatchA SomeProperty { get; set; } + } +}