From ef2de0a2d16eeb032c2d2f40e01d13de7a84b79a Mon Sep 17 00:00:00 2001 From: "Joshua \"Yoshi\" Askharoun" Date: Mon, 24 Nov 2025 02:18:59 -0600 Subject: [PATCH] Prevent DIS from producing invalid statements --- libs/UIX.DecompXml/Decompiler.Script.cs | 4 ++ .../Extensions/SyntaxNodeExtensions.cs | 64 +++++++++++++++++++ test/NOWPLAYINGLAND_decomp.uix | 14 ++-- 3 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 libs/UIX.DecompXml/Extensions/SyntaxNodeExtensions.cs diff --git a/libs/UIX.DecompXml/Decompiler.Script.cs b/libs/UIX.DecompXml/Decompiler.Script.cs index 1ccb18b..bbd50a4 100644 --- a/libs/UIX.DecompXml/Decompiler.Script.cs +++ b/libs/UIX.DecompXml/Decompiler.Script.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.Iris.Asm.Models; using Microsoft.Iris.Debug.Symbols; +using Microsoft.Iris.DecompXml.Extensions; using Microsoft.Iris.DecompXml.Mock; using Microsoft.Iris.Markup; using Microsoft.Iris.Markup.UIX; @@ -127,6 +128,9 @@ partial class Decompiler break; } + if (!expr.IsStatementExpression()) + break; + cfa.AppendToBlock(ExpressionStatement(expr)); } break; diff --git a/libs/UIX.DecompXml/Extensions/SyntaxNodeExtensions.cs b/libs/UIX.DecompXml/Extensions/SyntaxNodeExtensions.cs new file mode 100644 index 0000000..82cac4c --- /dev/null +++ b/libs/UIX.DecompXml/Extensions/SyntaxNodeExtensions.cs @@ -0,0 +1,64 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Microsoft.Iris.DecompXml.Extensions; + +internal static class SyntaxNodeExtensions +{ + public static bool IsStatementExpression(this SyntaxNode syntax) + { + // The grammar gives: + // + // expression-statement: + // statement-expression ; + // + // statement-expression: + // invocation-expression + // object-creation-expression + // assignment + // post-increment-expression + // post-decrement-expression + // pre-increment-expression + // pre-decrement-expression + // await-expression + + switch (syntax.Kind()) + { + case SyntaxKind.InvocationExpression: + case SyntaxKind.ObjectCreationExpression: + case SyntaxKind.SimpleAssignmentExpression: + case SyntaxKind.AddAssignmentExpression: + case SyntaxKind.SubtractAssignmentExpression: + case SyntaxKind.MultiplyAssignmentExpression: + case SyntaxKind.DivideAssignmentExpression: + case SyntaxKind.ModuloAssignmentExpression: + case SyntaxKind.AndAssignmentExpression: + case SyntaxKind.OrAssignmentExpression: + case SyntaxKind.ExclusiveOrAssignmentExpression: + case SyntaxKind.LeftShiftAssignmentExpression: + case SyntaxKind.RightShiftAssignmentExpression: + case SyntaxKind.UnsignedRightShiftAssignmentExpression: + case SyntaxKind.CoalesceAssignmentExpression: + case SyntaxKind.PostIncrementExpression: + case SyntaxKind.PostDecrementExpression: + case SyntaxKind.PreIncrementExpression: + case SyntaxKind.PreDecrementExpression: + case SyntaxKind.AwaitExpression: + return true; + + case SyntaxKind.ConditionalAccessExpression: + var access = (ConditionalAccessExpressionSyntax)syntax; + return IsStatementExpression(access.WhenNotNull); + + // Allow missing IdentifierNames; they will show up in error cases + // where there is no statement whatsoever. + + case SyntaxKind.IdentifierName: + return syntax.IsMissing; + + default: + return false; + } + } +} diff --git a/test/NOWPLAYINGLAND_decomp.uix b/test/NOWPLAYINGLAND_decomp.uix index e43867f..2824041 100644 --- a/test/NOWPLAYINGLAND_decomp.uix +++ b/test/NOWPLAYINGLAND_decomp.uix @@ -272,7 +272,7 @@ ActionContainer.Visible = #SaveAsPlaylistButton.Visible # || #ShowMPContentCheck ]]>