[generator] Add missing `EnsureUIThread` for generated `init` and `initWithCoder` (#8250)
Fix https://github.com/xamarin/xamarin-macios/issues/8249
This commit is contained in:
Родитель
862d200a18
Коммит
ac01b522f0
|
@ -4184,20 +4184,25 @@ public partial class Generator : IMemberGatherer {
|
|||
|
||||
string CurrentMethod;
|
||||
|
||||
void GenerateThreadCheck ()
|
||||
void GenerateThreadCheck (StreamWriter sw = null)
|
||||
{
|
||||
string s;
|
||||
switch (CurrentPlatform) {
|
||||
case PlatformName.iOS:
|
||||
case PlatformName.WatchOS:
|
||||
case PlatformName.TvOS:
|
||||
print ("global::{0}.UIApplication.EnsureUIThread ();", ns.Get ("UIKit"));
|
||||
s = $"global::{ns.Get ("UIKit")}.UIApplication.EnsureUIThread ();";
|
||||
break;
|
||||
case PlatformName.MacOSX:
|
||||
print ("global::{0}.NSApplication.EnsureUIThread ();", ns.Get ("AppKit"));
|
||||
s = $"global::{ns.Get ("AppKit")}.NSApplication.EnsureUIThread ();";
|
||||
break;
|
||||
default:
|
||||
throw new BindingException (1047, CurrentPlatform);
|
||||
}
|
||||
if (sw == null)
|
||||
print (s);
|
||||
else
|
||||
sw.WriteLine (s);
|
||||
}
|
||||
|
||||
// Stret.NeedStret is shared between generator and X.I dll so in order to wrap the exception
|
||||
|
@ -6451,6 +6456,10 @@ public partial class Generator : IMemberGatherer {
|
|||
sw.WriteLine ("\tthrow new PlatformNotSupportedException (\"This API is not supported on this version of iOS\");");
|
||||
sw.WriteLine ("\t\t#else");
|
||||
}
|
||||
if (type_needs_thread_checks) {
|
||||
sw.Write ("\t\t\t");
|
||||
GenerateThreadCheck (sw);
|
||||
}
|
||||
var indentation = 3;
|
||||
WriteIsDirectBindingCondition (sw, ref indentation, is_direct_binding, is_direct_binding_value,
|
||||
() => string.Format ("InitializeHandle (global::{1}.IntPtr_objc_msgSend (this.Handle, global::{2}.{0}), \"init\");", initSelector, ns.Messaging, ns.CoreObjCRuntime),
|
||||
|
@ -6478,7 +6487,10 @@ public partial class Generator : IMemberGatherer {
|
|||
if (nscoding) {
|
||||
if (debug)
|
||||
sw.WriteLine ("\t\t\tConsole.WriteLine (\"{0}.ctor (NSCoder)\");", TypeName);
|
||||
sw.WriteLine ();
|
||||
if (type_needs_thread_checks) {
|
||||
sw.Write ("\t\t\t");
|
||||
GenerateThreadCheck (sw);
|
||||
}
|
||||
var indentation = 3;
|
||||
WriteIsDirectBindingCondition (sw, ref indentation, is_direct_binding, is_direct_binding_value,
|
||||
() => string.Format ("InitializeHandle (global::{1}.IntPtr_objc_msgSend_IntPtr (this.Handle, {0}, coder.Handle), \"initWithCoder:\");", initWithCoderSelector, ns.Messaging),
|
||||
|
|
|
@ -63,8 +63,11 @@ namespace Cecil.Tests {
|
|||
yield return new TestCaseData (Path.Combine (Configuration.MonoTouchRootDirectory, "lib", "32bits", "Xamarin.iOS.dll"));
|
||||
yield return new TestCaseData (Path.Combine (Configuration.MonoTouchRootDirectory, "lib", "64bits", "Xamarin.iOS.dll"));
|
||||
|
||||
yield return new TestCaseData (Configuration.XamarinWatchOSDll);
|
||||
yield return new TestCaseData (Configuration.XamarinTVOSDll);
|
||||
// XamarinWatchOSDll is stripped of its IL
|
||||
yield return new TestCaseData (Path.Combine (Configuration.MonoTouchRootDirectory, "lib", "32bits", "Xamarin.WatchOS.dll"));
|
||||
// XamarinTVOSDll is stripped of it's IL
|
||||
yield return new TestCaseData (Path.Combine (Configuration.MonoTouchRootDirectory, "lib", "64bits", "Xamarin.TVOS.dll"));
|
||||
|
||||
yield return new TestCaseData (Configuration.XamarinMacMobileDll);
|
||||
yield return new TestCaseData (Configuration.XamarinMacFullDll);
|
||||
}
|
||||
|
|
|
@ -48,5 +48,43 @@ namespace Cecil.Tests {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestCaseSource (typeof (Helper), "PlatformAssemblies")]
|
||||
// ref: https://github.com/xamarin/xamarin-macios/issues/8249
|
||||
public void EnsureUIThreadOnInit (string assemblyPath)
|
||||
{
|
||||
var assembly = Helper.GetAssembly (assemblyPath);
|
||||
if (assembly == null) {
|
||||
Assert.Ignore ("{assemblyPath} could not be found (might be disabled in build)");
|
||||
return; // just to help nullability
|
||||
}
|
||||
|
||||
// `CNContactsUserDefaults` is `[ThreadSafe (false)]` and part of iOS and macOS
|
||||
var t = assembly.MainModule.GetType ("Contacts.CNContactsUserDefaults");
|
||||
if (t == null) {
|
||||
// tvOS does not have the type so let's find an alternative
|
||||
t = assembly.MainModule.GetType ("PhotosUI.PHLivePhotoView");
|
||||
}
|
||||
if (t == null) {
|
||||
Assert.Fail ($"No type found for {assembly}");
|
||||
return; // just to help nullability
|
||||
}
|
||||
|
||||
foreach (var c in t.Methods) {
|
||||
if (!c.IsConstructor || c.IsStatic || c.HasParameters)
|
||||
continue;
|
||||
// .ctor(IntPtr)
|
||||
var found = false;
|
||||
foreach (var ins in c.Body.Instructions) {
|
||||
if (ins.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
found |= (ins.Operand as MethodReference)?.Name == "EnsureUIThread";
|
||||
}
|
||||
if (!found)
|
||||
Assert.Fail ("EnsureUIThread missing");
|
||||
else
|
||||
return; // single case, no point in iterating anymore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Introspection
|
|||
[TestFixture]
|
||||
public class MacApiTypoTest : ApiTypoTest
|
||||
{
|
||||
NSSpellChecker checker = new NSSpellChecker ();
|
||||
NSSpellChecker checker;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp ()
|
||||
|
@ -20,6 +20,7 @@ namespace Introspection
|
|||
var sdk = new Version (Constants.SdkVersion);
|
||||
if (!PlatformHelper.CheckSystemVersion (sdk.Major, sdk.Minor))
|
||||
Assert.Ignore ("Typos only verified using the latest SDK");
|
||||
checker = new NSSpellChecker ();
|
||||
}
|
||||
|
||||
public override string GetTypo (string txt)
|
||||
|
|
Загрузка…
Ссылка в новой задаче