From 7843a5b95f9f27ff8d4e6f65d276d190f9f54e69 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 23 May 2011 20:54:42 +0200 Subject: [PATCH] implement ITypeResolver based on Cecil to avoid loading of assemblies using reflection --- ILSpy.BamlDecompiler/BamlResourceEntryNode.cs | 2 +- .../CecilDependencyPropertyDescriptor.cs | 34 +++++++++ ILSpy.BamlDecompiler/CecilType.cs | 71 +++++++++++++++++++ ILSpy.BamlDecompiler/CecilTypeResolver.cs | 51 +++++++++++++ .../ILSpy.BamlDecompiler.csproj | 3 + 5 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 ILSpy.BamlDecompiler/CecilDependencyPropertyDescriptor.cs create mode 100644 ILSpy.BamlDecompiler/CecilType.cs create mode 100644 ILSpy.BamlDecompiler/CecilTypeResolver.cs diff --git a/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs b/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs index 40d850c4a..cce7182f9 100644 --- a/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs +++ b/ILSpy.BamlDecompiler/BamlResourceEntryNode.cs @@ -51,7 +51,7 @@ namespace ILSpy.BamlDecompiler bamlStream.Position = 0; XDocument xamlDocument; - using (XmlBamlReader reader = new XmlBamlReader(bamlStream)) + using (XmlBamlReader reader = new XmlBamlReader(bamlStream, new CecilTypeResolver(asm))) xamlDocument = XDocument.Load(reader); output.Write(xamlDocument.ToString()); diff --git a/ILSpy.BamlDecompiler/CecilDependencyPropertyDescriptor.cs b/ILSpy.BamlDecompiler/CecilDependencyPropertyDescriptor.cs new file mode 100644 index 000000000..9a0e1e559 --- /dev/null +++ b/ILSpy.BamlDecompiler/CecilDependencyPropertyDescriptor.cs @@ -0,0 +1,34 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Linq; +using ICSharpCode.ILSpy; +using Mono.Cecil; +using Ricciolo.StylesExplorer.MarkupReflection; + +namespace ILSpy.BamlDecompiler +{ + public class CecilDependencyPropertyDescriptor : IDependencyPropertyDescriptor + { + string member; + TypeDefinition type; + + public CecilDependencyPropertyDescriptor(string member, TypeDefinition type) + { + this.member = member; + this.type = type; + } + + public bool IsAttached { + get { + return type.Methods.Any(m => m.Name == "Get" + member); + } + } + + public override string ToString() + { + return string.Format("[CecilDependencyPropertyDescriptor Member={0}, Type={1}]", member, type); + } + } +} diff --git a/ILSpy.BamlDecompiler/CecilType.cs b/ILSpy.BamlDecompiler/CecilType.cs new file mode 100644 index 000000000..41a0fc203 --- /dev/null +++ b/ILSpy.BamlDecompiler/CecilType.cs @@ -0,0 +1,71 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Linq; +using ICSharpCode.ILSpy; +using Mono.Cecil; +using Ricciolo.StylesExplorer.MarkupReflection; + +namespace ILSpy.BamlDecompiler +{ + public class CecilType : IType + { + internal readonly TypeDefinition type; + + public CecilType(TypeDefinition type) + { + this.type = type; + } + + public string AssemblyQualifiedName { + get { + return type.FullName + + ", " + type.Module.Assembly.FullName; + } + } + + public bool IsSubclassOf(IType type) + { + if (type == null) + throw new ArgumentNullException("type"); + if (!(type is CecilType)) + throw new ArgumentException("type has to be a CecilType"); + + CecilType ct = (CecilType)type; + + var t = ct.type; + + while (t != null) { + if (t == ct.type) + return true; + foreach (var @interface in t.Interfaces) { + var resolved = @interface.Resolve(); + if (resolved == ct.type) + return true; + } + if (t.BaseType == null) + break; + + t = t.BaseType.Resolve(); + } + + return false; + } + + public bool Equals(IType type) + { + if (type == null) + throw new ArgumentNullException("type"); + if (!(type is CecilType)) + throw new ArgumentException("type has to be a CecilType"); + + return this.type == ((CecilType)type).type; + } + + public override string ToString() + { + return string.Format("[CecilType Type={0}]", type); + } + } +} diff --git a/ILSpy.BamlDecompiler/CecilTypeResolver.cs b/ILSpy.BamlDecompiler/CecilTypeResolver.cs new file mode 100644 index 000000000..35d17c9d2 --- /dev/null +++ b/ILSpy.BamlDecompiler/CecilTypeResolver.cs @@ -0,0 +1,51 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt) + +using System; +using System.Linq; +using ICSharpCode.ILSpy; +using Mono.Cecil; +using Ricciolo.StylesExplorer.MarkupReflection; + +namespace ILSpy.BamlDecompiler +{ + /// + /// Description of CecilTypeResolver. + /// + public class CecilTypeResolver : ITypeResolver + { + LoadedAssembly assembly; + + public CecilTypeResolver(LoadedAssembly assembly) + { + this.assembly = assembly; + } + + public IType GetTypeByAssemblyQualifiedName(string name) + { + int comma = name.IndexOf(','); + + if (comma == -1) + throw new ArgumentException("invalid name"); + + string fullName = name.Substring(0, comma); + string assemblyName = name.Substring(comma + 1).Trim(); + + var type = assembly.AssemblyDefinition.MainModule.GetType(fullName); + if (type == null) { + var otherAssembly = assembly.LookupReferencedAssembly(assemblyName); + type = otherAssembly.AssemblyDefinition.MainModule.GetType(fullName); + } + + return new CecilType(type); + } + + public IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType) + { + if (!(ownerType is CecilType)) + throw new ArgumentException(); + + return new CecilDependencyPropertyDescriptor(name, ((CecilType)ownerType).type); + } + } +} diff --git a/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj b/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj index 587959be6..2dffb28a5 100644 --- a/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj +++ b/ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj @@ -66,6 +66,9 @@ + + +