Browse Source

Port BAML decompiler to SRM.

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
8884306244
  1. 2
      ICSharpCode.Decompiler/Documentation/XmlDocKeyProvider.cs
  2. 21
      ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs
  3. 1
      ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj
  4. 12
      ILSpy.BamlDecompiler/BamlResourceEntryNode.cs
  5. 4
      ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
  6. 15
      ILSpy.BamlDecompiler/CecilTypeResolver.cs
  7. 35
      ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs
  8. 4
      ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj
  9. 2
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs
  10. 4
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs
  11. 12
      ILSpy.sln

2
ICSharpCode.Decompiler/Documentation/XmlDocKeyProvider.cs

@ -32,7 +32,7 @@ namespace ICSharpCode.Decompiler.Documentation @@ -32,7 +32,7 @@ namespace ICSharpCode.Decompiler.Documentation
/// <summary>
/// Provides XML documentation tags.
/// </summary>
public sealed class XmlDocKeyProvider
public static class XmlDocKeyProvider
{
#region GetKey
public static string GetKey(Entity entity)

21
ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs

@ -8,8 +8,8 @@ using System.Linq; @@ -8,8 +8,8 @@ using System.Linq;
using System.Resources;
using System.Threading;
using System.Xml.Linq;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Tests.Helpers;
using Mono.Cecil;
using NUnit.Framework;
namespace ILSpy.BamlDecompiler.Tests
@ -112,16 +112,20 @@ namespace ILSpy.BamlDecompiler.Tests @@ -112,16 +112,20 @@ namespace ILSpy.BamlDecompiler.Tests
void RunTest(string name, string asmPath, string sourcePath)
{
var resolver = new DefaultAssemblyResolver();
using (var fileStream = new FileStream(asmPath, FileMode.Open, FileAccess.Read)) {
var module = new PEFile(asmPath, fileStream, System.Reflection.PortableExecutable.PEStreamOptions.Default);
var resolver = new UniversalAssemblyResolver(asmPath, false, true, module.Reader.DetectTargetFrameworkId(), System.Reflection.PortableExecutable.PEStreamOptions.Default);
resolver.RemoveSearchDirectory(".");
resolver.AddSearchDirectory(Path.GetDirectoryName(asmPath));
var assembly = AssemblyDefinition.ReadAssembly(asmPath, new ReaderParameters { AssemblyResolver = resolver, InMemory = true });
Resource res = assembly.MainModule.Resources.First();
module.AssemblyResolver = resolver;
var res = module.Resources.First();
Stream bamlStream = LoadBaml(res, name + ".baml");
Assert.IsNotNull(bamlStream);
XDocument document = BamlResourceEntryNode.LoadIntoDocument(resolver, assembly, bamlStream, CancellationToken.None);
XDocument document = BamlResourceEntryNode.LoadIntoDocument(module, bamlStream, CancellationToken.None);
XamlIsEqual(File.ReadAllText(sourcePath), document.ToString());
}
}
void XamlIsEqual(string input1, string input2)
@ -139,9 +143,8 @@ namespace ILSpy.BamlDecompiler.Tests @@ -139,9 +143,8 @@ namespace ILSpy.BamlDecompiler.Tests
Stream LoadBaml(Resource res, string name)
{
EmbeddedResource er = res as EmbeddedResource;
if (er != null) {
Stream s = er.GetResourceStream();
if (res.ResourceType != ResourceType.Embedded) return null;
Stream s = res.TryOpenStream();
s.Position = 0;
ResourceReader reader;
try {
@ -157,8 +160,6 @@ namespace ILSpy.BamlDecompiler.Tests @@ -157,8 +160,6 @@ namespace ILSpy.BamlDecompiler.Tests
return new MemoryStream((byte[])entry.Value);
}
}
}
return null;
}
#endregion

1
ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj

@ -38,6 +38,7 @@ @@ -38,6 +38,7 @@
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.Decompiler.Tests\ICSharpCode.Decompiler.Tests.csproj" />
<ProjectReference Include="..\ILSpy.BamlDecompiler\ILSpy.BamlDecompiler.csproj" />
<ProjectReference Include="..\ILSpy\ILSpy.csproj" />
<ProjectReference Include="..\SharpTreeView\ICSharpCode.TreeView.csproj" />
</ItemGroup>

12
ILSpy.BamlDecompiler/BamlResourceEntryNode.cs

