File: Language\Syntax\SyntaxList.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 Microsoft.AspNetCore.Razor.PooledObjects;
 
namespace Microsoft.AspNetCore.Razor.Language.Syntax;
 
internal abstract class SyntaxList(InternalSyntax.SyntaxList green, SyntaxNode parent, int position) : SyntaxNode(green, parent, position)
{
    public static SyntaxList<TNode> Create<TNode>(params ReadOnlySpan<TNode> nodes)
        where TNode : SyntaxNode
    {
        if (nodes.Length == 0)
        {
            return default;
        }
 
        using var builder = new PooledArrayBuilder<TNode>(nodes.Length);
        builder.AddRange(nodes);
 
        return builder.ToList();
    }
 
    public static SyntaxList<TNode> Create<TNode>(IEnumerable<TNode> nodes)
        where TNode : SyntaxNode
    {
        using var builder = new PooledArrayBuilder<TNode>();
        builder.AddRange(nodes);
 
        return builder.ToList();
    }
 
    public static SyntaxTokenList Create(params ReadOnlySpan<SyntaxToken> tokens)
    {
        if (tokens.Length == 0)
        {
            return default;
        }
 
        using var builder = new PooledArrayBuilder<SyntaxToken>(tokens.Length);
        builder.AddRange(tokens);
 
        return builder.ToList();
    }
 
    public static SyntaxTokenList Create(IEnumerable<SyntaxToken> tokens)
    {
        using var builder = new PooledArrayBuilder<SyntaxToken>();
        builder.AddRange(tokens);
 
        return builder.ToList();
    }
 
    // For debugging
#pragma warning disable IDE0051 // Remove unused private members
    private string SerializedValue => $"List: {SlotCount} slots";
#pragma warning restore IDE0051 // Remove unused private members
 
    protected internal override SyntaxNode ReplaceCore<TNode>(
        IEnumerable<TNode>? nodes = null,
        Func<TNode, TNode, SyntaxNode>? computeReplacementNode = null,
        IEnumerable<SyntaxToken>? tokens = null,
        Func<SyntaxToken, SyntaxToken, SyntaxToken>? computeReplacementToken = null)
        => Assumed.Unreachable<SyntaxNode>();
 
    protected internal override SyntaxNode ReplaceNodeInListCore(SyntaxNode originalNode, IEnumerable<SyntaxNode> replacementNodes)
        => Assumed.Unreachable<SyntaxNode>();
 
    protected internal override SyntaxNode InsertNodesInListCore(SyntaxNode nodeInList, IEnumerable<SyntaxNode> nodesToInsert, bool insertBefore)
        => Assumed.Unreachable<SyntaxNode>();
 
    protected internal override SyntaxNode ReplaceTokenInListCore(SyntaxToken originalToken, IEnumerable<SyntaxToken> newTokens)
        => Assumed.Unreachable<SyntaxNode>();
 
    protected internal override SyntaxNode InsertTokensInListCore(SyntaxToken originalToken, IEnumerable<SyntaxToken> newTokens, bool insertBefore)
        => Assumed.Unreachable<SyntaxNode>();
 
    internal sealed class WithTwoChildren : SyntaxList
    {
        private SyntaxNode? _child0;
        private SyntaxNode? _child1;
 
        internal WithTwoChildren(InternalSyntax.SyntaxList green, SyntaxNode parent, int position)
            : base(green, parent, position)
        {
        }
 
        internal override SyntaxNode? GetNodeSlot(int index)
            => index switch
            {
                0 => GetRedElement(ref _child0, 0),
                1 => GetRedElement(ref _child1, 1),
                _ => null,
            };
 
        internal override SyntaxNode? GetCachedSlot(int index)
            => index switch
            {
                0 => _child0,
                1 => _child1,
                _ => null,
            };
    }
 
    internal sealed class WithThreeChildren : SyntaxList
    {
        private SyntaxNode? _child0;
        private SyntaxNode? _child1;
        private SyntaxNode? _child2;
 
        internal WithThreeChildren(InternalSyntax.SyntaxList green, SyntaxNode parent, int position)
            : base(green, parent, position)
        {
        }
 
        internal override SyntaxNode? GetNodeSlot(int index)
            => index switch
            {
                0 => GetRedElement(ref _child0, 0),
                1 => GetRedElement(ref _child1, 1),
                2 => GetRedElement(ref _child2, 2),
                _ => null,
            };
 
        internal override SyntaxNode? GetCachedSlot(int index)
            => index switch
            {
                0 => _child0,
                1 => _child1,
                2 => _child2,
                _ => null,
            };
    }
 
    internal sealed class WithManyChildren : SyntaxList
    {
        private readonly ArrayElement<SyntaxNode?>[] _children;
 
        internal WithManyChildren(InternalSyntax.SyntaxList green, SyntaxNode parent, int position)
            : base(green, parent, position)
        {
            _children = new ArrayElement<SyntaxNode?>[green.SlotCount];
        }
 
        internal override SyntaxNode? GetNodeSlot(int index)
            => GetRedElement(ref _children[index].Value, index);
 
        internal override SyntaxNode? GetCachedSlot(int index)
            => _children[index];
    }
}