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 70de2500931..bcc78f1cf6f 100644
--- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/FixAbstractMethodsStep.cs
@@ -23,30 +23,18 @@ namespace MonoDroid.Tuner
///
/// NOTE: this step is subclassed so it can be called directly from Xamarin.Android.Build.Tasks
///
- public class FixAbstractMethodsStep :
-#if ILLINK
- BaseMarkHandler
-#else // !ILLINK
- BaseStep
-#endif // !ILLINK
+ public class FixAbstractMethodsStep : BaseStep
{
-
#if ILLINK
- public override void Initialize (LinkContext context, MarkContext markContext)
- {
- this.cache = context;
- base.Initialize (context, markContext);
- markContext.RegisterMarkTypeAction (type => ProcessType (type));
- }
+ IMetadataResolver cache => Context;
#else // !ILLINK
+ readonly IMetadataResolver cache;
+
public FixAbstractMethodsStep (IMetadataResolver cache)
{
this.cache = cache;
}
-
- readonly
#endif // !ILLINK
- IMetadataResolver cache;
bool CheckShouldProcessAssembly (AssemblyDefinition assembly)
{
@@ -74,29 +62,78 @@ void UpdateAssemblyAction (AssemblyDefinition assembly)
}
#if ILLINK
+ readonly List assemblies = new ();
+
+ protected override void ProcessAssembly (AssemblyDefinition assembly)
+ {
+ assemblies.Add (assembly);
+ }
+
+ protected override void EndProcess ()
+ {
+ foreach (var assembly in GetReferencedAssemblies().ToList()) {
+ ProcessAssembly_Actual(assembly);
+ }
+
+ IEnumerable GetReferencedAssemblies ()
+ {
+ var loaded = new HashSet (assemblies);
+ var toProcess = new Queue (assemblies);
+
+ while (toProcess.Count > 0) {
+ var assembly = toProcess.Dequeue ();
+ foreach (var reference in ResolveReferences (assembly)) {
+ if (!loaded.Add (reference))
+ continue;
+ yield return reference;
+ toProcess.Enqueue (reference);
+ }
+ }
+ }
+
+ ICollection ResolveReferences (AssemblyDefinition assembly)
+ {
+ List references = new List ();
+ if (assembly == null)
+ return references;
+
+ foreach (AssemblyNameReference reference in assembly.MainModule.AssemblyReferences) {
+ AssemblyDefinition? definition = Context.Resolve (reference);
+ if (definition != null)
+ references.Add (definition);
+ }
+
+ return references;
+ }
+ }
+
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 // !ILLINK
+#endif // ILLINK
+
+#if ILLINK
+ void ProcessAssembly_Actual (AssemblyDefinition assembly)
+#else // !ILLINK
protected override void ProcessAssembly (AssemblyDefinition assembly)
+#endif // !ILLINK
{
if (!CheckShouldProcessAssembly (assembly))
return;
if (FixAbstractMethods (assembly)) {
+#if !ILLINK
Context.SafeReadSymbols (assembly);
+#endif // !ILLINK
UpdateAssemblyAction (assembly);
MarkAbstractMethodErrorType ();
}
@@ -106,12 +143,19 @@ internal bool FixAbstractMethods (AssemblyDefinition assembly)
{
bool changed = false;
foreach (var type in assembly.MainModule.Types) {
- if (MightNeedFix (type))
- changed |= FixAbstractMethods (type);
+ changed |= FixAbstractMethodsNested (type);
}
return changed;
+
+ bool FixAbstractMethodsNested (TypeDefinition type)
+ {
+ bool changed = FixAbstractMethods (type);
+ foreach (var nested in type.NestedTypes) {
+ changed |= FixAbstractMethodsNested (nested);
+ }
+ return changed;
+ }
}
-#endif // !ILLINK
readonly HashSet warnedAssemblies = new (StringComparer.Ordinal);
@@ -242,6 +286,9 @@ bool HaveSameSignature (TypeReference iface, MethodDefinition iMethod, MethodDef
bool FixAbstractMethods (TypeDefinition type)
{
+ if (!MightNeedFix (type))
+ return false;
+
if (!type.HasInterfaces)
return false;
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 e99bfb0e722..d58bb7a0b43 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
@@ -50,6 +50,7 @@ This file contains the .NET 5-specific targets to customize ILLink
<_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" BeforeStep="MarkStep" Type="Microsoft.Android.Sdk.ILLink.SetupStep" />
+ <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" BeforeStep="MarkStep" Type="MonoDroid.Tuner.FixAbstractMethodsStep" />
<_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="Microsoft.Android.Sdk.ILLink.PreserveSubStepDispatcher" />
<_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="MonoDroid.Tuner.MarkJavaObjects" />
@@ -57,7 +58,6 @@ This file contains the .NET 5-specific targets to customize ILLink
<_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
Condition=" '$(_ProguardProjectConfiguration)' != '' "