mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
[WIP] Build source map for scripts
This commit is contained in:
+1
-1
Submodule libs/MicrosoftIris updated: 3307b6ea3c...55815fe59d
@@ -2,6 +2,7 @@
|
|||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.Iris.Asm;
|
using Microsoft.Iris.Asm;
|
||||||
using Microsoft.Iris.Asm.Models;
|
using Microsoft.Iris.Asm.Models;
|
||||||
|
using Microsoft.Iris.Debug.Symbols;
|
||||||
using Microsoft.Iris.Markup;
|
using Microsoft.Iris.Markup;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -58,6 +59,12 @@ internal class DecompileContext
|
|||||||
|
|
||||||
_scriptMap = [];
|
_scriptMap = [];
|
||||||
|
|
||||||
|
DebugSymbols = new()
|
||||||
|
{
|
||||||
|
CompiledFileName = _loadResult.ErrorContextUri,
|
||||||
|
ScriptSymbols = [],
|
||||||
|
};
|
||||||
|
|
||||||
_instructions = ObjectSection.Decode(_loadResult.ObjectSection)
|
_instructions = ObjectSection.Decode(_loadResult.ObjectSection)
|
||||||
.OfType<Instruction>()
|
.OfType<Instruction>()
|
||||||
.ToArray();
|
.ToArray();
|
||||||
@@ -71,6 +78,8 @@ internal class DecompileContext
|
|||||||
|
|
||||||
public MarkupImportTables ImportTables => _loadResult.ImportTables;
|
public MarkupImportTables ImportTables => _loadResult.ImportTables;
|
||||||
|
|
||||||
|
public FileDebugSymbols DebugSymbols { get; }
|
||||||
|
|
||||||
[MemberNotNullWhen(true, nameof(_dataTableLoadResult))]
|
[MemberNotNullWhen(true, nameof(_dataTableLoadResult))]
|
||||||
private bool UseSharedDataTable => _dataTableLoadResult is not null;
|
private bool UseSharedDataTable => _dataTableLoadResult is not null;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis.CSharp;
|
|||||||
using Microsoft.CodeAnalysis.CSharp.Extensions;
|
using Microsoft.CodeAnalysis.CSharp.Extensions;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using Microsoft.Iris.Asm.Models;
|
using Microsoft.Iris.Asm.Models;
|
||||||
|
using Microsoft.Iris.Debug.Symbols;
|
||||||
using Microsoft.Iris.DecompXml.Mock;
|
using Microsoft.Iris.DecompXml.Mock;
|
||||||
using Microsoft.Iris.Markup;
|
using Microsoft.Iris.Markup;
|
||||||
using Microsoft.Iris.Markup.UIX;
|
using Microsoft.Iris.Markup.UIX;
|
||||||
@@ -23,7 +24,7 @@ partial class Decompiler
|
|||||||
private SyntaxTree DecompileScript(uint startOffset, MarkupTypeSchema export)
|
private SyntaxTree DecompileScript(uint startOffset, MarkupTypeSchema export)
|
||||||
{
|
{
|
||||||
var statements = DecompileMethod(startOffset, export);
|
var statements = DecompileMethod(startOffset, export);
|
||||||
return CreateTree(statements);
|
return CreateTree(statements, startOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<StatementSyntax> DecompileMethod(uint startOffset, MarkupTypeSchema export)
|
public List<StatementSyntax> DecompileMethod(uint startOffset, MarkupTypeSchema export)
|
||||||
@@ -501,7 +502,7 @@ partial class Decompiler
|
|||||||
if (statements is null)
|
if (statements is null)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
scriptContent = CreateTree(statements);
|
scriptContent = CreateTree(statements, scriptOffset);
|
||||||
_context.SetScriptContent(initType, scriptOffset, scriptContent);
|
_context.SetScriptContent(initType, scriptOffset, scriptContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,26 +596,29 @@ partial class Decompiler
|
|||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SyntaxTree CreateTree(IEnumerable<StatementSyntax> statements)
|
public static SyntaxTree CreateTree(IEnumerable<StatementSyntax> statements, uint? startOffset = null)
|
||||||
{
|
{
|
||||||
return SyntaxTree(
|
var root = CompilationUnit()
|
||||||
CompilationUnit().WithMembers(
|
.WithMembers(
|
||||||
[.. statements.Select(GlobalStatement)]
|
[.. statements.Select(GlobalStatement)]
|
||||||
)
|
);
|
||||||
);
|
|
||||||
|
if (startOffset is not null)
|
||||||
|
root = root.WithOffset(startOffset.Value);
|
||||||
|
|
||||||
|
return SyntaxTree(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string FormatInlineExpression(ExpressionSyntax expr, CancellationToken token = default) => '{' + FormatSyntaxNode(expr, token) + '}';
|
public string FormatInlineExpression(ExpressionSyntax expr, CancellationToken token = default) => '{' + FormatSyntaxNode(expr, token) + '}';
|
||||||
|
|
||||||
public static string FormatScript(SyntaxTree tree, CancellationToken token = default) => FormatSyntaxNode(tree.GetRoot(token), token);
|
public string FormatScript(SyntaxTree tree, CancellationToken token = default) => FormatSyntaxNode(tree.GetRoot(token), token);
|
||||||
|
|
||||||
public static string FormatScript(IEnumerable<StatementSyntax> statements, CancellationToken token = default) => FormatScript(CreateTree(statements), token);
|
public string FormatSyntaxNode(SyntaxNode root, CancellationToken cancellationToken = default)
|
||||||
|
|
||||||
public static string FormatSyntaxNode(SyntaxNode root, CancellationToken cancellationToken = default)
|
|
||||||
{
|
{
|
||||||
Debug.Symbols.ScriptDebugSymbols symbols = new()
|
uint? scriptOffset = null;
|
||||||
|
ScriptDebugSymbols debugSymbols = new()
|
||||||
{
|
{
|
||||||
LineNumberMap = []
|
SourceMap = []
|
||||||
};
|
};
|
||||||
|
|
||||||
root = root.NormalizeWhitespace();
|
root = root.NormalizeWhitespace();
|
||||||
@@ -626,20 +630,22 @@ partial class Decompiler
|
|||||||
|
|
||||||
var location = node.GetLocation();
|
var location = node.GetLocation();
|
||||||
|
|
||||||
symbols.LineNumberMap[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;
|
||||||
}
|
}
|
||||||
|
|
||||||
var sourceText = root
|
var sourceText = root
|
||||||
.SyntaxTree
|
.SyntaxTree
|
||||||
.GetText(cancellationToken);
|
.GetText(cancellationToken);
|
||||||
|
|
||||||
foreach (var mapping in symbols.LineNumberMap.OrderBy(x => x.Key))
|
debugSymbols.SourceCode = sourceText.ToString();
|
||||||
{
|
|
||||||
var subtext = sourceText.GetSubText(CodeAnalysis.Text.TextSpan.FromBounds(mapping.Value.Start, mapping.Value.End));
|
|
||||||
System.Diagnostics.Debug.WriteLine($"0x{mapping.Key:X}: `{subtext}`");
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using Microsoft.Iris.Asm;
|
using Microsoft.Iris.Asm;
|
||||||
|
using Microsoft.Iris.Debug.Symbols;
|
||||||
using Microsoft.Iris.DecompXml.Mock;
|
using Microsoft.Iris.DecompXml.Mock;
|
||||||
using Microsoft.Iris.Markup;
|
using Microsoft.Iris.Markup;
|
||||||
using System;
|
using System;
|
||||||
@@ -87,7 +88,7 @@ public partial class Decompiler
|
|||||||
{
|
{
|
||||||
var statements = DecompileMethod(offset, export);
|
var statements = DecompileMethod(offset, export);
|
||||||
AddMethodAttribute(statements, "FinalEvaluate");
|
AddMethodAttribute(statements, "FinalEvaluate");
|
||||||
_context.SetScriptContent(export, offset, CreateTree(statements));
|
_context.SetScriptContent(export, offset, CreateTree(statements, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var offset in export.RefreshGroupOffsets ?? [])
|
foreach (var offset in export.RefreshGroupOffsets ?? [])
|
||||||
@@ -161,6 +162,8 @@ public partial class Decompiler
|
|||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FileDebugSymbols DebugSymbols => _context.DebugSymbols;
|
||||||
|
|
||||||
private Stack<object> AnalyzeMethodForInit(uint startOffset, XElement elemToInit, MarkupTypeSchema initType, string methodName = "")
|
private Stack<object> AnalyzeMethodForInit(uint startOffset, XElement elemToInit, MarkupTypeSchema initType, string methodName = "")
|
||||||
{
|
{
|
||||||
var methodBody = _context.GetMethodBody(startOffset).ToArray();
|
var methodBody = _context.GetMethodBody(startOffset).ToArray();
|
||||||
@@ -283,7 +286,10 @@ public partial class Decompiler
|
|||||||
|
|
||||||
// Ensure stack is in valid state
|
// Ensure stack is in valid state
|
||||||
var isPeek = instruction.OpCode is OpCode.JumpIfFalsePeek or OpCode.JumpIfTruePeek or OpCode.JumpIfNullPeek;
|
var isPeek = instruction.OpCode is OpCode.JumpIfFalsePeek or OpCode.JumpIfTruePeek or OpCode.JumpIfNullPeek;
|
||||||
var rawJumpCondition = IrisExpression.ToSyntax(isPeek ? stack.Peek() : stack.Pop(), _context);
|
if (isPeek)
|
||||||
|
stack.Peek();
|
||||||
|
else
|
||||||
|
stack.Pop();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode.ConstructObjectParam:
|
case OpCode.ConstructObjectParam:
|
||||||
|
|||||||
Reference in New Issue
Block a user