From 9ed4d084d530b90577b25804e08a8a8ce68c17cb Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 27 Jun 2022 15:03:29 +0200 Subject: [PATCH] #2718: Move XAML files that have an x:Class declaration next to their C# counterparts when using WholeProjectDecompiler. --- ILSpy.BamlDecompiler/BamlDecompilationResult.cs | 7 ++++++- ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs | 10 +++++++++- ILSpy.BamlDecompiler/Rewrite/XClassRewritePass.cs | 1 + ILSpy.BamlDecompiler/XamlContext.cs | 3 +++ ILSpy.BamlDecompiler/XamlDecompiler.cs | 3 ++- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/ILSpy.BamlDecompiler/BamlDecompilationResult.cs b/ILSpy.BamlDecompiler/BamlDecompilationResult.cs index f76d86d9e3..e46651b8a4 100644 --- a/ILSpy.BamlDecompiler/BamlDecompilationResult.cs +++ b/ILSpy.BamlDecompiler/BamlDecompilationResult.cs @@ -20,6 +20,8 @@ using System.Linq; using System.Xml.Linq; +using ICSharpCode.Decompiler.TypeSystem; + namespace ILSpy.BamlDecompiler { public class BamlDecompilationResult @@ -27,9 +29,12 @@ public class BamlDecompilationResult public XDocument Xaml { get; } public List AssemblyReferences { get; } - public BamlDecompilationResult(XDocument xaml, IEnumerable assemblyReferences) + public FullTypeName? TypeName { get; } + + public BamlDecompilationResult(XDocument xaml, FullTypeName? typeName, IEnumerable assemblyReferences) { this.Xaml = xaml; + this.TypeName = typeName; this.AssemblyReferences = assemblyReferences.ToList(); } } diff --git a/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs b/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs index 8a12280d29..d61f20b798 100644 --- a/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs +++ b/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs @@ -20,6 +20,7 @@ using System.ComponentModel.Composition; using System.IO; +using ICSharpCode.Decompiler.CSharp.ProjectDecompiler; using ICSharpCode.Decompiler.Metadata; using ICSharpCode.ILSpy; using ICSharpCode.ILSpy.TreeNodes; @@ -53,8 +54,15 @@ public string WriteResourceToFile(LoadedAssembly assembly, string fileName, Stre ThrowOnAssemblyResolveErrors = options.DecompilerSettings.ThrowOnAssemblyResolveErrors }); decompiler.CancellationToken = options.CancellationToken; - fileName = Path.ChangeExtension(fileName, ".xaml"); var result = decompiler.Decompile(stream); + if (result.TypeName.HasValue) + { + fileName = WholeProjectDecompiler.CleanUpPath(result.TypeName.Value.ReflectionName) + ".xaml"; + } + else + { + fileName = Path.ChangeExtension(fileName, ".xaml"); + } result.Xaml.Save(Path.Combine(options.SaveAsProjectDirectory, fileName)); return fileName; } diff --git a/ILSpy.BamlDecompiler/Rewrite/XClassRewritePass.cs b/ILSpy.BamlDecompiler/Rewrite/XClassRewritePass.cs index 8dbebfc565..7c4d956c1b 100644 --- a/ILSpy.BamlDecompiler/Rewrite/XClassRewritePass.cs +++ b/ILSpy.BamlDecompiler/Rewrite/XClassRewritePass.cs @@ -62,6 +62,7 @@ void RewriteClass(XamlContext ctx, XElement elem) attrs.Insert(0, new XAttribute(classModifierName, "internal")); } attrs.Insert(0, new XAttribute(attrName, type.ResolvedType.FullName)); + ctx.XClassNames.Add(type.ResolvedType.FullName); elem.ReplaceAttributes(attrs); } } diff --git a/ILSpy.BamlDecompiler/XamlContext.cs b/ILSpy.BamlDecompiler/XamlContext.cs index 31c010986e..437277f57c 100644 --- a/ILSpy.BamlDecompiler/XamlContext.cs +++ b/ILSpy.BamlDecompiler/XamlContext.cs @@ -40,6 +40,7 @@ internal class XamlContext TypeSystem = typeSystem; NodeMap = new Dictionary(); XmlNs = new XmlnsDictionary(); + XClassNames = new List(); } Dictionary typeMap = new Dictionary(); @@ -54,6 +55,8 @@ internal class XamlContext public BamlNode RootNode { get; private set; } public IDictionary NodeMap { get; } + public List XClassNames { get; } + public XmlnsDictionary XmlNs { get; } public static XamlContext Construct(IDecompilerTypeSystem typeSystem, BamlDocument document, CancellationToken token, BamlDecompilerSettings bamlDecompilerOptions) diff --git a/ILSpy.BamlDecompiler/XamlDecompiler.cs b/ILSpy.BamlDecompiler/XamlDecompiler.cs index 84dc908efa..e406516a2d 100644 --- a/ILSpy.BamlDecompiler/XamlDecompiler.cs +++ b/ILSpy.BamlDecompiler/XamlDecompiler.cs @@ -120,7 +120,8 @@ public BamlDecompilationResult Decompile(Stream stream) } var assemblyReferences = ctx.Baml.AssemblyIdMap.Select(a => a.Value.AssemblyFullName); - return new BamlDecompilationResult(xaml, assemblyReferences); + var typeName = ctx.XClassNames.FirstOrDefault() is string s ? (FullTypeName?)new FullTypeName(s) : null; + return new BamlDecompilationResult(xaml, typeName, assemblyReferences); } } } \ No newline at end of file