@ -10,7 +10,7 @@ using System.Threading.Tasks; @@ -10,7 +10,7 @@ using System.Threading.Tasks;
using System.Xml.Linq;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy;
using ICSharpCode.ILSpy.TextView;
@ -50,7 +50,7 @@ namespace ILSpy.BamlDecompiler @@ -50,7 +50,7 @@ namespace ILSpy.BamlDecompiler
{
var asm = this.Ancestors().OfType<AssemblyTreeNode>().FirstOrDefault().LoadedAssembly;
Data.Position = 0;
XDocument xamlDocument = LoadIntoDocument(asm.GetAssemblyResolver(), asm.GetPEFileOrNull(), Data, cancellationToken);
XDocument xamlDocument = LoadIntoDocument(asm.GetPEFileOrNull(), Data, cancellationToken);
output.Write(xamlDocument.ToString());
return true;
}
@ -59,21 +59,21 @@ namespace ILSpy.BamlDecompiler @@ -59,21 +59,21 @@ namespace ILSpy.BamlDecompiler
{
cancellationToken.ThrowIfCancellationRequested();
XDocument xamlDocument;
using (XmlBamlReader reader = new XmlBamlReader(stream, new NRTypeResolver(resolver, asm))) {
using (XmlBamlReader reader = new XmlBamlReader(stream, new NRTypeResolver(module))) {
xamlDocument = XDocument.Load(reader);
ConvertConnectionIds(xamlDocument, asm, cancellationToken);
ConvertConnectionIds(xamlDocument, module, cancellationToken);
ConvertToEmptyElements(xamlDocument.Root);
MoveNamespacesToRoot(xamlDocument, reader.XmlnsDefinitions);
return xamlDocument;
}
}
static void ConvertConnectionIds(XDocument xamlDocument, AssemblyDefinition asm, CancellationToken cancellationToken)
static void ConvertConnectionIds(XDocument xamlDocument, PEFile asm, CancellationToken cancellationToken)
{
var attr = xamlDocument.Root.Attribute(XName.Get("Class", XmlBamlReader.XWPFNamespace));
if (attr != null) {
string fullTypeName = attr.Value;
var mappings = new ConnectMethodDecompiler(asm).DecompileEventMappings(fullTypeName, cancellationToken);
var mappings = new ConnectMethodDecompiler().DecompileEventMappings(asm, fullTypeName, cancellationToken);
RemoveConnectionIds(xamlDocument.Root, mappings);
}
}

4
ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs

@ -7,7 +7,7 @@ using System.IO; @@ -7,7 +7,7 @@ using System.IO;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
namespace ILSpy.BamlDecompiler
{
@ -36,7 +36,7 @@ namespace ILSpy.BamlDecompiler @@ -36,7 +36,7 @@ namespace ILSpy.BamlDecompiler
public string WriteResourceToFile(LoadedAssembly assembly, string fileName, Stream stream, DecompilationOptions options)
{
var document = BamlResourceEntryNode.LoadIntoDocument(assembly.GetAssemblyResolver(), assembly.GetPEFileOrNull(), stream, options.CancellationToken);
var document = BamlResourceEntryNode.LoadIntoDocument(assembly.GetPEFileOrNull(), stream, options.CancellationToken);
fileName = Path.ChangeExtension(fileName, ".xaml");
document.Save(Path.Combine(options.SaveAsProjectDirectory, fileName));
return fileName;

15
ILSpy.BamlDecompiler/CecilTypeResolver.cs

@ -2,8 +2,8 @@ @@ -2,8 +2,8 @@
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
using Ricciolo.StylesExplorer.MarkupReflection;
namespace ILSpy.BamlDecompiler
@ -13,11 +13,15 @@ namespace ILSpy.BamlDecompiler @@ -13,11 +13,15 @@ namespace ILSpy.BamlDecompiler
/// </summary>
public class NRTypeResolver : IDotNetTypeResolver
{
readonly PEFile module;
readonly DecompilerTypeSystem typeSystem;
readonly ICompilation compilation;
public NRTypeResolver(ICompilation compilation)
public NRTypeResolver(PEFile module)
{
this.compilation = compilation;
this.module = module;
this.typeSystem = new DecompilerTypeSystem(module);
this.compilation = typeSystem.Compilation;
}
public bool IsLocalAssembly(string name)
@ -66,10 +70,9 @@ namespace ILSpy.BamlDecompiler @@ -66,10 +70,9 @@ namespace ILSpy.BamlDecompiler
throw new ArgumentException("Invalid IType: " + ownerType.GetType());
}
public string RuntimeVersion {
public TargetRuntime RuntimeVersion {
get {
throw new NotImplementedException();
//return thisAssembly.MainModule.Runtime.ToString();
return module.GetRuntime();
}
}
}

35
ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs

@ -5,14 +5,16 @@ using System; @@ -5,14 +5,16 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection.Metadata;
using System.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using Mono.Cecil;
using Metadata = ICSharpCode.Decompiler.Metadata;
namespace ILSpy.BamlDecompiler
{
@ -29,37 +31,36 @@ namespace ILSpy.BamlDecompiler @@ -29,37 +31,36 @@ namespace ILSpy.BamlDecompiler
/// </summary>
sealed class ConnectMethodDecompiler
{
AssemblyDefinition assembly;
public ConnectMethodDecompiler(AssemblyDefinition assembly)
{
this.assembly = assembly;
}
public List<(LongSet, EventRegistration[])> DecompileEventMappings(string fullTypeName, CancellationToken cancellationToken)
public List<(LongSet, EventRegistration[])> DecompileEventMappings(Metadata.PEFile module, string fullTypeName, CancellationToken cancellationToken)
{
var result = new List<(LongSet, EventRegistration[])>();
TypeDefinition type = this.assembly.MainModule.GetType(fullTypeName);
if (type == null)
var typeDefinition = (Metadata.TypeDefinition)XmlDocKeyProvider.FindMemberByKey(module, "T:" + fullTypeName);
if (typeDefinition.IsNil)
return result;
MethodDefinition method = null;
var metadata = module.GetMetadataReader();
TypeDefinition type = metadata.GetTypeDefinition(typeDefinition.Handle);
MethodDefinition method = default;
MethodDefinitionHandle handle = default;
foreach (var m in type.Methods) {
if (m.Name == "System.Windows.Markup.IComponentConnector.Connect") {
foreach (var h in type.GetMethods()) {
var m = metadata.GetMethodDefinition(h);
if (metadata.GetString(m.Name) == "System.Windows.Markup.IComponentConnector.Connect") {
handle = h;
method = m;
break;
}
}
if (method == null)
if (handle.IsNil)
return result;
// decompile method and optimize the switch
var typeSystem = new DecompilerTypeSystem(method.Module);
var typeSystem = new DecompilerTypeSystem(typeDefinition.Module);
var ilReader = new ILReader(typeSystem);
var function = ilReader.ReadIL(method.Body, cancellationToken);
var function = ilReader.ReadIL(typeDefinition.Module, handle, typeDefinition.Module.Reader.GetMethodBody(method.RelativeVirtualAddress), cancellationToken);
var context = new ILTransformContext(function, typeSystem) {
CancellationToken = cancellationToken

4
ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj

@ -28,6 +28,10 @@ @@ -28,6 +28,10 @@
<OutputPath>..\ILSpy\bin\$(Configuration)\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />

2
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs

@ -6,7 +6,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -6,7 +6,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
{
public interface IDotNetTypeResolver
{
string RuntimeVersion { get; }
ICSharpCode.Decompiler.Metadata.TargetRuntime RuntimeVersion { get; }
bool IsLocalAssembly(string name);
IDotNetType GetTypeByAssemblyQualifiedName(string name);
IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IDotNetType ownerType, IDotNetType targetType);

4
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs

@ -34,10 +34,10 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -34,10 +34,10 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
public KnownInfo(IDotNetTypeResolver resolver)
{
switch (resolver.RuntimeVersion) {
case "Net_2_0":
case ICSharpCode.Decompiler.Metadata.TargetRuntime.Net_2_0:
LoadKnownAssemblies30();
break;
case "Net_4_0":
case ICSharpCode.Decompiler.Metadata.TargetRuntime.Net_4_0:
LoadKnownAssemblies40();
break;
default:

12
ILSpy.sln

@ -24,6 +24,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestPlugin", "TestPlugin\Te @@ -24,6 +24,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestPlugin", "TestPlugin\Te
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Pdb", "cecil\symbols\pdb\Mono.Cecil.Pdb.csproj", "{63E6915C-7EA4-4D76-AB28-0D7191EEA626}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.BamlDecompiler", "ILSpy.BamlDecompiler\ILSpy.BamlDecompiler.csproj", "{A6BAD2BA-76BA-461C-8B6D-418607591247}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.BamlDecompiler.Tests", "ILSpy.BamlDecompiler.Tests\ILSpy.BamlDecompiler.Tests.csproj", "{1169E6D1-1899-43D4-A500-07CE4235B388}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.AddIn", "ILSpy.AddIn\ILSpy.AddIn.csproj", "{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0A344E19-D1FC-4F4C-8883-0844AC669113}"
@ -65,6 +69,14 @@ Global @@ -65,6 +69,14 @@ Global
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|Any CPU.Build.0 = net_4_0_Debug|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.Build.0 = Release|Any CPU
{1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.Build.0 = Release|Any CPU
{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Release|Any CPU.ActiveCfg = Release|Any CPU

Loading…
Cancel
Save