Skip to content

Commit

Permalink
[generator] Do not generate PlatformNotSupportedException in chaining…
Browse files Browse the repository at this point in the history
… .ctor

Types that are new in 64bits only OS are generated differently on 32bits
bindings. They mainly throw a `PlatformNotSupportedException` so it's
easier to diagnose (than a crash) what's happening at runtime.

This works well in all cases except one. When a new type, let's say
`UIMenuElement` is added **and** serves as a new base type for existing
types.

`UIKeyCommand` (iOS 7) -> `UICommand` (iOS 13)-> `UIMenuElement` (iOS 13)

This is _correct_ as new base types can be added (in ObjC and C#).
However the generated code for the constructors of `UICommand` and
`UIMenuElement` would be throwing a `PlatformNotSupportedException`
which breaks the `UIKeyCommand` on 32 bits devices.

We fixed this in a few places by tweaking the availability attribute
but that requires spotting the new base type while doing bindings and
that is error prone [1][2].

This PR simply does let the `protected` constructor, using when chaining,
be generated normally. It's simpler and will cover all the cases (without
requiring hacks in the availability of those types)

[1] xamarin#7083
[2] xamarin#7084
  • Loading branch information
Sebastien Pouliot committed Sep 24, 2019
1 parent e6f8a51 commit 45b23f9
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 14 deletions.
14 changes: 0 additions & 14 deletions src/generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6479,32 +6479,18 @@ public void Generate (Type type)
sw.WriteLine ("\t\t[EditorBrowsable (EditorBrowsableState.Advanced)]");
sw.WriteLine ("\t\tprotected {0} (NSObjectFlag t) : base (t)", TypeName);
sw.WriteLine ("\t\t{");
if (is32BitNotSupported) {
sw.WriteLine ("\t\t#if ARCH_32");
sw.WriteLine ("\t\t\tthrow new PlatformNotSupportedException (\"This API is not supported on this version of iOS\");");
sw.WriteLine ("\t\t#else");
}
if (is_direct_binding_value != null)
sw.WriteLine ("\t\t\tIsDirectBinding = {0};", is_direct_binding_value);
WriteMarkDirtyIfDerived (sw, type);
if (is32BitNotSupported)
sw.WriteLine ("\t\t#endif");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}
GeneratedCode (sw, 2);
sw.WriteLine ("\t\t[EditorBrowsable (EditorBrowsableState.Advanced)]");
sw.WriteLine ("\t\tprotected internal {0} (IntPtr handle) : base (handle)", TypeName);
sw.WriteLine ("\t\t{");
if (is32BitNotSupported) {
sw.WriteLine ("\t\t#if ARCH_32");
sw.WriteLine ("\t\t\tthrow new PlatformNotSupportedException (\"This API is not supported on this version of iOS\");");
sw.WriteLine ("\t\t#else");
}
if (is_direct_binding_value != null)
sw.WriteLine ("\t\t\tIsDirectBinding = {0};", is_direct_binding_value);
if (is32BitNotSupported)
sw.WriteLine ("\t\t#endif");
WriteMarkDirtyIfDerived (sw, type);
sw.WriteLine ("\t\t}");
sw.WriteLine ();
Expand Down
23 changes: 23 additions & 0 deletions tests/monotouch-test/UIKit/KeyCommandTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;

using Foundation;
using ObjCRuntime;
using UIKit;

using NUnit.Framework;

namespace MonoTouchFixtures.UIKit {

[TestFixture]
[Preserve (AllMembers = true)]
public class KeyCommandTest {

[Test]
public void Create ()
{
using (var key = new NSString ("a")) {
Assert.NotNull (UIKeyCommand.Create (key, UIKeyModifierFlags.Command, new Selector ("foo")), "Create");
}
}
}
}

0 comments on commit 45b23f9

Please sign in to comment.