From 9a938263943bfe4ad6e8a3a49d41a2bebfff7e46 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Fri, 9 Feb 2024 16:09:23 -0600 Subject: [PATCH] [Xamarin.Android.Build.Tasks] introduce BannedApiAnalyzers for Mono.Cecil Context: https://github.com/dotnet/roslyn-analyzers/blob/68c643b4667c6808bd21910ef32f7e2f7bd776c5/src/Microsoft.CodeAnalysis.BannedApiAnalyzers/BannedApiAnalyzers.Help.md In 526172b4, we had some reasonable performance wins just by using `TypeDefinitionCache`. Let's take this a step further by "banning" usage of: Mono.Cecil.FieldReference.Resolve() Mono.Cecil.MethodReference.Resolve() Mono.Cecil.TypeReference.Resolve() I applied this change to `Xamarin.Android.Build.Tasks.csproj` for now. In various places, I had to pass `TypeDefinitionCache` around or use an existing one. In a future PR, I'll make a small change in xamarin/java.interop so we can apply the same treatment to `Microsoft.Android.Sdk.ILLink.csproj`. --- build-tools/banned-apis/BannedSymbols.txt | 3 + build-tools/banned-apis/banned-apis.targets | 9 +++ .../MarkJavaObjects.cs | 10 +-- .../PreserveApplications.cs | 2 +- .../PreserveJavaExceptions.cs | 2 +- .../PreserveJavaInterfaces.cs | 2 +- .../External/Linker/OverrideInformation.cs | 16 +---- .../Linker/External/Mono.Tuner/CecilRocks.cs | 62 ------------------- .../Linker/MonoDroid.Tuner/Extensions.cs | 44 +++++++------ .../FixLegacyResourceDesignerStep.cs | 8 ++- .../MonoDroid.Tuner/LinkDesignerBase.cs | 14 ++++- .../RemoveResourceDesignerStep.cs | 5 ++ .../Mono.Android/ActivityAttribute.Partial.cs | 4 +- .../ApplicationAttribute.Partial.cs | 4 +- .../BroadcastReceiverAttribute.Partial.cs | 4 +- .../ContentProviderAttribute.Partial.cs | 4 +- .../GrantUriPermissionAttribute.Partial.cs | 4 +- .../InstrumentationAttribute.Partial.cs | 4 +- .../IntentFilterAttribute.Partial.cs | 4 +- .../Mono.Android/LayoutAttribute.Partial.cs | 4 +- .../Mono.Android/MetaDataAttribute.Partial.cs | 4 +- .../PermissionAttribute.Partial.cs | 4 +- .../PermissionGroupAttribute.Partial.cs | 4 +- .../PermissionTreeAttribute.Partial.cs | 4 +- .../Mono.Android/ServiceAttribute.Partial.cs | 4 +- .../SupportsGLTextureAttribute.Partial.cs | 4 +- .../UsesConfigurationAttribute.Partial.cs | 4 +- .../UsesFeatureAttribute.Partial.cs | 4 +- .../UsesLibraryAttribute.Partial.cs | 4 +- .../UsesPermissionAttribute.Partial.cs | 4 +- .../Tasks/CheckClientHandlerType.cs | 15 +++-- .../Tasks/GenerateResourceDesignerAssembly.cs | 52 ++++++++-------- .../Tasks/LinkAssembliesNoShrink.cs | 5 +- .../ManifestTest.cs | 7 ++- .../Utilities/ManifestDocument.cs | 50 +++++++-------- .../Utilities/ManifestDocumentElement.cs | 4 +- .../Utilities/MarshalMethodsClassifier.cs | 8 ++- .../Xamarin.Android.Build.Tasks.csproj | 1 + 38 files changed, 183 insertions(+), 208 deletions(-) create mode 100644 build-tools/banned-apis/BannedSymbols.txt create mode 100644 build-tools/banned-apis/banned-apis.targets diff --git a/build-tools/banned-apis/BannedSymbols.txt b/build-tools/banned-apis/BannedSymbols.txt new file mode 100644 index 00000000000..bcc45d92111 --- /dev/null +++ b/build-tools/banned-apis/BannedSymbols.txt @@ -0,0 +1,3 @@ +M:Mono.Cecil.FieldReference.Resolve();Use IMetadataResolver.Resolve() instead, so future calls can be cached +M:Mono.Cecil.MethodReference.Resolve();Use IMetadataResolver.Resolve() instead, so future calls can be cached. +M:Mono.Cecil.TypeReference.Resolve();Use IMetadataResolver.Resolve() instead, so future calls can be cached. diff --git a/build-tools/banned-apis/banned-apis.targets b/build-tools/banned-apis/banned-apis.targets new file mode 100644 index 00000000000..ec275b5ffc0 --- /dev/null +++ b/build-tools/banned-apis/banned-apis.targets @@ -0,0 +1,9 @@ + + + RS0030 + + + + + + diff --git a/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs b/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs index f9ee603b446..feb182dfad6 100644 --- a/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs +++ b/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs @@ -23,12 +23,12 @@ public void ProcessType (TypeDefinition type) { // If this isn't a JLO or IJavaObject implementer, // then we don't need to MarkJavaObjects - if (!type.ImplementsIJavaObject ()) + if (!type.ImplementsIJavaObject (cache)) return; PreserveJavaObjectImplementation (type); - if (IsImplementor (type)) + if (IsImplementor (type, cache)) PreserveImplementor (type); // If a user overrode a method, we need to preserve it, @@ -195,7 +195,7 @@ void PreserveInterfaces (TypeDefinition type) foreach (var iface in type.Interfaces) { var td = iface.InterfaceType.Resolve (); - if (!td.ImplementsIJavaPeerable ()) + if (!td.ImplementsIJavaPeerable (cache)) continue; Annotations.Mark (td); } @@ -302,9 +302,9 @@ void PreserveConstructors (TypeDefinition type, TypeDefinition helper) PreserveMethod (type, ctor); } - static bool IsImplementor (TypeDefinition type) + static bool IsImplementor (TypeDefinition type, IMetadataResolver cache) { - return type.Name.EndsWith ("Implementor", StringComparison.Ordinal) && type.Inherits ("Java.Lang.Object"); + return type.Name.EndsWith ("Implementor", StringComparison.Ordinal) && type.Inherits ("Java.Lang.Object", cache); } static bool IsUserType (TypeDefinition type) diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs index 16d2a4537d7..99ca8df9384 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs @@ -37,7 +37,7 @@ public void ProcessType (TypeDefinition type) { if (!IsActiveFor (type.Module.Assembly)) return; - if (!type.Inherits ("Android.App.Application")) + if (!type.Inherits ("Android.App.Application", cache)) return; ProcessAttributeProvider (type); diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs index 12a9c9f59fb..1c0ad8f0898 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs @@ -23,7 +23,7 @@ public override void Initialize (LinkContext context, MarkContext markContext) public void ProcessType (TypeDefinition type) { - if (type.IsJavaException ()) + if (type.IsJavaException (cache)) PreserveJavaException (type); } diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs index 0c132664e47..dfedbd5708b 100644 --- a/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs +++ b/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs @@ -29,7 +29,7 @@ void ProcessType (TypeDefinition type) return; // Mono.Android interfaces will always inherit IJavaObject - if (!type.ImplementsIJavaObject ()) + if (!type.ImplementsIJavaObject (cache)) return; foreach (MethodReference method in type.Methods) diff --git a/src/Xamarin.Android.Build.Tasks/Linker/External/Linker/OverrideInformation.cs b/src/Xamarin.Android.Build.Tasks/Linker/External/Linker/OverrideInformation.cs index f73d8bc1c63..70177f82833 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/External/Linker/OverrideInformation.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/External/Linker/OverrideInformation.cs @@ -25,19 +25,5 @@ public bool IsOverrideOfInterfaceMember return Base.DeclaringType.IsInterface; } } - - public TypeDefinition InterfaceType - { - get - { - if (!IsOverrideOfInterfaceMember) - return null; - - if (MatchingInterfaceImplementation != null) - return MatchingInterfaceImplementation.InterfaceType.Resolve (); - - return Base.DeclaringType; - } - } } -} \ No newline at end of file +} diff --git a/src/Xamarin.Android.Build.Tasks/Linker/External/Mono.Tuner/CecilRocks.cs b/src/Xamarin.Android.Build.Tasks/Linker/External/Mono.Tuner/CecilRocks.cs index 69958598dda..af5be955f95 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/External/Mono.Tuner/CecilRocks.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/External/Mono.Tuner/CecilRocks.cs @@ -453,67 +453,5 @@ public static ParameterDefinition GetParameter (this MethodBody self, int index) return parameters [index]; } - - public static bool Implements (this TypeReference self, string interfaceName) - { - if (interfaceName == null) - throw new ArgumentNullException ("interfaceName"); - if (self == null) - return false; - - TypeDefinition type = self.Resolve (); - if (type == null) - return false; // not enough information available - - // special case, check if we implement ourselves - if (type.IsInterface && (type.FullName == interfaceName)) - return true; - - return Implements (type, interfaceName, (interfaceName.IndexOf ('`') >= 0)); - } - - public static bool Implements (TypeDefinition type, string interfaceName, bool generic) - { - while (type != null) { - // does the type implements it itself - if (type.HasInterfaces) { - foreach (var iface in type.Interfaces) { - string fullname = (generic) ? iface.InterfaceType.GetElementType ().FullName : iface.InterfaceType.FullName; - if (fullname == interfaceName) - return true; - //if not, then maybe one of its parent interfaces does - if (Implements (iface.InterfaceType.Resolve (), interfaceName, generic)) - return true; - } - } - - type = type.BaseType != null ? type.BaseType.Resolve () : null; - } - return false; - } - - public static bool Inherits (this TypeReference self, string @namespace, string name) - { - if (@namespace == null) - throw new ArgumentNullException ("namespace"); - if (name == null) - throw new ArgumentNullException ("name"); - if (self == null) - return false; - - TypeReference current = self.Resolve (); - while (current != null) { - if (current.Is (@namespace, name)) - return true; - if (current.Is ("System", "Object")) - return false; - - TypeDefinition td = current.Resolve (); - if (td == null) - return false; // could not resolve type - current = td.BaseType; - } - return false; - } } } 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 11b5ff46f2f..8e816d7d3c6 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Extensions.cs @@ -20,30 +20,30 @@ static class Extensions { const string IJavaPeerable = "Java.Interop.IJavaPeerable"; const string JavaThrowable = "Java.Lang.Throwable"; - public static bool IsJavaObject (this TypeDefinition type) + public static bool IsJavaObject (this TypeDefinition type, IMetadataResolver resolver) { - return type.Inherits (JavaObject); + return type.Inherits (JavaObject, resolver); } - public static bool IsJavaException (this TypeDefinition type) + public static bool IsJavaException (this TypeDefinition type, IMetadataResolver resolver) { - return type.Inherits (JavaThrowable); + return type.Inherits (JavaThrowable, resolver); } - public static bool ImplementsIJavaObject (this TypeDefinition type) + public static bool ImplementsIJavaObject (this TypeDefinition type, IMetadataResolver resolver) { - return type.Implements (IJavaObject); + return type.Implements (IJavaObject, resolver); } - public static bool ImplementsIJavaPeerable (this TypeDefinition type) + public static bool ImplementsIJavaPeerable (this TypeDefinition type, IMetadataResolver resolver) { - return type.Implements (IJavaPeerable); + return type.Implements (IJavaPeerable, resolver); } - public static object GetSettableValue (this CustomAttributeArgument arg) + public static object GetSettableValue (this CustomAttributeArgument arg, IMetadataResolver cache) { TypeReference tr = arg.Value as TypeReference; - TypeDefinition td = tr != null ? tr.Resolve () : null; + TypeDefinition td = tr != null ? cache.Resolve (tr) : null; return td != null ? td.FullName + "," + td.Module.Assembly.FullName : arg.Value; } @@ -119,14 +119,14 @@ public static TypeDefinition GetType (AssemblyDefinition assembly, string typeNa return assembly.MainModule.GetType (typeName); } - public static bool Implements (this TypeReference self, string interfaceName) + public static bool Implements (this TypeReference self, string interfaceName, IMetadataResolver resolver) { if (interfaceName == null) throw new ArgumentNullException ("interfaceName"); if (self == null) return false; - TypeDefinition type = self.Resolve (); + TypeDefinition type = resolver.Resolve (self); if (type == null) return false; // not enough information available @@ -134,10 +134,10 @@ public static bool Implements (this TypeReference self, string interfaceName) if (type.IsInterface && (type.FullName == interfaceName)) return true; - return Implements (type, interfaceName, (interfaceName.IndexOf ('`') >= 0)); + return Implements (type, interfaceName, (interfaceName.IndexOf ('`') >= 0), resolver); } - public static bool Implements (TypeDefinition type, string interfaceName, bool generic) + public static bool Implements (TypeDefinition type, string interfaceName, bool generic, IMetadataResolver resolver) { while (type != null) { // does the type implements it itself @@ -148,24 +148,28 @@ public static bool Implements (TypeDefinition type, string interfaceName, bool g if (fullname == interfaceName) return true; //if not, then maybe one of its parent interfaces does - if (Implements (iface.Resolve (), interfaceName, generic)) + if (Implements (resolver.Resolve (iface), interfaceName, generic, resolver)) return true; } } - type = type.BaseType != null ? type.BaseType.Resolve () : null; + if (type.BaseType != null) { + type = resolver.Resolve (type.BaseType); + } else { + type = null; + } } return false; } - public static bool Inherits (this TypeReference self, string className) + public static bool Inherits (this TypeReference self, string className, IMetadataResolver resolver) { if (className == null) throw new ArgumentNullException ("className"); if (self == null) return false; - TypeReference current = self.Resolve (); + TypeReference current = resolver.Resolve (self); while (current != null) { string fullname = current.FullName; if (fullname == className) @@ -173,7 +177,7 @@ public static bool Inherits (this TypeReference self, string className) if (fullname == "System.Object") return false; - TypeDefinition td = current.Resolve (); + TypeDefinition td = resolver.Resolve (current); if (td == null) return false; // could not resolve type current = td.BaseType; @@ -285,7 +289,7 @@ public static bool TryGetBaseOrInterfaceRegisterMember (this MethodDefinition me if (iface.InterfaceType.IsGenericInstance) continue; - var itype = iface.InterfaceType.Resolve (); + var itype = resolver.Resolve (iface.InterfaceType); if (itype == null || !itype.HasMethods) continue; diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs index e07ec5e9751..777c419fbc8 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixLegacyResourceDesignerStep.cs @@ -26,6 +26,10 @@ public class FixLegacyResourceDesignerStep : LinkDesignerBase internal const string DesignerAssemblyName = "_Microsoft.Android.Resource.Designer"; internal const string DesignerAssemblyNamespace = "_Microsoft.Android.Resource.Designer"; +#if !ILLINK + public FixLegacyResourceDesignerStep (IMetadataResolver cache) : base (cache) { } +#endif + bool designerLoaded = false; AssemblyDefinition designerAssembly = null; TypeDefinition designerType = null; @@ -93,7 +97,7 @@ internal override bool ProcessAssemblyDesigner (AssemblyDefinition assembly) LogMessage ($" Adding reference {designerAssembly.Name.Name}."); assembly.MainModule.AssemblyReferences.Add (designerAssembly.Name); - var importedDesignerType = assembly.MainModule.ImportReference (designerType.Resolve ()); + var importedDesignerType = assembly.MainModule.ImportReference (Cache.Resolve (designerType)); LogMessage ($" FixupAssemblyTypes {assembly.Name.Name}."); // now replace all ldsfld with a call to the property get_ method. @@ -150,7 +154,7 @@ string GetFixupKey (Instruction instruction, string designerFullName) (fieldRef.DeclaringType?.ToString()?.Contains (".Resource/") ?? false)) { var canResolve = false; try { - var resolved = fieldRef.Resolve (); + var resolved = Cache.Resolve (fieldRef); canResolve = resolved != null; } catch (Exception) { } diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs index d999506b286..693727bd5cc 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkDesignerBase.cs @@ -15,7 +15,19 @@ namespace MonoDroid.Tuner { - public abstract class LinkDesignerBase : BaseStep { + public abstract class LinkDesignerBase : BaseStep + { +#if ILLINK + protected IMetadataResolver Cache => Context; +#else // !ILLINK + public LinkDesignerBase (IMetadataResolver cache) + { + Cache = cache; + } + + protected IMetadataResolver Cache { get; private set; } +#endif // !ILLINK + public virtual void LogMessage (string message) { Context.LogMessage (message); diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/RemoveResourceDesignerStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/RemoveResourceDesignerStep.cs index 2ef7e074cdc..0ac0e0e7c33 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/RemoveResourceDesignerStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/RemoveResourceDesignerStep.cs @@ -20,6 +20,11 @@ public class RemoveResourceDesignerStep : LinkDesignerBase CustomAttribute mainDesignerAttribute; Dictionary designerConstants; Regex opCodeRegex = new Regex (@"([\w]+): ([\w]+) ([\w.]+) ([\w:./]+)"); + +#if !ILLINK + public RemoveResourceDesignerStep (IMetadataResolver cache) : base (cache) { } +#endif + protected override void LoadDesigner () { if (mainAssembly != null) diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/ActivityAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/ActivityAttribute.Partial.cs index a51762461b8..bcf3cbac190 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/ActivityAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/ActivityAttribute.Partial.cs @@ -334,7 +334,7 @@ partial class ActivityAttribute { TypeDefinition type; ICollection specified; - public static ActivityAttribute FromTypeDefinition (TypeDefinition type) + public static ActivityAttribute FromTypeDefinition (TypeDefinition type, TypeDefinitionCache cache) { CustomAttribute attr = type.GetCustomAttributes ("Android.App.ActivityAttribute") .SingleOrDefault (); @@ -343,7 +343,7 @@ public static ActivityAttribute FromTypeDefinition (TypeDefinition type) ActivityAttribute self = new ActivityAttribute () { type = type, }; - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/ApplicationAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/ApplicationAttribute.Partial.cs index 4cf9e4a494d..36a9dd867d2 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/ApplicationAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/ApplicationAttribute.Partial.cs @@ -240,7 +240,7 @@ partial class ApplicationAttribute { ICollection specified; - public static ApplicationAttribute FromCustomAttributeProvider (ICustomAttributeProvider provider) + public static ApplicationAttribute FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache) { CustomAttribute attr = provider.GetCustomAttributes ("Android.App.ApplicationAttribute") .SingleOrDefault (); @@ -249,7 +249,7 @@ public static ApplicationAttribute FromCustomAttributeProvider (ICustomAttribute ApplicationAttribute self = new ApplicationAttribute () { provider = provider, }; - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); if (provider is TypeDefinition) { self.specified.Add ("Name"); } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/BroadcastReceiverAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/BroadcastReceiverAttribute.Partial.cs index 2b784d11c2b..013b79822da 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/BroadcastReceiverAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/BroadcastReceiverAttribute.Partial.cs @@ -71,14 +71,14 @@ partial class BroadcastReceiverAttribute { ICollection specified; - public static BroadcastReceiverAttribute FromTypeDefinition (TypeDefinition type) + public static BroadcastReceiverAttribute FromTypeDefinition (TypeDefinition type, TypeDefinitionCache cache) { CustomAttribute attr = type.GetCustomAttributes ("Android.Content.BroadcastReceiverAttribute") .SingleOrDefault (); if (attr == null) return null; var self = new BroadcastReceiverAttribute (); - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/ContentProviderAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/ContentProviderAttribute.Partial.cs index dfd659d0a40..fcef0600cb7 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/ContentProviderAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/ContentProviderAttribute.Partial.cs @@ -106,14 +106,14 @@ static string[] ToStringArray (object value) ICollection specified; - public static ContentProviderAttribute FromTypeDefinition (TypeDefinition type) + public static ContentProviderAttribute FromTypeDefinition (TypeDefinition type, TypeDefinitionCache cache) { CustomAttribute attr = type.GetCustomAttributes ("Android.Content.ContentProviderAttribute") .SingleOrDefault (); if (attr == null) return null; var self = new ContentProviderAttribute (ToStringArray (attr.ConstructorArguments [0].Value)); - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); self.specified.Add ("Authorities"); return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/GrantUriPermissionAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/GrantUriPermissionAttribute.Partial.cs index 15dc8907619..7fcd62eafef 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/GrantUriPermissionAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/GrantUriPermissionAttribute.Partial.cs @@ -33,14 +33,14 @@ partial class GrantUriPermissionAttribute { ICollection specified; - public static IEnumerable FromTypeDefinition (TypeDefinition type) + public static IEnumerable FromTypeDefinition (TypeDefinition type, TypeDefinitionCache cache) { IEnumerable attrs = type.GetCustomAttributes ("Android.Content.GrantUriPermissionAttribute"); if (!attrs.Any ()) yield break; foreach (CustomAttribute attr in attrs) { var self = new GrantUriPermissionAttribute (); - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); yield return self; } } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/InstrumentationAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/InstrumentationAttribute.Partial.cs index 1b31e8e681c..41a101a07d6 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/InstrumentationAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/InstrumentationAttribute.Partial.cs @@ -61,11 +61,11 @@ partial class InstrumentationAttribute { ICollection specified; - public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider) + public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache) { foreach (CustomAttribute attr in provider.GetCustomAttributes ("Android.App.InstrumentationAttribute")) { InstrumentationAttribute self = new InstrumentationAttribute (); - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); yield return self; } } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/IntentFilterAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/IntentFilterAttribute.Partial.cs index db765b53b2a..fb9e76ad9d4 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/IntentFilterAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/IntentFilterAttribute.Partial.cs @@ -66,7 +66,7 @@ static string[] ToStringArray (object value) HashSet specified = new HashSet (); - public static IEnumerable FromTypeDefinition (TypeDefinition type) + public static IEnumerable FromTypeDefinition (TypeDefinition type, IMetadataResolver cache) { IEnumerable attrs = type.GetCustomAttributes ("Android.App.IntentFilterAttribute"); if (!attrs.Any ()) @@ -75,7 +75,7 @@ public static IEnumerable FromTypeDefinition (TypeDefinit var self = new IntentFilterAttribute (ToStringArray (attr.ConstructorArguments [0].Value)); foreach (var e in attr.Properties) { self.specified.Add (e.Name); - setters [e.Name] (self, e.Argument.GetSettableValue ()); + setters [e.Name] (self, e.Argument.GetSettableValue (cache)); } yield return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/LayoutAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/LayoutAttribute.Partial.cs index 43bcf8e9438..19afcfea778 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/LayoutAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/LayoutAttribute.Partial.cs @@ -49,7 +49,7 @@ partial class LayoutAttribute TypeDefinition type; ICollection specified; - public static LayoutAttribute FromTypeDefinition (TypeDefinition type) + public static LayoutAttribute FromTypeDefinition (TypeDefinition type, TypeDefinitionCache cache) { CustomAttribute attr = type.GetCustomAttributes ("Android.App.LayoutAttribute") .SingleOrDefault (); @@ -58,7 +58,7 @@ public static LayoutAttribute FromTypeDefinition (TypeDefinition type) LayoutAttribute self = new LayoutAttribute () { type = type, }; - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/MetaDataAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/MetaDataAttribute.Partial.cs index 02b58638b0c..7e2b5a87d1d 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/MetaDataAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/MetaDataAttribute.Partial.cs @@ -33,14 +33,14 @@ partial class MetaDataAttribute { ICollection specified; - public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider type) + public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider type, TypeDefinitionCache cache) { IEnumerable attrs = type.GetCustomAttributes ("Android.App.MetaDataAttribute"); if (!attrs.Any ()) yield break; foreach (CustomAttribute attr in attrs) { var self = new MetaDataAttribute ((string) attr.ConstructorArguments [0].Value); - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); self.specified.Add ("Name"); yield return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionAttribute.Partial.cs index 6980b73d273..bbd0b7a8a06 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionAttribute.Partial.cs @@ -60,13 +60,13 @@ partial class PermissionAttribute { ICollection specified; - public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider) + public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache) { var attrs = provider.GetCustomAttributes ("Android.App.PermissionAttribute"); foreach (var attr in attrs) { PermissionAttribute self = new PermissionAttribute (); - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); yield return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionGroupAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionGroupAttribute.Partial.cs index 37292f0f557..2b71f9e1f64 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionGroupAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionGroupAttribute.Partial.cs @@ -50,13 +50,13 @@ partial class PermissionGroupAttribute { ICollection specified; - public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider) + public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache) { var attrs = provider.GetCustomAttributes ("Android.App.PermissionGroupAttribute"); foreach (var attr in attrs) { PermissionGroupAttribute self = new PermissionGroupAttribute (); - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); yield return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionTreeAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionTreeAttribute.Partial.cs index 266c09bd09b..17e6d7b3024 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionTreeAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionTreeAttribute.Partial.cs @@ -45,13 +45,13 @@ partial class PermissionTreeAttribute { ICollection specified; - public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider) + public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache) { var attrs = provider.GetCustomAttributes ("Android.App.PermissionTreeAttribute"); foreach (var attr in attrs) { PermissionTreeAttribute self = new PermissionTreeAttribute (); - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); yield return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/ServiceAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/ServiceAttribute.Partial.cs index 0c7b8ae56ec..9e931e2b3f2 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/ServiceAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/ServiceAttribute.Partial.cs @@ -79,14 +79,14 @@ partial class ServiceAttribute { ICollection specified; - public static ServiceAttribute FromTypeDefinition (TypeDefinition type) + public static ServiceAttribute FromTypeDefinition (TypeDefinition type, TypeDefinitionCache cache) { CustomAttribute attr = type.GetCustomAttributes ("Android.App.ServiceAttribute") .SingleOrDefault (); if (attr == null) return null; ServiceAttribute self = new ServiceAttribute (); - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/SupportsGLTextureAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/SupportsGLTextureAttribute.Partial.cs index 5f93492aeba..41d970eb8cb 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/SupportsGLTextureAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/SupportsGLTextureAttribute.Partial.cs @@ -27,13 +27,13 @@ internal XElement ToElement (string packageName, TypeDefinitionCache cache) ICollection specified; - public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider) + public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache) { var attrs = provider.GetCustomAttributes ("Android.App.SupportsGLTextureAttribute"); foreach (var attr in attrs) { if (attr.HasConstructorArguments && attr.ConstructorArguments.Count == 1) { SupportsGLTextureAttribute self = new SupportsGLTextureAttribute((string)attr.ConstructorArguments[0].Value); - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); self.specified.Add("Name"); yield return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesConfigurationAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesConfigurationAttribute.Partial.cs index 6d06b0fffae..8ee69c21d23 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesConfigurationAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesConfigurationAttribute.Partial.cs @@ -49,14 +49,14 @@ internal XElement ToElement (string packageName, TypeDefinitionCache cache) ICollection specified; - public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider) + public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache) { var attrs = provider.GetCustomAttributes ("Android.App.UsesConfigurationAttribute"); foreach (var attr in attrs) { UsesConfigurationAttribute self = new UsesConfigurationAttribute (); - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); yield return self; } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesFeatureAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesFeatureAttribute.Partial.cs index e638b939b33..5b9316bcbdb 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesFeatureAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesFeatureAttribute.Partial.cs @@ -50,7 +50,7 @@ internal XElement ToElement (string packageName, TypeDefinitionCache cache) ICollection specified; - public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider) + public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache) { var attrs = provider.GetCustomAttributes ("Android.App.UsesFeatureAttribute"); foreach (var attr in attrs) { @@ -59,7 +59,7 @@ public static IEnumerable FromCustomAttributeProvider (ICu if (attr.HasProperties) { // handle the case where the user sets additional properties - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); if (self.specified.Contains("GLESVersion") && self.GLESVersion==0) { throw new InvalidOperationException("Invalid value '0' for UsesFeatureAttribute.GLESVersion."); } diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesLibraryAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesLibraryAttribute.Partial.cs index 6ca0147370d..0e2c68b9669 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesLibraryAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesLibraryAttribute.Partial.cs @@ -28,7 +28,7 @@ partial class UsesLibraryAttribute { ICollection specified; - public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider) + public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache) { var attrs = provider.GetCustomAttributes ("Android.App.UsesLibraryAttribute"); foreach (var attr in attrs) { @@ -49,7 +49,7 @@ public static IEnumerable FromCustomAttributeProvider (ICu extra = Array.Empty (); } - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); foreach (var e in extra) self.specified.Add (e); diff --git a/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesPermissionAttribute.Partial.cs b/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesPermissionAttribute.Partial.cs index 4e3792883b5..d7d12ce4daf 100644 --- a/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesPermissionAttribute.Partial.cs +++ b/src/Xamarin.Android.Build.Tasks/Mono.Android/UsesPermissionAttribute.Partial.cs @@ -30,7 +30,7 @@ partial class UsesPermissionAttribute { ICollection specified; - public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider) + public static IEnumerable FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache) { var attrs = provider.GetCustomAttributes ("Android.App.UsesPermissionAttribute"); foreach (var attr in attrs) { @@ -45,7 +45,7 @@ public static IEnumerable FromCustomAttributeProvider ( extra = Array.Empty (); } - self.specified = mapping.Load (self, attr); + self.specified = mapping.Load (self, attr, cache); foreach (var e in extra) self.specified.Add (e); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/CheckClientHandlerType.cs b/src/Xamarin.Android.Build.Tasks/Tasks/CheckClientHandlerType.cs index d9ae701ba2c..9fbee563960 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/CheckClientHandlerType.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/CheckClientHandlerType.cs @@ -47,6 +47,7 @@ public override bool RunTask () ReadSymbols = false, }; using (var resolver = new DirectoryAssemblyResolver (this.CreateTaskLogger (), loadDebugSymbols: false, loadReaderParameters: readerParameters)) { + var cache = new TypeDefinitionCache (); foreach (var asm in ResolvedAssemblies) { var path = Path.GetFullPath (Path.GetDirectoryName (asm.ItemSpec)); if (!resolver.SearchDirectories.Contains (path)) { @@ -66,11 +67,11 @@ public override bool RunTask () return false; } - if (Extends (handlerType, "System.Net.Http.HttpClientHandler")) { + if (Extends (cache, handlerType, "System.Net.Http.HttpClientHandler")) { Log.LogCodedError ("XA1031", Xamarin.Android.Tasks.Properties.Resources.XA1031_HCH, type); } - if (!Extends (handlerType, "System.Net.Http.HttpMessageHandler")) { + if (!Extends (cache, handlerType, "System.Net.Http.HttpMessageHandler")) { Log.LogCodedError ("XA1031", Xamarin.Android.Tasks.Properties.Resources.XA1031, type, "System.Net.Http.HttpMessageHandler"); } @@ -78,12 +79,16 @@ public override bool RunTask () } } - static bool Extends (TypeDefinition type, string validBase) { - var bt = type.Resolve (); + static bool Extends (TypeDefinitionCache cache, TypeDefinition type, string validBase) { + var bt = cache.Resolve (type); while (bt != null) { if (bt.FullName == validBase) return true; - bt = bt.BaseType?.Resolve () ?? null; + if (bt.BaseType != null) { + bt = cache.Resolve (bt.BaseType); + } else { + bt = null; + } } return false; } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs index ff2b113044d..491e04c3c31 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesignerAssembly.cs @@ -67,8 +67,10 @@ public override bool RunTask () return !Log.HasLoggedErrors; } - bool Run(DirectoryAssemblyResolver res) + bool Run (DirectoryAssemblyResolver res) { + var cache = new TypeDefinitionCache (); + foreach (var dir in FrameworkDirectories) { if (Directory.Exists (dir.ItemSpec)) res.SearchDirectories.Add (dir.ItemSpec); @@ -98,26 +100,26 @@ bool Run(DirectoryAssemblyResolver res) var netstandardDef = module.AssemblyResolver.Resolve(netstandardAsm); if (!IsApplication) { - MethodReference referenceAssemblyConstructor = ImportCustomAttributeConstructor ("System.Runtime.CompilerServices.ReferenceAssemblyAttribute", module, netstandardDef.MainModule); + MethodReference referenceAssemblyConstructor = ImportCustomAttributeConstructor (cache, "System.Runtime.CompilerServices.ReferenceAssemblyAttribute", module, netstandardDef.MainModule); module.Assembly.CustomAttributes.Add (new CustomAttribute (referenceAssemblyConstructor)); } else { // Add the InternalsVisibleToAttribute so the app can access ResourceConstant if (!string.IsNullOrEmpty (AssemblyName)) { - MethodReference internalsVisibleToAttributeConstructor = ImportCustomAttributeConstructor ("System.Runtime.CompilerServices.InternalsVisibleToAttribute", module, netstandardDef.MainModule, argCount: 1); + MethodReference internalsVisibleToAttributeConstructor = ImportCustomAttributeConstructor (cache, "System.Runtime.CompilerServices.InternalsVisibleToAttribute", module, netstandardDef.MainModule, argCount: 1); var ar = new CustomAttribute (internalsVisibleToAttributeConstructor); ar.ConstructorArguments.Add (new CustomAttributeArgument (module.TypeSystem.String, AssemblyName)); module.Assembly.CustomAttributes.Add (ar); } } - MethodReference targetFrameworkConstructor = ImportCustomAttributeConstructor ("System.Runtime.Versioning.TargetFrameworkAttribute", module, netstandardDef.MainModule, argCount: 1); + MethodReference targetFrameworkConstructor = ImportCustomAttributeConstructor (cache, "System.Runtime.Versioning.TargetFrameworkAttribute", module, netstandardDef.MainModule, argCount: 1); var attr = new CustomAttribute (targetFrameworkConstructor); attr.ConstructorArguments.Add (new CustomAttributeArgument (module.TypeSystem.String, $".NETStandard,Version=v2.1")); attr.Properties.Add (new CustomAttributeNamedArgument ("FrameworkDisplayName", new CustomAttributeArgument (module.TypeSystem.String, ""))); module.Assembly.CustomAttributes.Add (attr); - MethodReference editorBrowserConstructor = ImportCustomAttributeConstructor ("System.ComponentModel.EditorBrowsableAttribute", module, netstandardDef.MainModule, argCount: 1); + MethodReference editorBrowserConstructor = ImportCustomAttributeConstructor (cache, "System.ComponentModel.EditorBrowsableAttribute", module, netstandardDef.MainModule, argCount: 1); TypeReference e = ImportType ("System.ComponentModel.EditorBrowsableState", module, netstandardDef.MainModule); var editorBrowserAttr = new CustomAttribute (editorBrowserConstructor); editorBrowserAttr.ConstructorArguments.Add (new CustomAttributeArgument (e, System.ComponentModel.EditorBrowsableState.Never)); @@ -135,7 +137,7 @@ bool Run(DirectoryAssemblyResolver res) att, objectRef ); - CreateCtor (resourceDesigner, module); + CreateCtor (cache, resourceDesigner, module); resourceDesigner.CustomAttributes.Add (editorBrowserAttr); module.Types.Add (resourceDesigner); TypeDefinition constDesigner = null; @@ -148,7 +150,7 @@ bool Run(DirectoryAssemblyResolver res) attrib | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit, objectRef ); - CreateCtor (constDesigner, module); + CreateCtor (cache, constDesigner, module); constDesigner.CustomAttributes.Add (editorBrowserAttr); module.Types.Add (constDesigner); } @@ -168,13 +170,13 @@ bool Run(DirectoryAssemblyResolver res) switch (r.Type) { case RType.Integer: if (IsApplication) - CreateIntField (r.ResourceTypeName, r.Identifier, r.Id, constDesigner, module); - CreateIntProperty (r.ResourceTypeName, r.Identifier, r.Id, resourceDesigner, module); + CreateIntField (cache, r.ResourceTypeName, r.Identifier, r.Id, constDesigner, module); + CreateIntProperty (cache, r.ResourceTypeName, r.Identifier, r.Id, resourceDesigner, module); break; case RType.Array: if (IsApplication) - CreateIntArrayField (r.ResourceTypeName, r.Identifier, r.Ids, constDesigner, module); - CreateIntArrayProperty (r.ResourceTypeName, r.Identifier, r.Ids, resourceDesigner, module); + CreateIntArrayField (cache, r.ResourceTypeName, r.Identifier, r.Ids, constDesigner, module); + CreateIntArrayProperty (cache, r.ResourceTypeName, r.Identifier, r.Ids, resourceDesigner, module); break; } } @@ -203,10 +205,10 @@ bool Run(DirectoryAssemblyResolver res) return !Log.HasLoggedErrors; } - MethodReference ImportCustomAttributeConstructor (string type, ModuleDefinition module, ModuleDefinition sourceModule = null, int argCount = 0) + MethodReference ImportCustomAttributeConstructor (TypeDefinitionCache cache, string type, ModuleDefinition module, ModuleDefinition sourceModule = null, int argCount = 0) { var tr = module.ImportReference ((sourceModule ?? module).ExportedTypes.First(x => x.FullName == type).Resolve ()); - var tv = tr.Resolve(); + var tv = cache.Resolve (tr); return module.ImportReference (tv.Methods.First(x => x.IsConstructor && (x.Parameters?.Count ?? 0) == argCount)); } @@ -215,36 +217,36 @@ TypeReference ImportType (string type, ModuleDefinition module, ModuleDefinition return module.ImportReference ((sourceModule ?? module).ExportedTypes.First(x => x.FullName == type).Resolve ()); } - void CreateIntProperty (string resourceClass, string propertyName, int value, TypeDefinition resourceDesigner, ModuleDefinition module, + void CreateIntProperty (TypeDefinitionCache cache, string resourceClass, string propertyName, int value, TypeDefinition resourceDesigner, ModuleDefinition module, MethodAttributes attributes = MethodAttributes.Public, TypeAttributes typeAttributes = TypeAttributes.NestedPublic) { - TypeDefinition nestedType = CreateResourceClass (resourceDesigner, resourceClass, module, typeAttributes); + TypeDefinition nestedType = CreateResourceClass (cache, resourceDesigner, resourceClass, module, typeAttributes); PropertyDefinition p = CreateProperty (propertyName, value, module, attributes); nestedType.Properties.Add (p); nestedType.Methods.Insert (Math.Max(0, nestedType.Methods.Count () - 1), p.GetMethod); } - void CreateIntField (string resourceClass, string fieldName, int value, TypeDefinition resourceDesigner, ModuleDefinition module, + void CreateIntField (TypeDefinitionCache cache, string resourceClass, string fieldName, int value, TypeDefinition resourceDesigner, ModuleDefinition module, FieldAttributes attributes = FieldAttributes.Public, TypeAttributes typeAttributes = TypeAttributes.NestedPublic) { - TypeDefinition nestedType = CreateResourceClass (resourceDesigner, resourceClass, module, typeAttributes); + TypeDefinition nestedType = CreateResourceClass (cache, resourceDesigner, resourceClass, module, typeAttributes); FieldDefinition p = CreateField (fieldName, value, module, attributes); nestedType.Fields.Add (p); } - void CreateIntArrayProperty (string resourceClass, string propertyName, int[] values, TypeDefinition resourceDesigner, ModuleDefinition module, + void CreateIntArrayProperty (TypeDefinitionCache cache, string resourceClass, string propertyName, int[] values, TypeDefinition resourceDesigner, ModuleDefinition module, MethodAttributes attributes = MethodAttributes.Public, TypeAttributes typeAttributes = TypeAttributes.NestedPublic) { - TypeDefinition nestedType = CreateResourceClass (resourceDesigner, resourceClass, module, typeAttributes); + TypeDefinition nestedType = CreateResourceClass (cache, resourceDesigner, resourceClass, module, typeAttributes); PropertyDefinition p = CreateArrayProperty (propertyName, values, module, attributes); nestedType.Properties.Add (p); nestedType.Methods.Insert (Math.Max(0, nestedType.Methods.Count () - 1), p.GetMethod); } - void CreateIntArrayField (string resourceClass, string fieldName, int[] values, TypeDefinition resourceDesigner, ModuleDefinition module, + void CreateIntArrayField (TypeDefinitionCache cache, string resourceClass, string fieldName, int[] values, TypeDefinition resourceDesigner, ModuleDefinition module, FieldAttributes attributes = FieldAttributes.Public, TypeAttributes typeAttributes = TypeAttributes.NestedPublic) { - TypeDefinition nestedType = CreateResourceClass (resourceDesigner, resourceClass, module, typeAttributes); + TypeDefinition nestedType = CreateResourceClass (cache, resourceDesigner, resourceClass, module, typeAttributes); FieldDefinition p = CreateArrayField (fieldName, values, module, attributes); nestedType.Fields.Add (p); MethodDefinition ctor = GetOrCreateStaticCtor (nestedType, module); @@ -264,12 +266,12 @@ void CreateIntArrayField (string resourceClass, string fieldName, int[] values, Dictionary resourceClasses = new Dictionary (StringComparer.OrdinalIgnoreCase); Dictionary staticConstructors = new Dictionary (); - void CreateCtor (TypeDefinition type, ModuleDefinition module) + void CreateCtor (TypeDefinitionCache cache, TypeDefinition type, ModuleDefinition module) { var ctor = new MethodDefinition (".ctor", MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, module.TypeSystem.Void); var ctoril = ctor.Body.GetILProcessor (); ctoril.Emit (OpCodes.Ldarg_0); - var o = module.TypeSystem.Object.Resolve (); + var o = cache.Resolve (module.TypeSystem.Object); ctoril.Emit (OpCodes.Call, module.ImportReference (o.Methods.First (x => x.IsConstructor))); ctoril.Emit (OpCodes.Ret); type.Methods.Add (ctor); @@ -287,7 +289,7 @@ MethodDefinition GetOrCreateStaticCtor (TypeDefinition type, ModuleDefinition mo return ctor; } - TypeDefinition CreateResourceClass (TypeDefinition resourceDesigner, string className, ModuleDefinition module, TypeAttributes attributes = TypeAttributes.NestedPublic) + TypeDefinition CreateResourceClass (TypeDefinitionCache cache, TypeDefinition resourceDesigner, string className, ModuleDefinition module, TypeAttributes attributes = TypeAttributes.NestedPublic) { string name = ResourceParser.GetNestedTypeName (className); string key = resourceDesigner.Name + name; @@ -295,7 +297,7 @@ TypeDefinition CreateResourceClass (TypeDefinition resourceDesigner, string clas return resourceClasses[key]; } var resourceClass = new TypeDefinition (string.Empty, name, attributes | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.Sealed, objectRef); - CreateCtor (resourceClass, module); + CreateCtor (cache, resourceClass, module); resourceDesigner.NestedTypes.Add (resourceClass); resourceClasses[key] = resourceClass; return resourceClass; diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs index 7f551dbc898..0533766aa12 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssembliesNoShrink.cs @@ -69,7 +69,7 @@ public override bool RunTask () var cache = new TypeDefinitionCache (); var fixAbstractMethodsStep = new FixAbstractMethodsStep (resolver, cache, Log); var addKeepAliveStep = new AddKeepAlivesStep (resolver, cache, Log); - var fixLegacyResourceDesignerStep = new FixLegacyResourceDesignerStep (resolver, Log); + var fixLegacyResourceDesignerStep = new FixLegacyResourceDesignerStep (resolver, cache, Log); for (int i = 0; i < SourceFiles.Length; i++) { var source = SourceFiles [i]; var destination = DestinationFiles [i]; @@ -126,7 +126,8 @@ class FixLegacyResourceDesignerStep : MonoDroid.Tuner.FixLegacyResourceDesignerS readonly DirectoryAssemblyResolver resolver; readonly TaskLoggingHelper logger; - public FixLegacyResourceDesignerStep (DirectoryAssemblyResolver resolver, TaskLoggingHelper logger) + public FixLegacyResourceDesignerStep (DirectoryAssemblyResolver resolver, TypeDefinitionCache cache, TaskLoggingHelper logger) + : base(cache) { this.resolver = resolver; this.logger = logger; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs index 4b445ce8c97..9ddfaf95bf7 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs @@ -13,6 +13,7 @@ using Android.App; using Mono.Cecil; using System.Reflection; +using Java.Interop.Tools.Cecil; namespace Xamarin.Android.Build.Tests { @@ -1172,10 +1173,11 @@ public class IntentFilterAttributeDataPathTestClass { } [Test] public void IntentFilterDataPathTest () { + var cache = new TypeDefinitionCache (); var asm = AssemblyDefinition.ReadAssembly (typeof (IntentFilterAttributeDataPathTestClass).Assembly.Location); var type = asm.MainModule.GetType ("Xamarin.Android.Build.Tests.ManifestTest/IntentFilterAttributeDataPathTestClass"); - var intent = IntentFilterAttribute.FromTypeDefinition (type).Single (f => f.Actions.Contains ("singularAction")); + var intent = IntentFilterAttribute.FromTypeDefinition (type, cache).Single (f => f.Actions.Contains ("singularAction")); var xml = intent.ToElement ("dummy.packageid").ToString (); var expected = @@ -1191,10 +1193,11 @@ public void IntentFilterDataPathTest () [Test] public void IntentFilterDataPathsTest () { + var cache = new TypeDefinitionCache (); var asm = AssemblyDefinition.ReadAssembly (typeof (IntentFilterAttributeDataPathTestClass).Assembly.Location); var type = asm.MainModule.GetType ("Xamarin.Android.Build.Tests.ManifestTest/IntentFilterAttributeDataPathTestClass"); - var intent = IntentFilterAttribute.FromTypeDefinition (type).Single (f => f.Actions.Contains ("pluralAction")); + var intent = IntentFilterAttribute.FromTypeDefinition (type, cache).Single (f => f.Actions.Contains ("pluralAction")); var xml = intent.ToElement ("dummy.packageid").ToString (); var expected = diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs b/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs index 8a1b8996794..292e7229d64 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs @@ -573,18 +573,18 @@ XElement CreateApplicationElement (XElement manifest, string applicationClass, L var application = manifest.Descendants ("application").FirstOrDefault (); List assemblyAttr = - Assemblies.Select (path => ApplicationAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path))) + Assemblies.Select (path => ApplicationAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path), cache)) .Where (attr => attr != null) .ToList (); List metadata = - Assemblies.SelectMany (path => MetaDataAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path))) + Assemblies.SelectMany (path => MetaDataAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path), cache)) .Where (attr => attr != null) .ToList (); var usesLibraryAttr = - Assemblies.SelectMany (path => UsesLibraryAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path))) + Assemblies.SelectMany (path => UsesLibraryAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path), cache)) .Where (attr => attr != null); var usesConfigurationAttr = - Assemblies.SelectMany (path => UsesConfigurationAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path))) + Assemblies.SelectMany (path => UsesConfigurationAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path), cache)) .Where (attr => attr != null); if (assemblyAttr.Count > 1) throw new InvalidOperationException ("There can be only one [assembly:Application] attribute defined."); @@ -594,7 +594,7 @@ XElement CreateApplicationElement (XElement manifest, string applicationClass, L List typeUsesConfigurationAttr = new List (); foreach (JavaType jt in subclasses) { TypeDefinition t = jt.Type; - ApplicationAttribute aa = ApplicationAttribute.FromCustomAttributeProvider (t); + ApplicationAttribute aa = ApplicationAttribute.FromCustomAttributeProvider (t, cache); if (aa == null) continue; @@ -602,9 +602,9 @@ XElement CreateApplicationElement (XElement manifest, string applicationClass, L throw new InvalidOperationException (string.Format ("Found [Application] on type {0}. [Application] can only be used on subclasses of Application.", t.FullName)); typeAttr.Add (aa); - metadata.AddRange (MetaDataAttribute.FromCustomAttributeProvider (t)); + metadata.AddRange (MetaDataAttribute.FromCustomAttributeProvider (t, cache)); - typeUsesLibraryAttr.AddRange (UsesLibraryAttribute.FromCustomAttributeProvider (t)); + typeUsesLibraryAttr.AddRange (UsesLibraryAttribute.FromCustomAttributeProvider (t, cache)); } if (typeAttr.Count > 1) @@ -743,7 +743,7 @@ XElement ActivityFromTypeDefinition (TypeDefinition type, string name, TypeDefin (aa, element) => { if (aa.MainLauncher) AddLauncherIntentElements (element); - var la = LayoutAttribute.FromTypeDefinition (type); + var la = LayoutAttribute.FromTypeDefinition (type, cache); if (la != null) element.Add (la.ToElement (Resolver, PackageName, cache)); }, @@ -753,7 +753,7 @@ XElement ActivityFromTypeDefinition (TypeDefinition type, string name, TypeDefin XElement InstrumentationFromTypeDefinition (TypeDefinition type, string name, TypeDefinitionCache cache) { return ToElement (type, name, - t => InstrumentationAttribute.FromCustomAttributeProvider (t).FirstOrDefault (), + (t, c) => InstrumentationAttribute.FromCustomAttributeProvider (t, c).FirstOrDefault (), ia => { if (ia.TargetPackage == null) ia.SetTargetPackage (PackageName); @@ -762,21 +762,21 @@ XElement InstrumentationFromTypeDefinition (TypeDefinition type, string name, Ty cache); } - XElement ToElement (TypeDefinition type, string name, Func parser, Func toElement, TypeDefinitionCache cache) + XElement ToElement (TypeDefinition type, string name, Func parser, Func toElement, TypeDefinitionCache cache) where TAttribute : class { return ToElement (type, name, parser, toElement, update: null, cache); } - XElement ToElement (TypeDefinition type, string name, Func parser, Func toElement, Action update, TypeDefinitionCache cache) + XElement ToElement (TypeDefinition type, string name, Func parser, Func toElement, Action update, TypeDefinitionCache cache) where TAttribute : class { - TAttribute attr = parser (type); + TAttribute attr = parser (type, cache); if (attr == null) return null; - IEnumerable metadata = MetaDataAttribute.FromCustomAttributeProvider (type); - IEnumerable intents = IntentFilterAttribute.FromTypeDefinition (type); + IEnumerable metadata = MetaDataAttribute.FromCustomAttributeProvider (type, cache); + IEnumerable intents = IntentFilterAttribute.FromTypeDefinition (type, cache); XElement element = toElement (attr); if (element.Attribute (attName) == null) @@ -790,13 +790,13 @@ XElement ToElement (TypeDefinition type, string name, Func metadata = MetaDataAttribute.FromCustomAttributeProvider (type); - IEnumerable grants = GrantUriPermissionAttribute.FromTypeDefinition (type); - IEnumerable intents = IntentFilterAttribute.FromTypeDefinition (type); + IEnumerable metadata = MetaDataAttribute.FromCustomAttributeProvider (type, cache); + IEnumerable grants = GrantUriPermissionAttribute.FromTypeDefinition (type, cache); + IEnumerable intents = IntentFilterAttribute.FromTypeDefinition (type, cache); XElement element = attr.ToElement (PackageName, cache); if (element.Attribute (attName) == null) @@ -838,7 +838,7 @@ public void AddInternetPermissionForDebugger () void AddPermissions (XElement application, TypeDefinitionCache cache) { var assemblyAttrs = - Assemblies.SelectMany (path => PermissionAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path))); + Assemblies.SelectMany (path => PermissionAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path), cache)); // Add unique permissions to the manifest foreach (var pa in assemblyAttrs.Distinct (new PermissionAttribute.PermissionAttributeComparer ())) if (!application.Parent.Descendants ("permission").Any (x => (string)x.Attribute (attName) == pa.Name)) @@ -848,7 +848,7 @@ void AddPermissions (XElement application, TypeDefinitionCache cache) void AddPermissionGroups (XElement application, TypeDefinitionCache cache) { var assemblyAttrs = - Assemblies.SelectMany (path => PermissionGroupAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path))); + Assemblies.SelectMany (path => PermissionGroupAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path), cache)); // Add unique permissionGroups to the manifest foreach (var pga in assemblyAttrs.Distinct (new PermissionGroupAttribute.PermissionGroupAttributeComparer ())) @@ -859,7 +859,7 @@ void AddPermissionGroups (XElement application, TypeDefinitionCache cache) void AddPermissionTrees (XElement application, TypeDefinitionCache cache) { var assemblyAttrs = - Assemblies.SelectMany (path => PermissionTreeAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path))); + Assemblies.SelectMany (path => PermissionTreeAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path), cache)); // Add unique permissionGroups to the manifest foreach (var pta in assemblyAttrs.Distinct (new PermissionTreeAttribute.PermissionTreeAttributeComparer ())) @@ -870,7 +870,7 @@ void AddPermissionTrees (XElement application, TypeDefinitionCache cache) void AddUsesPermissions (XElement application, TypeDefinitionCache cache) { var assemblyAttrs = - Assemblies.SelectMany (path => UsesPermissionAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path))); + Assemblies.SelectMany (path => UsesPermissionAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path), cache)); // Add unique permissions to the manifest foreach (var upa in assemblyAttrs.Distinct (new UsesPermissionAttribute.UsesPermissionComparer ())) @@ -894,7 +894,7 @@ void AddUsesLibraries (XElement application, IEnumerable l void AddUsesFeatures (XElement application, TypeDefinitionCache cache) { var assemblyAttrs = - Assemblies.SelectMany (path => UsesFeatureAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path))); + Assemblies.SelectMany (path => UsesFeatureAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path), cache)); // Add unique features by Name or glESVersion to the manifest foreach (var feature in assemblyAttrs) { @@ -915,7 +915,7 @@ void AddUsesFeatures (XElement application, TypeDefinitionCache cache) void AddSupportsGLTextures (XElement application, TypeDefinitionCache cache) { var assemblyAttrs = - Assemblies.SelectMany (path => SupportsGLTextureAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path))); + Assemblies.SelectMany (path => SupportsGLTextureAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path), cache)); // Add unique items by Name to the manifest foreach (var feature in assemblyAttrs) { @@ -928,7 +928,7 @@ void AddSupportsGLTextures (XElement application, TypeDefinitionCache cache) void AddInstrumentations (XElement manifest, IList subclasses, int targetSdkVersion, TypeDefinitionCache cache) { var assemblyAttrs = - Assemblies.SelectMany (path => InstrumentationAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path))); + Assemblies.SelectMany (path => InstrumentationAttribute.FromCustomAttributeProvider (Resolver.GetAssembly (path), cache)); // Add instrumentation to the manifest foreach (var ia in assemblyAttrs) { diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocumentElement.cs b/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocumentElement.cs index cf51a75094f..3139f366fb8 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocumentElement.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocumentElement.cs @@ -112,7 +112,7 @@ public void Add (string member, string attributeName, Action setter, }); } - public ICollection Load (T value, CustomAttribute attribute) + public ICollection Load (T value, CustomAttribute attribute, TypeDefinitionCache cache) { if (attribute == null) return null; @@ -123,7 +123,7 @@ public ICollection Load (T value, CustomAttribute attribute) specified.Add (e.Name); var s = Mappings [e.Name].Setter; if (s != null) - s (value, e.Argument.GetSettableValue ()); + s (value, e.Argument.GetSettableValue (cache)); } return specified; diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs b/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs index e7418e430a1..0792f992daa 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsClassifier.cs @@ -133,10 +133,12 @@ sealed class NativeCallbackSignature : IMethodSignatureMatcher readonly List paramTypes; readonly string returnType; readonly TaskLoggingHelper log; + readonly TypeDefinitionCache cache; - public NativeCallbackSignature (MethodDefinition target, TaskLoggingHelper log) + public NativeCallbackSignature (MethodDefinition target, TaskLoggingHelper log, TypeDefinitionCache cache) { this.log = log; + this.cache = cache; returnType = MapType (target.ReturnType); paramTypes = new List { "System.IntPtr", // jnienv @@ -152,7 +154,7 @@ string MapType (TypeReference typeRef) { string? typeName = null; if (!typeRef.IsGenericParameter && !typeRef.IsArray) { - TypeDefinition typeDef = typeRef.Resolve (); + TypeDefinition typeDef = cache.Resolve (typeRef); if (typeDef == null) { throw new InvalidOperationException ($"Unable to resolve type '{typeRef.FullName}'"); } @@ -453,7 +455,7 @@ bool IsStandardHandler (TypeDefinition topType, ConnectorInfo connector, MethodD return false; } - var ncbs = new NativeCallbackSignature (registeredMethod, log); + var ncbs = new NativeCallbackSignature (registeredMethod, log, tdCache); MethodDefinition nativeCallbackMethod = FindMethod (connectorDeclaringType, nativeCallbackName, ncbs); if (nativeCallbackMethod == null) { log.LogWarning ($"\tUnable to find native callback method '{nativeCallbackName}' in type '{connectorDeclaringType.FullName}', matching the '{registeredMethod.FullName}' signature (jniName: '{jniName}')"); diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj index b5160a3755b..d2304de5a5d 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj @@ -5,6 +5,7 @@ + netstandard2.0