From 19eb4a5ed0a697bab61ad46033fdbd1d30461d1a Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 18 Sep 2020 17:54:36 +0200 Subject: [PATCH 1/2] [dotnet-linker] Add a CollectUnmarkedMembersStep that will keep linked away types around for the static registrar. The static registrar may need access to types that have been linked away, so store unmarked types so that the static registrar can access them later. This also makes all the monotouch-test variations green, so enable them all. Fixes this monotouch-test when all optimizations are enabled: MonoTouchFixtures.ObjCRuntime.RegistrarTest [FAIL] TestProtocolRegistration : UIApplicationDelegate/17669 Expected: True But was: False at MonoTouchFixtures.ObjCRuntime.RegistrarTest.TestProtocolRegistration() in xamarin-macios/tests/monotouch-test/ObjCRuntime/RegistrarTest.cs:line 1350 --- .../xharness/Jenkins/TestVariationsFactory.cs | 2 - tools/dotnet-linker/SetupStep.cs | 1 + .../Steps/CollectUnmarkedMembers.cs | 37 +++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tools/dotnet-linker/Steps/CollectUnmarkedMembers.cs diff --git a/tests/xharness/Jenkins/TestVariationsFactory.cs b/tests/xharness/Jenkins/TestVariationsFactory.cs index e29c711ba722..438adb5157b5 100644 --- a/tests/xharness/Jenkins/TestVariationsFactory.cs +++ b/tests/xharness/Jenkins/TestVariationsFactory.cs @@ -60,8 +60,6 @@ IEnumerable GetTestData (RunTestTask test) switch (test.TestName) { case "monotouch-test": - if (test.TestProject.IsDotNetProject) - ignore = true; if (supports_dynamic_registrar_on_device) yield return new TestData { Variation = "Debug (dynamic registrar)", MTouchExtraArgs = "--registrar:dynamic", Debug = true, Profiling = false, Ignored = ignore }; yield return new TestData { Variation = "Release (all optimizations)", MTouchExtraArgs = "--registrar:static --optimize:all", Debug = false, Profiling = false, Defines = "OPTIMIZEALL", Ignored = ignore }; diff --git a/tools/dotnet-linker/SetupStep.cs b/tools/dotnet-linker/SetupStep.cs index b185524575eb..3e5d13f98d0d 100644 --- a/tools/dotnet-linker/SetupStep.cs +++ b/tools/dotnet-linker/SetupStep.cs @@ -77,6 +77,7 @@ protected override void Process () prelink_substeps.Add (new OptimizeGeneratedCodeSubStep ()); prelink_substeps.Add (new MarkNSObjects ()); prelink_substeps.Add (new PreserveSmartEnumConversionsSubStep ()); + prelink_substeps.Add (new CollectUnmarkedMembersSubStep ()); post_sweep_substeps.Add (new RemoveAttributesStep ()); } diff --git a/tools/dotnet-linker/Steps/CollectUnmarkedMembers.cs b/tools/dotnet-linker/Steps/CollectUnmarkedMembers.cs new file mode 100644 index 000000000000..73ab545d9b6e --- /dev/null +++ b/tools/dotnet-linker/Steps/CollectUnmarkedMembers.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; + +using Mono.Cecil; +using Mono.Linker.Steps; + +namespace Xamarin.Linker { + // The static registrar may need access to information that has been linked away, + // in particular types and interfaces, so we need to store those somewhere + // so that the static registrar can access them. + public class CollectUnmarkedMembersSubStep : ConfigurationAwareSubStep { + Dictionary> ProtocolImplementations => Configuration.DerivedLinkContext.ProtocolImplementations; + + public override SubStepTargets Targets { + get { + return SubStepTargets.Type; + } + } + + public override void ProcessType (TypeDefinition type) + { + if (!Annotations.IsMarked (type)) + LinkContext.AddLinkedAwayType (type); + + if (type.HasInterfaces) { + foreach (var iface in type.Interfaces) { + if (Annotations.IsMarked (iface)) + continue; + + // This interface might be removed, so save it + if (!ProtocolImplementations.TryGetValue (type, out var list)) + ProtocolImplementations [type] = list = new List (); + list.Add (iface.InterfaceType.Resolve ()); + } + } + } + } +} From 28e697a1a7c63518ee8a0ea8b8b673101b0d2cbd Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 29 Sep 2020 14:17:57 +0200 Subject: [PATCH 2/2] Unignore the right configuration. --- tests/xharness/Jenkins/TestVariationsFactory.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/xharness/Jenkins/TestVariationsFactory.cs b/tests/xharness/Jenkins/TestVariationsFactory.cs index 438adb5157b5..0a22dd6ce0f8 100644 --- a/tests/xharness/Jenkins/TestVariationsFactory.cs +++ b/tests/xharness/Jenkins/TestVariationsFactory.cs @@ -60,6 +60,8 @@ IEnumerable GetTestData (RunTestTask test) switch (test.TestName) { case "monotouch-test": + if (test.TestProject.IsDotNetProject) + ignore = true; if (supports_dynamic_registrar_on_device) yield return new TestData { Variation = "Debug (dynamic registrar)", MTouchExtraArgs = "--registrar:dynamic", Debug = true, Profiling = false, Ignored = ignore }; yield return new TestData { Variation = "Release (all optimizations)", MTouchExtraArgs = "--registrar:static --optimize:all", Debug = false, Profiling = false, Defines = "OPTIMIZEALL", Ignored = ignore }; @@ -91,8 +93,6 @@ IEnumerable GetTestData (RunTestTask test) case "iPhoneSimulator": switch (test.TestName) { case "monotouch-test": - if (test.TestProject.IsDotNetProject) - ignore = true; // The default is to run monotouch-test with the dynamic registrar (in the simulator), so that's already covered yield return new TestData { Variation = "Debug (LinkSdk)", Debug = true, Profiling = false, LinkMode = "LinkSdk", Ignored = ignore }; yield return new TestData { Variation = "Debug (static registrar)", MTouchExtraArgs = "--registrar:static", Debug = true, Profiling = false, Undefines = "DYNAMIC_REGISTRAR", Ignored = ignore };