mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
Declare scoped locals on first assignment
This commit is contained in:
@@ -37,6 +37,7 @@ partial class Decompiler
|
|||||||
Stack<CodeBlockInfo> blockStack = [];
|
Stack<CodeBlockInfo> blockStack = [];
|
||||||
blockStack.Push(new(0, methodBody[^1].Offset, SyntaxKind.Block, null));
|
blockStack.Push(new(0, methodBody[^1].Offset, SyntaxKind.Block, null));
|
||||||
|
|
||||||
|
HashSet<string> scopedLocals = [];
|
||||||
Stack<object> stack = new();
|
Stack<object> stack = new();
|
||||||
|
|
||||||
for (int i = 0; i < methodBody.Length; i++)
|
for (int i = 0; i < methodBody.Length; i++)
|
||||||
@@ -98,12 +99,36 @@ partial class Decompiler
|
|||||||
var newSymbolValue = opCode is OpCode.WriteSymbolPeek
|
var newSymbolValue = opCode is OpCode.WriteSymbolPeek
|
||||||
? stack.Peek() : stack.Pop();
|
? stack.Peek() : stack.Pop();
|
||||||
|
|
||||||
var symbolAssignmentExpr = AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
|
var symbolRef = export.SymbolReferenceTable[writeSymbolIndex];
|
||||||
IrisExpression.ToSyntax(export.SymbolReferenceTable[writeSymbolIndex]),
|
var symbolIdentifierExpr = IrisExpression.ToSyntax(symbolRef);
|
||||||
IrisExpression.ToSyntax(newSymbolValue, _context)
|
var newSymbolValueExpr = IrisExpression.ToSyntax(newSymbolValue, _context);
|
||||||
);
|
|
||||||
|
|
||||||
blockStack.Peek().Statements.Add(ExpressionStatement(symbolAssignmentExpr));
|
StatementSyntax symbolWriteExpr;
|
||||||
|
|
||||||
|
if (symbolRef.Origin is SymbolOrigin.ScopedLocal && !scopedLocals.Contains(symbolRef.Symbol))
|
||||||
|
{
|
||||||
|
// Scoped locals need to be declared the first time they're assigned
|
||||||
|
var newSymbolIrisObj = IrisObject.Create(newSymbolValue, null, _context);
|
||||||
|
var typeSchema = newSymbolIrisObj.Type ?? UIXTypes.MapIDToType(UIXTypeID.Object);
|
||||||
|
|
||||||
|
symbolWriteExpr = LocalDeclarationStatement(VariableDeclaration(
|
||||||
|
IrisExpression.ToSyntax(typeSchema, _context),
|
||||||
|
SingletonSeparatedList(
|
||||||
|
VariableDeclarator(symbolRef.Symbol)
|
||||||
|
.WithInitializer(EqualsValueClause(newSymbolValueExpr))
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var symbolAssignmentExpr = AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
|
||||||
|
symbolIdentifierExpr,
|
||||||
|
newSymbolValueExpr
|
||||||
|
);
|
||||||
|
symbolWriteExpr = ExpressionStatement(symbolAssignmentExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
blockStack.Peek().Statements.Add(symbolWriteExpr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode.PropertyAssign:
|
case OpCode.PropertyAssign:
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ internal record IrisObject(object Object, TypeSchema Type)
|
|||||||
else if (objIn is ExpressionSyntax expr)
|
else if (objIn is ExpressionSyntax expr)
|
||||||
{
|
{
|
||||||
type ??= GuessExpressionReturnType(expr, context);
|
type ??= GuessExpressionReturnType(expr, context);
|
||||||
|
return new(obj, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objIn is Disassembler.RawConstantInfo constantInfo)
|
if (objIn is Disassembler.RawConstantInfo constantInfo)
|
||||||
@@ -40,6 +41,9 @@ internal record IrisObject(object Object, TypeSchema Type)
|
|||||||
|
|
||||||
private static TypeSchema GuessExpressionReturnType(ExpressionSyntax expr, DecompileContext ctx)
|
private static TypeSchema GuessExpressionReturnType(ExpressionSyntax expr, DecompileContext ctx)
|
||||||
{
|
{
|
||||||
|
if (expr is ParenthesizedExpressionSyntax parenExpr)
|
||||||
|
expr = parenExpr.Expression;
|
||||||
|
|
||||||
if (expr is MemberAccessExpressionSyntax memberAccessExpression)
|
if (expr is MemberAccessExpressionSyntax memberAccessExpression)
|
||||||
{
|
{
|
||||||
// TODO: Handle member access on instance methods
|
// TODO: Handle member access on instance methods
|
||||||
|
|||||||
Reference in New Issue
Block a user