Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
[build] post-build fix of the assembly
Browse files Browse the repository at this point in the history
- fixes #2835
  • Loading branch information
StephaneDelcroix committed May 31, 2018
1 parent 7a06d91 commit 4df5184
Show file tree
Hide file tree
Showing 41 changed files with 1,195 additions and 0 deletions.
99 changes: 99 additions & 0 deletions ShameHat.Tasks/FixXFCoreAssembly.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using Microsoft.Build.Utilities;
using Mono.Cecil;
using Mono.Cecil.Rocks;

using System.Linq;
using Mono.Cecil.Cil;
using Microsoft.Build.Framework;
using System.IO;

namespace ShameHat.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 methodDef = new MethodDefinition("get_ResourceProvider",
MethodAttributes.Static | MethodAttributes.Public | MethodAttributes.SpecialName,
assemblyDefinition.MainModule.ImportReference(("mscorlib", "System", "Func`2"),
classArguments: new[] { ("mscorlib", "System", "String"), ("mscorlib", "System", "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
}));
}
}

public static class ModuleDefinitionExtensions
{
public static TypeReference ImportReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type)
{
return module.ImportReference(module.GetTypeDefinition(type));
}

public static TypeReference ImportReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, (string assemblyName, string clrNamespace, string typeName)[] classArguments)
{
return module.ImportReference(module.ImportReference(type).MakeGenericInstanceType(classArguments.Select(gp => module.ImportReference(module.GetTypeDefinition((gp.assemblyName, gp.clrNamespace, gp.typeName)))).ToArray()));
}

public static TypeDefinition GetTypeDefinition(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type)
{
var asm = module.Assembly.Name.Name == type.assemblyName
? module.Assembly
: module.AssemblyResolver.Resolve(AssemblyNameReference.Parse(type.assemblyName));
var typeDef = asm.MainModule.GetType($"{type.clrNamespace}.{type.typeName}");
if (typeDef != null) {
return typeDef;
}
var exportedType = asm.MainModule.ExportedTypes.FirstOrDefault(
arg => arg.IsForwarder && arg.Namespace == type.clrNamespace && arg.Name == type.typeName);
if (exportedType != null) {
typeDef = exportedType.Resolve();
return typeDef;
}

//I hate you, netstandard
if (type.assemblyName == "mscorlib" && type.clrNamespace == "System.Reflection")
return module.GetTypeDefinition(("System.Reflection", type.clrNamespace, type.typeName));
return null;
}
}
}
15 changes: 15 additions & 0 deletions ShameHat.Tasks/ShameHat.Tasks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="15.7.179" />
<PackageReference Include="Microsoft.Build.Framework" Version="15.7.179" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.7.179" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.7.179" />
<PackageReference Include="Mono.Cecil" Version="0.10.0-beta7" />
</ItemGroup>
</Project>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit 4df5184

Please sign in to comment.