Browse Source

Fix #1457: Refactor IModule usage in BAML decompiler.

pull/1464/head
Siegfried Pammer 6 years ago
parent
commit
cc915f5e85
  1. 10
      ILSpy.BamlDecompiler/Baml/BamlContext.cs
  2. 8
      ILSpy.BamlDecompiler/Handlers/Records/XmlnsPropertyHandler.cs
  3. 2
      ILSpy.BamlDecompiler/Rewrite/XClassRewritePass.cs
  4. 13
      ILSpy.BamlDecompiler/Xaml/NamespaceMap.cs
  5. 18
      ILSpy.BamlDecompiler/Xaml/XamlType.cs
  6. 10
      ILSpy.BamlDecompiler/XamlContext.cs
  7. 18
      ILSpy.BamlDecompiler/XmlnsDictionary.cs

10
ILSpy.BamlDecompiler/Baml/BamlContext.cs

@ -32,7 +32,7 @@ namespace ILSpy.BamlDecompiler.Baml { @@ -32,7 +32,7 @@ namespace ILSpy.BamlDecompiler.Baml {
public IDecompilerTypeSystem TypeSystem { get; }
public KnownThings KnownThings { get; }
Dictionary<ushort, IModule> assemblyMap = new Dictionary<ushort, IModule>();
Dictionary<ushort, (string FullAssemblyName, IModule Assembly)> assemblyMap = new Dictionary<ushort, (string FullAssemblyName, IModule Assembly)>();
public Dictionary<ushort, AssemblyInfoRecord> AssemblyIdMap { get; }
public Dictionary<ushort, AttributeInfoRecord> AttributeIdMap { get; }
@ -76,18 +76,18 @@ namespace ILSpy.BamlDecompiler.Baml { @@ -76,18 +76,18 @@ namespace ILSpy.BamlDecompiler.Baml {
return ctx;
}
public IModule ResolveAssembly(ushort id) {
public (string FullAssemblyName, IModule Assembly) ResolveAssembly(ushort id) {
id &= 0xfff;
if (!assemblyMap.TryGetValue(id, out var assembly)) {
if (AssemblyIdMap.TryGetValue(id, out var assemblyRec)) {
var assemblyName = Metadata.AssemblyNameReference.Parse(assemblyRec.AssemblyFullName);
if (assemblyName.Name == TypeSystem.MainModule.AssemblyName)
assembly = TypeSystem.MainModule;
assembly = (assemblyRec.AssemblyFullName, TypeSystem.MainModule);
else
assembly = TypeSystem.ReferencedModules.FirstOrDefault(m => m.FullAssemblyName == assemblyName.FullName);
assembly = (assemblyRec.AssemblyFullName, TypeSystem.ReferencedModules.FirstOrDefault(m => m.FullAssemblyName == assemblyName.FullName));
} else
assembly = null;
assembly = (null, null);
assemblyMap[id] = assembly;
}

8
ILSpy.BamlDecompiler/Handlers/Records/XmlnsPropertyHandler.cs

@ -50,11 +50,11 @@ namespace ILSpy.BamlDecompiler.Handlers { @@ -50,11 +50,11 @@ namespace ILSpy.BamlDecompiler.Handlers {
var record = (XmlnsPropertyRecord)((BamlRecordNode)node).Record;
foreach (var asmId in record.AssemblyIds) {
var assembly = ctx.Baml.ResolveAssembly(asmId);
ctx.XmlNs.Add(new NamespaceMap(record.Prefix, assembly, record.XmlNamespace));
ctx.XmlNs.Add(new NamespaceMap(record.Prefix, assembly.FullAssemblyName, record.XmlNamespace));
if (assembly.IsMainModule) {
foreach (var clrNs in ResolveCLRNamespaces(assembly, record.XmlNamespace))
ctx.XmlNs.Add(new NamespaceMap(record.Prefix, assembly, record.XmlNamespace, clrNs));
if (assembly.Assembly?.IsMainModule == true) {
foreach (var clrNs in ResolveCLRNamespaces(assembly.Assembly, record.XmlNamespace))
ctx.XmlNs.Add(new NamespaceMap(record.Prefix, assembly.FullAssemblyName, record.XmlNamespace, clrNs));
}
}

2
ILSpy.BamlDecompiler/Rewrite/XClassRewritePass.cs

@ -43,7 +43,7 @@ namespace ILSpy.BamlDecompiler.Rewrite { @@ -43,7 +43,7 @@ namespace ILSpy.BamlDecompiler.Rewrite {
var newType = typeDef.DirectBaseTypes.First().GetDefinition();
if (newType == null)
return;
var xamlType = new XamlType(newType.ParentModule, newType.Namespace, newType.Name);
var xamlType = new XamlType(newType.ParentModule, newType.ParentModule.FullAssemblyName, newType.Namespace, newType.Name);
xamlType.ResolveNamespace(elem, ctx);
elem.Name = xamlType.ToXName(ctx);

13
ILSpy.BamlDecompiler/Xaml/NamespaceMap.cs

@ -21,26 +21,27 @@ @@ -21,26 +21,27 @@
*/
using System;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ILSpy.BamlDecompiler.Xaml {
internal class NamespaceMap {
public string XmlnsPrefix { get; set; }
public IModule Assembly { get; set; }
public string FullAssemblyName { get; set; }
public string XMLNamespace { get; set; }
public string CLRNamespace { get; set; }
public NamespaceMap(string prefix, IModule asm, string xmlNs)
: this(prefix, asm, xmlNs, null) {
public NamespaceMap(string prefix, string fullAssemblyName, string xmlNs)
: this(prefix, fullAssemblyName, xmlNs, null) {
}
public NamespaceMap(string prefix, IModule asm, string xmlNs, string clrNs) {
public NamespaceMap(string prefix, string fullAssemblyName, string xmlNs, string clrNs) {
XmlnsPrefix = prefix;
Assembly = asm;
FullAssemblyName = fullAssemblyName;
XMLNamespace = xmlNs;
CLRNamespace = clrNs;
}
public override string ToString() => $"{XmlnsPrefix}:[{Assembly?.Name}|{CLRNamespace ?? XMLNamespace}]";
public override string ToString() => $"{XmlnsPrefix}:[{FullAssemblyName}|{CLRNamespace ?? XMLNamespace}]";
}
}

18
ILSpy.BamlDecompiler/Xaml/XamlType.cs

@ -25,20 +25,26 @@ using System.Xml.Linq; @@ -25,20 +25,26 @@ using System.Xml.Linq;
using ICSharpCode.Decompiler.TypeSystem;
namespace ILSpy.BamlDecompiler.Xaml {
internal class XamlType {
internal class XamlType
{
/// <summary>
/// Assembly that contains the type defintion. Can be null.
/// </summary>
public IModule Assembly { get; }
public string FullAssemblyName { get; }
public string TypeNamespace { get; }
public string TypeName { get; }
public XNamespace Namespace { get; private set; }
public IType ResolvedType { get; set; }
public XamlType(IModule assembly, string ns, string name)
: this(assembly, ns, name, null) {
public XamlType(IModule assembly, string fullAssemblyName, string ns, string name)
: this(assembly, fullAssemblyName, ns, name, null) {
}
public XamlType(IModule assembly, string ns, string name, XNamespace xmlns) {
public XamlType(IModule assembly, string fullAssemblyName, string ns, string name, XNamespace xmlns) {
Assembly = assembly;
FullAssemblyName = fullAssemblyName;
TypeNamespace = ns;
TypeName = name;
Namespace = xmlns;
@ -53,9 +59,9 @@ namespace ILSpy.BamlDecompiler.Xaml { @@ -53,9 +59,9 @@ namespace ILSpy.BamlDecompiler.Xaml {
string xmlNs = null;
if (elem.Annotation<XmlnsScope>() != null)
xmlNs = elem.Annotation<XmlnsScope>().LookupXmlns(Assembly, TypeNamespace);
xmlNs = elem.Annotation<XmlnsScope>().LookupXmlns(FullAssemblyName, TypeNamespace);
if (xmlNs == null)
xmlNs = ctx.XmlNs.LookupXmlns(Assembly, TypeNamespace);
xmlNs = ctx.XmlNs.LookupXmlns(FullAssemblyName, TypeNamespace);
// Sometimes there's no reference to System.Xaml even if x:Type is used
if (xmlNs == null)
xmlNs = ctx.TryGetXmlNamespace(Assembly, TypeNamespace);

10
ILSpy.BamlDecompiler/XamlContext.cs

@ -83,7 +83,7 @@ namespace ILSpy.BamlDecompiler { @@ -83,7 +83,7 @@ namespace ILSpy.BamlDecompiler {
if (piMap == null)
continue;
XmlNs.SetPIMapping(piMap.XmlNamespace, piMap.ClrNamespace, Baml.ResolveAssembly(piMap.AssemblyId));
XmlNs.SetPIMapping(piMap.XmlNamespace, piMap.ClrNamespace, Baml.ResolveAssembly(piMap.AssemblyId).FullAssemblyName);
}
}
@ -93,21 +93,23 @@ namespace ILSpy.BamlDecompiler { @@ -93,21 +93,23 @@ namespace ILSpy.BamlDecompiler {
IType type;
IModule assembly;
string fullAssemblyName;
if (id > 0x7fff) {
type = Baml.KnownThings.Types((KnownTypes)(short)-unchecked((short)id));
assembly = type.GetDefinition().ParentModule;
fullAssemblyName = assembly.FullAssemblyName;
}
else {
var typeRec = Baml.TypeIdMap[id];
assembly = Baml.ResolveAssembly(typeRec.AssemblyId);
(fullAssemblyName, assembly) = Baml.ResolveAssembly(typeRec.AssemblyId);
type = ReflectionHelper.ParseReflectionName(typeRec.TypeFullName).Resolve(new SimpleTypeResolveContext(TypeSystem));
}
var clrNs = type.Namespace;
var xmlNs = XmlNs.LookupXmlns(assembly, clrNs);
var xmlNs = XmlNs.LookupXmlns(fullAssemblyName, clrNs);
typeMap[id] = xamlType = new XamlType(assembly, clrNs, type.Name, GetXmlNamespace(xmlNs)) {
typeMap[id] = xamlType = new XamlType(assembly, fullAssemblyName, clrNs, type.Name, GetXmlNamespace(xmlNs)) {
ResolvedType = type
};

18
ILSpy.BamlDecompiler/XmlnsDictionary.cs

@ -21,6 +21,7 @@ @@ -21,6 +21,7 @@
*/
using System.Collections.Generic;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ILSpy.BamlDecompiler.Xaml;
@ -34,10 +35,9 @@ namespace ILSpy.BamlDecompiler { @@ -34,10 +35,9 @@ namespace ILSpy.BamlDecompiler {
Element = elem;
}
public string LookupXmlns(IModule asm, string clrNs) {
public string LookupXmlns(string fullAssemblyName, string clrNs) {
foreach (var ns in this) {
if (asm.FullAssemblyName == ns.Assembly?.FullAssemblyName && ns.CLRNamespace == clrNs)
if (fullAssemblyName == ns.FullAssemblyName && ns.CLRNamespace == clrNs)
return ns.XMLNamespace;
}
@ -58,16 +58,16 @@ namespace ILSpy.BamlDecompiler { @@ -58,16 +58,16 @@ namespace ILSpy.BamlDecompiler {
public void Add(NamespaceMap map) => CurrentScope.Add(map);
public void SetPIMapping(string xmlNs, string clrNs, IModule assembly) {
public void SetPIMapping(string xmlNs, string clrNs, string fullAssemblyName) {
if (!piMappings.ContainsKey(xmlNs)) {
var map = new NamespaceMap(null, assembly, xmlNs, clrNs);
var map = new NamespaceMap(null, fullAssemblyName, xmlNs, clrNs);
piMappings[xmlNs] = map;
}
}
NamespaceMap PIFixup(NamespaceMap map) {
if (piMappings.TryGetValue(map.XMLNamespace, out var piMap)) {
map.Assembly = piMap.Assembly;
map.FullAssemblyName = piMap.FullAssemblyName;
map.CLRNamespace = piMap.CLRNamespace;
}
return map;
@ -101,16 +101,16 @@ namespace ILSpy.BamlDecompiler { @@ -101,16 +101,16 @@ namespace ILSpy.BamlDecompiler {
return null;
}
public string LookupXmlns(IModule asm, string clrNs) {
public string LookupXmlns(string fullAssemblyName, string clrNs) {
foreach (var map in piMappings) {
if (asm.FullAssemblyName == map.Value.Assembly?.FullAssemblyName && map.Value.CLRNamespace == clrNs)
if (fullAssemblyName == map.Value.FullAssemblyName && map.Value.CLRNamespace == clrNs)
return map.Key;
}
var scope = CurrentScope;
while (scope != null) {
foreach (var ns in scope) {
if (asm.FullAssemblyName == ns.Assembly?.FullAssemblyName && ns.CLRNamespace == clrNs)
if (fullAssemblyName == ns.FullAssemblyName && ns.CLRNamespace == clrNs)
return ns.XMLNamespace;
}

Loading…
Cancel
Save