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()
|
||||
{
|
||||
CompiledFileName = _loadResult.ErrorContextUri,
|
||||
ScriptSymbols = [],
|
||||
};
|
||||
|
||||
_instructions = ObjectSection.Decode(_loadResult.ObjectSection)
|
||||
|
||||
@@ -622,10 +622,6 @@ partial class Decompiler
|
||||
public string FormatSyntaxNode(SyntaxNode root, CancellationToken cancellationToken = default)
|
||||
{
|
||||
uint? scriptOffset = null;
|
||||
ScriptDebugSymbols debugSymbols = new()
|
||||
{
|
||||
SourceMap = []
|
||||
};
|
||||
|
||||
root = root.NormalizeWhitespace();
|
||||
|
||||
@@ -636,7 +632,7 @@ partial class Decompiler
|
||||
|
||||
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)
|
||||
scriptOffset = offset;
|
||||
@@ -646,12 +642,7 @@ partial class Decompiler
|
||||
.SyntaxTree
|
||||
.GetText(cancellationToken);
|
||||
|
||||
debugSymbols.SourceCode = sourceText.ToString();
|
||||
|
||||
if (scriptOffset is not null)
|
||||
_context.DebugSymbols.ScriptSymbols[scriptOffset.Value] = debugSymbols;
|
||||
|
||||
return debugSymbols.SourceCode;
|
||||
return sourceText.ToString();
|
||||
}
|
||||
|
||||
private bool TryDecompileExpression(Instruction instruction, Stack<object> stack, ControlFlowAnalyzer cfa = null)
|
||||
|
||||
@@ -143,7 +143,7 @@ public partial class Decompiler
|
||||
return xDoc;
|
||||
}
|
||||
|
||||
public string DecompileToSource()
|
||||
public string DecompileToSource(bool generateDebugSymbols)
|
||||
{
|
||||
var xmlDoc = Decompile();
|
||||
|
||||
@@ -159,7 +159,47 @@ public partial class Decompiler
|
||||
{
|
||||
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;
|
||||
@@ -189,7 +229,7 @@ public partial class Decompiler
|
||||
|
||||
case OpCode.ConstructObject:
|
||||
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));
|
||||
break;
|
||||
|
||||
@@ -213,7 +253,8 @@ public partial class Decompiler
|
||||
var target = stack.Pop();
|
||||
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));
|
||||
break;
|
||||
@@ -231,10 +272,10 @@ public partial class Decompiler
|
||||
var dictValueObj = IrisObject.Create(dictValue, dictValueType, _context, initType);
|
||||
|
||||
var targetDictPropertyIndex = (ushort)instruction.Operands.ElementAt(0).Value;
|
||||
if (targetDictPropertyIndex is ushort.MaxValue)
|
||||
PropertyDictionaryAddOnXElement(targetInstance, dictValueObj, key);
|
||||
else
|
||||
PropertyDictionaryAddOnXElement(targetInstance, _context.ImportTables.PropertyImports[targetDictPropertyIndex], dictValueObj, key);
|
||||
var xKeyValue = targetDictPropertyIndex is ushort.MaxValue
|
||||
? PropertyDictionaryAddOnXElement(targetInstance, dictValueObj, key)
|
||||
: PropertyDictionaryAddOnXElement(targetInstance, _context.ImportTables.PropertyImports[targetDictPropertyIndex], dictValueObj, key);
|
||||
xKeyValue.SetOffset(instruction);
|
||||
break;
|
||||
|
||||
case OpCode.PropertyListAdd:
|
||||
@@ -252,6 +293,7 @@ public partial class Decompiler
|
||||
|
||||
var targetInstance2 = (XElement)ToXmlFriendlyObject(stack.Peek());
|
||||
|
||||
XObject xListItem;
|
||||
var targetListPropertyIndex = (ushort)instruction.Operands.First().Value;
|
||||
if (targetListPropertyIndex != ushort.MaxValue)
|
||||
{
|
||||
@@ -264,12 +306,14 @@ public partial class Decompiler
|
||||
valueToAddObj = valueToAddObj with { Type = valueToAddType };
|
||||
}
|
||||
|
||||
PropertyListAddOnXElement(targetInstance2, targetListProperty, valueToAddObj);
|
||||
xListItem = PropertyListAddOnXElement(targetInstance2, targetListProperty, valueToAddObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
PropertyListAddOnXElement(targetInstance2, valueToAddObj);
|
||||
xListItem = PropertyListAddOnXElement(targetInstance2, valueToAddObj);
|
||||
}
|
||||
|
||||
xListItem.SetOffset(instruction);
|
||||
break;
|
||||
|
||||
case OpCode.InitializeInstance:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.Iris.Asm.Models;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Microsoft.Iris.DecompXml;
|
||||
|
||||
@@ -23,5 +24,26 @@ internal static class UIBOffsetAnnotation
|
||||
}
|
||||
|
||||
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