diff --git a/docs/website/optimizations.md b/docs/website/optimizations.md index 18bf371fac..07baa6bf1a 100644 --- a/docs/website/optimizations.md +++ b/docs/website/optimizations.md @@ -755,3 +755,17 @@ disabling the managed linker. The default behavior can be overridden by passing `--optimize=[+|-]custom-attributes-removal` to `mtouch` or `mmp`. + +## Experimental Xamarin.Forms.Platform.iOS ProductType inclusion + +This optimization requires the linker to be enabled and is only applied +on `Xamarin.Forms.Platform.iOS.dll`. + +This is **experimental** and might be removed or replaced in future +versions of Xamarin.iOS. + +This optimization consider the assembly `Xamarin.Forms.Platform.iOS` as +a product assembly and does not automagically mark all `NSObject` +subclasses. This allows additional removes and optimizations to be +applied to the assembly, including the ability to remove `UIWebView` if +nothing else in the application requires it. diff --git a/tests/mmptest/src/MMPTest.cs b/tests/mmptest/src/MMPTest.cs index c1e3d03c63..e4eadefeac 100644 --- a/tests/mmptest/src/MMPTest.cs +++ b/tests/mmptest/src/MMPTest.cs @@ -622,7 +622,7 @@ namespace Xamarin.MMP.Tests "Full", }; var rv = TI.TestUnifiedExecutable (test, shouldFail: false); - rv.Messages.AssertWarning (132, $"Unknown optimization: '{opt}'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, trim-architectures, inline-is-arm64-calling-convention, cctor-beforefieldinit, custom-attributes-removal."); + rv.Messages.AssertWarning (132, $"Unknown optimization: '{opt}'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, trim-architectures, inline-is-arm64-calling-convention, cctor-beforefieldinit, custom-attributes-removal, experimental-xforms-product-type."); rv.Messages.AssertErrorCount (0); }); } diff --git a/tests/mtouch/MTouch.cs b/tests/mtouch/MTouch.cs index b2b045595c..a3fab9ba51 100644 --- a/tests/mtouch/MTouch.cs +++ b/tests/mtouch/MTouch.cs @@ -1773,7 +1773,7 @@ public class TestApp { mtouch.Linker = MTouchLinker.LinkSdk; mtouch.Optimize = new string [] { "foo" }; mtouch.AssertExecute (MTouchAction.BuildSim, "build"); - mtouch.AssertWarning (132, "Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, inline-runtime-arch, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, remove-dynamic-registrar, remove-unsupported-il-for-bitcode, inline-is-arm64-calling-convention, seal-and-devirtualize, cctor-beforefieldinit, custom-attributes-removal."); + mtouch.AssertWarning (132, "Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, inline-runtime-arch, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, remove-dynamic-registrar, remove-unsupported-il-for-bitcode, inline-is-arm64-calling-convention, seal-and-devirtualize, cctor-beforefieldinit, custom-attributes-removal, experimental-xforms-product-type."); } } @@ -3696,7 +3696,8 @@ public partial class NotificationService : UNNotificationServiceExtension mtouch.AssertWarning (2003, "Option '--optimize=seal-and-devirtualize' will be ignored since linking is disabled"); mtouch.AssertWarning (2003, "Option '--optimize=cctor-beforefieldinit' will be ignored since linking is disabled"); mtouch.AssertWarning (2003, "Option '--optimize=custom-attributes-removal' will be ignored since linking is disabled"); - mtouch.AssertWarningCount (14); + mtouch.AssertWarning (2003, "Option '--optimize=experimental-xforms-product-type' will be ignored since linking is disabled"); + mtouch.AssertWarningCount (15); } using (var mtouch = new MTouchTool ()) { diff --git a/tools/common/Optimizations.cs b/tools/common/Optimizations.cs index b1d724f4c9..d600fd250a 100644 --- a/tools/common/Optimizations.cs +++ b/tools/common/Optimizations.cs @@ -42,6 +42,7 @@ namespace Xamarin.Bundler #endif "cctor-beforefieldinit", "custom-attributes-removal", + "experimental-xforms-product-type", }; enum Opt @@ -62,6 +63,7 @@ namespace Xamarin.Bundler SealAndDevirtualize, StaticConstructorBeforeFieldInit, CustomAttributesRemoval, + ExperimentalFormsProductType, } bool? all; @@ -145,6 +147,11 @@ namespace Xamarin.Bundler set { values [(int) Opt.CustomAttributesRemoval] = value; } } + public bool? ExperimentalFormsProductType { + get { return values [(int) Opt.ExperimentalFormsProductType]; } + set { values [(int) Opt.ExperimentalFormsProductType] = value; } + } + public Optimizations () { values = new bool? [opt_names.Length]; diff --git a/tools/linker/MarkNSObjects.cs b/tools/linker/MarkNSObjects.cs index af4c10942f..0ab2fcfe82 100644 --- a/tools/linker/MarkNSObjects.cs +++ b/tools/linker/MarkNSObjects.cs @@ -33,6 +33,7 @@ using System; using Mono.Cecil; using Mono.Linker; using Mono.Tuner; +using Xamarin.Bundler; namespace Xamarin.Linker.Steps { @@ -151,9 +152,15 @@ namespace Xamarin.Linker.Steps { return (method.DeclaringType.Module.Assembly.Name.Name == ProductAssembly); } - static bool IsProductType (TypeDefinition type) + bool IsProductType (TypeDefinition type) { - return type.Module.Assembly.Name.Name == ProductAssembly; + var name = type.Module.Assembly.Name.Name; + switch (name) { + case "Xamarin.Forms.Platform.iOS": + return LinkContext.App.Optimizations.ExperimentalFormsProductType == true; + default: + return name == ProductAssembly; + } } } }