-
Notifications
You must be signed in to change notification settings - Fork 537
/
Copy pathSetupStep.cs
88 lines (74 loc) · 3.24 KB
/
SetupStep.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System;
using System.Collections.Generic;
using System.Reflection;
using Java.Interop.Tools.Cecil;
using Mono.Cecil;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Tuner;
using MonoDroid.Tuner;
namespace Microsoft.Android.Sdk.ILLink
{
class SetupStep : BaseStep
{
List<IStep> _steps;
List<IStep> Steps {
get {
if (_steps == null) {
var pipeline = typeof (LinkContext).GetProperty ("Pipeline").GetGetMethod ().Invoke (Context, null);
_steps = (List<IStep>) pipeline.GetType ().GetField ("_steps", BindingFlags.Instance | BindingFlags.NonPublic).GetValue (pipeline);
//foreach (var step in _steps)
// Console.WriteLine ($"step: {step.GetType ().Name}");
}
return _steps;
}
}
static MethodInfo getReferencedAssembliesMethod = typeof (LinkContext).GetMethod ("GetReferencedAssemblies", BindingFlags.Public | BindingFlags.Instance);
protected override void Process ()
{
string tfmPaths;
if (Context.TryGetCustomData ("XATargetFrameworkDirectories", out tfmPaths))
Xamarin.Android.Tasks.MonoAndroidHelper.TargetFrameworkDirectories = tfmPaths.Split (new char [] { ';' });
var subSteps1 = new SubStepDispatcher ();
subSteps1.Add (new ApplyPreserveAttribute ());
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 ());
InsertAfter (new FixAbstractMethodsStep (cache), "SetupStep");
InsertAfter (subSteps2, "SetupStep");
InsertAfter (subSteps1, "SetupStep");
// 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<AssemblyDefinition>)getReferencedAssembliesMethod.Invoke (Context, null))
Context.LogMessage ($"Reference assembly to process: {assembly}");
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}.");
}
}
}