Browse Source

BAML decompiler: introduce proxy for unknown named types - closes #298

pull/348/head
Siegfried Pammer 14 years ago
parent
commit
7345e8259d
  1. 104
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/TypeDeclaration.cs
  2. 42
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs
  3. 25
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlPIMapping.cs
  4. 3
      ILSpy/ILSpy.csproj

104
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/TypeDeclaration.cs

@ -5,44 +5,43 @@ using System; @@ -5,44 +5,43 @@ using System;
namespace Ricciolo.StylesExplorer.MarkupReflection
{
internal class TypeDeclaration
class TypeDeclaration
{
private readonly XmlBamlReader reader;
private readonly bool _isExtension;
private IType _type;
private bool _typeLoaded;
private readonly ITypeResolver resolver;
readonly XmlBamlReader reader;
readonly bool _isExtension;
IType _type;
bool _typeLoaded;
readonly ITypeResolver resolver;
protected TypeDeclaration(ITypeResolver resolver)
{
this.resolver = resolver;
}
public TypeDeclaration(ITypeResolver resolver, string name, string namespaceName, short assemblyId)
: this(null, resolver, name, namespaceName, assemblyId, true)
: this(null, resolver, name, namespaceName, assemblyId)
{
}
public TypeDeclaration(ITypeResolver resolver, string name, string enclosingTypeName, string namespaceName, short assemblyId)
: this(null, resolver, name, namespaceName, assemblyId, true)
: this(null, resolver, name, namespaceName, assemblyId)
{
this.EnclosingTypeName = enclosingTypeName;
}
public TypeDeclaration(ITypeResolver resolver, string name, string namespaceName, short assemblyId, bool isExtension)
: this(null, resolver, name, namespaceName, assemblyId, true)
: this(null, resolver, name, namespaceName, assemblyId)
{
_isExtension = isExtension;
}
public TypeDeclaration(XmlBamlReader reader, ITypeResolver resolver, string name, string namespaceName, short assemblyId)
: this(reader, resolver, name, namespaceName, assemblyId, true)
{
}
public TypeDeclaration(XmlBamlReader reader, ITypeResolver resolver, string name, string namespaceName, short assemblyId, bool isKnown)
{
this.reader = reader;
this.resolver = resolver;
this.Name = name;
this.Namespace = namespaceName;
this.AssemblyId = assemblyId;
this.IsKnown = isKnown;
if (!_isExtension)
_isExtension = name.EndsWith("Extension");
@ -53,14 +52,14 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -53,14 +52,14 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return this.Name;
}
public string EnclosingTypeName { get; private set; }
protected virtual string EnclosingTypeName { get; set; }
public bool IsExtension
{
get { return _isExtension; }
}
public string Assembly
public virtual string Assembly
{
get {
if (reader != null)
@ -70,17 +69,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -70,17 +69,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
}
}
public short AssemblyId { get; private set; }
public string Name { get; private set; }
public virtual short AssemblyId { get; protected set; }
public bool IsKnown { get; private set; }
public virtual string Name { get; protected set; }
public IType Type {
get
{
if (!_typeLoaded)
{
get {
if (!_typeLoaded) {
if (this.Name.Length > 0)
_type = resolver.GetTypeByAssemblyQualifiedName(AssemblyQualifiedName);
_typeLoaded = true;
@ -90,7 +85,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -90,7 +85,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
}
}
public string Namespace { get; private set; }
public virtual string Namespace { get; protected set; }
public string FullyQualifiedName {
get { return EnclosingTypeName == null ? string.Format("{0}.{1}", Namespace, Name) : string.Format("{0}.{1}+{2}", Namespace, EnclosingTypeName, Name); }
@ -103,9 +98,9 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -103,9 +98,9 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
public override bool Equals(object obj)
{
TypeDeclaration td = obj as TypeDeclaration;
if (td != null)
if (td != null && !(obj is ResolverTypeDeclaration))
return (this.Name == td.Name && this.EnclosingTypeName == td.EnclosingTypeName && this.Namespace == td.Namespace && this.AssemblyId == td.AssemblyId);
else
return false;
}
@ -115,4 +110,57 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -115,4 +110,57 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
}
}
class ResolverTypeDeclaration : TypeDeclaration
{
string assembly;
public override short AssemblyId {
get { throw new NotSupportedException(); }
protected set { throw new NotSupportedException(); }
}
public ResolverTypeDeclaration(ITypeResolver resolver, string assemblyQualifiedName)
: base(resolver)
{
string name, @namespace, assembly;
ParseName(assemblyQualifiedName, out name, out @namespace, out assembly);
Name = name;
Namespace = @namespace;
this.assembly = assembly;
}
void ParseName(string assemblyQualifiedName, out string name, out string @namespace, out string assembly)
{
int commaSeparator = assemblyQualifiedName.IndexOf(", ");
assembly = "";
if (commaSeparator >= 0) {
assembly = assemblyQualifiedName.Substring(commaSeparator + 2);
assemblyQualifiedName = assemblyQualifiedName.Remove(commaSeparator);
}
int namespaceSeparator = assemblyQualifiedName.LastIndexOf('.');
@namespace = "";
if (namespaceSeparator >= 0) {
@namespace = assemblyQualifiedName.Substring(0, namespaceSeparator);
}
name = assemblyQualifiedName.Substring(namespaceSeparator + 1);
}
public override string Assembly {
get { return assembly; }
}
public override bool Equals(object obj)
{
ResolverTypeDeclaration td = obj as ResolverTypeDeclaration;
if (td != null)
return (this.Name == td.Name && this.EnclosingTypeName == td.EnclosingTypeName && this.Namespace == td.Namespace);
return false;
}
public override int GetHashCode()
{
return this.Name.GetHashCode() ^ this.EnclosingTypeName.GetHashCode() ^ this.Namespace.GetHashCode();
}
}
}

42
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs

@ -968,7 +968,8 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -968,7 +968,8 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
string recordName = this.stringTable[identifier];
if (recordName != "Key") throw new NotSupportedException(recordName);
pd = new PropertyDeclaration(recordName, XamlTypeDeclaration);
if (keys == null)
keys = new List<KeyMapping>();
keys.Add(new KeyMapping(text) { Position = -1 });
break;
}
@ -1020,7 +1021,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1020,7 +1021,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
if (mappingToChange == null)
throw new InvalidOperationException("Cannot find mapping");
@namespace = String.Format("{0};assembly={1}", @namespace, GetAssembly(mappingToChange.AssemblyId).Replace(" ", ""));
@namespace = String.Format("{0};assembly={1}", @namespace, mappingToChange.Assembly.Replace(" ", ""));
mappingToChange.XmlNamespace = @namespace;
}
namespaces.Add(new XmlNamespace(prefix, @namespace));
@ -1247,18 +1248,14 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1247,18 +1248,14 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
XmlPIMapping FindByClrNamespaceAndAssemblyId(TypeDeclaration declaration)
{
return FindByClrNamespaceAndAssemblyId(declaration.Namespace, declaration.AssemblyId);
return FindByClrNamespaceAndAssemblyName(declaration.Namespace, declaration.Assembly);
}
XmlPIMapping FindByClrNamespaceAndAssemblyId(string clrNamespace, int assemblyId)
{
if (clrNamespace == XamlTypeDeclaration.Namespace && assemblyId == XamlTypeDeclaration.AssemblyId)
return new XmlPIMapping(XmlPIMapping.XamlNamespace, 0, clrNamespace);
for (int x = 0; x < Mappings.Count; x++)
XmlPIMapping FindByClrNamespaceAndAssemblyName(string clrNamespace, string assemblyName)
{
for (int x = 0; x < Mappings.Count; x++) {
XmlPIMapping xp = Mappings[x];
if (xp.AssemblyId == assemblyId && String.CompareOrdinal(xp.ClrNamespace, clrNamespace) == 0)
if (string.Equals(xp.Assembly, assemblyName, StringComparison.Ordinal) && string.Equals(xp.ClrNamespace, clrNamespace, StringComparison.Ordinal))
return xp;
}
@ -1271,7 +1268,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1271,7 +1268,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
string clrNamespace = reader.ReadString();
short assemblyId = reader.ReadInt16();
Mappings.Add(new XmlPIMapping(xmlNamespace, assemblyId, clrNamespace));
Mappings.Add(new XmlPIMapping(xmlNamespace, GetAssembly(assemblyId), clrNamespace));
}
void ReadContentProperty()
@ -1452,7 +1449,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1452,7 +1449,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
string FormatTypeDeclaration(TypeDeclaration typeDeclaration)
{
XmlPIMapping mapping = FindByClrNamespaceAndAssemblyId(typeDeclaration.Namespace, typeDeclaration.AssemblyId);
XmlPIMapping mapping = FindByClrNamespaceAndAssemblyName(typeDeclaration.Namespace, typeDeclaration.Assembly);
string prefix = (mapping != null) ? this.LookupPrefix(mapping.XmlNamespace, false) : null;
string name = typeDeclaration.Name;
if (name.EndsWith("Extension"))
@ -1479,7 +1476,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1479,7 +1476,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
bool differentType = ((propertyDeclaration.DeclaringType != propertyDeclaration.DeclaringType || !isDescendant));
if (withPrefix) {
XmlPIMapping mapping = FindByClrNamespaceAndAssemblyId(propertyDeclaration.DeclaringType.Namespace, propertyDeclaration.DeclaringType.AssemblyId);
XmlPIMapping mapping = FindByClrNamespaceAndAssemblyName(propertyDeclaration.DeclaringType.Namespace, propertyDeclaration.DeclaringType.Assembly);
string prefix = (mapping != null) ? this.LookupPrefix(mapping.XmlNamespace, false) : null;
if (!String.IsNullOrEmpty(prefix)) {
@ -1519,7 +1516,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1519,7 +1516,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return keys[currentKey - 1].StaticResources[(int)identifier];
// return "???" + identifier + "???";
throw new ArgumentException("Cannot find StaticResource", "identifier");
throw new ArgumentException("Cannot find StaticResource: " + identifier, "identifier");
}
void ReadTextWithConverter()
@ -1542,11 +1539,11 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1542,11 +1539,11 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
{
string name = fullName.Substring(length + 1);
string namespaceName = fullName.Substring(0, length);
declaration = new TypeDeclaration(this, this.Resolver, name, namespaceName, assemblyId, false);
declaration = new TypeDeclaration(this, this.Resolver, name, namespaceName, assemblyId);
}
else
{
declaration = new TypeDeclaration(this, this.Resolver, fullName, string.Empty, assemblyId, false);
declaration = new TypeDeclaration(this, this.Resolver, fullName, string.Empty, assemblyId);
}
this.typeTable.Add(typeId, declaration);
}
@ -1579,14 +1576,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1579,14 +1576,13 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
return declaration;
}
TypeDeclaration GetKnownTypeDeclarationByName(string name)
TypeDeclaration GetKnownTypeDeclarationByName(string assemblyQualifiedName)
{
foreach (var type in KnownInfo.KnownTypeTable) {
if (name == type.AssemblyQualifiedName)
if (assemblyQualifiedName == type.AssemblyQualifiedName)
return type;
}
throw new NotSupportedException("Type '" + name + "' not found!");
return new ResolverTypeDeclaration(_resolver, assemblyQualifiedName);
}
internal string GetAssembly(short identifier)
@ -1616,8 +1612,8 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1616,8 +1612,8 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
declaration = ((XmlBamlProperty)node).PropertyDeclaration.DeclaringType;
TypeDeclaration elementDeclaration = this.readingElements.Peek().TypeDeclaration;
XmlPIMapping propertyMapping = FindByClrNamespaceAndAssemblyId(declaration) ?? XmlPIMapping.Presentation;
XmlPIMapping elementMapping = FindByClrNamespaceAndAssemblyId(elementDeclaration) ?? XmlPIMapping.Presentation;
XmlPIMapping propertyMapping = FindByClrNamespaceAndAssemblyId(declaration) ?? XmlPIMapping.GetPresentationMapping(GetAssembly);
XmlPIMapping elementMapping = FindByClrNamespaceAndAssemblyId(elementDeclaration) ?? XmlPIMapping.GetPresentationMapping(GetAssembly);
if (((XmlBamlProperty)node).PropertyDeclaration.Name == "Name" &&
_resolver.IsLocalAssembly(((XmlBamlProperty)node).Parent.TypeDeclaration.Assembly))
@ -1634,7 +1630,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1634,7 +1630,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
XmlPIMapping mapping = FindByClrNamespaceAndAssemblyId(declaration);
if (mapping == null)
mapping = XmlPIMapping.Presentation;
mapping = XmlPIMapping.GetPresentationMapping(GetAssembly);
return mapping.XmlNamespace;
}

25
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlPIMapping.cs

@ -10,20 +10,19 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -10,20 +10,19 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
/// </summary>
public class XmlPIMapping
{
private string _xmlNamespace;
private short _assemblyId;
private string _clrNamespace;
private static XmlPIMapping _default = new XmlPIMapping(PresentationNamespace, 0, String.Empty);
string _xmlNamespace;
string assemblyName;
string _clrNamespace;
public const string XamlNamespace = "http://schemas.microsoft.com/winfx/2006/xaml";
public const string PresentationNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
public const string PresentationOptionsNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation/options";
public const string McNamespace = "http://schemas.openxmlformats.org/markup-compatibility/2006";
public XmlPIMapping(string xmlNamespace, short assemblyId, string clrNamespace)
public XmlPIMapping(string xmlNamespace, string assembly, string clrNamespace)
{
_xmlNamespace = xmlNamespace;
_assemblyId = assemblyId;
assemblyName = assembly;
_clrNamespace = clrNamespace;
}
@ -37,11 +36,10 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -37,11 +36,10 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
}
/// <summary>
/// Restituisce l'id dell'assembly
/// Name of the assembly.
/// </summary>
public short AssemblyId
{
get { return _assemblyId; }
public string Assembly {
get { return assemblyName; }
}
/// <summary>
@ -52,12 +50,9 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -52,12 +50,9 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
get { return _clrNamespace; }
}
/// <summary>
/// Restituisce il mapping di default di WPF
/// </summary>
public static XmlPIMapping Presentation
public static XmlPIMapping GetPresentationMapping(Func<short, string> assemblyResolve)
{
get { return _default; }
return new XmlPIMapping(PresentationNamespace, assemblyResolve(0), string.Empty);
}
}
}

3
ILSpy/ILSpy.csproj

@ -31,10 +31,11 @@ @@ -31,10 +31,11 @@
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<PlatformTarget>x86</PlatformTarget>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath>

Loading…
Cancel
Save