| File: Syntax\SyntaxTriviaListBuilder.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 System.Collections; using System.Collections.Generic; namespace Microsoft.CodeAnalysis.Syntax { internal class SyntaxTriviaListBuilder { private SyntaxTrivia[] _nodes; private int _count; public SyntaxTriviaListBuilder(int size) { _nodes = new SyntaxTrivia[size]; } public static SyntaxTriviaListBuilder Create() { return new SyntaxTriviaListBuilder(4); } public static SyntaxTriviaList Create(IEnumerable<SyntaxTrivia>? trivia) { if (trivia == null) { return new SyntaxTriviaList(); } var builder = SyntaxTriviaListBuilder.Create(); builder.AddRange(trivia); return builder.ToList(); } public int Count { get { return _count; } } public void Clear() { _count = 0; } public SyntaxTrivia this[int index] { get { if (index < 0 || index >= _count) { throw new IndexOutOfRangeException(); } return _nodes[index]; } } public void AddRange(IEnumerable<SyntaxTrivia>? items) { if (items != null) { foreach (var item in items) { this.Add(item); } } } public SyntaxTriviaListBuilder Add(SyntaxTrivia item) { if (_count >= _nodes.Length) { this.Grow(_count == 0 ? 8 : _nodes.Length * 2); } _nodes[_count++] = item; return this; } public void Add(SyntaxTrivia[] items) => Add(items.AsSpan()); public void Add(ReadOnlySpan<SyntaxTrivia> items) { this.Add(items, 0, items.Length); } public void Add(SyntaxTrivia[] items, int offset, int length) => Add(items.AsSpan(), offset, length); public void Add(ReadOnlySpan<SyntaxTrivia> items, int offset, int length) { if (_count + length > _nodes.Length) { this.Grow(_count + length); } items.Slice(offset, length).CopyTo(_nodes.AsSpan().Slice(_count, length)); _count += length; } public void Add(in SyntaxTriviaList list) { this.Add(list, 0, list.Count); } public void Add(in SyntaxTriviaList list, int offset, int length) { if (_count + length > _nodes.Length) { this.Grow(_count + length); } list.CopyTo(offset, _nodes, _count, length); _count += length; } private void Grow(int size) { var tmp = new SyntaxTrivia[size]; Array.Copy(_nodes, tmp, _nodes.Length); _nodes = tmp; } public static implicit operator SyntaxTriviaList(SyntaxTriviaListBuilder builder) { return builder.ToList(); } public SyntaxTriviaList ToList() { if (_count > 0) { switch (_count) { case 1: return new SyntaxTriviaList(default(SyntaxToken), _nodes[0].UnderlyingNode, position: 0, index: 0); case 2: return new SyntaxTriviaList(default(SyntaxToken), InternalSyntax.SyntaxList.List( _nodes[0].UnderlyingNode!, _nodes[1].UnderlyingNode!), position: 0, index: 0); case 3: return new SyntaxTriviaList(default(SyntaxToken), InternalSyntax.SyntaxList.List( _nodes[0].UnderlyingNode!, _nodes[1].UnderlyingNode!, _nodes[2].UnderlyingNode!), position: 0, index: 0); default: { var tmp = new ArrayElement<GreenNode>[_count]; for (int i = 0; i < _count; i++) { tmp[i].Value = _nodes[i].UnderlyingNode!; } return new SyntaxTriviaList(default(SyntaxToken), InternalSyntax.SyntaxList.List(tmp), position: 0, index: 0); } } } else { return default(SyntaxTriviaList); } } } }