| File: Syntax\InternalSyntax\SyntaxList.WithManyChildren.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. using System; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax { internal partial class SyntaxList { internal abstract class WithManyChildrenBase : SyntaxList { internal readonly ArrayElement<GreenNode>[] children; internal WithManyChildrenBase(ArrayElement<GreenNode>[] children) { this.children = children; this.InitializeChildren(); } internal WithManyChildrenBase(DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations, ArrayElement<GreenNode>[] children) : base(diagnostics, annotations) { this.children = children; this.InitializeChildren(); } private void InitializeChildren() { int n = children.Length; // Attempt to store small lengths directly into the storage provided within GreenNode. If, however, the // length is too long, we will store a special value in the space, which will `SlotCount` to call back // into `GetSlotCount` to retrieve the true length. this.SlotCount = n < SlotCountTooLarge ? (byte)n : SlotCountTooLarge; for (int i = 0; i < children.Length; i++) { this.AdjustFlagsAndWidth(children[i]); } } protected override int GetSlotCount() { return children.Length; } internal override GreenNode GetSlot(int index) { return this.children[index]; } internal override void CopyTo(ArrayElement<GreenNode>[] array, int offset) { Array.Copy(this.children, 0, array, offset, this.children.Length); } internal override SyntaxNode CreateRed(SyntaxNode? parent, int position) { var separated = this.SlotCount > 1 && HasNodeTokenPattern(); if (parent != null && parent.ShouldCreateWeakList()) { return separated ? new Syntax.SyntaxList.SeparatedWithManyWeakChildren(this, parent, position) : (SyntaxNode)new Syntax.SyntaxList.WithManyWeakChildren(this, parent, position); } else { return separated ? new Syntax.SyntaxList.SeparatedWithManyChildren(this, parent, position) : (SyntaxNode)new Syntax.SyntaxList.WithManyChildren(this, parent, position); } } private bool HasNodeTokenPattern() { for (int i = 0; i < this.SlotCount; i++) { // even slots must not be tokens, odds slots must be tokens if (this.GetSlot(i).IsToken == ((i & 1) == 0)) { return false; } } return true; } } internal sealed class WithManyChildren : WithManyChildrenBase { internal WithManyChildren(ArrayElement<GreenNode>[] children) : base(children) { } internal WithManyChildren(DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations, ArrayElement<GreenNode>[] children) : base(diagnostics, annotations, children) { } internal override GreenNode SetDiagnostics(DiagnosticInfo[]? errors) { return new WithManyChildren(errors, this.GetAnnotations(), children); } internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations) { return new WithManyChildren(GetDiagnostics(), annotations, children); } } } }