| File: Syntax\SyntaxList.SeparatedWithManyChildren.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. namespace Microsoft.CodeAnalysis.Syntax { internal partial class SyntaxList { internal sealed class SeparatedWithManyChildren : SyntaxList { private readonly ArrayElement<SyntaxNode?>[] _children; internal SeparatedWithManyChildren(InternalSyntax.SyntaxList green, SyntaxNode? parent, int position) : base(green, parent, position) { _children = new ArrayElement<SyntaxNode?>[(green.SlotCount + 1) >> 1]; } internal override SyntaxNode? GetNodeSlot(int i) { if ((i & 1) != 0) { //separator return null; } return this.GetRedElement(ref _children[i >> 1].Value, i); } internal override SyntaxNode? GetCachedSlot(int i) { if ((i & 1) != 0) { //separator return null; } return _children[i >> 1].Value; } internal override int GetChildPosition(int index) { // If the previous sibling (ignoring separator) is not cached, but the next sibling // (ignoring separator) is cached, use the next sibling to determine position. int valueIndex = (index & 1) != 0 ? index - 1 : index; // The check for valueIndex >= Green.SlotCount - 2 ignores the last item because the last item // is a separator and separators are not cached. In those cases, when the index represents // the last or next to last item, we still want to calculate the position from the end of // the list rather than the start. if (valueIndex > 1 && GetCachedSlot(valueIndex - 2) is null && (valueIndex >= Green.SlotCount - 2 || GetCachedSlot(valueIndex + 2) is { })) { return GetChildPositionFromEnd(index); } return base.GetChildPosition(index); } } } }