File: Language\Intermediate\IntermediateNodeReference.cs
Web Access
Project: src\src\Razor\src\Compiler\Microsoft.CodeAnalysis.Razor.Compiler\src\Microsoft.CodeAnalysis.Razor.Compiler.csproj (Microsoft.CodeAnalysis.Razor.Compiler)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Collections.Generic;
using System.Diagnostics;
 
namespace Microsoft.AspNetCore.Razor.Language.Intermediate;
 
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
public readonly struct IntermediateNodeReference
{
    public IntermediateNode Node { get; }
    public IntermediateNode Parent { get; }
 
    public IntermediateNodeReference(IntermediateNode node, IntermediateNode parent)
    {
        ArgHelper.ThrowIfNull(parent);
        ArgHelper.ThrowIfNull(node);
 
        Parent = parent;
        Node = node;
    }
 
    public void Deconstruct(out IntermediateNode node, out IntermediateNode parent)
    {
        node = Node;
        parent = Parent;
    }
 
    private int GetNodeIndexForMutation()
    {
        if (Parent == null)
        {
            throw new InvalidOperationException(Resources.IntermediateNodeReference_NotInitialized);
        }
 
        if (Parent.Children.IsReadOnly)
        {
            throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_CollectionIsReadOnly(Parent));
        }
 
        var index = Parent.Children.IndexOf(Node);
        if (index < 0)
        {
            throw new InvalidOperationException(Resources.FormatIntermediateNodeReference_NodeNotFound(Node, Parent));
        }
 
        return index;
    }
 
    public IntermediateNodeReference InsertAfter(IntermediateNode node)
    {
        ArgHelper.ThrowIfNull(node);
 
        var index = GetNodeIndexForMutation();
 
        Parent.Children.Insert(index + 1, node);
        return new IntermediateNodeReference(node, Parent);
    }
 
    public void InsertAfter(IEnumerable<IntermediateNode> nodes)
    {
        ArgHelper.ThrowIfNull(nodes);
 
        var index = GetNodeIndexForMutation();
 
        foreach (var node in nodes)
        {
            Parent.Children.Insert(++index, node);
        }
    }
 
    public IntermediateNodeReference InsertBefore(IntermediateNode node)
    {
        ArgHelper.ThrowIfNull(node);
 
        var index = GetNodeIndexForMutation();
 
        Parent.Children.Insert(index, node);
        return new IntermediateNodeReference(node, Parent);
    }
 
    public void InsertBefore(IEnumerable<IntermediateNode> nodes)
    {
        ArgHelper.ThrowIfNull(nodes);
 
        var index = GetNodeIndexForMutation();
 
        foreach (var node in nodes)
        {
            Parent.Children.Insert(index++, node);
        }
    }
 
    public void Remove()
    {
        var index = GetNodeIndexForMutation();
 
        Parent.Children.RemoveAt(index);
    }
 
    public IntermediateNodeReference Replace(IntermediateNode node)
    {
        ArgHelper.ThrowIfNull(node);
 
        var index = GetNodeIndexForMutation();
 
        Parent.Children[index] = node;
        return new IntermediateNodeReference(node, Parent);
    }
 
    private string GetDebuggerDisplay()
        => $"ref: {Parent.GetDebuggerDisplay()} - {Node.GetDebuggerDisplay()}";
}