From 9c3ffb96ec3d49189ad4d84ce3722de94c18373d Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 19 Feb 2021 10:01:42 -0800 Subject: [PATCH 01/33] Build locally against new IMarkHandler interface --- Makefile | 5 +- NuGet.config | 1 + Xamarin.Android.code-workspace | 3 + .../FixAbstractMethods.cs | 325 ++++++++++++++++++ src/Microsoft.Android.Sdk.ILLink/SetupStep.cs | 17 +- .../SubStepDispatcher.cs | 2 +- .../MonoDroid.Tuner/FixAbstractMethodsStep.cs | 1 + .../Linker/MonoDroid.Tuner/MarkJavaObjects.cs | 2 +- .../Tasks/ResolveSdksTask.cs | 1 + src/monodroid/monodroid.targets | 1 + 10 files changed, 352 insertions(+), 6 deletions(-) create mode 100644 src/Microsoft.Android.Sdk.ILLink/FixAbstractMethods.cs diff --git a/Makefile b/Makefile index 9cd9c22c786..28285ad738b 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ V ?= 0 prefix = /usr/local -CONFIGURATION ?= Debug +CONFIGURATION ?= Release RUNTIME := $(shell which mono64 2> /dev/null && echo mono64 || echo mono) --debug=casts SOLUTION = Xamarin.Android.sln TEST_TARGETS = build-tools/scripts/RunTests.targets @@ -108,6 +108,9 @@ all-tests:: pack-dotnet:: $(call MSBUILD_BINLOG,pack-dotnet,$(_SLN_BUILD)) $(MSBUILD_FLAGS) Xamarin.Android.sln /t:PackDotNet +customstep:: + $(call MSBUILD_BINLOG,pack-customstep,$(_SLN_BUILD)) $(MSBUILD_FLAGS) build-tools/create-packs/Microsoft.Android.Sdk.proj /t:BuildILLinkCustomStep,ExtractWorkloadPacks + install:: @if [ ! -d "bin/$(CONFIGURATION)" ]; then \ echo "run 'make all' before you execute 'make install'!"; \ diff --git a/NuGet.config b/NuGet.config index 0a58edcda1e..399361b093e 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,6 +9,7 @@ + diff --git a/Xamarin.Android.code-workspace b/Xamarin.Android.code-workspace index 876a1499c09..80b8a7f50df 100644 --- a/Xamarin.Android.code-workspace +++ b/Xamarin.Android.code-workspace @@ -2,6 +2,9 @@ "folders": [ { "path": "." + }, + { + "path": "../net6-mobile-samples" } ], "settings": {} diff --git a/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethods.cs b/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethods.cs new file mode 100644 index 00000000000..e82581d1b61 --- /dev/null +++ b/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethods.cs @@ -0,0 +1,325 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Mono.Cecil; + +using Java.Interop.Tools.Cecil; + +using Mono.Linker; +using Mono.Linker.Steps; + +#if NET5_LINKER +using Microsoft.Android.Sdk.ILLink; +#else +using Mono.Tuner; +#endif + + +namespace Microsoft.Android.Sdk.ILLink +{ + public class FixAbstractMethodsHandler : IMarkHandler + { + readonly TypeDefinitionCache cache; + protected LinkContext Context { get; private set; } + protected AnnotationStore Annotations => Context?.Annotations; + + public FixAbstractMethodsHandler (TypeDefinitionCache cache) + { + this.cache = cache; + } + + public void Initialize (LinkContext context, MarkContext markContext) + { + Context = context; + markContext.RegisterMarkAssemblyAction (assembly => ProcessAssembly (assembly)); + } + + protected void ProcessAssembly (AssemblyDefinition assembly) + { + if (!Annotations.HasAction (assembly)) + Annotations.SetAction (assembly, AssemblyAction.Skip); + + if (IsProductOrSdkAssembly (assembly)) + return; + +#if !NET5_LINKER + CheckAppDomainUsageUnconditional (assembly, (string msg) => Context.LogMessage (MessageImportance.High, msg)); +#endif + + if (FixAbstractMethodsUnconditional (assembly)) { +#if !NET5_LINKER + Context.SafeReadSymbols (assembly); +#endif + AssemblyAction action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip; + if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) + Annotations.SetAction (assembly, AssemblyAction.Save); + var td = AbstractMethodErrorConstructor.DeclaringType.Resolve (); + Annotations.Mark (td); + Annotations.SetPreserve (td, TypePreserve.Nothing); + Annotations.AddPreservedMethod (td, AbstractMethodErrorConstructor.Resolve ()); + } + } + + +#if !NET5_LINKER + internal void CheckAppDomainUsage (AssemblyDefinition assembly, Action warn) + { + if (IsProductOrSdkAssembly (assembly)) + return; + + CheckAppDomainUsageUnconditional (assembly, warn); + } + + void CheckAppDomainUsageUnconditional (AssemblyDefinition assembly, Action warn) + { + if (!assembly.MainModule.HasTypeReference ("System.AppDomain")) + return; + + foreach (var mr in assembly.MainModule.GetMemberReferences ()) { + if (mr.ToString ().Contains ("System.AppDomain System.AppDomain::CreateDomain")) { + warn (string.Format ("warning XA2000: " + Xamarin.Android.Tasks.Properties.Resources.XA2000, assembly)); + break; + } + } + } +#endif + + internal bool FixAbstractMethods (AssemblyDefinition assembly) + { + return !IsProductOrSdkAssembly (assembly) && FixAbstractMethodsUnconditional (assembly); + } + + bool FixAbstractMethodsUnconditional (AssemblyDefinition assembly) + { + if (!assembly.MainModule.HasTypeReference ("Java.Lang.Object")) + return false; + + bool changed = false; + foreach (var type in assembly.MainModule.Types) { + if (MightNeedFix (type)) + changed |= FixAbstractMethods (type); + } + return changed; + } + + bool IsProductOrSdkAssembly (AssemblyDefinition assembly) + { + return Profile.IsSdkAssembly (assembly) || Profile.IsProductAssembly (assembly); + } + + bool MightNeedFix (TypeDefinition type) + { + return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", cache); + } + + static bool CompareTypes (TypeReference iType, TypeReference tType) + { + if (iType.IsGenericParameter) + return true; + + if (iType.IsArray) { + if (!tType.IsArray) + return false; + return CompareTypes (iType.GetElementType (), tType.GetElementType ()); + } + + if (iType.IsByReference) { + if (!tType.IsByReference) + return false; + return CompareTypes (iType.GetElementType (), tType.GetElementType ()); + } + + if (iType.Name != tType.Name) + return false; + + if (iType.Namespace != tType.Namespace) + return false; + + TypeDefinition iTypeDef = iType.Resolve (); + if (iTypeDef == null) + return false; + + TypeDefinition tTypeDef = tType.Resolve (); + if (tTypeDef == null) + return false; + + if (iTypeDef.Module.FullyQualifiedName != tTypeDef.Module.FullyQualifiedName) + return false; + + if (iType is Mono.Cecil.GenericInstanceType && tType is Mono.Cecil.GenericInstanceType) { + GenericInstanceType iGType = iType as GenericInstanceType; + GenericInstanceType tGType = tType as GenericInstanceType; + + if (iGType.GenericArguments.Count != tGType.GenericArguments.Count) + return false; + for (int i = 0; i < iGType.GenericArguments.Count; i++) { + if (iGType.GenericArguments [i].IsGenericParameter) + continue; + if (!CompareTypes (iGType.GenericArguments [i], tGType.GenericArguments [i])) + return false; + } + } + + return true; + } + + bool IsInOverrides (MethodDefinition iMethod, MethodDefinition tMethod) + { + if (!tMethod.HasOverrides) + return false; + + foreach (var o in tMethod.Overrides) + if (o != null && iMethod == o.Resolve ()) + return true; + + return false; + } + + bool HaveSameSignature (TypeReference iface, MethodDefinition iMethod, MethodDefinition tMethod) + { + if (IsInOverrides (iMethod, tMethod)) + return true; + + if (iMethod.Name != tMethod.Name) + return false; + + if (!CompareTypes (iMethod.MethodReturnType.ReturnType, tMethod.MethodReturnType.ReturnType)) + return false; + + if (iMethod.Parameters.Count != tMethod.Parameters.Count || iMethod.GenericParameters.Count != tMethod.GenericParameters.Count) + return false; + + if (iMethod.HasParameters) { + List m1p = new List (iMethod.Parameters); + List m2p = new List (tMethod.Parameters); + + for (int i = 0; i < m1p.Count; i++) { + if (!CompareTypes (m1p [i].ParameterType, m2p [i].ParameterType)) + return false; + } + } + + if (iMethod.HasGenericParameters) { + List m1p = new List (iMethod.GenericParameters); + List m2p = new List (tMethod.GenericParameters); + + for (int i = 0; i < m1p.Count; i++) + if (!CompareTypes (m1p [i], m2p [i])) + return false; + } + + return true; + } + + bool FixAbstractMethods (TypeDefinition type) + { + if (!type.HasInterfaces) + return false; + + bool rv = false; + List typeMethods = new List (type.Methods); + foreach (var baseType in type.GetBaseTypes (cache)) + typeMethods.AddRange (baseType.Methods); + + foreach (var ifaceInfo in type.Interfaces) { + var iface = ifaceInfo.InterfaceType; + var ifaceDef = iface.Resolve (); + if (ifaceDef == null) { + LogMessage ($"Unable to unresolve interface: {iface.FullName}"); + continue; + } + if (ifaceDef.HasGenericParameters) + continue; + + foreach (var iMethod in ifaceDef.Methods.Where (m => m.IsAbstract)) { + bool exists = false; + + foreach (var tMethod in typeMethods) { + if (HaveSameSignature (iface, iMethod, tMethod)) { + exists = true; + break; + } + } + + if (!exists) { + AddNewExceptionMethod (type, iMethod); + rv = true; + } + } + } + + return rv; + } + + TypeReference TryImportType (TypeDefinition declaringType, TypeReference type) + { + if (type.IsGenericParameter) + return type; + + return declaringType.Module.Import (type); + } + + void AddNewExceptionMethod (TypeDefinition type, MethodDefinition method) + { + var newMethod = new MethodDefinition (method.Name, (method.Attributes | MethodAttributes.Final) & ~MethodAttributes.Abstract, TryImportType (type, method.ReturnType)); + + foreach (var paramater in method.Parameters) + newMethod.Parameters.Add (new ParameterDefinition (paramater.Name, paramater.Attributes, TryImportType (type, paramater.ParameterType))); + + var ilP = newMethod.Body.GetILProcessor (); + + ilP.Append (ilP.Create (Mono.Cecil.Cil.OpCodes.Newobj, type.Module.Import (AbstractMethodErrorConstructor))); + ilP.Append (ilP.Create (Mono.Cecil.Cil.OpCodes.Throw)); + + type.Methods.Add (newMethod); + + LogMessage ($"Added method: {method} to type: {type.FullName} scope: {type.Scope}"); + } + + MethodReference abstractMethodErrorConstructor; + + MethodReference AbstractMethodErrorConstructor { + get { + if (abstractMethodErrorConstructor != null) + return abstractMethodErrorConstructor; + + var assembly = GetMonoAndroidAssembly (); + if (assembly != null) { + var errorException = assembly.MainModule.GetType ("Java.Lang.AbstractMethodError"); + if (errorException != null) { + foreach (var method in errorException.Methods) { + if (method.Name == ".ctor" && !method.HasParameters) { + abstractMethodErrorConstructor = method; + break; + } + } + } + } + + if (abstractMethodErrorConstructor == null) + throw new Exception ("Unable to find Java.Lang.AbstractMethodError constructor in Mono.Android assembly"); + + return abstractMethodErrorConstructor; + } + } + + public virtual void LogMessage (string message) + { + Context.LogMessage (message); + } + + protected virtual AssemblyDefinition GetMonoAndroidAssembly () + { +#if !NET5_LINKER + foreach (var assembly in Context.GetAssemblies ()) { + if (assembly.Name.Name == "Mono.Android") + return assembly; + } + return null; +#else + return Context.GetLoadedAssembly ("Mono.Android"); +#endif + } + } +} diff --git a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs index 3a12a92d450..6abbdd12c25 100644 --- a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs +++ b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs @@ -13,6 +13,7 @@ namespace Microsoft.Android.Sdk.ILLink class SetupStep : BaseStep { List _steps; + List _markHandlers; List Steps { get { @@ -28,6 +29,16 @@ List Steps { static MethodInfo getReferencedAssembliesMethod = typeof (LinkContext).GetMethod ("GetReferencedAssemblies", BindingFlags.Public | BindingFlags.Instance); + List MarkHandlers { + get { + if (_markHandlers == null) { + var pipeline = typeof (LinkContext).GetProperty ("Pipeline").GetGetMethod ().Invoke (Context, null); + _markHandlers = (List) pipeline.GetType ().GetProperty ("MarkHandlers").GetValue (pipeline); + } + return _markHandlers; + } + } + protected override void Process () { string tfmPaths; @@ -46,9 +57,9 @@ protected override void Process () subSteps2.Add (new PreserveRegistrations (cache)); subSteps2.Add (new PreserveJavaInterfaces ()); - InsertAfter (new FixAbstractMethodsStep (cache), "SetupStep"); - InsertAfter (subSteps2, "SetupStep"); - InsertAfter (subSteps1, "SetupStep"); + MarkHandlers.Add (subSteps1); + MarkHandlers.Add (subSteps2); + MarkHandlers.Add (new FixAbstractMethodsHandler (cache)); // temporary workaround: this call forces illink to process all the assemblies if (getReferencedAssembliesMethod == null) diff --git a/src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs b/src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs index 60a0fd08774..9dfd4120962 100644 --- a/src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs +++ b/src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs @@ -4,7 +4,7 @@ namespace Microsoft.Android.Sdk.ILLink { - public class SubStepDispatcher : Mono.Linker.Steps.SubStepsDispatcher + public class SubStepDispatcher : Mono.Linker.Steps.MarkHandlerDispatcher { } } diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index fa725c384f7..fd896ec6ceb 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -44,6 +44,7 @@ protected override void ProcessAssembly (AssemblyDefinition assembly) #if !NET5_LINKER Context.SafeReadSymbols (assembly); #endif + // TODO: fix this. AssemblyAction action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip; if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) Annotations.SetAction (assembly, AssemblyAction.Save); diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs index 4995981a4bc..001e06a697d 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs @@ -193,7 +193,7 @@ void PreserveInvoker (TypeDefinition type) if (invoker == null) return; - PreserveIntPtrConstructor (invoker); + PreserveIntPtrConstructor (invoker); // seems redundant. PreserveInterfaceMethods (type, invoker); } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveSdksTask.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveSdksTask.cs index 119ac921a23..8b08ae7bde0 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveSdksTask.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveSdksTask.cs @@ -74,6 +74,7 @@ public override bool RunTask () { // OS X: $prefix/lib/xamarin.android/xbuild/Xamarin/Android // Windows: %ProgramFiles(x86)%\MSBuild\Xamarin\Android + // Linux: !? if (string.IsNullOrEmpty (MonoAndroidToolsPath)) { MonoAndroidToolsPath = Path.GetDirectoryName (typeof (ResolveSdks).Assembly.Location); } diff --git a/src/monodroid/monodroid.targets b/src/monodroid/monodroid.targets index 9610c46361d..a45a135afe4 100644 --- a/src/monodroid/monodroid.targets +++ b/src/monodroid/monodroid.targets @@ -96,6 +96,7 @@ DependsOnTargets="_BuildAndroidRuntimesInputs" Inputs="@(_BuildAndroidRuntimesInputs)" Outputs="@(_BuildAndroidRuntimesOutputs)"> + Date: Mon, 22 Feb 2021 09:42:56 -0800 Subject: [PATCH 02/33] Fix up custom steps --- ...ethods.cs => FixAbstractMethodsHandler.cs} | 45 ++- .../MarkJavaObjects.cs | 299 ++++++++++++++++++ .../Microsoft.Android.Sdk.ILLink.csproj | 6 + .../PreserveApplications.cs | 102 ++++++ .../PreserveJavaExceptions.cs | 68 ++++ .../PreserveJavaInterfaces.cs | 23 +- .../PreserveRegistrations.cs | 31 +- src/Microsoft.Android.Sdk.ILLink/SetupStep.cs | 20 +- .../MonoDroid.Tuner/FixAbstractMethodsStep.cs | 1 + test.sh | 3 + 10 files changed, 550 insertions(+), 48 deletions(-) rename src/Microsoft.Android.Sdk.ILLink/{FixAbstractMethods.cs => FixAbstractMethodsHandler.cs} (88%) create mode 100644 src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs create mode 100644 src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs create mode 100644 src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs create mode 100755 test.sh diff --git a/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethods.cs b/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs similarity index 88% rename from src/Microsoft.Android.Sdk.ILLink/FixAbstractMethods.cs rename to src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs index e82581d1b61..a40f09949ee 100644 --- a/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethods.cs +++ b/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs @@ -32,36 +32,52 @@ public FixAbstractMethodsHandler (TypeDefinitionCache cache) public void Initialize (LinkContext context, MarkContext markContext) { Context = context; - markContext.RegisterMarkAssemblyAction (assembly => ProcessAssembly (assembly)); + markContext.RegisterMarkTypeAction (type => ProcessType (type)); } - protected void ProcessAssembly (AssemblyDefinition assembly) + bool ShouldProcessTypeFromAssembly (AssemblyDefinition assembly) { if (!Annotations.HasAction (assembly)) Annotations.SetAction (assembly, AssemblyAction.Skip); if (IsProductOrSdkAssembly (assembly)) - return; + return false; #if !NET5_LINKER CheckAppDomainUsageUnconditional (assembly, (string msg) => Context.LogMessage (MessageImportance.High, msg)); #endif - if (FixAbstractMethodsUnconditional (assembly)) { + if (!assembly.MainModule.HasTypeReference ("Java.Lang.Object")) + return false; + + return true; + } + + protected void ProcessType (TypeDefinition type) + { + var assembly = type.Module.Assembly; + if (!ShouldProcessTypeFromAssembly (assembly)) + return; + + bool changed = false; + if (!MightNeedFix (type)) + return; + + if (!FixAbstractMethods (type)) + return; + #if !NET5_LINKER - Context.SafeReadSymbols (assembly); + Context.SafeReadSymbols (assembly); #endif - AssemblyAction action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip; - if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) - Annotations.SetAction (assembly, AssemblyAction.Save); - var td = AbstractMethodErrorConstructor.DeclaringType.Resolve (); - Annotations.Mark (td); - Annotations.SetPreserve (td, TypePreserve.Nothing); - Annotations.AddPreservedMethod (td, AbstractMethodErrorConstructor.Resolve ()); - } + AssemblyAction action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip; + if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) + Annotations.SetAction (assembly, AssemblyAction.Save); + var td = AbstractMethodErrorConstructor.DeclaringType.Resolve (); + Annotations.Mark (td); + Annotations.SetPreserve (td, TypePreserve.Nothing); + Annotations.AddPreservedMethod (td, AbstractMethodErrorConstructor.Resolve ()); } - #if !NET5_LINKER internal void CheckAppDomainUsage (AssemblyDefinition assembly, Action warn) { @@ -85,6 +101,7 @@ void CheckAppDomainUsageUnconditional (AssemblyDefinition assembly, Action> module_types = new Dictionary> (); + + LinkContext context; + + public void Initialize (LinkContext context, MarkContext markContext) + { + this.context = context; + markContext.RegisterMarkTypeAction (type => ProcessType (type)); + } + + void ProcessType (TypeDefinition type) + { + // If this isn't a JLO or IJavaObject implementer, + // then we don't need to MarkJavaObjects + if (!type.ImplementsIJavaObject ()) + return; + + PreserveJavaObjectImplementation (type); + + if (IsImplementor (type)) + PreserveImplementor (type); + + // If a user overrode a method, we need to preserve it, + // because it won't be referenced anywhere, but it will + // be called from Java + if (IsUserType (type) && type.HasMethods) { + foreach (var method in type.Methods.Where (m => m.Overrides != null)) + PreserveMethod (type, method); + } + } + + void PreserveJavaObjectImplementation (TypeDefinition type) + { + PreserveIntPtrConstructor (type); + PreserveAttributeSetConstructor (type); + PreserveAdapter (type); + PreserveInvoker (type); + } + + void PreserveAttributeSetConstructor (TypeDefinition type) + { + if (!type.HasMethods) + return; + + foreach (var constructor in GetAttributeSetConstructors (type)) + PreserveMethod (type, constructor); + } + + static IEnumerable GetAttributeSetConstructors (TypeDefinition type) + { + foreach (MethodDefinition constructor in type.Methods.Where (m => m.IsConstructor)) { + if (!constructor.HasParameters) + continue; + + var parameters = constructor.Parameters; + + if (parameters.Count < 2 || parameters.Count > 3) + continue; + + if (parameters [0].ParameterType.FullName != "Android.Content.Context") + continue; + + if (parameters [1].ParameterType.FullName != "Android.Util.IAttributeSet") + continue; + + if (parameters.Count == 3 && parameters [2].ParameterType.FullName != "System.Int32") + continue; + + yield return constructor; + } + } + + void PreserveIntPtrConstructor (TypeDefinition type) + { + var constructor = GetIntPtrConstructor (type); + + if (constructor != null) + PreserveMethod (type, constructor); + + var constructor2 = GetNewIntPtrConstructor (type); + + if (constructor2 != null) + PreserveMethod (type, constructor2); + } + + static MethodDefinition GetIntPtrConstructor (TypeDefinition type) + { + if (!type.HasMethods) + return null; + + foreach (MethodDefinition constructor in type.Methods.Where (m => m.IsConstructor)) { + if (!constructor.HasParameters) + continue; + + if (constructor.Parameters.Count != 1 || constructor.Parameters[0].ParameterType.FullName != "System.IntPtr") + continue; + + return constructor; + } + + return null; + } + + static MethodDefinition GetNewIntPtrConstructor (TypeDefinition type) + { + if (!type.HasMethods) + return null; + + foreach (MethodDefinition constructor in type.Methods.Where (m => m.IsConstructor)) { + if (!constructor.HasParameters) + continue; + + if (constructor.Parameters.Count != 2 || constructor.Parameters[0].ParameterType.FullName != "System.IntPtr" + || constructor.Parameters[1].ParameterType.FullName != "Android.Runtime.JniHandleOwnership") + continue; + + return constructor; + } + + return null; + } + + void PreserveMethod (TypeDefinition type, MethodDefinition method) + { + context.Annotations.AddPreservedMethod (type, method); + } + + void PreserveAdapter (TypeDefinition type) + { + var adapter = PreserveHelperType (type, "Adapter"); + + if (adapter == null || !adapter.HasMethods) + return; + + foreach (MethodDefinition method in adapter.Methods) { + if (method.Name != "GetObject") + continue; + + if (method.Parameters.Count != 2) + continue; + + PreserveMethod (type, method); + } + } + + string TypeNameWithoutKey (string name) + { + var idx = name.IndexOf (", PublicKeyToken="); + if (idx > 0) + name = name.Substring (0, idx); + + return name; + } + + bool CheckInvokerType (TypeDefinition type, string name) + { + return TypeNameWithoutKey (name) == TypeNameWithoutKey ($"{ type.FullName}, { type.Module.Assembly.FullName}"); + } + + void PreserveInterfaceMethods (TypeDefinition type, TypeDefinition invoker) + { + foreach (var m in type.Methods.Where (m => !m.IsConstructor)) { + string methodAndType; + if (!m.TryGetRegisterMember (out methodAndType)) + continue; + + if (!methodAndType.Contains (":")) + continue; + + var values = methodAndType.Split (new char [] { ':' }, 2); + if (!CheckInvokerType (invoker, values [1])) + continue; + + foreach (var invokerMethod in invoker.Methods.Where (m => !m.IsConstructor)) { + if (invokerMethod.Name == values [0]) { + PreserveMethod (invoker, invokerMethod); + break; + } + } + } + } + + void PreserveInvoker (TypeDefinition type) + { + var invoker = PreserveHelperType (type, "Invoker"); + if (invoker == null) + return; + + PreserveIntPtrConstructor (invoker); // seems redundant. + PreserveInterfaceMethods (type, invoker); + } + + TypeDefinition PreserveHelperType (TypeDefinition type, string suffix) + { + var helper = GetHelperType (type, suffix); + if (helper != null) + PreserveConstructors (type, helper); + + return helper; + } + + TypeDefinition GetHelperType (TypeDefinition type, string suffix) + { + string fullname = type.FullName; + + if (type.HasGenericParameters) { + var pos = fullname.IndexOf ('`'); + if (pos == -1) + throw new ArgumentException (); + + fullname = fullname.Substring (0, pos) + suffix + fullname.Substring (pos); + } else + fullname = fullname + suffix; + + return FindType (type, fullname); + } + + // Keep a dictionary cache of all types in a module rather than + // looping through them on every lookup. + TypeDefinition FindType (TypeDefinition type, string fullname) + { + Dictionary types; + + if (!module_types.TryGetValue (type.Module, out types)) { + types = GetTypesInModule (type.Module); + module_types.Add (type.Module, types); + } + + TypeDefinition helper; + + if (types.TryGetValue (fullname, out helper)) + return helper; + + return null; + } + + static Dictionary GetTypesInModule (ModuleDefinition module) + { + var types = module.Types.ToDictionary (p => p.FullName); + + foreach (var t in module.Types) + AddNestedTypes (types, t); + + return types; + } + + static void AddNestedTypes (Dictionary types, TypeDefinition type) + { + if (!type.HasNestedTypes) + return; + + foreach (var t in type.NestedTypes) { + types.Add (t.FullName, t); + AddNestedTypes (types, t); + } + } + + void PreserveConstructors (TypeDefinition type, TypeDefinition helper) + { + if (!helper.HasMethods) + return; + + foreach (MethodDefinition ctor in helper.Methods.Where (m => m.IsConstructor)) + PreserveMethod (type, ctor); + } + + static bool IsImplementor (TypeDefinition type) + { + return type.Name.EndsWith ("Implementor") && type.Inherits ("Java.Lang.Object"); + } + + static bool IsUserType (TypeDefinition type) + { + return !MonoAndroidHelper.IsFrameworkAssembly (type.Module.Assembly.Name.Name + ".dll"); + } + + void PreserveImplementor (TypeDefinition type) + { + if (!type.HasMethods) + return; + + foreach (MethodDefinition method in type.Methods) + if (method.Name.EndsWith ("Handler")) + PreserveMethod (type, method); + } + } +} diff --git a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj index 8e12748a8f1..8f4f5e43c8f 100644 --- a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj +++ b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj @@ -24,6 +24,12 @@ + + + + + + diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs new file mode 100644 index 00000000000..5d44e64cf04 --- /dev/null +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections; +using System.Linq; + +using Mono.Linker; +using Mono.Linker.Steps; + +using Mono.Tuner; +using Mobile.Tuner; + +using Mono.Cecil; + +namespace MonoDroid.Tuner { + + public class PreserveApplications : IMarkHandler { + + LinkContext context; + + public void Initialize (LinkContext context, MarkContext markContext) + { + this.context = context; + markContext.RegisterMarkAssemblyAction (assembly => ProcessAssembly (assembly)); + markContext.RegisterMarkTypeAction (type => ProcessType (type)); + } + + bool IsActiveFor (AssemblyDefinition assembly) + { + return context.Annotations.GetAction (assembly) == AssemblyAction.Link; + } + + public void ProcessAssembly (AssemblyDefinition assembly) + { + if (!IsActiveFor (assembly)) + return; + + ProcessAttributeProvider (assembly); + } + + public void ProcessType (TypeDefinition type) + { + if (!IsActiveFor (type.Module.Assembly)) + return; + + if (!type.Inherits ("Android.App.Application")) + return; + + ProcessAttributeProvider (type); + } + + void ProcessAttributeProvider (ICustomAttributeProvider provider) + { + if (!provider.HasCustomAttributes) + return; + + const string ApplicationAttribute = "Android.App.ApplicationAttribute"; + + foreach (CustomAttribute attribute in provider.CustomAttributes) + if (attribute.Constructor.DeclaringType.FullName == ApplicationAttribute) + PreserveApplicationAttribute (attribute); + } + + void PreserveApplicationAttribute (CustomAttribute attribute) + { + PreserveTypeProperty (attribute, "BackupAgent"); + PreserveTypeProperty (attribute, "ManageSpaceActivity"); + } + + void PreserveTypeProperty (CustomAttribute attribute, string property) + { + if (!attribute.HasProperties) + return; + + var type_ref = (TypeReference) attribute.Properties.First (p => p.Name == property).Argument.Value; + if (type_ref == null) + return; + + var type = type_ref.Resolve (); + if (type == null) + return; + + PreserveDefaultConstructor (type); + } + + void PreserveDefaultConstructor (TypeDefinition type) + { + if (!type.HasMethods) + return; + + foreach (MethodDefinition ctor in type.Methods.Where (t => t.IsConstructor)) { + if (!ctor.IsStatic && !ctor.HasParameters) { + PreserveMethod (type, ctor); + break; + } + } + } + + void PreserveMethod (TypeDefinition type, MethodDefinition method) + { + context.Annotations.AddPreservedMethod (type, method); + } + } +} diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs new file mode 100644 index 00000000000..07e93515826 --- /dev/null +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections; +using System.Linq; + +using Mono.Linker; +using Mono.Linker.Steps; + +using Mono.Tuner; +using Mobile.Tuner; + +using Mono.Cecil; + +namespace MonoDroid.Tuner { + + public class PreserveJavaExceptions : IMarkHandler { + + LinkContext context; + + public void Initialize (LinkContext context, MarkContext markContext) + { + this.context = context; + markContext.RegisterMarkTypeAction (type => ProcessType (type)); + } + + void ProcessType (TypeDefinition type) + { + if (type.IsJavaException ()) + PreserveJavaException (type); + } + + void PreserveJavaException (TypeDefinition type) + { + PreserveStringConstructor (type); + } + + void PreserveStringConstructor (TypeDefinition type) + { + var constructor = GetStringConstructor (type); + if (constructor == null) + return; + + PreserveMethod (type, constructor); + } + + MethodDefinition GetStringConstructor (TypeDefinition type) + { + if (!type.HasMethods) + return null; + + foreach (MethodDefinition constructor in type.Methods.Where (m => m.IsConstructor)) { + if (!constructor.HasParameters) + continue; + + if (constructor.Parameters.Count != 1 || constructor.Parameters [0].ParameterType.FullName != "System.String") + continue; + + return constructor; + } + + return null; + } + + void PreserveMethod (TypeDefinition type, MethodDefinition method) + { + context.Annotations.AddPreservedMethod (type, method); + } + } +} diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs index 09745170d64..9fb4c68467c 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs @@ -1,20 +1,31 @@ using Mono.Cecil; +using Mono.Linker; using Mono.Linker.Steps; using MonoDroid.Tuner; namespace Microsoft.Android.Sdk.ILLink { - class PreserveJavaInterfaces : BaseSubStep + class PreserveJavaInterfaces : IMarkHandler { - public override bool IsActiveFor (AssemblyDefinition assembly) + LinkContext context; + + public void Initialize (LinkContext context, MarkContext markContext) { - return assembly.Name.Name == "Mono.Android" || assembly.MainModule.HasTypeReference ("Android.Runtime.IJavaObject"); + this.context = context; + markContext.RegisterMarkTypeAction (type => ProcessType (type)); } - public override SubStepTargets Targets { get { return SubStepTargets.Type; } } + bool IsActiveFor (AssemblyDefinition assembly) + { + return assembly.Name.Name == "Mono.Android" || assembly.MainModule.HasTypeReference ("Android.Runtime.IJavaObject"); + } - public override void ProcessType (TypeDefinition type) + void ProcessType (TypeDefinition type) { + // TODO: is there a way for this to happen outside of the Mono.Android assemblies? + if (!IsActiveFor (type.Module.Assembly)) + return; + // If we are preserving a Mono.Android interface, // preserve all members on the interface. if (!type.IsInterface) @@ -25,7 +36,7 @@ public override void ProcessType (TypeDefinition type) return; foreach (MethodReference method in type.Methods) - Annotations.AddPreservedMethod (type, method.Resolve ()); + context.Annotations.AddPreservedMethod (type, method.Resolve ()); } } } diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs index 304af3f1363..375f1b63918 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs @@ -10,34 +10,28 @@ namespace Microsoft.Android.Sdk.ILLink { - class PreserveRegistrations : BaseSubStep + class PreserveRegistrations : IMarkHandler { - delegate void AddPreservedMethodDelegate (AnnotationStore store, MethodDefinition key, MethodDefinition method); - - static readonly AddPreservedMethodDelegate addPreservedMethod; - readonly TypeDefinitionCache cache; + LinkContext context; + public PreserveRegistrations (TypeDefinitionCache cache) => this.cache = cache; - static PreserveRegistrations () + public void Initialize (LinkContext context, MarkContext markContext) { - // temporarily use reflection to get void AnnotationStore::AddPreservedMethod (MethodDefinition key, MethodDefinition method) - // this can be removed once we have newer Microsoft.NET.ILLink containing https://github.com/mono/linker/commit/e6dadc995a834603e1178f9a1918f0ae38056b29 - var method = typeof (AnnotationStore).GetMethod ("AddPreservedMethod", new Type [] { typeof (MethodDefinition), typeof (MethodDefinition) }); - addPreservedMethod = (AddPreservedMethodDelegate)(method != null ? Delegate.CreateDelegate (typeof (AddPreservedMethodDelegate), null, method, false) : null); + this.context = context; + markContext.RegisterMarkMethodAction (method => ProcessMethod (method)); } - public override bool IsActiveFor (AssemblyDefinition assembly) + bool IsActiveFor (AssemblyDefinition assembly) { - return addPreservedMethod != null && (assembly.Name.Name == "Mono.Android" || assembly.MainModule.HasTypeReference ("Android.Runtime.RegisterAttribute")); + return assembly.Name.Name == "Mono.Android" || assembly.MainModule.HasTypeReference ("Android.Runtime.RegisterAttribute"); } - public override SubStepTargets Targets { get { return SubStepTargets.Method; } } - bool PreserveJniMarshalMethods () { - if (Context.TryGetCustomData ("XAPreserveJniMarshalMethods", out var boolValue)) + if (context.TryGetCustomData ("XAPreserveJniMarshalMethods", out var boolValue)) return bool.Parse (boolValue); return false; @@ -78,8 +72,11 @@ void PreserveRegisteredMethod (TypeDefinition type, string member, MethodDefinit type = type.BaseType.Resolve (); } - public override void ProcessMethod (MethodDefinition method) + void ProcessMethod (MethodDefinition method) { + if (!IsActiveFor (method.Module.Assembly)) + return; + bool preserveJniMarshalMethodOnly = false; if (!method.TryGetRegisterMember (out var member, out var nativeMethod, out var signature)) { if (PreserveJniMarshalMethods () && @@ -105,7 +102,7 @@ public override void ProcessMethod (MethodDefinition method) void AddPreservedMethod (MethodDefinition key, MethodDefinition method) { - addPreservedMethod.Invoke (Context.Annotations, key, method); + context.Annotations.AddPreservedMethod (key, method); } } } diff --git a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs index 6abbdd12c25..a217fd07386 100644 --- a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs +++ b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs @@ -45,20 +45,18 @@ protected override void Process () if (Context.TryGetCustomData ("XATargetFrameworkDirectories", out tfmPaths)) Xamarin.Android.Tasks.MonoAndroidHelper.TargetFrameworkDirectories = tfmPaths.Split (new char [] { ';' }); - var subSteps1 = new SubStepDispatcher (); - subSteps1.Add (new ApplyPreserveAttribute ()); + var subSteps = new SubStepDispatcher (); + subSteps.Add (new ApplyPreserveAttribute ()); + subSteps.Add (new PreserveExportedTypes ()); + MarkHandlers.Add (subSteps); + MarkHandlers.Add (new MarkJavaObjects ()); + MarkHandlers.Add (new PreserveJavaExceptions ()); + MarkHandlers.Add (new PreserveApplications ()); var cache = new TypeDefinitionCache (); - var subSteps2 = new SubStepDispatcher (); - subSteps2.Add (new PreserveExportedTypes ()); - subSteps2.Add (new MarkJavaObjects ()); - subSteps2.Add (new PreserveJavaExceptions ()); - subSteps2.Add (new PreserveApplications ()); - subSteps2.Add (new PreserveRegistrations (cache)); - subSteps2.Add (new PreserveJavaInterfaces ()); + MarkHandlers.Add (new PreserveRegistrations (cache)); + MarkHandlers.Add (new PreserveJavaInterfaces ()); - MarkHandlers.Add (subSteps1); - MarkHandlers.Add (subSteps2); MarkHandlers.Add (new FixAbstractMethodsHandler (cache)); // temporary workaround: this call forces illink to process all the assemblies diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index fd896ec6ceb..45f406cef41 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -79,6 +79,7 @@ void CheckAppDomainUsageUnconditional (AssemblyDefinition assembly, Action Date: Wed, 3 Mar 2021 11:59:06 -0800 Subject: [PATCH 03/33] Update to latest interface --- src/Microsoft.Android.Sdk.ILLink/SetupStep.cs | 8 ++++---- src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs index a217fd07386..90a54844109 100644 --- a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs +++ b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs @@ -45,10 +45,10 @@ protected override void Process () if (Context.TryGetCustomData ("XATargetFrameworkDirectories", out tfmPaths)) Xamarin.Android.Tasks.MonoAndroidHelper.TargetFrameworkDirectories = tfmPaths.Split (new char [] { ';' }); - var subSteps = new SubStepDispatcher (); - subSteps.Add (new ApplyPreserveAttribute ()); - subSteps.Add (new PreserveExportedTypes ()); - MarkHandlers.Add (subSteps); + MarkHandlers.Add (new SubStepDispatcher (new List () { + new ApplyPreserveAttribute (), + new PreserveExportedTypes () + })); MarkHandlers.Add (new MarkJavaObjects ()); MarkHandlers.Add (new PreserveJavaExceptions ()); diff --git a/src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs b/src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs index 9dfd4120962..644295a9834 100644 --- a/src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs +++ b/src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs @@ -1,10 +1,14 @@ using System; using System.Collections.Generic; using System.Text; +using Mono.Linker.Steps; namespace Microsoft.Android.Sdk.ILLink { - public class SubStepDispatcher : Mono.Linker.Steps.MarkHandlerDispatcher + public class SubStepDispatcher : MarkSubStepsDispatcher { + public SubStepDispatcher (IEnumerable subSteps) : base (subSteps) + { + } } } From 8fd0cb3225a04cd546dee74db2f06fe0da8b95c7 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 3 Mar 2021 15:03:16 -0800 Subject: [PATCH 04/33] Cleanup --- Makefile | 5 +---- NuGet.config | 1 - Xamarin.Android.code-workspace | 3 --- .../FixAbstractMethodsHandler.cs | 6 ------ src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs | 2 +- .../Microsoft.Android.Sdk.ILLink.csproj | 10 ++++------ .../PreserveJavaInterfaces.cs | 1 - .../Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs | 4 +--- .../Linker/MonoDroid.Tuner/MarkJavaObjects.cs | 2 +- .../Tasks/ResolveSdksTask.cs | 1 - src/monodroid/monodroid.targets | 1 - test.sh | 3 --- 12 files changed, 8 insertions(+), 31 deletions(-) delete mode 100755 test.sh diff --git a/Makefile b/Makefile index 28285ad738b..9cd9c22c786 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ V ?= 0 prefix = /usr/local -CONFIGURATION ?= Release +CONFIGURATION ?= Debug RUNTIME := $(shell which mono64 2> /dev/null && echo mono64 || echo mono) --debug=casts SOLUTION = Xamarin.Android.sln TEST_TARGETS = build-tools/scripts/RunTests.targets @@ -108,9 +108,6 @@ all-tests:: pack-dotnet:: $(call MSBUILD_BINLOG,pack-dotnet,$(_SLN_BUILD)) $(MSBUILD_FLAGS) Xamarin.Android.sln /t:PackDotNet -customstep:: - $(call MSBUILD_BINLOG,pack-customstep,$(_SLN_BUILD)) $(MSBUILD_FLAGS) build-tools/create-packs/Microsoft.Android.Sdk.proj /t:BuildILLinkCustomStep,ExtractWorkloadPacks - install:: @if [ ! -d "bin/$(CONFIGURATION)" ]; then \ echo "run 'make all' before you execute 'make install'!"; \ diff --git a/NuGet.config b/NuGet.config index 399361b093e..0a58edcda1e 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,7 +9,6 @@ - diff --git a/Xamarin.Android.code-workspace b/Xamarin.Android.code-workspace index 80b8a7f50df..876a1499c09 100644 --- a/Xamarin.Android.code-workspace +++ b/Xamarin.Android.code-workspace @@ -2,9 +2,6 @@ "folders": [ { "path": "." - }, - { - "path": "../net6-mobile-samples" } ], "settings": {} diff --git a/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs b/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs index a40f09949ee..c179cf538e3 100644 --- a/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs +++ b/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs @@ -101,12 +101,6 @@ void CheckAppDomainUsageUnconditional (AssemblyDefinition assembly, Action - - - - - - + + + + diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs index 9fb4c68467c..b78ce6dd4d7 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs @@ -22,7 +22,6 @@ bool IsActiveFor (AssemblyDefinition assembly) void ProcessType (TypeDefinition type) { - // TODO: is there a way for this to happen outside of the Mono.Android assemblies? if (!IsActiveFor (type.Module.Assembly)) return; diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index 45f406cef41..08f02859309 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; @@ -44,7 +44,6 @@ protected override void ProcessAssembly (AssemblyDefinition assembly) #if !NET5_LINKER Context.SafeReadSymbols (assembly); #endif - // TODO: fix this. AssemblyAction action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip; if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) Annotations.SetAction (assembly, AssemblyAction.Save); @@ -79,7 +78,6 @@ void CheckAppDomainUsageUnconditional (AssemblyDefinition assembly, Action - Date: Wed, 3 Mar 2021 15:18:09 -0800 Subject: [PATCH 05/33] Remove unused code under defines --- .../FixAbstractMethodsHandler.cs | 43 ------------------- .../MonoDroid.Tuner/ApplyPreserveAttribute.cs | 4 -- .../MonoDroid.Tuner/FixAbstractMethodsStep.cs | 3 -- 3 files changed, 50 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs b/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs index c179cf538e3..755beabc52c 100644 --- a/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs +++ b/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs @@ -9,12 +9,7 @@ using Mono.Linker; using Mono.Linker.Steps; -#if NET5_LINKER using Microsoft.Android.Sdk.ILLink; -#else -using Mono.Tuner; -#endif - namespace Microsoft.Android.Sdk.ILLink { @@ -43,10 +38,6 @@ bool ShouldProcessTypeFromAssembly (AssemblyDefinition assembly) if (IsProductOrSdkAssembly (assembly)) return false; -#if !NET5_LINKER - CheckAppDomainUsageUnconditional (assembly, (string msg) => Context.LogMessage (MessageImportance.High, msg)); -#endif - if (!assembly.MainModule.HasTypeReference ("Java.Lang.Object")) return false; @@ -66,9 +57,6 @@ protected void ProcessType (TypeDefinition type) if (!FixAbstractMethods (type)) return; -#if !NET5_LINKER - Context.SafeReadSymbols (assembly); -#endif AssemblyAction action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip; if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) Annotations.SetAction (assembly, AssemblyAction.Save); @@ -78,29 +66,6 @@ protected void ProcessType (TypeDefinition type) Annotations.AddPreservedMethod (td, AbstractMethodErrorConstructor.Resolve ()); } -#if !NET5_LINKER - internal void CheckAppDomainUsage (AssemblyDefinition assembly, Action warn) - { - if (IsProductOrSdkAssembly (assembly)) - return; - - CheckAppDomainUsageUnconditional (assembly, warn); - } - - void CheckAppDomainUsageUnconditional (AssemblyDefinition assembly, Action warn) - { - if (!assembly.MainModule.HasTypeReference ("System.AppDomain")) - return; - - foreach (var mr in assembly.MainModule.GetMemberReferences ()) { - if (mr.ToString ().Contains ("System.AppDomain System.AppDomain::CreateDomain")) { - warn (string.Format ("warning XA2000: " + Xamarin.Android.Tasks.Properties.Resources.XA2000, assembly)); - break; - } - } - } -#endif - bool FixAbstractMethodsUnconditional (AssemblyDefinition assembly) { if (!assembly.MainModule.HasTypeReference ("Java.Lang.Object")) @@ -322,15 +287,7 @@ public virtual void LogMessage (string message) protected virtual AssemblyDefinition GetMonoAndroidAssembly () { -#if !NET5_LINKER - foreach (var assembly in Context.GetAssemblies ()) { - if (assembly.Name.Name == "Mono.Android") - return assembly; - } - return null; -#else return Context.GetLoadedAssembly ("Mono.Android"); -#endif } } } diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/ApplyPreserveAttribute.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/ApplyPreserveAttribute.cs index 20db8902d8c..9d8eb089366 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/ApplyPreserveAttribute.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/ApplyPreserveAttribute.cs @@ -8,10 +8,6 @@ using Mono.Cecil; -#if NET5_LINKER -using Microsoft.Android.Sdk.ILLink; -#endif - namespace MonoDroid.Tuner { public class ApplyPreserveAttribute : ApplyPreserveAttributeBase { diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index 08f02859309..3c095766955 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -10,9 +10,6 @@ using Mono.Linker.Steps; using Mono.Tuner; -#if NET5_LINKER -using Microsoft.Android.Sdk.ILLink; -#endif namespace MonoDroid.Tuner { From cc8a65428225f198600bab5e054c711498baffe4 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 10 Mar 2021 08:43:22 -0800 Subject: [PATCH 06/33] Fix whitespace --- src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs b/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs index 755beabc52c..ba4ee5a2809 100644 --- a/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs +++ b/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs @@ -49,7 +49,7 @@ protected void ProcessType (TypeDefinition type) var assembly = type.Module.Assembly; if (!ShouldProcessTypeFromAssembly (assembly)) return; - + bool changed = false; if (!MightNeedFix (type)) return; @@ -261,7 +261,7 @@ MethodReference AbstractMethodErrorConstructor { return abstractMethodErrorConstructor; var assembly = GetMonoAndroidAssembly (); - if (assembly != null) { + if (assembly != null) { var errorException = assembly.MainModule.GetType ("Java.Lang.AbstractMethodError"); if (errorException != null) { foreach (var method in errorException.Methods) { From 5d8d8979e59259ae1fc22f426b225e687fa6b54d Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 15 Mar 2021 17:49:34 -0700 Subject: [PATCH 07/33] Remove workaround --- src/Microsoft.Android.Sdk.ILLink/SetupStep.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs index 90a54844109..fcc2fe64fb5 100644 --- a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs +++ b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs @@ -27,8 +27,6 @@ List Steps { } } - static MethodInfo getReferencedAssembliesMethod = typeof (LinkContext).GetMethod ("GetReferencedAssemblies", BindingFlags.Public | BindingFlags.Instance); - List MarkHandlers { get { if (_markHandlers == null) { @@ -50,22 +48,15 @@ protected override void Process () new PreserveExportedTypes () })); + var cache = new TypeDefinitionCache (); MarkHandlers.Add (new MarkJavaObjects ()); MarkHandlers.Add (new PreserveJavaExceptions ()); MarkHandlers.Add (new PreserveApplications ()); - var cache = new TypeDefinitionCache (); MarkHandlers.Add (new PreserveRegistrations (cache)); MarkHandlers.Add (new PreserveJavaInterfaces ()); MarkHandlers.Add (new FixAbstractMethodsHandler (cache)); - // temporary workaround: this call forces illink to process all the assemblies - if (getReferencedAssembliesMethod == null) - throw new InvalidOperationException ($"Temporary linker workaround failed, {nameof (getReferencedAssembliesMethod)} is null."); - - foreach (var assembly in (IEnumerable)getReferencedAssembliesMethod.Invoke (Context, null)) - Context.LogMessage ($"Reference assembly to process: {assembly}"); - string proguardPath; if (Context.TryGetCustomData ("ProguardConfiguration", out proguardPath)) InsertAfter (new GenerateProguardConfiguration (proguardPath), "CleanStep"); From 6e941ee80e8060c2a08d9fc7d321ba374dde70ee Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 15 Mar 2021 17:49:46 -0700 Subject: [PATCH 08/33] Clean up targets --- .../Microsoft.Android.Sdk.ILLink.targets | 42 +++++++------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets index 6fe8cb3294d..5b2233562aa 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets @@ -13,6 +13,13 @@ This file contains the .NET 5-specific targets to customize ILLink Condition=" '$(PublishTrimmed)' == 'true' " AfterTargets="ComputeResolvedFilesToPublishList" DependsOnTargets="GetReferenceAssemblyPaths;_CreatePropertiesCache"> + + + <_TrimmerDefaultAction Condition=" '$(AndroidLinkMode)' == 'Full' ">link + <_TrimmerDumpDependencies Condition=" '$(LinkerDumpDependencies)' == 'true' ">true + + <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --verbose + link - - - - - - <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --verbose --deterministic --custom-data XATargetFrameworkDirectories="$(_XATargetFrameworkDirectories)" - <_AdditionalTaskAssemblyDirectory>$(XamarinSdkRootDirectory)tools/dotnet-linker/ - <_AdditionalTaskAssembly>$(_AdditionalTaskAssemblyDirectory)dotnet-linker.dll - - - <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --custom-data AddKeepAlivesStep="$(AndroidAddKeepAlives)" - - - <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --custom-data ProguardConfiguration="$(_ProguardProjectConfiguration)" - - - <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --custom-data AndroidLinkResources="$(AndroidLinkResources)" - - - <_ExtraTrimmerArgs>--dump-dependencies $(_ExtraTrimmerArgs)" - - + + <_TrimmerCustomData Include="XATargetFrameworkDirectories" Value="$(_XATargetFrameworkDirectories)" /> + <_TrimmerCustomData Condition=" '$(AndroidAddKeepAlives)' != '' " Include="AddKeepAlivesStep" Value="$(AndroidAddKeepAlives)" /> + <_TrimmerCustomData Condition=" '$(_ProguardProjectConfiguration)' != '' " Include="ProguardConfiguration" Value="$(_ProguardProjectConfiguration)" /> + <_TrimmerCustomData Condition=" '$(AndroidLinkResources)' != '' " Include="AndroidLinkResources" Value="$(AndroidLinkResources)" /> + <_TrimmerCustomSteps Include="$(MSBuildThisFileDirectory)..\tools\Microsoft.Android.Sdk.ILLink.dll"> MarkStep Microsoft.Android.Sdk.ILLink.SetupStep - - + <_PreserveLists Include="$(MSBuildThisFileDirectory)..\PreserveLists\*.xml" /> Date: Tue, 23 Mar 2021 14:25:30 -0700 Subject: [PATCH 09/33] Don't duplicate MonoDroid.Tuner steps Instead use ifdefs in the existing steps. --- .../FixAbstractMethodsHandler.cs | 293 ----------------- .../MarkJavaObjects.cs | 299 ------------------ .../Microsoft.Android.Sdk.ILLink.csproj | 4 - .../PreserveApplications.cs | 102 ------ .../PreserveJavaExceptions.cs | 68 ---- src/Microsoft.Android.Sdk.ILLink/SetupStep.cs | 2 +- .../MonoDroid.Tuner/FixAbstractMethodsStep.cs | 90 ++++-- .../Linker/MonoDroid.Tuner/MarkJavaObjects.cs | 28 +- .../MonoDroid.Tuner/PreserveApplications.cs | 48 ++- .../MonoDroid.Tuner/PreserveJavaExceptions.cs | 27 +- 10 files changed, 166 insertions(+), 795 deletions(-) delete mode 100644 src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs delete mode 100644 src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs delete mode 100644 src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs delete mode 100644 src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs diff --git a/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs b/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs deleted file mode 100644 index ba4ee5a2809..00000000000 --- a/src/Microsoft.Android.Sdk.ILLink/FixAbstractMethodsHandler.cs +++ /dev/null @@ -1,293 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using Mono.Cecil; - -using Java.Interop.Tools.Cecil; - -using Mono.Linker; -using Mono.Linker.Steps; - -using Microsoft.Android.Sdk.ILLink; - -namespace Microsoft.Android.Sdk.ILLink -{ - public class FixAbstractMethodsHandler : IMarkHandler - { - readonly TypeDefinitionCache cache; - protected LinkContext Context { get; private set; } - protected AnnotationStore Annotations => Context?.Annotations; - - public FixAbstractMethodsHandler (TypeDefinitionCache cache) - { - this.cache = cache; - } - - public void Initialize (LinkContext context, MarkContext markContext) - { - Context = context; - markContext.RegisterMarkTypeAction (type => ProcessType (type)); - } - - bool ShouldProcessTypeFromAssembly (AssemblyDefinition assembly) - { - if (!Annotations.HasAction (assembly)) - Annotations.SetAction (assembly, AssemblyAction.Skip); - - if (IsProductOrSdkAssembly (assembly)) - return false; - - if (!assembly.MainModule.HasTypeReference ("Java.Lang.Object")) - return false; - - return true; - } - - protected void ProcessType (TypeDefinition type) - { - var assembly = type.Module.Assembly; - if (!ShouldProcessTypeFromAssembly (assembly)) - return; - - bool changed = false; - if (!MightNeedFix (type)) - return; - - if (!FixAbstractMethods (type)) - return; - - AssemblyAction action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip; - if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) - Annotations.SetAction (assembly, AssemblyAction.Save); - var td = AbstractMethodErrorConstructor.DeclaringType.Resolve (); - Annotations.Mark (td); - Annotations.SetPreserve (td, TypePreserve.Nothing); - Annotations.AddPreservedMethod (td, AbstractMethodErrorConstructor.Resolve ()); - } - - bool FixAbstractMethodsUnconditional (AssemblyDefinition assembly) - { - if (!assembly.MainModule.HasTypeReference ("Java.Lang.Object")) - return false; - - bool changed = false; - foreach (var type in assembly.MainModule.Types) { - if (MightNeedFix (type)) - changed |= FixAbstractMethods (type); - } - return changed; - } - - bool IsProductOrSdkAssembly (AssemblyDefinition assembly) - { - return Profile.IsSdkAssembly (assembly) || Profile.IsProductAssembly (assembly); - } - - bool MightNeedFix (TypeDefinition type) - { - return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", cache); - } - - static bool CompareTypes (TypeReference iType, TypeReference tType) - { - if (iType.IsGenericParameter) - return true; - - if (iType.IsArray) { - if (!tType.IsArray) - return false; - return CompareTypes (iType.GetElementType (), tType.GetElementType ()); - } - - if (iType.IsByReference) { - if (!tType.IsByReference) - return false; - return CompareTypes (iType.GetElementType (), tType.GetElementType ()); - } - - if (iType.Name != tType.Name) - return false; - - if (iType.Namespace != tType.Namespace) - return false; - - TypeDefinition iTypeDef = iType.Resolve (); - if (iTypeDef == null) - return false; - - TypeDefinition tTypeDef = tType.Resolve (); - if (tTypeDef == null) - return false; - - if (iTypeDef.Module.FullyQualifiedName != tTypeDef.Module.FullyQualifiedName) - return false; - - if (iType is Mono.Cecil.GenericInstanceType && tType is Mono.Cecil.GenericInstanceType) { - GenericInstanceType iGType = iType as GenericInstanceType; - GenericInstanceType tGType = tType as GenericInstanceType; - - if (iGType.GenericArguments.Count != tGType.GenericArguments.Count) - return false; - for (int i = 0; i < iGType.GenericArguments.Count; i++) { - if (iGType.GenericArguments [i].IsGenericParameter) - continue; - if (!CompareTypes (iGType.GenericArguments [i], tGType.GenericArguments [i])) - return false; - } - } - - return true; - } - - bool IsInOverrides (MethodDefinition iMethod, MethodDefinition tMethod) - { - if (!tMethod.HasOverrides) - return false; - - foreach (var o in tMethod.Overrides) - if (o != null && iMethod == o.Resolve ()) - return true; - - return false; - } - - bool HaveSameSignature (TypeReference iface, MethodDefinition iMethod, MethodDefinition tMethod) - { - if (IsInOverrides (iMethod, tMethod)) - return true; - - if (iMethod.Name != tMethod.Name) - return false; - - if (!CompareTypes (iMethod.MethodReturnType.ReturnType, tMethod.MethodReturnType.ReturnType)) - return false; - - if (iMethod.Parameters.Count != tMethod.Parameters.Count || iMethod.GenericParameters.Count != tMethod.GenericParameters.Count) - return false; - - if (iMethod.HasParameters) { - List m1p = new List (iMethod.Parameters); - List m2p = new List (tMethod.Parameters); - - for (int i = 0; i < m1p.Count; i++) { - if (!CompareTypes (m1p [i].ParameterType, m2p [i].ParameterType)) - return false; - } - } - - if (iMethod.HasGenericParameters) { - List m1p = new List (iMethod.GenericParameters); - List m2p = new List (tMethod.GenericParameters); - - for (int i = 0; i < m1p.Count; i++) - if (!CompareTypes (m1p [i], m2p [i])) - return false; - } - - return true; - } - - bool FixAbstractMethods (TypeDefinition type) - { - if (!type.HasInterfaces) - return false; - - bool rv = false; - List typeMethods = new List (type.Methods); - foreach (var baseType in type.GetBaseTypes (cache)) - typeMethods.AddRange (baseType.Methods); - - foreach (var ifaceInfo in type.Interfaces) { - var iface = ifaceInfo.InterfaceType; - var ifaceDef = iface.Resolve (); - if (ifaceDef == null) { - LogMessage ($"Unable to unresolve interface: {iface.FullName}"); - continue; - } - if (ifaceDef.HasGenericParameters) - continue; - - foreach (var iMethod in ifaceDef.Methods.Where (m => m.IsAbstract)) { - bool exists = false; - - foreach (var tMethod in typeMethods) { - if (HaveSameSignature (iface, iMethod, tMethod)) { - exists = true; - break; - } - } - - if (!exists) { - AddNewExceptionMethod (type, iMethod); - rv = true; - } - } - } - - return rv; - } - - TypeReference TryImportType (TypeDefinition declaringType, TypeReference type) - { - if (type.IsGenericParameter) - return type; - - return declaringType.Module.Import (type); - } - - void AddNewExceptionMethod (TypeDefinition type, MethodDefinition method) - { - var newMethod = new MethodDefinition (method.Name, (method.Attributes | MethodAttributes.Final) & ~MethodAttributes.Abstract, TryImportType (type, method.ReturnType)); - - foreach (var paramater in method.Parameters) - newMethod.Parameters.Add (new ParameterDefinition (paramater.Name, paramater.Attributes, TryImportType (type, paramater.ParameterType))); - - var ilP = newMethod.Body.GetILProcessor (); - - ilP.Append (ilP.Create (Mono.Cecil.Cil.OpCodes.Newobj, type.Module.Import (AbstractMethodErrorConstructor))); - ilP.Append (ilP.Create (Mono.Cecil.Cil.OpCodes.Throw)); - - type.Methods.Add (newMethod); - - LogMessage ($"Added method: {method} to type: {type.FullName} scope: {type.Scope}"); - } - - MethodReference abstractMethodErrorConstructor; - - MethodReference AbstractMethodErrorConstructor { - get { - if (abstractMethodErrorConstructor != null) - return abstractMethodErrorConstructor; - - var assembly = GetMonoAndroidAssembly (); - if (assembly != null) { - var errorException = assembly.MainModule.GetType ("Java.Lang.AbstractMethodError"); - if (errorException != null) { - foreach (var method in errorException.Methods) { - if (method.Name == ".ctor" && !method.HasParameters) { - abstractMethodErrorConstructor = method; - break; - } - } - } - } - - if (abstractMethodErrorConstructor == null) - throw new Exception ("Unable to find Java.Lang.AbstractMethodError constructor in Mono.Android assembly"); - - return abstractMethodErrorConstructor; - } - } - - public virtual void LogMessage (string message) - { - Context.LogMessage (message); - } - - protected virtual AssemblyDefinition GetMonoAndroidAssembly () - { - return Context.GetLoadedAssembly ("Mono.Android"); - } - } -} diff --git a/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs b/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs deleted file mode 100644 index 2194bbcf1c4..00000000000 --- a/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs +++ /dev/null @@ -1,299 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Mono.Cecil; -using Mono.Linker; -using Mono.Linker.Steps; -using Mono.Tuner; -using Xamarin.Android.Tasks; - -namespace MonoDroid.Tuner { - - public class MarkJavaObjects : IMarkHandler { - Dictionary> module_types = new Dictionary> (); - - LinkContext context; - - public void Initialize (LinkContext context, MarkContext markContext) - { - this.context = context; - markContext.RegisterMarkTypeAction (type => ProcessType (type)); - } - - void ProcessType (TypeDefinition type) - { - // If this isn't a JLO or IJavaObject implementer, - // then we don't need to MarkJavaObjects - if (!type.ImplementsIJavaObject ()) - return; - - PreserveJavaObjectImplementation (type); - - if (IsImplementor (type)) - PreserveImplementor (type); - - // If a user overrode a method, we need to preserve it, - // because it won't be referenced anywhere, but it will - // be called from Java - if (IsUserType (type) && type.HasMethods) { - foreach (var method in type.Methods.Where (m => m.Overrides != null)) - PreserveMethod (type, method); - } - } - - void PreserveJavaObjectImplementation (TypeDefinition type) - { - PreserveIntPtrConstructor (type); - PreserveAttributeSetConstructor (type); - PreserveAdapter (type); - PreserveInvoker (type); - } - - void PreserveAttributeSetConstructor (TypeDefinition type) - { - if (!type.HasMethods) - return; - - foreach (var constructor in GetAttributeSetConstructors (type)) - PreserveMethod (type, constructor); - } - - static IEnumerable GetAttributeSetConstructors (TypeDefinition type) - { - foreach (MethodDefinition constructor in type.Methods.Where (m => m.IsConstructor)) { - if (!constructor.HasParameters) - continue; - - var parameters = constructor.Parameters; - - if (parameters.Count < 2 || parameters.Count > 3) - continue; - - if (parameters [0].ParameterType.FullName != "Android.Content.Context") - continue; - - if (parameters [1].ParameterType.FullName != "Android.Util.IAttributeSet") - continue; - - if (parameters.Count == 3 && parameters [2].ParameterType.FullName != "System.Int32") - continue; - - yield return constructor; - } - } - - void PreserveIntPtrConstructor (TypeDefinition type) - { - var constructor = GetIntPtrConstructor (type); - - if (constructor != null) - PreserveMethod (type, constructor); - - var constructor2 = GetNewIntPtrConstructor (type); - - if (constructor2 != null) - PreserveMethod (type, constructor2); - } - - static MethodDefinition GetIntPtrConstructor (TypeDefinition type) - { - if (!type.HasMethods) - return null; - - foreach (MethodDefinition constructor in type.Methods.Where (m => m.IsConstructor)) { - if (!constructor.HasParameters) - continue; - - if (constructor.Parameters.Count != 1 || constructor.Parameters[0].ParameterType.FullName != "System.IntPtr") - continue; - - return constructor; - } - - return null; - } - - static MethodDefinition GetNewIntPtrConstructor (TypeDefinition type) - { - if (!type.HasMethods) - return null; - - foreach (MethodDefinition constructor in type.Methods.Where (m => m.IsConstructor)) { - if (!constructor.HasParameters) - continue; - - if (constructor.Parameters.Count != 2 || constructor.Parameters[0].ParameterType.FullName != "System.IntPtr" - || constructor.Parameters[1].ParameterType.FullName != "Android.Runtime.JniHandleOwnership") - continue; - - return constructor; - } - - return null; - } - - void PreserveMethod (TypeDefinition type, MethodDefinition method) - { - context.Annotations.AddPreservedMethod (type, method); - } - - void PreserveAdapter (TypeDefinition type) - { - var adapter = PreserveHelperType (type, "Adapter"); - - if (adapter == null || !adapter.HasMethods) - return; - - foreach (MethodDefinition method in adapter.Methods) { - if (method.Name != "GetObject") - continue; - - if (method.Parameters.Count != 2) - continue; - - PreserveMethod (type, method); - } - } - - string TypeNameWithoutKey (string name) - { - var idx = name.IndexOf (", PublicKeyToken="); - if (idx > 0) - name = name.Substring (0, idx); - - return name; - } - - bool CheckInvokerType (TypeDefinition type, string name) - { - return TypeNameWithoutKey (name) == TypeNameWithoutKey ($"{ type.FullName}, { type.Module.Assembly.FullName}"); - } - - void PreserveInterfaceMethods (TypeDefinition type, TypeDefinition invoker) - { - foreach (var m in type.Methods.Where (m => !m.IsConstructor)) { - string methodAndType; - if (!m.TryGetRegisterMember (out methodAndType)) - continue; - - if (!methodAndType.Contains (":")) - continue; - - var values = methodAndType.Split (new char [] { ':' }, 2); - if (!CheckInvokerType (invoker, values [1])) - continue; - - foreach (var invokerMethod in invoker.Methods.Where (m => !m.IsConstructor)) { - if (invokerMethod.Name == values [0]) { - PreserveMethod (invoker, invokerMethod); - break; - } - } - } - } - - void PreserveInvoker (TypeDefinition type) - { - var invoker = PreserveHelperType (type, "Invoker"); - if (invoker == null) - return; - - PreserveIntPtrConstructor (invoker); - PreserveInterfaceMethods (type, invoker); - } - - TypeDefinition PreserveHelperType (TypeDefinition type, string suffix) - { - var helper = GetHelperType (type, suffix); - if (helper != null) - PreserveConstructors (type, helper); - - return helper; - } - - TypeDefinition GetHelperType (TypeDefinition type, string suffix) - { - string fullname = type.FullName; - - if (type.HasGenericParameters) { - var pos = fullname.IndexOf ('`'); - if (pos == -1) - throw new ArgumentException (); - - fullname = fullname.Substring (0, pos) + suffix + fullname.Substring (pos); - } else - fullname = fullname + suffix; - - return FindType (type, fullname); - } - - // Keep a dictionary cache of all types in a module rather than - // looping through them on every lookup. - TypeDefinition FindType (TypeDefinition type, string fullname) - { - Dictionary types; - - if (!module_types.TryGetValue (type.Module, out types)) { - types = GetTypesInModule (type.Module); - module_types.Add (type.Module, types); - } - - TypeDefinition helper; - - if (types.TryGetValue (fullname, out helper)) - return helper; - - return null; - } - - static Dictionary GetTypesInModule (ModuleDefinition module) - { - var types = module.Types.ToDictionary (p => p.FullName); - - foreach (var t in module.Types) - AddNestedTypes (types, t); - - return types; - } - - static void AddNestedTypes (Dictionary types, TypeDefinition type) - { - if (!type.HasNestedTypes) - return; - - foreach (var t in type.NestedTypes) { - types.Add (t.FullName, t); - AddNestedTypes (types, t); - } - } - - void PreserveConstructors (TypeDefinition type, TypeDefinition helper) - { - if (!helper.HasMethods) - return; - - foreach (MethodDefinition ctor in helper.Methods.Where (m => m.IsConstructor)) - PreserveMethod (type, ctor); - } - - static bool IsImplementor (TypeDefinition type) - { - return type.Name.EndsWith ("Implementor") && type.Inherits ("Java.Lang.Object"); - } - - static bool IsUserType (TypeDefinition type) - { - return !MonoAndroidHelper.IsFrameworkAssembly (type.Module.Assembly.Name.Name + ".dll"); - } - - void PreserveImplementor (TypeDefinition type) - { - if (!type.HasMethods) - return; - - foreach (MethodDefinition method in type.Methods) - if (method.Name.EndsWith ("Handler")) - PreserveMethod (type, method); - } - } -} diff --git a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj index 911e7b1f459..8e12748a8f1 100644 --- a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj +++ b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj @@ -26,14 +26,10 @@ - - - - diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs deleted file mode 100644 index 5d44e64cf04..00000000000 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections; -using System.Linq; - -using Mono.Linker; -using Mono.Linker.Steps; - -using Mono.Tuner; -using Mobile.Tuner; - -using Mono.Cecil; - -namespace MonoDroid.Tuner { - - public class PreserveApplications : IMarkHandler { - - LinkContext context; - - public void Initialize (LinkContext context, MarkContext markContext) - { - this.context = context; - markContext.RegisterMarkAssemblyAction (assembly => ProcessAssembly (assembly)); - markContext.RegisterMarkTypeAction (type => ProcessType (type)); - } - - bool IsActiveFor (AssemblyDefinition assembly) - { - return context.Annotations.GetAction (assembly) == AssemblyAction.Link; - } - - public void ProcessAssembly (AssemblyDefinition assembly) - { - if (!IsActiveFor (assembly)) - return; - - ProcessAttributeProvider (assembly); - } - - public void ProcessType (TypeDefinition type) - { - if (!IsActiveFor (type.Module.Assembly)) - return; - - if (!type.Inherits ("Android.App.Application")) - return; - - ProcessAttributeProvider (type); - } - - void ProcessAttributeProvider (ICustomAttributeProvider provider) - { - if (!provider.HasCustomAttributes) - return; - - const string ApplicationAttribute = "Android.App.ApplicationAttribute"; - - foreach (CustomAttribute attribute in provider.CustomAttributes) - if (attribute.Constructor.DeclaringType.FullName == ApplicationAttribute) - PreserveApplicationAttribute (attribute); - } - - void PreserveApplicationAttribute (CustomAttribute attribute) - { - PreserveTypeProperty (attribute, "BackupAgent"); - PreserveTypeProperty (attribute, "ManageSpaceActivity"); - } - - void PreserveTypeProperty (CustomAttribute attribute, string property) - { - if (!attribute.HasProperties) - return; - - var type_ref = (TypeReference) attribute.Properties.First (p => p.Name == property).Argument.Value; - if (type_ref == null) - return; - - var type = type_ref.Resolve (); - if (type == null) - return; - - PreserveDefaultConstructor (type); - } - - void PreserveDefaultConstructor (TypeDefinition type) - { - if (!type.HasMethods) - return; - - foreach (MethodDefinition ctor in type.Methods.Where (t => t.IsConstructor)) { - if (!ctor.IsStatic && !ctor.HasParameters) { - PreserveMethod (type, ctor); - break; - } - } - } - - void PreserveMethod (TypeDefinition type, MethodDefinition method) - { - context.Annotations.AddPreservedMethod (type, method); - } - } -} diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs deleted file mode 100644 index 07e93515826..00000000000 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections; -using System.Linq; - -using Mono.Linker; -using Mono.Linker.Steps; - -using Mono.Tuner; -using Mobile.Tuner; - -using Mono.Cecil; - -namespace MonoDroid.Tuner { - - public class PreserveJavaExceptions : IMarkHandler { - - LinkContext context; - - public void Initialize (LinkContext context, MarkContext markContext) - { - this.context = context; - markContext.RegisterMarkTypeAction (type => ProcessType (type)); - } - - void ProcessType (TypeDefinition type) - { - if (type.IsJavaException ()) - PreserveJavaException (type); - } - - void PreserveJavaException (TypeDefinition type) - { - PreserveStringConstructor (type); - } - - void PreserveStringConstructor (TypeDefinition type) - { - var constructor = GetStringConstructor (type); - if (constructor == null) - return; - - PreserveMethod (type, constructor); - } - - MethodDefinition GetStringConstructor (TypeDefinition type) - { - if (!type.HasMethods) - return null; - - foreach (MethodDefinition constructor in type.Methods.Where (m => m.IsConstructor)) { - if (!constructor.HasParameters) - continue; - - if (constructor.Parameters.Count != 1 || constructor.Parameters [0].ParameterType.FullName != "System.String") - continue; - - return constructor; - } - - return null; - } - - void PreserveMethod (TypeDefinition type, MethodDefinition method) - { - context.Annotations.AddPreservedMethod (type, method); - } - } -} diff --git a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs index fcc2fe64fb5..ab1a6cabcf6 100644 --- a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs +++ b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs @@ -55,7 +55,7 @@ protected override void Process () MarkHandlers.Add (new PreserveRegistrations (cache)); MarkHandlers.Add (new PreserveJavaInterfaces ()); - MarkHandlers.Add (new FixAbstractMethodsHandler (cache)); + MarkHandlers.Add (new FixAbstractMethodsStep (cache)); string proguardPath; if (Context.TryGetCustomData ("ProguardConfiguration", out proguardPath)) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index 3c095766955..53577bb3546 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -10,49 +10,93 @@ using Mono.Linker.Steps; using Mono.Tuner; +#if NET5_LINKER +using Microsoft.Android.Sdk.ILLink; +#endif namespace MonoDroid.Tuner { /// /// NOTE: this step is subclassed so it can be called directly from Xamarin.Android.Build.Tasks /// - public class FixAbstractMethodsStep : BaseStep + public class FixAbstractMethodsStep +#if NET5_LINKER + : IMarkHandler +#else + : BaseStep +#endif { readonly TypeDefinitionCache cache; +#if NET5_LINKER + protected LinkContext Context { get; private set; } + protected AnnotationStore Annotations => Context?.Annotations; +#endif + public FixAbstractMethodsStep (TypeDefinitionCache cache) { this.cache = cache; } - protected override void ProcessAssembly (AssemblyDefinition assembly) +#if NET5_LINKER + public void Initialize (LinkContext context, MarkContext markContext) + { + Context = context; + markContext.RegisterMarkTypeAction (type => ProcessType (type)); + } +#endif + + bool CheckShouldProcessAssembly (AssemblyDefinition assembly) { if (!Annotations.HasAction (assembly)) Annotations.SetAction (assembly, AssemblyAction.Skip); if (IsProductOrSdkAssembly (assembly)) - return; + return false; #if !NET5_LINKER CheckAppDomainUsageUnconditional (assembly, (string msg) => Context.LogMessage (MessageImportance.High, msg)); #endif + return assembly.MainModule.HasTypeReference ("Java.Lang.Object"); + } + + void UpdateAssemblyAction (AssemblyDefinition assembly) + { + AssemblyAction action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip; + if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) + Annotations.SetAction (assembly, AssemblyAction.Save); + } + +#if NET5_LINKER + protected void ProcessType (TypeDefinition type) + { + var assembly = type.Module.Assembly; + if (!CheckShouldProcessAssembly (assembly)) + return; + + if (!MightNeedFix (type)) + return; + + if (!FixAbstractMethods (type)) + return; + + UpdateAssemblyAction (assembly); + MarkAbstractMethodErrorType (); + } +#else + protected override void ProcessAssembly (AssemblyDefinition assembly) + { + if (!CheckShouldProcessAssembly (assembly)) + return; + if (FixAbstractMethodsUnconditional (assembly)) { -#if !NET5_LINKER Context.SafeReadSymbols (assembly); -#endif - AssemblyAction action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip; - if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) - Annotations.SetAction (assembly, AssemblyAction.Save); - var td = AbstractMethodErrorConstructor.DeclaringType.Resolve (); - Annotations.Mark (td); - Annotations.SetPreserve (td, TypePreserve.Nothing); - Annotations.AddPreservedMethod (td, AbstractMethodErrorConstructor.Resolve ()); + UpdateAssemblyAction (assembly); + MarkAbstractMethodErrorType (); } } - -#if !NET5_LINKER internal void CheckAppDomainUsage (AssemblyDefinition assembly, Action warn) { if (IsProductOrSdkAssembly (assembly)) @@ -73,7 +117,6 @@ void CheckAppDomainUsageUnconditional (AssemblyDefinition assembly, Action> module_types = new Dictionary> (); +#if NET5_LINKER + AnnotationStore Annotations => context?.Annotations; + LinkContext context; +#else public override SubStepTargets Targets { get { return SubStepTargets.Type; } } +#endif - public override void ProcessType (TypeDefinition type) +#if NET5_LINKER + public void Initialize (LinkContext context, MarkContext markContext) + { + this.context = context; + markContext.RegisterMarkTypeAction (type => ProcessType (type)); + } +#endif + + public +#if !NET5_LINKER + override +#endif + void ProcessType (TypeDefinition type) { // If this isn't a JLO or IJavaObject implementer, // then we don't need to MarkJavaObjects diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs index 20db776258e..68cd4fcdf4d 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs @@ -12,26 +12,64 @@ namespace MonoDroid.Tuner { - public class PreserveApplications : BaseSubStep { - + public class PreserveApplications +#if NET5_LINKER + : IMarkHandler +#else + : BaseSubStep +#endif + { + +#if NET5_LINKER + LinkContext context; + AnnotationStore Annotations => context?.Annotations; + + public void Initialize (LinkContext context, MarkContext markContext) + { + this.context = context; + markContext.RegisterMarkAssemblyAction (assembly => ProcessAssembly (assembly)); + markContext.RegisterMarkTypeAction (type => ProcessType (type)); + } +#else public override SubStepTargets Targets { get { return SubStepTargets.Type | SubStepTargets.Assembly; } } +#endif - public override bool IsActiveFor (AssemblyDefinition assembly) + public +#if !NET5_LINKER + override +#endif + bool IsActiveFor (AssemblyDefinition assembly) { return Annotations.GetAction (assembly) == AssemblyAction.Link; } - public override void ProcessAssembly (AssemblyDefinition assembly) + public +#if !NET5_LINKER + override +#endif + void ProcessAssembly (AssemblyDefinition assembly) { +#if NET5_LINKER + if (!IsActiveFor (assembly)) + return; +#endif ProcessAttributeProvider (assembly); } - public override void ProcessType (TypeDefinition type) + public +#if !NET5_LINKER + override +#endif + void ProcessType (TypeDefinition type) { +#if NET5_LINKER + if (!IsActiveFor (type.Module.Assembly)) + return; +#endif if (!type.Inherits ("Android.App.Application")) return; diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs index 2356bdd4407..3ae1e1f8429 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs @@ -12,13 +12,34 @@ namespace MonoDroid.Tuner { - public class PreserveJavaExceptions : BaseSubStep { - + public class PreserveJavaExceptions +#if NET5_LINKER + : IMarkHandler +#else + : BaseSubStep +#endif + { + +#if NET5_LINKER + LinkContext context; + AnnotationStore Annotations => context?.Annotations; + + public void Initialize (LinkContext context, MarkContext markContext) + { + this.context = context; + markContext.RegisterMarkTypeAction (type => ProcessType (type)); + } +#else public override SubStepTargets Targets { get { return SubStepTargets.Type; } } +#endif - public override void ProcessType (TypeDefinition type) + public +#if !NET5_LINKER + override +#endif + void ProcessType (TypeDefinition type) { if (type.IsJavaException ()) PreserveJavaException (type); From e90b93a386ab1911f41ad02b585da662f4ab9b06 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 27 Apr 2021 11:03:05 -0700 Subject: [PATCH 10/33] Use LinkContext's type resolve cache This allows the custom steps to be added using the supported mechanism, one at a time, instead of injecting them using reflection. Depends on https://github.com/xamarin/xamarin-android/pull/5870. --- .../LinkContextExtensions.cs | 161 ++++++++++++++++++ .../Microsoft.Android.Sdk.ILLink.csproj | 3 - .../PreserveRegistrations.cs | 6 +- .../PreserveSubStepDispatcher.cs | 19 +++ src/Microsoft.Android.Sdk.ILLink/SetupStep.cs | 69 +------- .../SubStepDispatcher.cs | 14 -- .../MonoDroid.Tuner/AddKeepAlivesStep.cs | 9 + .../Linker/MonoDroid.Tuner/Extensions.cs | 29 +++- .../MonoDroid.Tuner/FixAbstractMethodsStep.cs | 30 ++-- .../GenerateProguardConfiguration.cs | 9 + .../Microsoft.Android.Sdk.ILLink.targets | 27 ++- 11 files changed, 266 insertions(+), 110 deletions(-) create mode 100644 src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs create mode 100644 src/Microsoft.Android.Sdk.ILLink/PreserveSubStepDispatcher.cs delete mode 100644 src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs diff --git a/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs b/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs new file mode 100644 index 00000000000..53448781477 --- /dev/null +++ b/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs @@ -0,0 +1,161 @@ +#nullable enable + +using Mono.Cecil; +using Mono.Collections.Generic; +using Mono.Linker; +using System.Collections.Generic; + +namespace Microsoft.Android.Sdk.ILLink +{ + public static class LinkContextExtensions + { + public static MethodDefinition GetBaseDefinition (this LinkContext context, MethodDefinition method) + { + if (method.IsStatic || method.IsNewSlot || !method.IsVirtual) + return method; + + foreach (var baseType in context.GetBaseTypes (method.DeclaringType)) { + foreach (var m in baseType.Methods) { + if (!m.IsConstructor && + m.Name == method.Name && + (m.IsVirtual || m.IsAbstract) && + context.AreParametersCompatibleWith (m.Parameters, method.Parameters)) { + return m; + } + } + } + return method; + } + + public static bool AreParametersCompatibleWith (this LinkContext context, Collection a, Collection b) + { + if (a.Count != b.Count) + return false; + + if (a.Count == 0) + return true; + + for (int i = 0; i < a.Count; i++) + if (!context.IsParameterCompatibleWith (a [i].ParameterType, b [i].ParameterType)) + return false; + + return true; + } + + static bool IsParameterCompatibleWith (this LinkContext context, IModifierType a, IModifierType b) + { + if (!context.IsParameterCompatibleWith (a.ModifierType, b.ModifierType)) + return false; + + return context.IsParameterCompatibleWith (a.ElementType, b.ElementType); + } + + static bool IsParameterCompatibleWith (this LinkContext context, TypeSpecification a, TypeSpecification b) + { + if (a is GenericInstanceType) + return context.IsParameterCompatibleWith ((GenericInstanceType) a, (GenericInstanceType) b); + + if (a is IModifierType) + return context.IsParameterCompatibleWith ((IModifierType) a, (IModifierType) b); + + return context.IsParameterCompatibleWith (a.ElementType, b.ElementType); + } + + static bool IsParameterCompatibleWith (this LinkContext context, GenericInstanceType a, GenericInstanceType b) + { + if (!context.IsParameterCompatibleWith (a.ElementType, b.ElementType)) + return false; + + if (a.GenericArguments.Count != b.GenericArguments.Count) + return false; + + if (a.GenericArguments.Count == 0) + return true; + + for (int i = 0; i < a.GenericArguments.Count; i++) + if (!context.IsParameterCompatibleWith (a.GenericArguments [i], b.GenericArguments [i])) + return false; + + return true; + } + + static bool IsParameterCompatibleWith (this LinkContext context, TypeReference a, TypeReference b) + { + if (a is TypeSpecification || b is TypeSpecification) { + if (a.GetType () != b.GetType ()) + return false; + + return context.IsParameterCompatibleWith ((TypeSpecification) a, (TypeSpecification) b); + } + + if (a.IsGenericParameter) { + if (b.IsGenericParameter && a.Name == b.Name) + return true; + var gpa = (GenericParameter) a; + foreach (var c in gpa.Constraints) { + if (!context.IsAssignableFrom (c.ConstraintType, b)) + return false; + } + return true; + } + + return a.FullName == b.FullName; + } + + public static TypeDefinition? GetBaseType (this LinkContext context, TypeDefinition type) + { + var bt = type.BaseType; + if (bt == null) + return null; + return context.ResolveTypeDefinition (bt); + } + + public static IEnumerable GetTypeAndBaseTypes (this LinkContext context, TypeDefinition type) + { + TypeDefinition? t = type; + + while (t != null) { + yield return t; + t = context.GetBaseType (t); + } + } + + public static IEnumerable GetBaseTypes (this LinkContext context, TypeDefinition type) + { + TypeDefinition? t = type; + + while ((t = context.GetBaseType (t)) != null) { + yield return t; + } + } + + public static bool IsAssignableFrom (this LinkContext context, TypeReference type, TypeReference c) + { + if (type.FullName == c.FullName) + return true; + var d = context.ResolveTypeDefinition (c); + if (d == null) + return false; + foreach (var t in context.GetTypeAndBaseTypes (d)) { + if (type.FullName == t.FullName) + return true; + foreach (var ifaceImpl in t.Interfaces) { + var i = ifaceImpl.InterfaceType; + if (context.IsAssignableFrom (type, i)) + return true; + } + } + return false; + } + + public static bool IsSubclassOf (this LinkContext context, TypeDefinition type, string typeName) + { + foreach (var t in context.GetTypeAndBaseTypes (type)) { + if (t.FullName == typeName) { + return true; + } + } + return false; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj index 8e12748a8f1..947a019eb84 100644 --- a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj +++ b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj @@ -41,9 +41,6 @@ - - - diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs index 375f1b63918..e4a8ab7a772 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs @@ -12,12 +12,8 @@ namespace Microsoft.Android.Sdk.ILLink { class PreserveRegistrations : IMarkHandler { - readonly TypeDefinitionCache cache; - LinkContext context; - public PreserveRegistrations (TypeDefinitionCache cache) => this.cache = cache; - public void Initialize (LinkContext context, MarkContext markContext) { this.context = context; @@ -81,7 +77,7 @@ void ProcessMethod (MethodDefinition method) if (!method.TryGetRegisterMember (out var member, out var nativeMethod, out var signature)) { if (PreserveJniMarshalMethods () && method.DeclaringType.GetMarshalMethodsType () != null && - method.TryGetBaseOrInterfaceRegisterMember (cache, out member, out nativeMethod, out signature)) { + context.TryGetBaseOrInterfaceRegisterMember (method, out member, out nativeMethod, out signature)) { preserveJniMarshalMethodOnly = true; } else { return; diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveSubStepDispatcher.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveSubStepDispatcher.cs new file mode 100644 index 00000000000..2abc6de5d46 --- /dev/null +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveSubStepDispatcher.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Mono.Linker.Steps; +using Mono.Tuner; + +namespace Microsoft.Android.Sdk.ILLink +{ + public class PreserveSubStepDispatcher : MarkSubStepsDispatcher + { + public PreserveSubStepDispatcher () + : base (new List () { + new ApplyPreserveAttribute (), + new PreserveExportedTypes () + }) + { + } + } +} diff --git a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs index ab1a6cabcf6..c8f56b575be 100644 --- a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs +++ b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs @@ -12,77 +12,10 @@ namespace Microsoft.Android.Sdk.ILLink { class SetupStep : BaseStep { - List _steps; - List _markHandlers; - - List Steps { - get { - if (_steps == null) { - var pipeline = typeof (LinkContext).GetProperty ("Pipeline").GetGetMethod ().Invoke (Context, null); - _steps = (List) pipeline.GetType ().GetField ("_steps", BindingFlags.Instance | BindingFlags.NonPublic).GetValue (pipeline); - //foreach (var step in _steps) - // Console.WriteLine ($"step: {step.GetType ().Name}"); - } - return _steps; - } - } - - List MarkHandlers { - get { - if (_markHandlers == null) { - var pipeline = typeof (LinkContext).GetProperty ("Pipeline").GetGetMethod ().Invoke (Context, null); - _markHandlers = (List) pipeline.GetType ().GetProperty ("MarkHandlers").GetValue (pipeline); - } - return _markHandlers; - } - } - protected override void Process () { - string tfmPaths; - if (Context.TryGetCustomData ("XATargetFrameworkDirectories", out tfmPaths)) + if (Context.TryGetCustomData ("XATargetFrameworkDirectories", out string tfmPaths)) Xamarin.Android.Tasks.MonoAndroidHelper.TargetFrameworkDirectories = tfmPaths.Split (new char [] { ';' }); - - MarkHandlers.Add (new SubStepDispatcher (new List () { - new ApplyPreserveAttribute (), - new PreserveExportedTypes () - })); - - var cache = new TypeDefinitionCache (); - MarkHandlers.Add (new MarkJavaObjects ()); - MarkHandlers.Add (new PreserveJavaExceptions ()); - MarkHandlers.Add (new PreserveApplications ()); - MarkHandlers.Add (new PreserveRegistrations (cache)); - MarkHandlers.Add (new PreserveJavaInterfaces ()); - - MarkHandlers.Add (new FixAbstractMethodsStep (cache)); - - string proguardPath; - if (Context.TryGetCustomData ("ProguardConfiguration", out proguardPath)) - InsertAfter (new GenerateProguardConfiguration (proguardPath), "CleanStep"); - - string addKeepAlivesStep; - if (Context.TryGetCustomData ("AddKeepAlivesStep", out addKeepAlivesStep) && bool.TryParse (addKeepAlivesStep, out var bv) && bv) - InsertAfter (new AddKeepAlivesStep (cache), "CleanStep"); - - string androidLinkResources; - if (Context.TryGetCustomData ("AndroidLinkResources", out androidLinkResources) && bool.TryParse (androidLinkResources, out var linkResources) && linkResources) { - InsertAfter (new RemoveResourceDesignerStep (), "CleanStep"); - InsertAfter (new GetAssembliesStep (), "CleanStep"); - } - InsertAfter (new StripEmbeddedLibraries (), "CleanStep"); - } - - void InsertAfter (IStep step, string stepName) - { - for (int i = 0; i < Steps.Count;) { - if (Steps [i++].GetType ().Name == stepName) { - Steps.Insert (i, step); - return; - } - } - - throw new InvalidOperationException ($"Could not insert {step} after {stepName}."); } } } diff --git a/src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs b/src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs deleted file mode 100644 index 644295a9834..00000000000 --- a/src/Microsoft.Android.Sdk.ILLink/SubStepDispatcher.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Mono.Linker.Steps; - -namespace Microsoft.Android.Sdk.ILLink -{ - public class SubStepDispatcher : MarkSubStepsDispatcher - { - public SubStepDispatcher (IEnumerable subSteps) : base (subSteps) - { - } - } -} diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs index d3e10d9a040..8939c24caac 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs @@ -10,17 +10,22 @@ using Mono.Linker.Steps; using Mono.Cecil.Cil; +#if NET5_LINKER +using Microsoft.Android.Sdk.ILLink; +#endif namespace MonoDroid.Tuner { public class AddKeepAlivesStep : BaseStep { +#if !NET5_LINKER readonly TypeDefinitionCache cache; public AddKeepAlivesStep (TypeDefinitionCache cache) { this.cache = cache; } +#endif protected override void ProcessAssembly (AssemblyDefinition assembly) { @@ -65,7 +70,11 @@ static void AddNestedTypes (List types, TypeDefinition type) bool MightNeedFix (TypeDefinition type) { +#if NET5_LINKER + return !type.IsAbstract && Context.IsSubclassOf (type, "Java.Lang.Object"); +#else return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", cache); +#endif } MethodDefinition methodKeepAlive = null; diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs index 9c5b53dacc7..e2792c89e33 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs @@ -11,6 +11,10 @@ using Java.Interop; using Java.Interop.Tools.Cecil; +#if NET5_LINKER +using Microsoft.Android.Sdk.ILLink; +#endif + namespace MonoDroid.Tuner { static class Extensions { @@ -255,7 +259,11 @@ public static TypeDefinition GetMarshalMethodsType (this TypeDefinition type) return null; } +#if NET5_LINKER + public static bool TryGetBaseOrInterfaceRegisterMember (this LinkContext context, MethodDefinition method, out string member, out string nativeMethod, out string signature) +#else public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition method, TypeDefinitionCache cache, out string member, out string nativeMethod, out string signature) +#endif { var type = method.DeclaringType; @@ -264,7 +272,11 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me if (method.IsConstructor || type == null || !type.HasNestedTypes) return false; +#if NET5_LINKER + var m = context.GetBaseDefinition (method); +#else var m = method.GetBaseDefinition (cache); +#endif while (m != null) { if (m == method) @@ -275,7 +287,11 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me if (m.TryGetRegisterMember (out member, out nativeMethod, out signature)) return true; +#if NET5_LINKER + context.GetBaseDefinition (m); +#else m = m.GetBaseDefinition (cache); +#endif } if (!method.DeclaringType.HasInterfaces || !method.IsNewSlot) @@ -290,19 +306,30 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me continue; foreach (var im in itype.Methods) +#if NET5_LINKER + if (context.IsEqual (im, method)) +#else if (im.IsEqual (method, cache)) +#endif return im.TryGetRegisterMember (out member, out nativeMethod, out signature); } return false; } +#if NET5_LINKER + public static bool IsEqual (this LinkContext context, MethodDefinition m1, MethodDefinition m2) +#else public static bool IsEqual (this MethodDefinition m1, MethodDefinition m2, TypeDefinitionCache cache) +#endif { if (m1.Name != m2.Name || m1.ReturnType.Name != m2.ReturnType.Name) return false; - +#if NET5_LINKER + return context.AreParametersCompatibleWith (m1.Parameters, m2.Parameters); +#else return m1.Parameters.AreParametersCompatibleWith (m2.Parameters, cache); +#endif } public static bool TryGetMarshalMethod (this MethodDefinition method, string nativeMethod, string signature, out MethodDefinition marshalMethod) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index 53577bb3546..ebcb3af727a 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -22,28 +22,24 @@ namespace MonoDroid.Tuner public class FixAbstractMethodsStep #if NET5_LINKER : IMarkHandler -#else - : BaseStep -#endif { - readonly TypeDefinitionCache cache; - -#if NET5_LINKER protected LinkContext Context { get; private set; } protected AnnotationStore Annotations => Context?.Annotations; -#endif - public FixAbstractMethodsStep (TypeDefinitionCache cache) - { - this.cache = cache; - } - -#if NET5_LINKER public void Initialize (LinkContext context, MarkContext markContext) { Context = context; markContext.RegisterMarkTypeAction (type => ProcessType (type)); } +#else + : BaseStep + { + readonly TypeDefinitionCache cache; + + public FixAbstractMethodsStep (TypeDefinitionCache cache) + { + this.cache = cache; + } #endif bool CheckShouldProcessAssembly (AssemblyDefinition assembly) @@ -141,7 +137,11 @@ bool IsProductOrSdkAssembly (AssemblyDefinition assembly) bool MightNeedFix (TypeDefinition type) { +#if NET5_LINKER + return !type.IsAbstract && Context.IsSubclassOf (type, "Java.Lang.Object"); +#else return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", cache); +#endif } static bool CompareTypes (TypeReference iType, TypeReference tType) @@ -250,7 +250,11 @@ bool FixAbstractMethods (TypeDefinition type) bool rv = false; List typeMethods = new List (type.Methods); +#if NET5_LINKER + foreach (var baseType in Context.GetBaseTypes (type)) +#else foreach (var baseType in type.GetBaseTypes (cache)) +#endif typeMethods.AddRange (baseType.Methods); foreach (var ifaceInfo in type.Interfaces) { diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs index a627f8143b8..e81cb800231 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs @@ -16,10 +16,19 @@ namespace Mono.Linker.Steps { public class GenerateProguardConfiguration : BaseStep { + +#if NET5_LINKER + public GenerateProguardConfiguration () + { + if (Context.TryGetCustomData ("ProguardConfiguration", out string proguardPath)) + this.filename = proguardPath; + } +#else public GenerateProguardConfiguration (string outputFileName) { this.filename = outputFileName; } +#endif string filename; TextWriter writer; diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets index 5b2233562aa..1d85f63330b 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets @@ -19,6 +19,7 @@ This file contains the .NET 5-specific targets to customize ILLink <_TrimmerDumpDependencies Condition=" '$(LinkerDumpDependencies)' == 'true' ">true <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --verbose + <_CustomStepDll>$(MSBuildThisFileDirectory)..\tools\Microsoft.Android.Sdk.ILLink.dll <_TrimmerCustomData Include="XATargetFrameworkDirectories" Value="$(_XATargetFrameworkDirectories)" /> - <_TrimmerCustomData Condition=" '$(AndroidAddKeepAlives)' != '' " Include="AddKeepAlivesStep" Value="$(AndroidAddKeepAlives)" /> <_TrimmerCustomData Condition=" '$(_ProguardProjectConfiguration)' != '' " Include="ProguardConfiguration" Value="$(_ProguardProjectConfiguration)" /> - <_TrimmerCustomData Condition=" '$(AndroidLinkResources)' != '' " Include="AndroidLinkResources" Value="$(AndroidLinkResources)" /> - <_TrimmerCustomSteps Include="$(MSBuildThisFileDirectory)..\tools\Microsoft.Android.Sdk.ILLink.dll"> - MarkStep - Microsoft.Android.Sdk.ILLink.SetupStep - + + <_TrimmerCustomSteps Include="$(_CustomStepDll)" BeforeStep="MarkStep" Type="Microsoft.Android.Sdk.ILLink.SetupStep" /> + + <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="Microsoft.Android.Sdk.ILLink.PreserveSubStepDispatcher" /> + <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="MonoDroid.Tuner.MarkJavaObjects" /> + <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="MonoDroid.Tuner.PreserveJavaExceptions" /> + <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="MonoDroid.Tuner.PreserveApplications" /> + <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="Microsoft.Android.Sdk.ILLink.PreserveRegistrations" /> + <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="Microsoft.Android.Sdk.ILLink.PreserveJavaInterfaces" /> + <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="MonoDroid.Tuner.FixAbstractMethodsStep" /> + + <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="Mono.Linker.Steps.GenerateProguardConfiguration" + Condition=" '$(_ProguardProjectConfiguration)' != '' " /> + <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="MonoDroid.Tuner.AddKeepAlivesStep" + Condition=" '$(AndroidAddKeepAlives)' == 'true' " /> + <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="MonoDroid.Tuner.RemoveResourceDesignerStep" + Condition=" '$(AndroidLinkResources)' == 'true' " /> + <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="MonoDroid.Tuner.GetAssembliesStep" + Condition=" '$(AndroidLinkResources)' == 'true' " /> + <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="MonoDroid.Tuner.StripEmbeddedLibraries" /> <_PreserveLists Include="$(MSBuildThisFileDirectory)..\PreserveLists\*.xml" /> Date: Tue, 27 Apr 2021 11:12:39 -0700 Subject: [PATCH 11/33] Undo TrimmerDefaultAction change This is being handled in https://github.com/xamarin/xamarin-android/pull/5878 --- .../targets/Microsoft.Android.Sdk.ILLink.targets | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets index 1d85f63330b..f3fb6a280d9 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets @@ -14,8 +14,6 @@ This file contains the .NET 5-specific targets to customize ILLink AfterTargets="ComputeResolvedFilesToPublishList" DependsOnTargets="GetReferenceAssemblyPaths;_CreatePropertiesCache"> - - <_TrimmerDefaultAction Condition=" '$(AndroidLinkMode)' == 'Full' ">link <_TrimmerDumpDependencies Condition=" '$(LinkerDumpDependencies)' == 'true' ">true <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --verbose @@ -26,6 +24,12 @@ This file contains the .NET 5-specific targets to customize ILLink Condition="'$(VSAndroidDesigner)' != ''" Value="$(VSAndroidDesigner)" Trim="true" /> + + From d6aaa38dfd3252f075cdfa5a21347c670dd92ed2 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 28 Apr 2021 10:33:34 -0700 Subject: [PATCH 12/33] PR feedback --- .../LinkContextExtensions.cs | 2 +- .../PreserveSubStepDispatcher.cs | 2 +- .../Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs b/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs index 53448781477..2e064aa5bc1 100644 --- a/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs +++ b/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs @@ -133,7 +133,7 @@ public static bool IsAssignableFrom (this LinkContext context, TypeReference typ { if (type.FullName == c.FullName) return true; - var d = context.ResolveTypeDefinition (c); + var d = context.TryResolveTypeDefinition (c); if (d == null) return false; foreach (var t in context.GetTypeAndBaseTypes (d)) { diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveSubStepDispatcher.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveSubStepDispatcher.cs index 2abc6de5d46..2e0937abe0e 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveSubStepDispatcher.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveSubStepDispatcher.cs @@ -9,7 +9,7 @@ namespace Microsoft.Android.Sdk.ILLink public class PreserveSubStepDispatcher : MarkSubStepsDispatcher { public PreserveSubStepDispatcher () - : base (new List () { + : base (new ISubStep[] { new ApplyPreserveAttribute (), new PreserveExportedTypes () }) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index ebcb3af727a..b5f5934d885 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -312,9 +312,9 @@ void AddNewExceptionMethod (TypeDefinition type, MethodDefinition method) LogMessage ($"Added method: {method} to type: {type.FullName} scope: {type.Scope}"); } - MethodReference abstractMethodErrorConstructor; + MethodDefinition abstractMethodErrorConstructor; - MethodReference AbstractMethodErrorConstructor { + MethodDefinition AbstractMethodErrorConstructor { get { if (abstractMethodErrorConstructor != null) return abstractMethodErrorConstructor; @@ -345,11 +345,12 @@ void MarkAbstractMethodErrorType () { if (markedAbstractMethodErrorType) return; markedAbstractMethodErrorType = true; - - var td = AbstractMethodErrorConstructor.DeclaringType.Resolve (); + + + var td = AbstractMethodErrorConstructor.DeclaringType; Annotations.Mark (td); Annotations.SetPreserve (td, TypePreserve.Nothing); - Annotations.AddPreservedMethod (td, AbstractMethodErrorConstructor.Resolve ()); + Annotations.AddPreservedMethod (td, AbstractMethodErrorConstructor); } public virtual void LogMessage (string message) From 41de20f903477d299cc9a9f68bdb224b4e2fb904 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Thu, 29 Apr 2021 15:06:04 -0700 Subject: [PATCH 13/33] PR feedback - fix formatting - clarify verbosity behavior - don't modify Skip or Delete assemblies --- .../LinkContextExtensions.cs | 10 +++++----- .../Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs | 2 +- .../targets/Microsoft.Android.Sdk.ILLink.targets | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs b/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs index 2e064aa5bc1..8995b2c3b1e 100644 --- a/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs +++ b/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs @@ -7,9 +7,9 @@ namespace Microsoft.Android.Sdk.ILLink { - public static class LinkContextExtensions - { - public static MethodDefinition GetBaseDefinition (this LinkContext context, MethodDefinition method) + public static class LinkContextExtensions + { + public static MethodDefinition GetBaseDefinition (this LinkContext context, MethodDefinition method) { if (method.IsStatic || method.IsNewSlot || !method.IsVirtual) return method; @@ -79,7 +79,7 @@ static bool IsParameterCompatibleWith (this LinkContext context, GenericInstance return true; } - static bool IsParameterCompatibleWith (this LinkContext context, TypeReference a, TypeReference b) + static bool IsParameterCompatibleWith (this LinkContext context, TypeReference a, TypeReference b) { if (a is TypeSpecification || b is TypeSpecification) { if (a.GetType () != b.GetType ()) @@ -157,5 +157,5 @@ public static bool IsSubclassOf (this LinkContext context, TypeDefinition type, } return false; } - } + } } \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index b5f5934d885..de1a279765c 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -60,7 +60,7 @@ bool CheckShouldProcessAssembly (AssemblyDefinition assembly) void UpdateAssemblyAction (AssemblyDefinition assembly) { AssemblyAction action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip; - if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete) + if (action == AssemblyAction.Copy) Annotations.SetAction (assembly, AssemblyAction.Save); } diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets index f3fb6a280d9..f1289a7030e 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets @@ -15,7 +15,8 @@ This file contains the .NET 5-specific targets to customize ILLink DependsOnTargets="GetReferenceAssemblyPaths;_CreatePropertiesCache"> <_TrimmerDumpDependencies Condition=" '$(LinkerDumpDependencies)' == 'true' ">true - + <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --verbose <_CustomStepDll>$(MSBuildThisFileDirectory)..\tools\Microsoft.Android.Sdk.ILLink.dll From e0c002e075f4d34d5b2d418be41553d510ee561a Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 30 Apr 2021 16:01:06 -0700 Subject: [PATCH 14/33] PR feedback - Don't check HasAction twice --- .../Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index de1a279765c..a097b2b0712 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -59,8 +59,7 @@ bool CheckShouldProcessAssembly (AssemblyDefinition assembly) void UpdateAssemblyAction (AssemblyDefinition assembly) { - AssemblyAction action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip; - if (action == AssemblyAction.Copy) + if (Annotations.GetAction (assembly) == AssemblyAction.Copy) Annotations.SetAction (assembly, AssemblyAction.Save); } From f26d8dd4c07142eb5c18a429dc8cb4a3919bc5f8 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 4 May 2021 14:25:15 -0700 Subject: [PATCH 15/33] Don't pass --verbose argument --- .../targets/Microsoft.Android.Sdk.ILLink.targets | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets index f1289a7030e..e33293aefce 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets @@ -15,9 +15,6 @@ This file contains the .NET 5-specific targets to customize ILLink DependsOnTargets="GetReferenceAssemblyPaths;_CreatePropertiesCache"> <_TrimmerDumpDependencies Condition=" '$(LinkerDumpDependencies)' == 'true' ">true - - <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --verbose <_CustomStepDll>$(MSBuildThisFileDirectory)..\tools\Microsoft.Android.Sdk.ILLink.dll From 3b616b63d9c20784d6b5a90c27102e5a37462e97 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 7 May 2021 16:25:36 +0000 Subject: [PATCH 16/33] Fix nullref in GenerateProguardConfiguration Context member isn't initialized until Process is called --- .../GenerateProguardConfiguration.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs index e81cb800231..4f80ddcbba9 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs @@ -17,13 +17,7 @@ namespace Mono.Linker.Steps { public class GenerateProguardConfiguration : BaseStep { -#if NET5_LINKER - public GenerateProguardConfiguration () - { - if (Context.TryGetCustomData ("ProguardConfiguration", out string proguardPath)) - this.filename = proguardPath; - } -#else +#if !NET5_LINKER public GenerateProguardConfiguration (string outputFileName) { this.filename = outputFileName; @@ -35,6 +29,10 @@ public GenerateProguardConfiguration (string outputFileName) protected override void Process () { +#if NET5_LINKER + if (Context.TryGetCustomData ("ProguardConfiguration", out string proguardPath)) + filename = proguardPath; +#endif var dir = Path.GetDirectoryName (filename); if (!Directory.Exists (dir)) Directory.CreateDirectory (dir); @@ -97,4 +95,3 @@ void ProcessMethod (MethodDefinition method) } } } - From cec24b8a7d3068f443c34510098b127bce5656d3 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 10 May 2021 21:22:38 +0000 Subject: [PATCH 17/33] Fix RemoveDesigner test This requires two steps which share state, so they can't be passed as separate --custom-step arguments yet. --- src/Microsoft.Android.Sdk.ILLink/SetupStep.cs | 34 +++++++++++++++++++ .../Microsoft.Android.Sdk.ILLink.targets | 5 +-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs index c8f56b575be..e1d7f453aee 100644 --- a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs +++ b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs @@ -12,10 +12,44 @@ namespace Microsoft.Android.Sdk.ILLink { class SetupStep : BaseStep { + List _steps; + + List Steps { + get { + if (_steps == null) { + var pipeline = typeof (LinkContext).GetProperty ("Pipeline").GetGetMethod ().Invoke (Context, null); + _steps = (List) pipeline.GetType ().GetField ("_steps", BindingFlags.Instance | BindingFlags.NonPublic).GetValue (pipeline); + //foreach (var step in _steps) + // Console.WriteLine ($"step: {step.GetType ().Name}"); + } + return _steps; + } + } + protected override void Process () { if (Context.TryGetCustomData ("XATargetFrameworkDirectories", out string tfmPaths)) Xamarin.Android.Tasks.MonoAndroidHelper.TargetFrameworkDirectories = tfmPaths.Split (new char [] { ';' }); + + // The following steps share state and must be injected via reflection until we get + // a linker with the fix from https://github.com/mono/linker/pull/2019. + string androidLinkResources; + if (Context.TryGetCustomData ("AndroidLinkResources", out androidLinkResources) && bool.TryParse (androidLinkResources, out var linkResources) && linkResources) { + InsertAfter (new RemoveResourceDesignerStep (), "CleanStep"); + InsertAfter (new GetAssembliesStep (), "CleanStep"); + } + } + + void InsertAfter (IStep step, string stepName) + { + for (int i = 0; i < Steps.Count;) { + if (Steps [i++].GetType ().Name == stepName) { + Steps.Insert (i, step); + return; + } + } + + throw new InvalidOperationException ($"Could not insert {step} after {stepName}."); } } } diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets index e33293aefce..645575b9dae 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets @@ -36,6 +36,7 @@ This file contains the .NET 5-specific targets to customize ILLink <_TrimmerCustomData Include="XATargetFrameworkDirectories" Value="$(_XATargetFrameworkDirectories)" /> <_TrimmerCustomData Condition=" '$(_ProguardProjectConfiguration)' != '' " Include="ProguardConfiguration" Value="$(_ProguardProjectConfiguration)" /> + <_TrimmerCustomData Conditiont=" '$(AndroidLinkResources)' != '' " Include="AndroidLinkResources" Value="$(AndroidLinkResources)" /> @@ -53,10 +54,6 @@ This file contains the .NET 5-specific targets to customize ILLink Condition=" '$(_ProguardProjectConfiguration)' != '' " /> <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="MonoDroid.Tuner.AddKeepAlivesStep" Condition=" '$(AndroidAddKeepAlives)' == 'true' " /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="MonoDroid.Tuner.RemoveResourceDesignerStep" - Condition=" '$(AndroidLinkResources)' == 'true' " /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="MonoDroid.Tuner.GetAssembliesStep" - Condition=" '$(AndroidLinkResources)' == 'true' " /> <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="MonoDroid.Tuner.StripEmbeddedLibraries" /> <_PreserveLists Include="$(MSBuildThisFileDirectory)..\PreserveLists\*.xml" /> From 3111a9414cdb394597ffc62599f0feafdee7e9e4 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Mon, 10 May 2021 23:57:03 +0000 Subject: [PATCH 18/33] Fix typo --- .../targets/Microsoft.Android.Sdk.ILLink.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets index 645575b9dae..963378541d4 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets @@ -36,7 +36,7 @@ This file contains the .NET 5-specific targets to customize ILLink <_TrimmerCustomData Include="XATargetFrameworkDirectories" Value="$(_XATargetFrameworkDirectories)" /> <_TrimmerCustomData Condition=" '$(_ProguardProjectConfiguration)' != '' " Include="ProguardConfiguration" Value="$(_ProguardProjectConfiguration)" /> - <_TrimmerCustomData Conditiont=" '$(AndroidLinkResources)' != '' " Include="AndroidLinkResources" Value="$(AndroidLinkResources)" /> + <_TrimmerCustomData Condition=" '$(AndroidLinkResources)' != '' " Include="AndroidLinkResources" Value="$(AndroidLinkResources)" /> From b1d9ec75af3df46ee9ba05db1c3b8b923cca620f Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 12 May 2021 15:45:27 +0000 Subject: [PATCH 19/33] _CustomStepDll -> _AndroidLinkerCustomStepAssembly --- .../Microsoft.Android.Sdk.ILLink.targets | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets index 963378541d4..e63c2af6b31 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets @@ -15,7 +15,7 @@ This file contains the .NET 5-specific targets to customize ILLink DependsOnTargets="GetReferenceAssemblyPaths;_CreatePropertiesCache"> <_TrimmerDumpDependencies Condition=" '$(LinkerDumpDependencies)' == 'true' ">true - <_CustomStepDll>$(MSBuildThisFileDirectory)..\tools\Microsoft.Android.Sdk.ILLink.dll + <_AndroidLinkerCustomStepAssembly>$(MSBuildThisFileDirectory)..\tools\Microsoft.Android.Sdk.ILLink.dll - <_TrimmerCustomSteps Include="$(_CustomStepDll)" BeforeStep="MarkStep" Type="Microsoft.Android.Sdk.ILLink.SetupStep" /> + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" BeforeStep="MarkStep" Type="Microsoft.Android.Sdk.ILLink.SetupStep" /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="Microsoft.Android.Sdk.ILLink.PreserveSubStepDispatcher" /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="MonoDroid.Tuner.MarkJavaObjects" /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="MonoDroid.Tuner.PreserveJavaExceptions" /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="MonoDroid.Tuner.PreserveApplications" /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="Microsoft.Android.Sdk.ILLink.PreserveRegistrations" /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="Microsoft.Android.Sdk.ILLink.PreserveJavaInterfaces" /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" Type="MonoDroid.Tuner.FixAbstractMethodsStep" /> + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="Microsoft.Android.Sdk.ILLink.PreserveSubStepDispatcher" /> + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="MonoDroid.Tuner.MarkJavaObjects" /> + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="MonoDroid.Tuner.PreserveJavaExceptions" /> + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="MonoDroid.Tuner.PreserveApplications" /> + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="Microsoft.Android.Sdk.ILLink.PreserveRegistrations" /> + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="Microsoft.Android.Sdk.ILLink.PreserveJavaInterfaces" /> + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="MonoDroid.Tuner.FixAbstractMethodsStep" /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="Mono.Linker.Steps.GenerateProguardConfiguration" + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" AfterStep="CleanStep" Type="Mono.Linker.Steps.GenerateProguardConfiguration" Condition=" '$(_ProguardProjectConfiguration)' != '' " /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="MonoDroid.Tuner.AddKeepAlivesStep" + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" AfterStep="CleanStep" Type="MonoDroid.Tuner.AddKeepAlivesStep" Condition=" '$(AndroidAddKeepAlives)' == 'true' " /> - <_TrimmerCustomSteps Include="$(_CustomStepDll)" AfterStep="CleanStep" Type="MonoDroid.Tuner.StripEmbeddedLibraries" /> + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" AfterStep="CleanStep" Type="MonoDroid.Tuner.StripEmbeddedLibraries" /> <_PreserveLists Include="$(MSBuildThisFileDirectory)..\PreserveLists\*.xml" /> Date: Tue, 18 May 2021 15:01:43 +0000 Subject: [PATCH 20/33] Fix code style - Add comments for #else and #endif - Avoid matching braces across #if/#else regions - Fix brace formatting --- .../MonoDroid.Tuner/AddKeepAlivesStep.cs | 8 ++--- .../Linker/MonoDroid.Tuner/Extensions.cs | 34 +++++++++--------- .../MonoDroid.Tuner/FixAbstractMethodsStep.cs | 36 ++++++++++--------- .../GenerateProguardConfiguration.cs | 4 +-- .../Linker/MonoDroid.Tuner/MarkJavaObjects.cs | 18 +++++----- .../MonoDroid.Tuner/PreserveApplications.cs | 24 ++++++------- .../MonoDroid.Tuner/PreserveJavaExceptions.cs | 16 ++++----- 7 files changed, 72 insertions(+), 68 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs index 8939c24caac..a9f35d86615 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs @@ -12,7 +12,7 @@ using Mono.Cecil.Cil; #if NET5_LINKER using Microsoft.Android.Sdk.ILLink; -#endif +#endif // NET5_LINKER namespace MonoDroid.Tuner { @@ -25,7 +25,7 @@ public AddKeepAlivesStep (TypeDefinitionCache cache) { this.cache = cache; } -#endif +#endif // !NET5_LINKER protected override void ProcessAssembly (AssemblyDefinition assembly) { @@ -72,9 +72,9 @@ bool MightNeedFix (TypeDefinition type) { #if NET5_LINKER return !type.IsAbstract && Context.IsSubclassOf (type, "Java.Lang.Object"); -#else +#else // !NET5_LINKER return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", cache); -#endif +#endif // !NET5_LINKER } MethodDefinition methodKeepAlive = null; diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs index e2792c89e33..46ad27a95fd 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs @@ -13,7 +13,7 @@ #if NET5_LINKER using Microsoft.Android.Sdk.ILLink; -#endif +#endif // NET5_LINKER namespace MonoDroid.Tuner { @@ -261,9 +261,9 @@ public static TypeDefinition GetMarshalMethodsType (this TypeDefinition type) #if NET5_LINKER public static bool TryGetBaseOrInterfaceRegisterMember (this LinkContext context, MethodDefinition method, out string member, out string nativeMethod, out string signature) -#else +#else // !NET5_LINKER public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition method, TypeDefinitionCache cache, out string member, out string nativeMethod, out string signature) -#endif +#endif // !NET5_LINKER { var type = method.DeclaringType; @@ -274,13 +274,13 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me #if NET5_LINKER var m = context.GetBaseDefinition (method); -#else +#else // !NET5_LINKER var m = method.GetBaseDefinition (cache); -#endif +#endif // !NET5_LINKER while (m != null) { if (m == method) - break; + break; method = m; @@ -289,9 +289,9 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me #if NET5_LINKER context.GetBaseDefinition (m); -#else +#else // !NET5_LINKER m = m.GetBaseDefinition (cache); -#endif +#endif // !NET5_LINKER } if (!method.DeclaringType.HasInterfaces || !method.IsNewSlot) @@ -299,7 +299,7 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me foreach (var iface in method.DeclaringType.Interfaces) { if (iface.InterfaceType.IsGenericInstance) - continue; + continue; var itype = iface.InterfaceType.Resolve (); if (itype == null || !itype.HasMethods) @@ -308,28 +308,28 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me foreach (var im in itype.Methods) #if NET5_LINKER if (context.IsEqual (im, method)) -#else +#else // !NET5_LINKER if (im.IsEqual (method, cache)) -#endif +#endif // !NET5_LINKER return im.TryGetRegisterMember (out member, out nativeMethod, out signature); - } + } - return false; + return false; } #if NET5_LINKER public static bool IsEqual (this LinkContext context, MethodDefinition m1, MethodDefinition m2) -#else +#else // !NET5_LINKER public static bool IsEqual (this MethodDefinition m1, MethodDefinition m2, TypeDefinitionCache cache) -#endif +#endif // !NET5_LINKER { if (m1.Name != m2.Name || m1.ReturnType.Name != m2.ReturnType.Name) return false; #if NET5_LINKER return context.AreParametersCompatibleWith (m1.Parameters, m2.Parameters); -#else +#else // !NET5_LINKER return m1.Parameters.AreParametersCompatibleWith (m2.Parameters, cache); -#endif +#endif // !NET5_LINKER } public static bool TryGetMarshalMethod (this MethodDefinition method, string nativeMethod, string signature, out MethodDefinition marshalMethod) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index a097b2b0712..668f4dc68b3 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -19,10 +19,15 @@ namespace MonoDroid.Tuner /// /// NOTE: this step is subclassed so it can be called directly from Xamarin.Android.Build.Tasks /// - public class FixAbstractMethodsStep + public class FixAbstractMethodsStep : #if NET5_LINKER - : IMarkHandler + IMarkHandler +#else // !NET5_LINKER + BaseStep +#endif // !NET5_LINKER { + +#if NET5_LINKER protected LinkContext Context { get; private set; } protected AnnotationStore Annotations => Context?.Annotations; @@ -31,16 +36,14 @@ public void Initialize (LinkContext context, MarkContext markContext) Context = context; markContext.RegisterMarkTypeAction (type => ProcessType (type)); } -#else - : BaseStep - { +#else // !NET5_LINKER readonly TypeDefinitionCache cache; public FixAbstractMethodsStep (TypeDefinitionCache cache) { this.cache = cache; } -#endif +#endif // !NET5_LINKER bool CheckShouldProcessAssembly (AssemblyDefinition assembly) { @@ -52,7 +55,7 @@ bool CheckShouldProcessAssembly (AssemblyDefinition assembly) #if !NET5_LINKER CheckAppDomainUsageUnconditional (assembly, (string msg) => Context.LogMessage (MessageImportance.High, msg)); -#endif +#endif // !NET5_LINKER return assembly.MainModule.HasTypeReference ("Java.Lang.Object"); } @@ -79,7 +82,7 @@ protected void ProcessType (TypeDefinition type) UpdateAssemblyAction (assembly); MarkAbstractMethodErrorType (); } -#else +#else // !NET5_LINKER protected override void ProcessAssembly (AssemblyDefinition assembly) { if (!CheckShouldProcessAssembly (assembly)) @@ -127,7 +130,7 @@ bool FixAbstractMethodsUnconditional (AssemblyDefinition assembly) } return changed; } -#endif +#endif // !NET5_LINKER bool IsProductOrSdkAssembly (AssemblyDefinition assembly) { @@ -138,9 +141,9 @@ bool MightNeedFix (TypeDefinition type) { #if NET5_LINKER return !type.IsAbstract && Context.IsSubclassOf (type, "Java.Lang.Object"); -#else +#else // !NET5_LINKER return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", cache); -#endif +#endif // !NET5_LINKER } static bool CompareTypes (TypeReference iType, TypeReference tType) @@ -251,9 +254,9 @@ bool FixAbstractMethods (TypeDefinition type) List typeMethods = new List (type.Methods); #if NET5_LINKER foreach (var baseType in Context.GetBaseTypes (type)) -#else +#else // !NET5_LINKER foreach (var baseType in type.GetBaseTypes (cache)) -#endif +#endif // !NET5_LINKER typeMethods.AddRange (baseType.Methods); foreach (var ifaceInfo in type.Interfaces) { @@ -340,7 +343,8 @@ MethodDefinition AbstractMethodErrorConstructor { bool markedAbstractMethodErrorType; - void MarkAbstractMethodErrorType () { + void MarkAbstractMethodErrorType () + { if (markedAbstractMethodErrorType) return; markedAbstractMethodErrorType = true; @@ -365,9 +369,9 @@ protected virtual AssemblyDefinition GetMonoAndroidAssembly () return assembly; } return null; -#else +#else // NET5_LINKER return Context.GetLoadedAssembly ("Mono.Android"); -#endif +#endif // NET5_LINKER } } } diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs index 4f80ddcbba9..1f7ca08c2f9 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/GenerateProguardConfiguration.cs @@ -22,7 +22,7 @@ public GenerateProguardConfiguration (string outputFileName) { this.filename = outputFileName; } -#endif +#endif // !NET5_LINKER string filename; TextWriter writer; @@ -32,7 +32,7 @@ protected override void Process () #if NET5_LINKER if (Context.TryGetCustomData ("ProguardConfiguration", out string proguardPath)) filename = proguardPath; -#endif +#endif // NET5_LINKER var dir = Path.GetDirectoryName (filename); if (!Directory.Exists (dir)) Directory.CreateDirectory (dir); diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs index c3f0d06b23e..180d826ef25 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs @@ -9,23 +9,23 @@ namespace MonoDroid.Tuner { - public class MarkJavaObjects + public class MarkJavaObjects : #if NET5_LINKER - : IMarkHandler -#else - : BaseSubStep -#endif + IMarkHandler +#else // !NET5_LINKER + BaseSubStep +#endif // !NET5_LINKER { Dictionary> module_types = new Dictionary> (); #if NET5_LINKER AnnotationStore Annotations => context?.Annotations; LinkContext context; -#else +#else // !NET5_LINKER public override SubStepTargets Targets { get { return SubStepTargets.Type; } } -#endif +#endif // !NET5_LINKER #if NET5_LINKER public void Initialize (LinkContext context, MarkContext markContext) @@ -33,12 +33,12 @@ public void Initialize (LinkContext context, MarkContext markContext) this.context = context; markContext.RegisterMarkTypeAction (type => ProcessType (type)); } -#endif +#endif // NET5_LINKER public #if !NET5_LINKER override -#endif +#endif // !NET5_LINKER void ProcessType (TypeDefinition type) { // If this isn't a JLO or IJavaObject implementer, diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs index 68cd4fcdf4d..8ca2bde303e 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs @@ -12,12 +12,12 @@ namespace MonoDroid.Tuner { - public class PreserveApplications + public class PreserveApplications : #if NET5_LINKER - : IMarkHandler -#else - : BaseSubStep -#endif + IMarkHandler +#else // !NET5_LINKER + BaseSubStep +#endif // !NET5_LINKER { #if NET5_LINKER @@ -30,18 +30,18 @@ public void Initialize (LinkContext context, MarkContext markContext) markContext.RegisterMarkAssemblyAction (assembly => ProcessAssembly (assembly)); markContext.RegisterMarkTypeAction (type => ProcessType (type)); } -#else +#else // !NET5_LINKER public override SubStepTargets Targets { get { return SubStepTargets.Type | SubStepTargets.Assembly; } } -#endif +#endif // !NET5_LINKER public #if !NET5_LINKER override -#endif +#endif // !NET5_LINKER bool IsActiveFor (AssemblyDefinition assembly) { return Annotations.GetAction (assembly) == AssemblyAction.Link; @@ -50,26 +50,26 @@ bool IsActiveFor (AssemblyDefinition assembly) public #if !NET5_LINKER override -#endif +#endif // !NET5_LINKER void ProcessAssembly (AssemblyDefinition assembly) { #if NET5_LINKER if (!IsActiveFor (assembly)) return; -#endif +#endif // NET5_LINKER ProcessAttributeProvider (assembly); } public #if !NET5_LINKER override -#endif +#endif // !NET5_LINKER void ProcessType (TypeDefinition type) { #if NET5_LINKER if (!IsActiveFor (type.Module.Assembly)) return; -#endif +#endif // NET5_LINKER if (!type.Inherits ("Android.App.Application")) return; diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs index 3ae1e1f8429..fead0a419b4 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs @@ -12,12 +12,12 @@ namespace MonoDroid.Tuner { - public class PreserveJavaExceptions + public class PreserveJavaExceptions : #if NET5_LINKER - : IMarkHandler -#else - : BaseSubStep -#endif + IMarkHandler +#else // !NET5_LINKER + BaseSubStep +#endif // !NET5_LINKER { #if NET5_LINKER @@ -29,16 +29,16 @@ public void Initialize (LinkContext context, MarkContext markContext) this.context = context; markContext.RegisterMarkTypeAction (type => ProcessType (type)); } -#else +#else // !NET5_LINKER public override SubStepTargets Targets { get { return SubStepTargets.Type; } } -#endif +#endif // !NET5_LINKER public #if !NET5_LINKER override -#endif +#endif // !NET5_LINKER void ProcessType (TypeDefinition type) { if (type.IsJavaException ()) From 5643dfa82d4ad3faf6765fe1fbb05e6b193a3bc2 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 18 May 2021 16:35:43 +0000 Subject: [PATCH 21/33] Add BaseMarkHandler --- .../BaseMarkHandler.cs | 16 ++++++++++++++++ .../PreserveJavaInterfaces.cs | 8 +++----- .../PreserveRegistrations.cs | 14 ++++++-------- .../MonoDroid.Tuner/FixAbstractMethodsStep.cs | 7 ++----- .../Linker/MonoDroid.Tuner/MarkJavaObjects.cs | 17 ++++++----------- .../MonoDroid.Tuner/PreserveApplications.cs | 7 ++----- .../MonoDroid.Tuner/PreserveJavaExceptions.cs | 7 ++----- 7 files changed, 37 insertions(+), 39 deletions(-) create mode 100644 src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs diff --git a/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs b/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs new file mode 100644 index 00000000000..6bce413337f --- /dev/null +++ b/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs @@ -0,0 +1,16 @@ +using Mono.Linker; +using Mono.Linker.Steps; + +namespace Mono.Linker +{ + public class BaseMarkHandler : IMarkHandler + { + protected LinkContext Context; + protected AnnotationStore Annotations => Context?.Annotations; + + public virtual void Initialize (LinkContext context, MarkContext markContext) + { + Context = context; + } + } +} diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs index b78ce6dd4d7..b2d0b5b25e8 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs @@ -5,13 +5,11 @@ namespace Microsoft.Android.Sdk.ILLink { - class PreserveJavaInterfaces : IMarkHandler + class PreserveJavaInterfaces : BaseMarkHandler { - LinkContext context; - public void Initialize (LinkContext context, MarkContext markContext) { - this.context = context; + base.Initialize (context, markContext); markContext.RegisterMarkTypeAction (type => ProcessType (type)); } @@ -35,7 +33,7 @@ void ProcessType (TypeDefinition type) return; foreach (MethodReference method in type.Methods) - context.Annotations.AddPreservedMethod (type, method.Resolve ()); + Annotations.AddPreservedMethod (type, method.Resolve ()); } } } diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs index e4a8ab7a772..ac09e3cc8e2 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs @@ -10,13 +10,11 @@ namespace Microsoft.Android.Sdk.ILLink { - class PreserveRegistrations : IMarkHandler + class PreserveRegistrations : BaseMarkHandler { - LinkContext context; - public void Initialize (LinkContext context, MarkContext markContext) { - this.context = context; + base.Initialize (context, markContext); markContext.RegisterMarkMethodAction (method => ProcessMethod (method)); } @@ -27,7 +25,7 @@ bool IsActiveFor (AssemblyDefinition assembly) bool PreserveJniMarshalMethods () { - if (context.TryGetCustomData ("XAPreserveJniMarshalMethods", out var boolValue)) + if (Context.TryGetCustomData ("XAPreserveJniMarshalMethods", out var boolValue)) return bool.Parse (boolValue); return false; @@ -76,8 +74,8 @@ void ProcessMethod (MethodDefinition method) bool preserveJniMarshalMethodOnly = false; if (!method.TryGetRegisterMember (out var member, out var nativeMethod, out var signature)) { if (PreserveJniMarshalMethods () && - method.DeclaringType.GetMarshalMethodsType () != null && - context.TryGetBaseOrInterfaceRegisterMember (method, out member, out nativeMethod, out signature)) { + method.DeclaringType.GetMarshalMethodsType () != null && + Context.TryGetBaseOrInterfaceRegisterMember (method, out member, out nativeMethod, out signature)) { preserveJniMarshalMethodOnly = true; } else { return; @@ -98,7 +96,7 @@ void ProcessMethod (MethodDefinition method) void AddPreservedMethod (MethodDefinition key, MethodDefinition method) { - context.Annotations.AddPreservedMethod (key, method); + Annotations.AddPreservedMethod (key, method); } } } diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index 668f4dc68b3..def1e3f091e 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -21,19 +21,16 @@ namespace MonoDroid.Tuner /// public class FixAbstractMethodsStep : #if NET5_LINKER - IMarkHandler + BaseMarkHandler #else // !NET5_LINKER BaseStep #endif // !NET5_LINKER { #if NET5_LINKER - protected LinkContext Context { get; private set; } - protected AnnotationStore Annotations => Context?.Annotations; - public void Initialize (LinkContext context, MarkContext markContext) { - Context = context; + base.Initialize (context, markContext); markContext.RegisterMarkTypeAction (type => ProcessType (type)); } #else // !NET5_LINKER diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs index 180d826ef25..224a9325a00 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs @@ -11,7 +11,7 @@ namespace MonoDroid.Tuner { public class MarkJavaObjects : #if NET5_LINKER - IMarkHandler + BaseMarkHandler #else // !NET5_LINKER BaseSubStep #endif // !NET5_LINKER @@ -19,22 +19,17 @@ public class MarkJavaObjects : Dictionary> module_types = new Dictionary> (); #if NET5_LINKER - AnnotationStore Annotations => context?.Annotations; - LinkContext context; + public void Initialize (LinkContext context, MarkContext markContext) + { + base.Initialize (context, markContext); + markContext.RegisterMarkTypeAction (type => ProcessType (type)); + } #else // !NET5_LINKER public override SubStepTargets Targets { get { return SubStepTargets.Type; } } #endif // !NET5_LINKER -#if NET5_LINKER - public void Initialize (LinkContext context, MarkContext markContext) - { - this.context = context; - markContext.RegisterMarkTypeAction (type => ProcessType (type)); - } -#endif // NET5_LINKER - public #if !NET5_LINKER override diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs index 8ca2bde303e..4b8d0cb1f72 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs @@ -14,19 +14,16 @@ namespace MonoDroid.Tuner { public class PreserveApplications : #if NET5_LINKER - IMarkHandler + BaseMarkHandler #else // !NET5_LINKER BaseSubStep #endif // !NET5_LINKER { #if NET5_LINKER - LinkContext context; - AnnotationStore Annotations => context?.Annotations; - public void Initialize (LinkContext context, MarkContext markContext) { - this.context = context; + base.Initialize (context, markContext); markContext.RegisterMarkAssemblyAction (assembly => ProcessAssembly (assembly)); markContext.RegisterMarkTypeAction (type => ProcessType (type)); } diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs index fead0a419b4..bfd75608be9 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs @@ -14,19 +14,16 @@ namespace MonoDroid.Tuner { public class PreserveJavaExceptions : #if NET5_LINKER - IMarkHandler + BaseMarkHandler #else // !NET5_LINKER BaseSubStep #endif // !NET5_LINKER { #if NET5_LINKER - LinkContext context; - AnnotationStore Annotations => context?.Annotations; - public void Initialize (LinkContext context, MarkContext markContext) { - this.context = context; + base.Initialize (context, markContext); markContext.RegisterMarkTypeAction (type => ProcessType (type)); } #else // !NET5_LINKER From 20d1ca67f70ffa1c17f9775972b755ab741a1347 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 19 May 2021 15:31:40 +0000 Subject: [PATCH 22/33] Fix overrides --- src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs | 2 +- src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs | 2 +- .../Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs | 2 +- .../Linker/MonoDroid.Tuner/MarkJavaObjects.cs | 2 +- .../Linker/MonoDroid.Tuner/PreserveApplications.cs | 2 +- .../Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs index b2d0b5b25e8..0c132664e47 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs @@ -7,7 +7,7 @@ namespace Microsoft.Android.Sdk.ILLink { class PreserveJavaInterfaces : BaseMarkHandler { - public void Initialize (LinkContext context, MarkContext markContext) + public override void Initialize (LinkContext context, MarkContext markContext) { base.Initialize (context, markContext); markContext.RegisterMarkTypeAction (type => ProcessType (type)); diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs index ac09e3cc8e2..f55608df36e 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs @@ -12,7 +12,7 @@ namespace Microsoft.Android.Sdk.ILLink { class PreserveRegistrations : BaseMarkHandler { - public void Initialize (LinkContext context, MarkContext markContext) + public override void Initialize (LinkContext context, MarkContext markContext) { base.Initialize (context, markContext); markContext.RegisterMarkMethodAction (method => ProcessMethod (method)); diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index def1e3f091e..2a2ea29a3f6 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -28,7 +28,7 @@ public class FixAbstractMethodsStep : { #if NET5_LINKER - public void Initialize (LinkContext context, MarkContext markContext) + public override void Initialize (LinkContext context, MarkContext markContext) { base.Initialize (context, markContext); markContext.RegisterMarkTypeAction (type => ProcessType (type)); diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs index 224a9325a00..7870b2ca1e6 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs @@ -19,7 +19,7 @@ public class MarkJavaObjects : Dictionary> module_types = new Dictionary> (); #if NET5_LINKER - public void Initialize (LinkContext context, MarkContext markContext) + public override void Initialize (LinkContext context, MarkContext markContext) { base.Initialize (context, markContext); markContext.RegisterMarkTypeAction (type => ProcessType (type)); diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs index 4b8d0cb1f72..f4ff92d5ecf 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs @@ -21,7 +21,7 @@ public class PreserveApplications : { #if NET5_LINKER - public void Initialize (LinkContext context, MarkContext markContext) + public override void Initialize (LinkContext context, MarkContext markContext) { base.Initialize (context, markContext); markContext.RegisterMarkAssemblyAction (assembly => ProcessAssembly (assembly)); diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs index bfd75608be9..77e7c88ba8c 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs @@ -21,7 +21,7 @@ public class PreserveJavaExceptions : { #if NET5_LINKER - public void Initialize (LinkContext context, MarkContext markContext) + public override void Initialize (LinkContext context, MarkContext markContext) { base.Initialize (context, markContext); markContext.RegisterMarkTypeAction (type => ProcessType (type)); From 3a1efaac5a40d840c2dbcbf4deb7668839f63f4b Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 19 May 2021 22:30:39 +0000 Subject: [PATCH 23/33] Subclass TypeDefinitionCache This implements @jonathanpepper's idea to use the linker's built-in Resolve cache without duplicating the extension methods from java.interop. By overriding TypeDefinitionCache, we can continue using the existing extension methods that take TypeDefinitionCache, and this leaves open the option to modify the extension method signatures to instead take an IMetadataResolver as in https://github.com/xamarin/java.interop/pull/842. --- .../BaseMarkHandler.cs | 4 +- .../LinkContextExtensions.cs | 161 ------------------ .../LinkContextMetadataResolver.cs | 20 +++ .../Microsoft.Android.Sdk.ILLink.csproj | 3 + .../PreserveRegistrations.cs | 2 +- .../MonoDroid.Tuner/AddKeepAlivesStep.cs | 14 +- .../Linker/MonoDroid.Tuner/Extensions.cs | 29 +--- .../MonoDroid.Tuner/FixAbstractMethodsStep.cs | 8 - .../MonoDroid.Tuner/RemoveAttributes.cs | 4 - 9 files changed, 37 insertions(+), 208 deletions(-) delete mode 100644 src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs create mode 100644 src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs diff --git a/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs b/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs index 6bce413337f..d3ef59088d4 100644 --- a/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs +++ b/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs @@ -1,5 +1,5 @@ -using Mono.Linker; using Mono.Linker.Steps; +using Microsoft.Android.Sdk.ILLink; namespace Mono.Linker { @@ -7,10 +7,12 @@ public class BaseMarkHandler : IMarkHandler { protected LinkContext Context; protected AnnotationStore Annotations => Context?.Annotations; + protected LinkContextMetadataResolver cache; public virtual void Initialize (LinkContext context, MarkContext markContext) { Context = context; + cache = new LinkContextMetadataResolver (context); } } } diff --git a/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs b/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs deleted file mode 100644 index 8995b2c3b1e..00000000000 --- a/src/Microsoft.Android.Sdk.ILLink/LinkContextExtensions.cs +++ /dev/null @@ -1,161 +0,0 @@ -#nullable enable - -using Mono.Cecil; -using Mono.Collections.Generic; -using Mono.Linker; -using System.Collections.Generic; - -namespace Microsoft.Android.Sdk.ILLink -{ - public static class LinkContextExtensions - { - public static MethodDefinition GetBaseDefinition (this LinkContext context, MethodDefinition method) - { - if (method.IsStatic || method.IsNewSlot || !method.IsVirtual) - return method; - - foreach (var baseType in context.GetBaseTypes (method.DeclaringType)) { - foreach (var m in baseType.Methods) { - if (!m.IsConstructor && - m.Name == method.Name && - (m.IsVirtual || m.IsAbstract) && - context.AreParametersCompatibleWith (m.Parameters, method.Parameters)) { - return m; - } - } - } - return method; - } - - public static bool AreParametersCompatibleWith (this LinkContext context, Collection a, Collection b) - { - if (a.Count != b.Count) - return false; - - if (a.Count == 0) - return true; - - for (int i = 0; i < a.Count; i++) - if (!context.IsParameterCompatibleWith (a [i].ParameterType, b [i].ParameterType)) - return false; - - return true; - } - - static bool IsParameterCompatibleWith (this LinkContext context, IModifierType a, IModifierType b) - { - if (!context.IsParameterCompatibleWith (a.ModifierType, b.ModifierType)) - return false; - - return context.IsParameterCompatibleWith (a.ElementType, b.ElementType); - } - - static bool IsParameterCompatibleWith (this LinkContext context, TypeSpecification a, TypeSpecification b) - { - if (a is GenericInstanceType) - return context.IsParameterCompatibleWith ((GenericInstanceType) a, (GenericInstanceType) b); - - if (a is IModifierType) - return context.IsParameterCompatibleWith ((IModifierType) a, (IModifierType) b); - - return context.IsParameterCompatibleWith (a.ElementType, b.ElementType); - } - - static bool IsParameterCompatibleWith (this LinkContext context, GenericInstanceType a, GenericInstanceType b) - { - if (!context.IsParameterCompatibleWith (a.ElementType, b.ElementType)) - return false; - - if (a.GenericArguments.Count != b.GenericArguments.Count) - return false; - - if (a.GenericArguments.Count == 0) - return true; - - for (int i = 0; i < a.GenericArguments.Count; i++) - if (!context.IsParameterCompatibleWith (a.GenericArguments [i], b.GenericArguments [i])) - return false; - - return true; - } - - static bool IsParameterCompatibleWith (this LinkContext context, TypeReference a, TypeReference b) - { - if (a is TypeSpecification || b is TypeSpecification) { - if (a.GetType () != b.GetType ()) - return false; - - return context.IsParameterCompatibleWith ((TypeSpecification) a, (TypeSpecification) b); - } - - if (a.IsGenericParameter) { - if (b.IsGenericParameter && a.Name == b.Name) - return true; - var gpa = (GenericParameter) a; - foreach (var c in gpa.Constraints) { - if (!context.IsAssignableFrom (c.ConstraintType, b)) - return false; - } - return true; - } - - return a.FullName == b.FullName; - } - - public static TypeDefinition? GetBaseType (this LinkContext context, TypeDefinition type) - { - var bt = type.BaseType; - if (bt == null) - return null; - return context.ResolveTypeDefinition (bt); - } - - public static IEnumerable GetTypeAndBaseTypes (this LinkContext context, TypeDefinition type) - { - TypeDefinition? t = type; - - while (t != null) { - yield return t; - t = context.GetBaseType (t); - } - } - - public static IEnumerable GetBaseTypes (this LinkContext context, TypeDefinition type) - { - TypeDefinition? t = type; - - while ((t = context.GetBaseType (t)) != null) { - yield return t; - } - } - - public static bool IsAssignableFrom (this LinkContext context, TypeReference type, TypeReference c) - { - if (type.FullName == c.FullName) - return true; - var d = context.TryResolveTypeDefinition (c); - if (d == null) - return false; - foreach (var t in context.GetTypeAndBaseTypes (d)) { - if (type.FullName == t.FullName) - return true; - foreach (var ifaceImpl in t.Interfaces) { - var i = ifaceImpl.InterfaceType; - if (context.IsAssignableFrom (type, i)) - return true; - } - } - return false; - } - - public static bool IsSubclassOf (this LinkContext context, TypeDefinition type, string typeName) - { - foreach (var t in context.GetTypeAndBaseTypes (type)) { - if (t.FullName == typeName) { - return true; - } - } - return false; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs b/src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs new file mode 100644 index 00000000000..b4d8a8537d4 --- /dev/null +++ b/src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs @@ -0,0 +1,20 @@ +using Java.Interop.Tools.Cecil; +using Mono.Cecil; +using Mono.Linker; + +namespace Microsoft.Android.Sdk.ILLink +{ + public class LinkContextMetadataResolver : TypeDefinitionCache { + LinkContext context; + + public LinkContextMetadataResolver (LinkContext context) + { + this.context = context; + } + + public override TypeDefinition Resolve (TypeReference typeReference) + { + return context.ResolveTypeDefinition (typeReference); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj index 947a019eb84..8e12748a8f1 100644 --- a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj +++ b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj @@ -41,6 +41,9 @@ + + + diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs index f55608df36e..7f10d1a3676 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs @@ -75,7 +75,7 @@ void ProcessMethod (MethodDefinition method) if (!method.TryGetRegisterMember (out var member, out var nativeMethod, out var signature)) { if (PreserveJniMarshalMethods () && method.DeclaringType.GetMarshalMethodsType () != null && - Context.TryGetBaseOrInterfaceRegisterMember (method, out member, out nativeMethod, out signature)) { + method.TryGetBaseOrInterfaceRegisterMember (cache, out member, out nativeMethod, out signature)) { preserveJniMarshalMethodOnly = true; } else { return; diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs index a9f35d86615..618649541af 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs @@ -18,7 +18,15 @@ namespace MonoDroid.Tuner { public class AddKeepAlivesStep : BaseStep { -#if !NET5_LINKER + +#if NET5_LINKER + LinkContextMetadataResolver cache; + + protected override void Process () + { + cache = new LinkContextMetadataResolver (Context); + } +#else // !NET5_LINKER readonly TypeDefinitionCache cache; public AddKeepAlivesStep (TypeDefinitionCache cache) @@ -70,11 +78,7 @@ static void AddNestedTypes (List types, TypeDefinition type) bool MightNeedFix (TypeDefinition type) { -#if NET5_LINKER - return !type.IsAbstract && Context.IsSubclassOf (type, "Java.Lang.Object"); -#else // !NET5_LINKER return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", cache); -#endif // !NET5_LINKER } MethodDefinition methodKeepAlive = null; diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs index 46ad27a95fd..3e798db86dd 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs @@ -11,10 +11,6 @@ using Java.Interop; using Java.Interop.Tools.Cecil; -#if NET5_LINKER -using Microsoft.Android.Sdk.ILLink; -#endif // NET5_LINKER - namespace MonoDroid.Tuner { static class Extensions { @@ -259,11 +255,7 @@ public static TypeDefinition GetMarshalMethodsType (this TypeDefinition type) return null; } -#if NET5_LINKER - public static bool TryGetBaseOrInterfaceRegisterMember (this LinkContext context, MethodDefinition method, out string member, out string nativeMethod, out string signature) -#else // !NET5_LINKER public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition method, TypeDefinitionCache cache, out string member, out string nativeMethod, out string signature) -#endif // !NET5_LINKER { var type = method.DeclaringType; @@ -272,11 +264,7 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me if (method.IsConstructor || type == null || !type.HasNestedTypes) return false; -#if NET5_LINKER - var m = context.GetBaseDefinition (method); -#else // !NET5_LINKER var m = method.GetBaseDefinition (cache); -#endif // !NET5_LINKER while (m != null) { if (m == method) @@ -287,11 +275,7 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me if (m.TryGetRegisterMember (out member, out nativeMethod, out signature)) return true; -#if NET5_LINKER - context.GetBaseDefinition (m); -#else // !NET5_LINKER m = m.GetBaseDefinition (cache); -#endif // !NET5_LINKER } if (!method.DeclaringType.HasInterfaces || !method.IsNewSlot) @@ -306,30 +290,19 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me continue; foreach (var im in itype.Methods) -#if NET5_LINKER - if (context.IsEqual (im, method)) -#else // !NET5_LINKER if (im.IsEqual (method, cache)) -#endif // !NET5_LINKER return im.TryGetRegisterMember (out member, out nativeMethod, out signature); } return false; } -#if NET5_LINKER - public static bool IsEqual (this LinkContext context, MethodDefinition m1, MethodDefinition m2) -#else // !NET5_LINKER public static bool IsEqual (this MethodDefinition m1, MethodDefinition m2, TypeDefinitionCache cache) -#endif // !NET5_LINKER { if (m1.Name != m2.Name || m1.ReturnType.Name != m2.ReturnType.Name) return false; -#if NET5_LINKER - return context.AreParametersCompatibleWith (m1.Parameters, m2.Parameters); -#else // !NET5_LINKER + return m1.Parameters.AreParametersCompatibleWith (m2.Parameters, cache); -#endif // !NET5_LINKER } public static bool TryGetMarshalMethod (this MethodDefinition method, string nativeMethod, string signature, out MethodDefinition marshalMethod) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index 2a2ea29a3f6..8b8c8ab0fa3 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -136,11 +136,7 @@ bool IsProductOrSdkAssembly (AssemblyDefinition assembly) bool MightNeedFix (TypeDefinition type) { -#if NET5_LINKER - return !type.IsAbstract && Context.IsSubclassOf (type, "Java.Lang.Object"); -#else // !NET5_LINKER return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", cache); -#endif // !NET5_LINKER } static bool CompareTypes (TypeReference iType, TypeReference tType) @@ -249,11 +245,7 @@ bool FixAbstractMethods (TypeDefinition type) bool rv = false; List typeMethods = new List (type.Methods); -#if NET5_LINKER - foreach (var baseType in Context.GetBaseTypes (type)) -#else // !NET5_LINKER foreach (var baseType in type.GetBaseTypes (cache)) -#endif // !NET5_LINKER typeMethods.AddRange (baseType.Methods); foreach (var ifaceInfo in type.Interfaces) { diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/RemoveAttributes.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/RemoveAttributes.cs index 493b37cd66e..f8de0df662f 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/RemoveAttributes.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/RemoveAttributes.cs @@ -6,10 +6,6 @@ using Mono.Linker; using Mono.Linker.Steps; -#if NET5_LINKER -using Microsoft.Android.Sdk.ILLink; -#endif - using Mono.Tuner; using Mobile.Tuner; From 1cc2d5ad3ed8ff0bce037f30e9b2914068efcb12 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 25 May 2021 21:19:27 +0000 Subject: [PATCH 24/33] Implement IMetadataResolver for LinkContextMetadataResolver --- .../BaseMarkHandler.cs | 4 ++-- .../LinkContextMetadataResolver.cs | 16 +++++++++++++--- .../PreserveRegistrations.cs | 2 +- .../Linker/MonoDroid.Tuner/Extensions.cs | 12 ++++++------ .../MonoDroid.Tuner/FixAbstractMethodsStep.cs | 8 ++++---- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs b/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs index d3ef59088d4..286f2f23efa 100644 --- a/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs +++ b/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs @@ -7,12 +7,12 @@ public class BaseMarkHandler : IMarkHandler { protected LinkContext Context; protected AnnotationStore Annotations => Context?.Annotations; - protected LinkContextMetadataResolver cache; + protected LinkContextMetadataResolver resolver; public virtual void Initialize (LinkContext context, MarkContext markContext) { Context = context; - cache = new LinkContextMetadataResolver (context); + resolver = new LinkContextMetadataResolver (context); } } } diff --git a/src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs b/src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs index b4d8a8537d4..4254607cd6e 100644 --- a/src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs +++ b/src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs @@ -4,7 +4,7 @@ namespace Microsoft.Android.Sdk.ILLink { - public class LinkContextMetadataResolver : TypeDefinitionCache { + public class LinkContextMetadataResolver : IMetadataResolver { LinkContext context; public LinkContextMetadataResolver (LinkContext context) @@ -12,9 +12,19 @@ public LinkContextMetadataResolver (LinkContext context) this.context = context; } - public override TypeDefinition Resolve (TypeReference typeReference) + public virtual TypeDefinition Resolve (TypeReference type) { - return context.ResolveTypeDefinition (typeReference); + return context.ResolveTypeDefinition (type); + } + + public virtual FieldDefinition Resolve (FieldReference field) + { + return context.ResolveFieldDefinition (field); + } + + public virtual MethodDefinition Resolve (MethodReference method) + { + return context.ResolveMethodDefinition (method); } } } \ No newline at end of file diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs index 7f10d1a3676..93f3037a472 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs @@ -75,7 +75,7 @@ void ProcessMethod (MethodDefinition method) if (!method.TryGetRegisterMember (out var member, out var nativeMethod, out var signature)) { if (PreserveJniMarshalMethods () && method.DeclaringType.GetMarshalMethodsType () != null && - method.TryGetBaseOrInterfaceRegisterMember (cache, out member, out nativeMethod, out signature)) { + method.TryGetBaseOrInterfaceRegisterMember (resolver, out member, out nativeMethod, out signature)) { preserveJniMarshalMethodOnly = true; } else { return; diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs index 3e798db86dd..9e9a21e4ff8 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs @@ -255,7 +255,7 @@ public static TypeDefinition GetMarshalMethodsType (this TypeDefinition type) return null; } - public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition method, TypeDefinitionCache cache, out string member, out string nativeMethod, out string signature) + public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition method, IMetadataResolver resolver, out string member, out string nativeMethod, out string signature) { var type = method.DeclaringType; @@ -264,7 +264,7 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me if (method.IsConstructor || type == null || !type.HasNestedTypes) return false; - var m = method.GetBaseDefinition (cache); + var m = method.GetBaseDefinition (resolver); while (m != null) { if (m == method) @@ -275,7 +275,7 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me if (m.TryGetRegisterMember (out member, out nativeMethod, out signature)) return true; - m = m.GetBaseDefinition (cache); + m = m.GetBaseDefinition (resolver); } if (!method.DeclaringType.HasInterfaces || !method.IsNewSlot) @@ -290,19 +290,19 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me continue; foreach (var im in itype.Methods) - if (im.IsEqual (method, cache)) + if (im.IsEqual (method, resolver)) return im.TryGetRegisterMember (out member, out nativeMethod, out signature); } return false; } - public static bool IsEqual (this MethodDefinition m1, MethodDefinition m2, TypeDefinitionCache cache) + public static bool IsEqual (this MethodDefinition m1, MethodDefinition m2, IMetadataResolver resolver) { if (m1.Name != m2.Name || m1.ReturnType.Name != m2.ReturnType.Name) return false; - return m1.Parameters.AreParametersCompatibleWith (m2.Parameters, cache); + return m1.Parameters.AreParametersCompatibleWith (m2.Parameters, resolver); } public static bool TryGetMarshalMethod (this MethodDefinition method, string nativeMethod, string signature, out MethodDefinition marshalMethod) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index 8b8c8ab0fa3..97e9688e1d8 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -34,11 +34,11 @@ public override void Initialize (LinkContext context, MarkContext markContext) markContext.RegisterMarkTypeAction (type => ProcessType (type)); } #else // !NET5_LINKER - readonly TypeDefinitionCache cache; + readonly TypeDefinitionCache resolver; public FixAbstractMethodsStep (TypeDefinitionCache cache) { - this.cache = cache; + resolver = cache; } #endif // !NET5_LINKER @@ -136,7 +136,7 @@ bool IsProductOrSdkAssembly (AssemblyDefinition assembly) bool MightNeedFix (TypeDefinition type) { - return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", cache); + return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", resolver); } static bool CompareTypes (TypeReference iType, TypeReference tType) @@ -245,7 +245,7 @@ bool FixAbstractMethods (TypeDefinition type) bool rv = false; List typeMethods = new List (type.Methods); - foreach (var baseType in type.GetBaseTypes (cache)) + foreach (var baseType in type.GetBaseTypes (resolver)) typeMethods.AddRange (baseType.Methods); foreach (var ifaceInfo in type.Interfaces) { From 67c9593c16f3079e875df1a31537cf8b0d1321ec Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 28 May 2021 01:47:18 +0000 Subject: [PATCH 25/33] PR feedback - Use "IMetadataResolver cache" fields --- src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs | 7 ++++--- .../PreserveRegistrations.cs | 2 +- .../Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs | 9 ++++----- .../MonoDroid.Tuner/FixAbstractMethodsStep.cs | 13 +++++++------ 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs b/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs index 286f2f23efa..a0642073107 100644 --- a/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs +++ b/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs @@ -1,5 +1,6 @@ -using Mono.Linker.Steps; using Microsoft.Android.Sdk.ILLink; +using Mono.Cecil; +using Mono.Linker.Steps; namespace Mono.Linker { @@ -7,12 +8,12 @@ public class BaseMarkHandler : IMarkHandler { protected LinkContext Context; protected AnnotationStore Annotations => Context?.Annotations; - protected LinkContextMetadataResolver resolver; + protected IMetadataResolver cache; public virtual void Initialize (LinkContext context, MarkContext markContext) { Context = context; - resolver = new LinkContextMetadataResolver (context); + cache = new LinkContextMetadataResolver (context); } } } diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs index 93f3037a472..7f10d1a3676 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs @@ -75,7 +75,7 @@ void ProcessMethod (MethodDefinition method) if (!method.TryGetRegisterMember (out var member, out var nativeMethod, out var signature)) { if (PreserveJniMarshalMethods () && method.DeclaringType.GetMarshalMethodsType () != null && - method.TryGetBaseOrInterfaceRegisterMember (resolver, out member, out nativeMethod, out signature)) { + method.TryGetBaseOrInterfaceRegisterMember (cache, out member, out nativeMethod, out signature)) { preserveJniMarshalMethodOnly = true; } else { return; diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs index 618649541af..2a887e327b2 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs @@ -20,20 +20,19 @@ public class AddKeepAlivesStep : BaseStep { #if NET5_LINKER - LinkContextMetadataResolver cache; - protected override void Process () { cache = new LinkContextMetadataResolver (Context); } #else // !NET5_LINKER - readonly TypeDefinitionCache cache; - - public AddKeepAlivesStep (TypeDefinitionCache cache) + public AddKeepAlivesStep (IMetadataResolver cache) { this.cache = cache; } + + readonly #endif // !NET5_LINKER + IMetadataResolver cache; protected override void ProcessAssembly (AssemblyDefinition assembly) { diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs index 97e9688e1d8..570f013e36d 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs @@ -34,13 +34,14 @@ public override void Initialize (LinkContext context, MarkContext markContext) markContext.RegisterMarkTypeAction (type => ProcessType (type)); } #else // !NET5_LINKER - readonly TypeDefinitionCache resolver; - - public FixAbstractMethodsStep (TypeDefinitionCache cache) + public FixAbstractMethodsStep (IMetadataResolver cache) { - resolver = cache; + this.cache = cache; } + + readonly #endif // !NET5_LINKER + IMetadataResolver cache; bool CheckShouldProcessAssembly (AssemblyDefinition assembly) { @@ -136,7 +137,7 @@ bool IsProductOrSdkAssembly (AssemblyDefinition assembly) bool MightNeedFix (TypeDefinition type) { - return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", resolver); + return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", cache); } static bool CompareTypes (TypeReference iType, TypeReference tType) @@ -245,7 +246,7 @@ bool FixAbstractMethods (TypeDefinition type) bool rv = false; List typeMethods = new List (type.Methods); - foreach (var baseType in type.GetBaseTypes (resolver)) + foreach (var baseType in type.GetBaseTypes (cache)) typeMethods.AddRange (baseType.Methods); foreach (var ifaceInfo in type.Interfaces) { From 01b56ec5168dabf90aa3eebdf1dec2aaddb8e813 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Fri, 28 May 2021 13:53:49 -0400 Subject: [PATCH 26/33] Fix indentation --- src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs index 7f10d1a3676..881e9884843 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs @@ -74,8 +74,8 @@ void ProcessMethod (MethodDefinition method) bool preserveJniMarshalMethodOnly = false; if (!method.TryGetRegisterMember (out var member, out var nativeMethod, out var signature)) { if (PreserveJniMarshalMethods () && - method.DeclaringType.GetMarshalMethodsType () != null && - method.TryGetBaseOrInterfaceRegisterMember (cache, out member, out nativeMethod, out signature)) { + method.DeclaringType.GetMarshalMethodsType () != null && + method.TryGetBaseOrInterfaceRegisterMember (cache, out member, out nativeMethod, out signature)) { preserveJniMarshalMethodOnly = true; } else { return; From 7c70a520f03e5bf832ee9bf5951dced18878917a Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Fri, 28 May 2021 13:55:57 -0400 Subject: [PATCH 27/33] Fix indentation --- .../Linker/MonoDroid.Tuner/MarkJavaObjects.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs index 7870b2ca1e6..55d0204f431 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MarkJavaObjects.cs @@ -11,9 +11,9 @@ namespace MonoDroid.Tuner { public class MarkJavaObjects : #if NET5_LINKER - BaseMarkHandler + BaseMarkHandler #else // !NET5_LINKER - BaseSubStep + BaseSubStep #endif // !NET5_LINKER { Dictionary> module_types = new Dictionary> (); From 6c6d4c8e5e8e1a3a0c35fa4ef19e89e151363e19 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Fri, 28 May 2021 13:56:40 -0400 Subject: [PATCH 28/33] Fix indentation --- .../Linker/MonoDroid.Tuner/PreserveApplications.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs index f4ff92d5ecf..08014537fa0 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveApplications.cs @@ -14,9 +14,9 @@ namespace MonoDroid.Tuner { public class PreserveApplications : #if NET5_LINKER - BaseMarkHandler + BaseMarkHandler #else // !NET5_LINKER - BaseSubStep + BaseSubStep #endif // !NET5_LINKER { From d83a79312ea8c108cd47581063e0e6c3a387e540 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Fri, 28 May 2021 13:57:10 -0400 Subject: [PATCH 29/33] Fix indentation --- .../Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs index 77e7c88ba8c..d79f5448b31 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PreserveJavaExceptions.cs @@ -14,9 +14,9 @@ namespace MonoDroid.Tuner { public class PreserveJavaExceptions : #if NET5_LINKER - BaseMarkHandler + BaseMarkHandler #else // !NET5_LINKER - BaseSubStep + BaseSubStep #endif // !NET5_LINKER { From b13b50c8fbe025ff6d9538ab159e4e32f43615c3 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Fri, 28 May 2021 14:02:04 -0400 Subject: [PATCH 30/33] Add comment for why we're setting _TrimmerDumpDependencies --- .../targets/Microsoft.Android.Sdk.ILLink.targets | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets index e63c2af6b31..10e9116b27d 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets @@ -14,6 +14,10 @@ This file contains the .NET 5-specific targets to customize ILLink AfterTargets="ComputeResolvedFilesToPublishList" DependsOnTargets="GetReferenceAssemblyPaths;_CreatePropertiesCache"> + <_TrimmerDumpDependencies Condition=" '$(LinkerDumpDependencies)' == 'true' ">true <_AndroidLinkerCustomStepAssembly>$(MSBuildThisFileDirectory)..\tools\Microsoft.Android.Sdk.ILLink.dll From 8b4c908d196ef1afb50c61d1bc059220ab141445 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Fri, 28 May 2021 14:11:25 -0400 Subject: [PATCH 31/33] Fix indentation --- .../Microsoft.Android.Sdk.ILLink.targets | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets index 10e9116b27d..711c7d074b2 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets @@ -38,10 +38,26 @@ This file contains the .NET 5-specific targets to customize ILLink link + <_TrimmerCustomData Include="XATargetFrameworkDirectories" Value="$(_XATargetFrameworkDirectories)" /> - <_TrimmerCustomData Condition=" '$(_ProguardProjectConfiguration)' != '' " Include="ProguardConfiguration" Value="$(_ProguardProjectConfiguration)" /> - <_TrimmerCustomData Condition=" '$(AndroidLinkResources)' != '' " Include="AndroidLinkResources" Value="$(AndroidLinkResources)" /> + <_TrimmerCustomData + Condition=" '$(_ProguardProjectConfiguration)' != '' " + Include="ProguardConfiguration" + Value="$(_ProguardProjectConfiguration)" + /> + <_TrimmerCustomData + Condition=" '$(AndroidLinkResources)' != '' " + Include="AndroidLinkResources" + Value="$(AndroidLinkResources)" + /> + <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" BeforeStep="MarkStep" Type="Microsoft.Android.Sdk.ILLink.SetupStep" /> @@ -54,10 +70,18 @@ This file contains the .NET 5-specific targets to customize ILLink <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="Microsoft.Android.Sdk.ILLink.PreserveJavaInterfaces" /> <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="MonoDroid.Tuner.FixAbstractMethodsStep" /> - <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" AfterStep="CleanStep" Type="Mono.Linker.Steps.GenerateProguardConfiguration" - Condition=" '$(_ProguardProjectConfiguration)' != '' " /> - <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" AfterStep="CleanStep" Type="MonoDroid.Tuner.AddKeepAlivesStep" - Condition=" '$(AndroidAddKeepAlives)' == 'true' " /> + <_TrimmerCustomSteps + Condition=" '$(_ProguardProjectConfiguration)' != '' " + Include="$(_AndroidLinkerCustomStepAssembly)" + AfterStep="CleanStep" + Type="Mono.Linker.Steps.GenerateProguardConfiguration" + /> + <_TrimmerCustomSteps + Condition=" '$(AndroidAddKeepAlives)' == 'true' " + Include="$(_AndroidLinkerCustomStepAssembly)" + AfterStep="CleanStep" + Type="MonoDroid.Tuner.AddKeepAlivesStep" + /> <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" AfterStep="CleanStep" Type="MonoDroid.Tuner.StripEmbeddedLibraries" /> <_PreserveLists Include="$(MSBuildThisFileDirectory)..\PreserveLists\*.xml" /> From bda4b4f2f7b2a3e2bd64c0ddc510d3188f128127 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 28 May 2021 19:51:28 +0000 Subject: [PATCH 32/33] Remove LinkContextMetadataResolver LinkContext now directly implements IMetadataResolver. --- .../BaseMarkHandler.cs | 2 +- .../LinkContextMetadataResolver.cs | 30 ------------------- .../MonoDroid.Tuner/AddKeepAlivesStep.cs | 2 +- 3 files changed, 2 insertions(+), 32 deletions(-) delete mode 100644 src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs diff --git a/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs b/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs index a0642073107..eb7996aafe7 100644 --- a/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs +++ b/src/Microsoft.Android.Sdk.ILLink/BaseMarkHandler.cs @@ -13,7 +13,7 @@ public class BaseMarkHandler : IMarkHandler public virtual void Initialize (LinkContext context, MarkContext markContext) { Context = context; - cache = new LinkContextMetadataResolver (context); + cache = context; } } } diff --git a/src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs b/src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs deleted file mode 100644 index 4254607cd6e..00000000000 --- a/src/Microsoft.Android.Sdk.ILLink/LinkContextMetadataResolver.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Java.Interop.Tools.Cecil; -using Mono.Cecil; -using Mono.Linker; - -namespace Microsoft.Android.Sdk.ILLink -{ - public class LinkContextMetadataResolver : IMetadataResolver { - LinkContext context; - - public LinkContextMetadataResolver (LinkContext context) - { - this.context = context; - } - - public virtual TypeDefinition Resolve (TypeReference type) - { - return context.ResolveTypeDefinition (type); - } - - public virtual FieldDefinition Resolve (FieldReference field) - { - return context.ResolveFieldDefinition (field); - } - - public virtual MethodDefinition Resolve (MethodReference method) - { - return context.ResolveMethodDefinition (method); - } - } -} \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs index 2a887e327b2..02c35157d13 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs @@ -22,7 +22,7 @@ public class AddKeepAlivesStep : BaseStep #if NET5_LINKER protected override void Process () { - cache = new LinkContextMetadataResolver (Context); + cache = Context; } #else // !NET5_LINKER public AddKeepAlivesStep (IMetadataResolver cache) From ff9ea5181ef0032030757783f5906a9b2889e6db Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 2 Jun 2021 01:01:07 +0000 Subject: [PATCH 33/33] Remove reflection workaround --- src/Microsoft.Android.Sdk.ILLink/SetupStep.cs | 34 ------------------- .../Microsoft.Android.Sdk.ILLink.targets | 18 +++++++--- 2 files changed, 13 insertions(+), 39 deletions(-) diff --git a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs index e1d7f453aee..c8f56b575be 100644 --- a/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs +++ b/src/Microsoft.Android.Sdk.ILLink/SetupStep.cs @@ -12,44 +12,10 @@ namespace Microsoft.Android.Sdk.ILLink { class SetupStep : BaseStep { - List _steps; - - List Steps { - get { - if (_steps == null) { - var pipeline = typeof (LinkContext).GetProperty ("Pipeline").GetGetMethod ().Invoke (Context, null); - _steps = (List) pipeline.GetType ().GetField ("_steps", BindingFlags.Instance | BindingFlags.NonPublic).GetValue (pipeline); - //foreach (var step in _steps) - // Console.WriteLine ($"step: {step.GetType ().Name}"); - } - return _steps; - } - } - protected override void Process () { if (Context.TryGetCustomData ("XATargetFrameworkDirectories", out string tfmPaths)) Xamarin.Android.Tasks.MonoAndroidHelper.TargetFrameworkDirectories = tfmPaths.Split (new char [] { ';' }); - - // The following steps share state and must be injected via reflection until we get - // a linker with the fix from https://github.com/mono/linker/pull/2019. - string androidLinkResources; - if (Context.TryGetCustomData ("AndroidLinkResources", out androidLinkResources) && bool.TryParse (androidLinkResources, out var linkResources) && linkResources) { - InsertAfter (new RemoveResourceDesignerStep (), "CleanStep"); - InsertAfter (new GetAssembliesStep (), "CleanStep"); - } - } - - void InsertAfter (IStep step, string stepName) - { - for (int i = 0; i < Steps.Count;) { - if (Steps [i++].GetType ().Name == stepName) { - Steps.Insert (i, step); - return; - } - } - - throw new InvalidOperationException ($"Could not insert {step} after {stepName}."); } } } diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets index 711c7d074b2..1b3af1eb034 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets @@ -48,11 +48,6 @@ This file contains the .NET 5-specific targets to customize ILLink Include="ProguardConfiguration" Value="$(_ProguardProjectConfiguration)" /> - <_TrimmerCustomData - Condition=" '$(AndroidLinkResources)' != '' " - Include="AndroidLinkResources" - Value="$(AndroidLinkResources)" - /> <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" AfterStep="CleanStep" Type="MonoDroid.Tuner.StripEmbeddedLibraries" /> + <_TrimmerCustomSteps + Condition=" '$(AndroidLinkResources)' == 'true' " + Include="$(_AndroidLinkerCustomStepAssembly)" + AfterStep="CleanStep" + Type="MonoDroid.Tuner.GetAssembliesStep" + /> + <_TrimmerCustomSteps + Condition=" '$(AndroidLinkResources)' == 'true' " + Include="$(_AndroidLinkerCustomStepAssembly)" + AfterStep="CleanStep" + Type="MonoDroid.Tuner.RemoveResourceDesignerStep" + /> <_PreserveLists Include="$(MSBuildThisFileDirectory)..\PreserveLists\*.xml" />