Files
PURErat-crack-scode/decompiled/Libraries/microsoft.codeanalysis.csharp/Microsoft.CodeAnalysis.CSharp/ExitPointsWalker.cs
T
2026-08-27 10:56:38 -06:00

161 lines
4.1 KiB
C#

using System;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal class ExitPointsWalker : AbstractRegionControlFlowPass
{
private readonly ArrayBuilder<LabelSymbol> _labelsInside;
private readonly ArrayBuilder<StatementSyntax> _branchesOutOf;
private ExitPointsWalker(CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion)
: base(compilation, member, node, firstInRegion, lastInRegion)
{
_labelsInside = new ArrayBuilder<LabelSymbol>();
_branchesOutOf = ArrayBuilder<StatementSyntax>.GetInstance();
}
protected override void Free()
{
if (_branchesOutOf != null)
{
_branchesOutOf.Free();
}
_labelsInside.Free();
base.Free();
}
internal static ImmutableArray<StatementSyntax> Analyze(CSharpCompilation compilation, Symbol member, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion)
{
ExitPointsWalker exitPointsWalker = new ExitPointsWalker(compilation, member, node, firstInRegion, lastInRegion);
try
{
return exitPointsWalker.Analyze();
}
finally
{
exitPointsWalker.Free();
}
}
private ImmutableArray<StatementSyntax> Analyze()
{
bool badRegion = false;
Scan(ref badRegion);
if (badRegion)
{
return ImmutableArray<StatementSyntax>.Empty;
}
_branchesOutOf.Sort((Comparison<StatementSyntax>)((StatementSyntax x, StatementSyntax y) => ((SyntaxNode)x).SpanStart - ((SyntaxNode)y).SpanStart));
return _branchesOutOf.ToImmutable();
}
public override BoundNode VisitLabelStatement(BoundLabelStatement node)
{
if (base.IsInside)
{
_labelsInside.Add(node.Label);
}
return base.VisitLabelStatement(node);
}
public override BoundNode VisitDoStatement(BoundDoStatement node)
{
if (base.IsInside)
{
_labelsInside.Add((LabelSymbol)node.BreakLabel);
_labelsInside.Add((LabelSymbol)node.ContinueLabel);
}
return base.VisitDoStatement(node);
}
public override BoundNode VisitForEachStatement(BoundForEachStatement node)
{
if (base.IsInside)
{
_labelsInside.Add((LabelSymbol)node.BreakLabel);
_labelsInside.Add((LabelSymbol)node.ContinueLabel);
}
return base.VisitForEachStatement(node);
}
public override BoundNode VisitForStatement(BoundForStatement node)
{
if (base.IsInside)
{
_labelsInside.Add((LabelSymbol)node.BreakLabel);
_labelsInside.Add((LabelSymbol)node.ContinueLabel);
}
return base.VisitForStatement(node);
}
public override BoundNode VisitWhileStatement(BoundWhileStatement node)
{
if (base.IsInside)
{
_labelsInside.Add((LabelSymbol)node.BreakLabel);
}
return base.VisitWhileStatement(node);
}
protected override void EnterRegion()
{
base.EnterRegion();
}
protected override void LeaveRegion()
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
foreach (PendingBranch item in base.PendingBranches.AsEnumerable())
{
if (item.Branch == null || !RegionContains(item.Branch.Syntax.Span))
{
continue;
}
switch (item.Branch.Kind)
{
case BoundKind.GotoStatement:
if (_labelsInside.Contains(((BoundGotoStatement)item.Branch).Label))
{
continue;
}
break;
case BoundKind.BreakStatement:
if (_labelsInside.Contains((LabelSymbol)((BoundBreakStatement)item.Branch).Label))
{
continue;
}
break;
case BoundKind.ContinueStatement:
if (_labelsInside.Contains((LabelSymbol)((BoundContinueStatement)item.Branch).Label))
{
continue;
}
break;
case BoundKind.ForEachStatement:
if (((BoundForEachStatement)item.Branch).AwaitOpt != null)
{
continue;
}
goto default;
default:
throw ExceptionUtilities.UnexpectedValue((object)item.Branch.Kind);
case BoundKind.ReturnStatement:
case BoundKind.YieldBreakStatement:
break;
case BoundKind.AwaitExpression:
case BoundKind.YieldReturnStatement:
case BoundKind.UsingStatement:
continue;
}
_branchesOutOf.Add((StatementSyntax)(object)item.Branch.Syntax);
}
base.LeaveRegion();
}
}