80 lines
2.2 KiB
C#
80 lines
2.2 KiB
C#
using Microsoft.CodeAnalysis.PooledObjects;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp;
|
|
|
|
internal abstract class BoundTreeWalkerWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator : BoundTreeWalkerWithStackGuard
|
|
{
|
|
protected BoundTreeWalkerWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator()
|
|
{
|
|
}
|
|
|
|
protected BoundTreeWalkerWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator(int recursionDepth)
|
|
: base(recursionDepth)
|
|
{
|
|
}
|
|
|
|
public sealed override BoundNode? VisitBinaryOperator(BoundBinaryOperator node)
|
|
{
|
|
if (node.Left.Kind != BoundKind.BinaryOperator)
|
|
{
|
|
return base.VisitBinaryOperator(node);
|
|
}
|
|
ArrayBuilder<BoundExpression> instance = ArrayBuilder<BoundExpression>.GetInstance();
|
|
ArrayBuilderExtensions.Push<BoundExpression>(instance, node.Right);
|
|
BoundBinaryOperator boundBinaryOperator = (BoundBinaryOperator)node.Left;
|
|
ArrayBuilderExtensions.Push<BoundExpression>(instance, boundBinaryOperator.Right);
|
|
BoundExpression left = boundBinaryOperator.Left;
|
|
while (left.Kind == BoundKind.BinaryOperator)
|
|
{
|
|
boundBinaryOperator = (BoundBinaryOperator)left;
|
|
ArrayBuilderExtensions.Push<BoundExpression>(instance, boundBinaryOperator.Right);
|
|
left = boundBinaryOperator.Left;
|
|
}
|
|
Visit(left);
|
|
while (instance.Count > 0)
|
|
{
|
|
Visit(ArrayBuilderExtensions.Pop<BoundExpression>(instance));
|
|
}
|
|
instance.Free();
|
|
return null;
|
|
}
|
|
|
|
public sealed override BoundNode? VisitCall(BoundCall node)
|
|
{
|
|
if (node.ReceiverOpt is BoundCall boundCall)
|
|
{
|
|
ArrayBuilder<BoundCall> instance = ArrayBuilder<BoundCall>.GetInstance();
|
|
ArrayBuilderExtensions.Push<BoundCall>(instance, node);
|
|
node = boundCall;
|
|
while (node.ReceiverOpt is BoundCall boundCall2)
|
|
{
|
|
ArrayBuilderExtensions.Push<BoundCall>(instance, node);
|
|
node = boundCall2;
|
|
}
|
|
VisitReceiver(node);
|
|
do
|
|
{
|
|
VisitArguments(node);
|
|
}
|
|
while (ArrayBuilderExtensions.TryPop<BoundCall>(instance, ref node));
|
|
instance.Free();
|
|
}
|
|
else
|
|
{
|
|
VisitReceiver(node);
|
|
VisitArguments(node);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
protected virtual void VisitReceiver(BoundCall node)
|
|
{
|
|
Visit(node.ReceiverOpt);
|
|
}
|
|
|
|
protected virtual void VisitArguments(BoundCall node)
|
|
{
|
|
VisitList(node.Arguments);
|
|
}
|
|
}
|