Skip to content

Commit 991dce4

Browse files
committed
fix xaml type name
1 parent 0530d33 commit 991dce4

File tree

8 files changed

+45
-5
lines changed

8 files changed

+45
-5
lines changed

Extensions/dnSpy.BamlDecompiler/BamlDecompiler.cs

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ You should have received a copy of the GNU General Public License
2929
namespace dnSpy.BamlDecompiler {
3030
[Export(typeof(IBamlDecompiler))]
3131
sealed class BamlDecompiler : IBamlDecompiler {
32+
public string DecompileTypeName(ModuleDef module, byte[] data, CancellationToken token, BamlDecompilerOptions bamlDecompilerOptions) {
33+
var doc = BamlReader.ReadDocument(new MemoryStream(data), token);
34+
return XamlDecompiler.DecompileTypeName(module, doc, token, bamlDecompilerOptions);
35+
}
36+
3237
public IList<string> Decompile(ModuleDef module, byte[] data, CancellationToken token, BamlDecompilerOptions bamlDecompilerOptions, Stream output, XamlOutputOptions outputOptions) {
3338
var doc = BamlReader.ReadDocument(new MemoryStream(data), token);
3439
var asmRefs = new List<string>();

Extensions/dnSpy.BamlDecompiler/XamlDecompiler.cs

+15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,21 @@ static class XamlDecompiler {
3939
new DocumentRewritePass(),
4040
};
4141

42+
public static string DecompileTypeName(ModuleDef module, BamlDocument document, CancellationToken token, BamlDecompilerOptions bamlDecompilerOptions) {
43+
var ctx = XamlContext.Construct(module, document, token, bamlDecompilerOptions);
44+
45+
var handler = HandlerMap.LookupHandler(ctx.RootNode.Type);
46+
var elem = handler.Translate(ctx, ctx.RootNode, null);
47+
48+
var xaml = new XDocument();
49+
xaml.Add(elem.Xaml.Element);
50+
51+
token.ThrowIfCancellationRequested();
52+
rewritePasses[0].Run(ctx, xaml);
53+
54+
return xaml.Root.Elements().FirstOrDefault().Attributes().FirstOrDefault(x => x.Name.LocalName == "Class")?.Value;
55+
}
56+
4257
public static XDocument Decompile(ModuleDef module, BamlDocument document, CancellationToken token, BamlDecompilerOptions bamlDecompilerOptions, List<string> assemblyReferences) {
4358
var ctx = XamlContext.Construct(module, document, token, bamlDecompilerOptions);
4459

dnSpy/dnSpy.Console/Program.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -971,8 +971,10 @@ ProjectModuleOptions CreateProjectModuleOptions(ModuleDef mod) {
971971
NewLineChars = Environment.NewLine,
972972
NewLineOnAttributes = true,
973973
};
974-
if (bamlDecompiler is not null)
974+
if (bamlDecompiler is not null) {
975+
proj.DecompileBamlTypeName = (a, b, c) => bamlDecompiler.DecompileTypeName(a, b, c, o);
975976
proj.DecompileBaml = (a, b, c, d) => bamlDecompiler.Decompile(a, b, c, o, d, outputOptions);
977+
}
976978
return proj;
977979
}
978980

dnSpy/dnSpy.Contracts.Logic/Decompiler/IBamlDecompiler.cs

+10
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ namespace dnSpy.Contracts.Decompiler {
2727
/// Baml to xaml decompiler
2828
/// </summary>
2929
public interface IBamlDecompiler {
30+
/// <summary>
31+
/// Decompile the type name from baml data
32+
/// </summary>
33+
/// <param name="module"></param>
34+
/// <param name="data"></param>
35+
/// <param name="token"></param>
36+
/// <param name="bamlDecompilerOptions"></param>
37+
/// <returns></returns>
38+
string DecompileTypeName(ModuleDef module, byte[] data, CancellationToken token, BamlDecompilerOptions bamlDecompilerOptions);
39+
3040
/// <summary>
3141
/// Decompiles baml to xaml. Returns all assembly references.
3242
/// </summary>

dnSpy/dnSpy.Decompiler/MSBuild/Project.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,8 @@ IEnumerable<ProjectFile> CreateXamlResourceFiles(ModuleDef module, ResourceNameC
416416

417417
var rsrcName = Uri.UnescapeDataString(e.Name);
418418
if (decompileBaml && rsrcName.EndsWith(".baml", StringComparison.OrdinalIgnoreCase)) {
419-
var filename = resourceNameCreator.GetBamlResourceName(rsrcName, out string typeFullName);
419+
var bamlTypeName = Options.DecompileBamlTypeName!(module, data, Options.DecompilationContext.CancellationToken);
420+
var filename = resourceNameCreator.GetBamlResourceName(rsrcName, bamlTypeName, out string typeFullName);
420421
yield return new BamlResourceProjectFile(filename, data, typeFullName, (bamlData, stream) => Options.DecompileBaml!(module, bamlData, Options.DecompilationContext.CancellationToken, stream));
421422
}
422423
else if (StringComparer.InvariantCultureIgnoreCase.Equals(splashScreenImageName, e.Name)) {

dnSpy/dnSpy.Decompiler/MSBuild/ProjectModuleOptions.cs

+5
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ sealed class ProjectModuleOptions {
7373
/// </summary>
7474
public bool DecompileXaml { get; set; }
7575

76+
/// <summary>
77+
/// Decompiles type name from baml data
78+
/// </summary>
79+
public Func<ModuleDef, byte[], CancellationToken, string>? DecompileBamlTypeName;
80+
7681
/// <summary>
7782
/// Decompiles baml data to a <see cref="Stream"/>
7883
/// </summary>

dnSpy/dnSpy.Decompiler/MSBuild/ResourceNameCreator.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public License
2020
using System;
2121
using System.Collections.Generic;
2222
using System.Diagnostics;
23+
using System.Globalization;
2324
using System.Linq;
2425
using System.Text;
2526
using dnlib.DotNet;
@@ -159,7 +160,7 @@ static string GetNamespace(string name) {
159160
return name.Substring(0, i).Replace('/', '.');
160161
}
161162

162-
public string GetBamlResourceName(string resourceName, out string typeFullName) {
163+
public string GetBamlResourceName(string resourceName, string bamlTypeName, out string typeFullName) {
163164
if (namespaces is null)
164165
Initialize();
165166
Debug2.Assert(partialNamespaceMap is not null);
@@ -169,10 +170,10 @@ public string GetBamlResourceName(string resourceName, out string typeFullName)
169170
Debug2.Assert(namespaces is not null);
170171

171172
Debug.Assert(resourceName.EndsWith(".baml", StringComparison.OrdinalIgnoreCase));
172-
var name = resourceName.Substring(0, resourceName.Length - ".baml".Length);
173+
var name = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(resourceName.Substring(0, resourceName.Length - ".baml".Length));
173174
var nameNoExt = name;
174175
name = name.Replace('/', '.');
175-
typeFullName = GetFullName(name) ?? string.Empty;
176+
typeFullName = !string.IsNullOrWhiteSpace(bamlTypeName) ? bamlTypeName : GetFullName(name) ?? string.Empty;
176177
if (!string.IsNullOrEmpty(typeFullName))
177178
return filenameCreator.Create(".xaml", typeFullName);
178179

dnSpy/dnSpy/Documents/Tabs/SaveCommands.cs

+1
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ public void Execute(ExportToProjectVM vm) {
189189
if (bamlDecompiler is not null) {
190190
var o = BamlDecompilerOptions.Create(vm.Decompiler.Decompiler);
191191
var outputOptions = xamlOutputOptionsProvider?.Default ?? new XamlOutputOptions();
192+
projOpts.DecompileBamlTypeName = (a, b, c) => bamlDecompiler.DecompileTypeName(a, b, c, o);
192193
projOpts.DecompileBaml = (a, b, c, d) => bamlDecompiler.Decompile(a, b, c, o, d, outputOptions);
193194
}
194195
options.ProjectModules.Add(projOpts);

0 commit comments

Comments
 (0)