Initial implementation of UIX Script debug symbols

This commit is contained in:
Joshua "Yoshi" Askharoun
2025-11-29 18:43:39 -06:00
parent a8f1f2c305
commit 288acbe21e
5 changed files with 4710 additions and 41 deletions
-34
View File
@@ -152,40 +152,6 @@ public partial class Decompiler
return writer.WriteToString();
}
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;
private Stack<object> AnalyzeMethodForInit(uint startOffset, XElement elemToInit, MarkupTypeSchema initType, string methodName = "")
+22 -4
View File
@@ -1,6 +1,6 @@
using Microsoft.Iris.Debug.Symbols;
using Microsoft.CodeAnalysis.Text;
using Microsoft.Iris.Debug.Symbols;
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using System.Xml.Linq;
@@ -75,6 +75,20 @@ internal class IrisXmlWriter : IDisposable
}
else if (obj is XIrisScriptContent script)
{
foreach (var node in script.Syntax.GetAnnotatedNodes(UIBOffsetAnnotation.Kind))
{
var expressionOffset = node.GetOffset();
if (expressionOffset is null)
continue;
var location = node.GetLocation().GetLineSpan().Span;
SourceSpan span = new(
RoslynToIrisPosition(location.Start, startPos.Line),
RoslynToIrisPosition(location.End, startPos.Line));
_symbols.SourceMap[expressionOffset.Value] = span;
}
_xmlWriter.WriteCData(script.Value);
}
else if (obj is XCData cdata)
@@ -86,7 +100,6 @@ internal class IrisXmlWriter : IDisposable
_xmlWriter.WriteAttributeString(attribute.Name.LocalName, attribute.Name.NamespaceName, attribute.Value);
}
var offset = obj.GetOffset();
if (offset is not null)
{
@@ -94,7 +107,12 @@ internal class IrisXmlWriter : IDisposable
var endPos = _textWriter.Position;
var span = new SourceSpan(startPos, endPos);
_symbols.SourceMap.Xml[offset.Value] = span;
_symbols.SourceMap[offset.Value] = span;
}
}
private static SourcePosition RoslynToIrisPosition(LinePosition linePosition, int currentLine)
{
return new(linePosition.Line + currentLine + 1, linePosition.Character + 1);
}
}
+8 -1
View File
@@ -1,5 +1,6 @@
using Microsoft.CodeAnalysis;
using Microsoft.Iris.Asm.Models;
using System.Linq;
using System.Xml.Linq;
namespace Microsoft.Iris.DecompXml;
@@ -23,7 +24,13 @@ internal static class UIBOffsetAnnotation
return node.WithOffset(instruction.Offset);
}
public static uint GetOffset(SyntaxAnnotation offsetAnnotation) => uint.Parse(offsetAnnotation.Data);
public static uint? GetOffset(this SyntaxNode node)
{
var annotation = node.GetAnnotations(Kind).SingleOrDefault();
return annotation is null
? null
: uint.Parse(annotation.Data);
}
public static void SetOffset(this XObject xObj, uint offset) => xObj.AddAnnotation(new UIBOffsetXmlAnnotation(offset));
+5 -1
View File
@@ -1,4 +1,5 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System;
using System.Xml.Linq;
@@ -8,9 +9,12 @@ internal class XIrisScriptContent : XCData
{
public SyntaxNode Syntax { get; }
public SourceText Text { get; }
public XIrisScriptContent(SyntaxNode syntax) : base("")
{
Syntax = syntax.NormalizeWhitespace();
Value = $"{Environment.NewLine}{Syntax.GetText()}{Environment.NewLine}";
Text = Syntax.GetText();
Value = $"{Environment.NewLine}{Text}{Environment.NewLine}";
}
}
File diff suppressed because one or more lines are too long