From 8355a6ad3e437f770de3018e3023f91b471d778f Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Mon, 18 Sep 2023 21:06:09 +0200 Subject: [PATCH] Improve support for special attribute usages in BAML decompiler --- Extensions/dnSpy.BamlDecompiler/BamlDisassembler.cs | 2 +- .../Handlers/Records/PropertyHandler.cs | 9 +++++++++ Extensions/dnSpy.BamlDecompiler/Xaml/XamlProperty.cs | 2 ++ Extensions/dnSpy.BamlDecompiler/Xaml/XamlPropertyKind.cs | 9 +++++++++ Extensions/dnSpy.BamlDecompiler/XamlContext.cs | 6 +++++- 5 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 Extensions/dnSpy.BamlDecompiler/Xaml/XamlPropertyKind.cs diff --git a/Extensions/dnSpy.BamlDecompiler/BamlDisassembler.cs b/Extensions/dnSpy.BamlDecompiler/BamlDisassembler.cs index 5514e75c73..17438cb273 100644 --- a/Extensions/dnSpy.BamlDecompiler/BamlDisassembler.cs +++ b/Extensions/dnSpy.BamlDecompiler/BamlDisassembler.cs @@ -523,7 +523,7 @@ void DisassembleRecord(BamlContext ctx, AttributeInfoRecord record) { WriteFlagField("XmlSpace"); break; case BamlAttributeUsage.RuntimeName: - WriteFlagField("XmlSpace"); + WriteFlagField("RuntimeName"); break; default: WriteHexNumber((byte)record.AttributeUsage); diff --git a/Extensions/dnSpy.BamlDecompiler/Handlers/Records/PropertyHandler.cs b/Extensions/dnSpy.BamlDecompiler/Handlers/Records/PropertyHandler.cs index 1aba6c5a84..38aaa0bf74 100644 --- a/Extensions/dnSpy.BamlDecompiler/Handlers/Records/PropertyHandler.cs +++ b/Extensions/dnSpy.BamlDecompiler/Handlers/Records/PropertyHandler.cs @@ -42,6 +42,15 @@ public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) return null; XAttribute ConstructXAttribute() { + switch (xamlProp.PropertyKind) { + case XamlPropertyKind.XmlSpace: + return new XAttribute(XNamespace.Xml + "space", value); + case XamlPropertyKind.XmlLang: + return new XAttribute(XNamespace.Xml + "lang", value); + case XamlPropertyKind.RuntimeName: + return new XAttribute(ctx.GetKnownNamespace("Name", XamlContext.KnownNamespace_Xaml), value); + } + if (xamlProp.IsAttachedTo(elemType)) return new XAttribute(xamlProp.ToXName(ctx, parent.Xaml), value); diff --git a/Extensions/dnSpy.BamlDecompiler/Xaml/XamlProperty.cs b/Extensions/dnSpy.BamlDecompiler/Xaml/XamlProperty.cs index 9b01623be8..a94c5eaed2 100644 --- a/Extensions/dnSpy.BamlDecompiler/Xaml/XamlProperty.cs +++ b/Extensions/dnSpy.BamlDecompiler/Xaml/XamlProperty.cs @@ -35,6 +35,8 @@ sealed class XamlProperty { public ITypeDefOrRef ResolvedMemberDeclaringType { get; set; } + public XamlPropertyKind PropertyKind { get; set; } + public XamlProperty(XamlType type, string name) { DeclaringType = type; PropertyName = name; diff --git a/Extensions/dnSpy.BamlDecompiler/Xaml/XamlPropertyKind.cs b/Extensions/dnSpy.BamlDecompiler/Xaml/XamlPropertyKind.cs new file mode 100644 index 0000000000..83de5b0dcf --- /dev/null +++ b/Extensions/dnSpy.BamlDecompiler/Xaml/XamlPropertyKind.cs @@ -0,0 +1,9 @@ +namespace dnSpy.BamlDecompiler.Xaml { + enum XamlPropertyKind : byte { + // Note: The order of these should remain consistent with BamlAttributeUsage! + Default, + XmlLang, + XmlSpace, + RuntimeName, + } +} diff --git a/Extensions/dnSpy.BamlDecompiler/XamlContext.cs b/Extensions/dnSpy.BamlDecompiler/XamlContext.cs index e70ede0778..715e6e6cf8 100644 --- a/Extensions/dnSpy.BamlDecompiler/XamlContext.cs +++ b/Extensions/dnSpy.BamlDecompiler/XamlContext.cs @@ -123,23 +123,27 @@ public XamlProperty ResolveProperty(ushort id) { XamlType type; string name; IMemberDef member; + XamlPropertyKind propertyKind; if (id > 0x7fff) { var knownProp = Baml.KnownThings.Members((KnownMembers)unchecked((short)-(short)id)); type = ResolveType(unchecked((ushort)(short)-(short)knownProp.Parent)); name = knownProp.Name; member = knownProp.Property; + propertyKind = XamlPropertyKind.Default; } else { var attrRec = Baml.AttributeIdMap[id]; type = ResolveType(attrRec.OwnerTypeId); name = attrRec.Name; + propertyKind = (XamlPropertyKind)attrRec.AttributeUsage; member = null; } propertyMap[id] = xamlProp = new XamlProperty(type, name) { - ResolvedMember = member + ResolvedMember = member, + PropertyKind = propertyKind }; xamlProp.TryResolve();