Files

82 lines
2.4 KiB
C#
Raw Permalink Normal View History

2025-09-24 21:52:20 -05:00
using Microsoft.CodeAnalysis.CSharp.Syntax;
2025-09-25 15:52:13 -05:00
using System;
2025-07-18 14:04:06 -05:00
using System.Collections.Generic;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace Microsoft.Iris.DecompXml;
2025-09-26 13:20:12 -05:00
public record CodeBlock
2025-07-18 14:04:06 -05:00
{
2025-09-26 13:20:12 -05:00
public CodeBlock(uint startOffset, uint endOffset, ICodeBlockInfo meta = null)
2025-07-18 14:04:06 -05:00
{
StartOffset = startOffset;
EndOffset = endOffset;
2025-09-26 13:20:12 -05:00
Info = meta;
2025-07-18 14:04:06 -05:00
}
public uint StartOffset { get; init; }
public uint EndOffset { get; init; }
2025-09-26 13:20:12 -05:00
public ICodeBlockInfo Info { get; init; }
2025-07-18 14:04:06 -05:00
public List<StatementSyntax> Statements { get; } = [];
2025-09-26 13:20:12 -05:00
public void FinalizeBlock(CodeBlock parentBlock)
2025-07-18 14:04:06 -05:00
{
var blockBody = Block(Statements);
2025-09-26 13:20:12 -05:00
switch (Info)
2025-07-18 14:04:06 -05:00
{
2025-09-24 21:52:20 -05:00
case IfBlockInfo ifBlockInfo:
var ifStatement = IfStatement(ifBlockInfo.Condition, blockBody)
.WithOffset(StartOffset);
2025-09-26 13:20:12 -05:00
if (ifBlockInfo.ElseClause is not null)
ifStatement = ifStatement.WithElse(ifBlockInfo.ElseClause);
2025-07-18 14:04:06 -05:00
parentBlock.Statements.Add(ifStatement);
break;
2025-09-24 21:52:20 -05:00
case ElseBlockInfo _:
2025-09-26 13:20:12 -05:00
if (parentBlock.Info is not IfBlockInfo ifElseBlockInfo)
throw new InvalidOperationException($"Else block must be preceded by an if block, got '{parentBlock.Info}'");
2025-09-25 15:52:13 -05:00
ifElseBlockInfo.ElseClause = ElseClause(blockBody)
.WithOffset(StartOffset);
2025-07-18 14:04:06 -05:00
break;
2025-09-24 21:52:20 -05:00
case ForEachBlockInfo forEachBlockInfo:
var foreachStatement = ForEachStatement(forEachBlockInfo.Type, forEachBlockInfo.Identifier,
forEachBlockInfo.Source, blockBody)
.WithOffset(StartOffset);
2025-09-24 21:52:20 -05:00
parentBlock.Statements.Add(foreachStatement);
break;
2025-07-18 14:04:06 -05:00
default:
2025-09-26 13:20:12 -05:00
throw new NotImplementedException($"Unrecognized code block kind '{Info.GetType().Name}'");
2025-07-18 14:04:06 -05:00
}
}
}
2025-09-24 21:52:20 -05:00
2025-09-26 13:20:12 -05:00
public interface ICodeBlockInfo;
2025-09-24 21:52:20 -05:00
2025-09-26 13:20:12 -05:00
public class IfBlockInfo(ExpressionSyntax condition = null) : ICodeBlockInfo
2025-09-24 21:52:20 -05:00
{
public ExpressionSyntax Condition { get; set; } = condition;
2025-09-26 13:20:12 -05:00
public ElseClauseSyntax ElseClause { get; set; }
2025-09-24 21:52:20 -05:00
}
2025-09-26 13:20:12 -05:00
public class ElseBlockInfo : ICodeBlockInfo;
2025-09-24 21:52:20 -05:00
2025-09-26 13:20:12 -05:00
public class ForEachBlockInfo : ICodeBlockInfo
2025-09-24 21:52:20 -05:00
{
public ExpressionSyntax Source { get; set; }
public string Identifier { get; set; }
public TypeSyntax Type { get; set; }
}