|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using System;
using System.Collections.Generic;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate;
internal class DefaultRazorIntermediateNodeBuilder : IntermediateNodeBuilder
{
private readonly List<IntermediateNode> _stack;
private int _depth;
public DefaultRazorIntermediateNodeBuilder()
{
_stack = new List<IntermediateNode>();
}
public override IntermediateNode Current
{
get
{
return _depth > 0 ? _stack[_depth - 1] : null;
}
}
public override void Add(IntermediateNode node)
{
if (node == null)
{
throw new ArgumentNullException(nameof(node));
}
Current.Children.Add(node);
}
public override void Insert(int index, IntermediateNode node)
{
if (index < 0 || index - Current.Children.Count > 0)
{
throw new ArgumentOutOfRangeException(nameof(index));
}
if (index == Current.Children.Count)
{
// Allow inserting at 'Children.Count' to be friendlier than List<> typically is.
Current.Children.Add(node);
}
else
{
Current.Children.Insert(index, node);
}
}
public override IntermediateNode Build()
{
IntermediateNode node = null;
while (_depth > 0)
{
node = Pop();
}
return node;
}
public override IntermediateNode Pop()
{
if (_depth == 0)
{
throw new InvalidOperationException(Resources.FormatIntermediateNodeBuilder_PopInvalid(nameof(Pop)));
}
var node = _stack[--_depth];
return node;
}
public override void Push(IntermediateNode node)
{
if (node == null)
{
throw new ArgumentNullException(nameof(node));
}
if (_depth >= _stack.Count)
{
_stack.Add(node);
}
else
{
_stack[_depth] = node;
}
if (_depth > 0)
{
var parent = _stack[_depth - 1];
parent.Children.Add(node);
}
_depth++;
}
}
|