/
FixXFCoreAssembly.cs
70 lines (60 loc) · 2.1 KB
/
FixXFCoreAssembly.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
using System;
using System.IO;
using System.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Mono.Cecil;
using Mono.Cecil.Rocks;
using Mono.Cecil.Cil;
namespace XFCorePostProcessor.Tasks
{
public class FixXFCoreAssembly : Task
{
[Required]
public string Assembly { get; set; }
public string ReferencePath { get; set; }
public override bool Execute()
{
Log.LogMessage("Generating backcompat code for #2835");
var resolver = new AssemblyResolver();
if (!string.IsNullOrEmpty(ReferencePath)) {
var paths = ReferencePath.Replace("//", "/").Split(';');
foreach (var p in paths) {
var searchpath = Path.GetDirectoryName(p);
resolver.AddSearchDirectory(searchpath);
}
}
using (var assemblyDefinition = AssemblyDefinition.ReadAssembly(Assembly, new ReaderParameters { AssemblyResolver = resolver, ReadWrite = true, ReadSymbols = true })) {
var resourceLoader = assemblyDefinition.MainModule.GetType("Xamarin.Forms.Internals.ResourceLoader");
var module = assemblyDefinition.MainModule;
if(resourceLoader.GetMethods().Count(md=>md.Name == "get_ResourceProvider") > 1) {
Log.LogMessage(" already executed");
return true;
}
var methodDef = new MethodDefinition("get_ResourceProvider",
MethodAttributes.Static | MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
module.ImportReference(module.ImportReference(typeof(Func<,>)).MakeGenericInstanceType(module.ImportReference(typeof(string)),
module.ImportReference(typeof(string)))));
var body = new MethodBody(methodDef);
var il = body.GetILProcessor();
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Ret);
methodDef.Body = body;
resourceLoader.Methods.Add(methodDef);
assemblyDefinition.Write(new WriterParameters {
WriteSymbols = true,
});
}
return true;
}
}
class AssemblyResolver : DefaultAssemblyResolver
{
public void AddAssembly(string p)
{
RegisterAssembly(AssemblyDefinition.ReadAssembly(p, new ReaderParameters {
AssemblyResolver = this
}));
}
}
}