[generator] Fix generation of ReturnRelease code for third-party bindings. (#6135)

Don't use internal platform API (the Selector.Release field), and make sure
the void_objc_msgSend function exists in the binding.
This commit is contained in:
Rolf Bjarne Kvinge 2019-05-27 23:08:45 -07:00
Родитель 26d10477ec
Коммит ff86152ecc
4 изменённых файлов: 37 добавлений и 3 удалений

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

@ -4449,14 +4449,23 @@ public partial class Generator : IMemberGatherer {
}
if (minfo.is_return_release) {
// Make sure we generate the required signature in Messaging only if needed
// bool_objc_msgSendSuper_IntPtr: for respondsToSelector:
if (!send_methods.ContainsKey ("void_objc_msgSend")) {
print (m, "[DllImport (LIBOBJC_DYLIB, EntryPoint=\"objc_msgSendSuper\")]");
print (m, "public extern static void void_objc_msgSend (IntPtr receiever, IntPtr selector);");
RegisterMethodName ("void_objc_msgSend");
}
if (!needsPtrZeroCheck)
print ("{0}.void_objc_msgSend (ret.Handle, Selector.GetHandle (Selector.Release));", ns.Messaging);
print ("global::{0}.void_objc_msgSend (ret.Handle, Selector.GetHandle (\"release\"));", ns.Messaging);
else {
// We must create the managed wrapper before calling Release on it
// FIXME: https://trello.com/c/1ukS9TbL/43-introduce-common-object-type-for-all-unmanaged-types-which-will-correctly-implement-idisposable-and-inativeobject
// We should consider using return INativeObject<T> (ptr, bool); here at some point
print ("global::{0} relObj = ret == IntPtr.Zero ? null : new global::{0} (ret);", mi.ReturnType.FullName);
print ("if (relObj != null) global::{0}.void_objc_msgSend (relObj.Handle, Selector.GetHandle (Selector.Release));", ns.Messaging);
print ("if (relObj != null) global::{0}.void_objc_msgSend (relObj.Handle, Selector.GetHandle (\"release\"));", ns.Messaging);
}
}

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

@ -588,10 +588,16 @@ namespace GeneratorTests
[Test]
public void GHIssue5692 () => BuildFile (Profile.iOS, "ghissue5692.cs");
[Test]
public void RefOutParameters ()
{
BuildFile (Profile.macOSMobile, true, "tests/ref-out-parameters.cs");
}
[Test]
public void ReturnRelease ()
{
BuildFile (Profile.iOS, "tests/return-release.cs");
}
BGenTool BuildFile (Profile profile, params string [] filenames)

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

@ -70,7 +70,8 @@
<ItemGroup>
<None Include="tests\is-direct-binding.cs" />
<None Include="packages.config" />
<None Include="tests\ref-out-parameters.cs" />
<None Include="tests\ref-out-parameters.cs" />
<None Include="tests\return-release.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="tests\" />

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

@ -0,0 +1,18 @@
using System;
using Foundation;
namespace NS
{
[Protocol]
interface ProtocolWithReturnRelease
{
[Abstract, Export ("newRequiredObject")]
[return: Release]
NSObject CreateRequiredObject ();
[Export ("newOptionalObject")]
[return: Release]
NSObject CreateOptionalObject ();
}
}