mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
XML debug symbols
This commit is contained in:
+1
-1
Submodule libs/MicrosoftIris updated: ae9b24dc34...2f293ec6dd
@@ -62,7 +62,6 @@ internal class DecompileContext
|
|||||||
DebugSymbols = new()
|
DebugSymbols = new()
|
||||||
{
|
{
|
||||||
CompiledFileName = _loadResult.ErrorContextUri,
|
CompiledFileName = _loadResult.ErrorContextUri,
|
||||||
ScriptSymbols = [],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_instructions = ObjectSection.Decode(_loadResult.ObjectSection)
|
_instructions = ObjectSection.Decode(_loadResult.ObjectSection)
|
||||||
|
|||||||
@@ -622,10 +622,6 @@ partial class Decompiler
|
|||||||
public string FormatSyntaxNode(SyntaxNode root, CancellationToken cancellationToken = default)
|
public string FormatSyntaxNode(SyntaxNode root, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
uint? scriptOffset = null;
|
uint? scriptOffset = null;
|
||||||
ScriptDebugSymbols debugSymbols = new()
|
|
||||||
{
|
|
||||||
SourceMap = []
|
|
||||||
};
|
|
||||||
|
|
||||||
root = root.NormalizeWhitespace();
|
root = root.NormalizeWhitespace();
|
||||||
|
|
||||||
@@ -636,7 +632,7 @@ partial class Decompiler
|
|||||||
|
|
||||||
var location = node.GetLocation();
|
var location = node.GetLocation();
|
||||||
|
|
||||||
debugSymbols.SourceMap[offset] = new(location.SourceSpan.Start, location.SourceSpan.End);
|
//debugSymbols.SourceMap[offset] = new(location.SourceSpan.Start, location.SourceSpan.End);
|
||||||
|
|
||||||
if (scriptOffset is null && node is CompilationUnitSyntax)
|
if (scriptOffset is null && node is CompilationUnitSyntax)
|
||||||
scriptOffset = offset;
|
scriptOffset = offset;
|
||||||
@@ -646,12 +642,7 @@ partial class Decompiler
|
|||||||
.SyntaxTree
|
.SyntaxTree
|
||||||
.GetText(cancellationToken);
|
.GetText(cancellationToken);
|
||||||
|
|
||||||
debugSymbols.SourceCode = sourceText.ToString();
|
return sourceText.ToString();
|
||||||
|
|
||||||
if (scriptOffset is not null)
|
|
||||||
_context.DebugSymbols.ScriptSymbols[scriptOffset.Value] = debugSymbols;
|
|
||||||
|
|
||||||
return debugSymbols.SourceCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryDecompileExpression(Instruction instruction, Stack<object> stack, ControlFlowAnalyzer cfa = null)
|
private bool TryDecompileExpression(Instruction instruction, Stack<object> stack, ControlFlowAnalyzer cfa = null)
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ public partial class Decompiler
|
|||||||
return xDoc;
|
return xDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string DecompileToSource()
|
public string DecompileToSource(bool generateDebugSymbols)
|
||||||
{
|
{
|
||||||
var xmlDoc = Decompile();
|
var xmlDoc = Decompile();
|
||||||
|
|
||||||
@@ -159,7 +159,47 @@ public partial class Decompiler
|
|||||||
{
|
{
|
||||||
xmlDoc.WriteTo(writer);
|
xmlDoc.WriteTo(writer);
|
||||||
}
|
}
|
||||||
return sb.ToString();
|
|
||||||
|
var xmlStr = sb.ToString();
|
||||||
|
|
||||||
|
if (generateDebugSymbols)
|
||||||
|
PopulateDebugSymbolsWithXml(xmlDoc, xmlStr);
|
||||||
|
|
||||||
|
return xmlStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PopulateDebugSymbolsWithXml(XDocument xmlDoc, string xmlStr)
|
||||||
|
{
|
||||||
|
// Reparse the file to get line info
|
||||||
|
var xmlDocWithLineInfo = XDocument.Parse(xmlStr, LoadOptions.SetLineInfo);
|
||||||
|
var lineInfoNodes = xmlDocWithLineInfo.DescendantNodes();
|
||||||
|
var offsetInfoNodes = xmlDoc.DescendantNodes();
|
||||||
|
|
||||||
|
foreach (var (liNode, oiNode) in lineInfoNodes.Zip(offsetInfoNodes, (l, o) => (l, o)))
|
||||||
|
{
|
||||||
|
var offsetInfo = oiNode.Annotation<UIBOffsetXmlAnnotation>();
|
||||||
|
if (offsetInfo is null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (liNode is not IXmlLineInfo lineInfo || !lineInfo.HasLineInfo())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var offset = offsetInfo.Offset;
|
||||||
|
var start = new SourcePosition(lineInfo.LineNumber, lineInfo.LinePosition);
|
||||||
|
|
||||||
|
var elementStr = oiNode.ToString();
|
||||||
|
var endLine = start.Line + elementStr.Count(c => c == '\n');
|
||||||
|
var endColumn = elementStr.Length;
|
||||||
|
var idxLastLine = elementStr.LastIndexOf('\n');
|
||||||
|
if (idxLastLine > 0)
|
||||||
|
endColumn -= idxLastLine;
|
||||||
|
|
||||||
|
var end = new SourcePosition(endLine, endColumn);
|
||||||
|
|
||||||
|
var span = new SourceSpan(start, end);
|
||||||
|
|
||||||
|
DebugSymbols.SourceMap.Xml[offset] = span;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileDebugSymbols DebugSymbols => _context.DebugSymbols;
|
public FileDebugSymbols DebugSymbols => _context.DebugSymbols;
|
||||||
@@ -189,7 +229,7 @@ public partial class Decompiler
|
|||||||
|
|
||||||
case OpCode.ConstructObject:
|
case OpCode.ConstructObject:
|
||||||
var typeToCtor = _context.GetImportedType(instruction.Operands.ElementAt(0));
|
var typeToCtor = _context.GetImportedType(instruction.Operands.ElementAt(0));
|
||||||
var xObj = new XElement(_context.GetXName(typeToCtor));
|
var xObj = new XElement(_context.GetXName(typeToCtor)).WithOffset(instruction);
|
||||||
stack.Push(new IrisObject(xObj, typeToCtor));
|
stack.Push(new IrisObject(xObj, typeToCtor));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -213,7 +253,8 @@ public partial class Decompiler
|
|||||||
var target = stack.Pop();
|
var target = stack.Pop();
|
||||||
var xTarget = (XElement)ToXmlFriendlyObject(target);
|
var xTarget = (XElement)ToXmlFriendlyObject(target);
|
||||||
|
|
||||||
PropertyAssignOnXElement(xTarget, propertyToInit, IrisObject.Create(newPropValue, propertyToInit.PropertyType, _context, initType));
|
var xPropSetter = PropertyAssignOnXElement(xTarget, propertyToInit, IrisObject.Create(newPropValue, propertyToInit.PropertyType, _context, initType));
|
||||||
|
xPropSetter.SetOffset(instruction);
|
||||||
|
|
||||||
stack.Push(new IrisObject(xTarget, propertyToInit.Owner));
|
stack.Push(new IrisObject(xTarget, propertyToInit.Owner));
|
||||||
break;
|
break;
|
||||||
@@ -231,10 +272,10 @@ public partial class Decompiler
|
|||||||
var dictValueObj = IrisObject.Create(dictValue, dictValueType, _context, initType);
|
var dictValueObj = IrisObject.Create(dictValue, dictValueType, _context, initType);
|
||||||
|
|
||||||
var targetDictPropertyIndex = (ushort)instruction.Operands.ElementAt(0).Value;
|
var targetDictPropertyIndex = (ushort)instruction.Operands.ElementAt(0).Value;
|
||||||
if (targetDictPropertyIndex is ushort.MaxValue)
|
var xKeyValue = targetDictPropertyIndex is ushort.MaxValue
|
||||||
PropertyDictionaryAddOnXElement(targetInstance, dictValueObj, key);
|
? PropertyDictionaryAddOnXElement(targetInstance, dictValueObj, key)
|
||||||
else
|
: PropertyDictionaryAddOnXElement(targetInstance, _context.ImportTables.PropertyImports[targetDictPropertyIndex], dictValueObj, key);
|
||||||
PropertyDictionaryAddOnXElement(targetInstance, _context.ImportTables.PropertyImports[targetDictPropertyIndex], dictValueObj, key);
|
xKeyValue.SetOffset(instruction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode.PropertyListAdd:
|
case OpCode.PropertyListAdd:
|
||||||
@@ -252,6 +293,7 @@ public partial class Decompiler
|
|||||||
|
|
||||||
var targetInstance2 = (XElement)ToXmlFriendlyObject(stack.Peek());
|
var targetInstance2 = (XElement)ToXmlFriendlyObject(stack.Peek());
|
||||||
|
|
||||||
|
XObject xListItem;
|
||||||
var targetListPropertyIndex = (ushort)instruction.Operands.First().Value;
|
var targetListPropertyIndex = (ushort)instruction.Operands.First().Value;
|
||||||
if (targetListPropertyIndex != ushort.MaxValue)
|
if (targetListPropertyIndex != ushort.MaxValue)
|
||||||
{
|
{
|
||||||
@@ -264,12 +306,14 @@ public partial class Decompiler
|
|||||||
valueToAddObj = valueToAddObj with { Type = valueToAddType };
|
valueToAddObj = valueToAddObj with { Type = valueToAddType };
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyListAddOnXElement(targetInstance2, targetListProperty, valueToAddObj);
|
xListItem = PropertyListAddOnXElement(targetInstance2, targetListProperty, valueToAddObj);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PropertyListAddOnXElement(targetInstance2, valueToAddObj);
|
xListItem = PropertyListAddOnXElement(targetInstance2, valueToAddObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xListItem.SetOffset(instruction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode.InitializeInstance:
|
case OpCode.InitializeInstance:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.Iris.Asm.Models;
|
using Microsoft.Iris.Asm.Models;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Microsoft.Iris.DecompXml;
|
namespace Microsoft.Iris.DecompXml;
|
||||||
|
|
||||||
@@ -23,5 +24,26 @@ internal static class UIBOffsetAnnotation
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static uint GetOffset(SyntaxAnnotation offsetAnnotation) => uint.Parse(offsetAnnotation.Data);
|
public static uint GetOffset(SyntaxAnnotation offsetAnnotation) => uint.Parse(offsetAnnotation.Data);
|
||||||
|
|
||||||
|
public static void SetOffset(this XObject xObj, uint offset) => xObj.AddAnnotation(new UIBOffsetXmlAnnotation(offset));
|
||||||
|
|
||||||
|
public static void SetOffset(this XObject xObj, Instruction instruction) => xObj.SetOffset(instruction.Offset);
|
||||||
|
|
||||||
|
public static XObject WithOffset(this XObject xObj, Instruction instruction)
|
||||||
|
{
|
||||||
|
xObj.SetOffset(instruction.Offset);
|
||||||
|
return xObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static XObject WithNewOffset(this XObject xObj, Instruction instruction)
|
||||||
|
{
|
||||||
|
if (xObj.GetOffset() is null)
|
||||||
|
xObj.SetOffset(instruction.Offset);
|
||||||
|
return xObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint? GetOffset(this XObject xObj) => xObj.Annotation<UIBOffsetXmlAnnotation>()?.Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal record UIBOffsetXmlAnnotation(uint Offset);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user