|
// 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.Diagnostics;
namespace Microsoft.CodeAnalysis.Syntax
{
internal class SyntaxTokenListBuilder
{
private GreenNode?[] _nodes;
private int _count;
public SyntaxTokenListBuilder(int size)
{
_nodes = new GreenNode?[size];
_count = 0;
}
public static SyntaxTokenListBuilder Create()
{
return new SyntaxTokenListBuilder(8);
}
public int Count
{
get
{
return _count;
}
}
public void Add(SyntaxToken item)
{
Debug.Assert(item.Node is object);
this.Add(item.Node);
}
internal void Add(GreenNode item)
{
CheckSpace(1);
_nodes[_count++] = item;
}
public void Add(SyntaxTokenList list)
{
this.Add(list, 0, list.Count);
}
public void Add(SyntaxTokenList list, int offset, int length)
{
CheckSpace(length);
list.CopyTo(offset, _nodes, _count, length);
_count += length;
}
public void Add(SyntaxToken[] list)
{
this.Add(list, 0, list.Length);
}
public void Add(SyntaxToken[] list, int offset, int length)
{
CheckSpace(length);
for (int i = 0; i < length; i++)
{
_nodes[_count + i] = list[offset + i].Node;
}
_count += length;
}
private void CheckSpace(int delta)
{
var requiredSize = _count + delta;
if (requiredSize > _nodes.Length)
{
this.Grow(requiredSize);
}
}
private void Grow(int newSize)
{
var tmp = new GreenNode[newSize];
Array.Copy(_nodes, tmp, _nodes.Length);
_nodes = tmp;
}
public SyntaxTokenList ToList()
{
if (_count > 0)
{
switch (_count)
{
case 1:
return new SyntaxTokenList(null, _nodes[0], 0, 0);
case 2:
Debug.Assert(_nodes[0] is object);
Debug.Assert(_nodes[1] is object);
return new SyntaxTokenList(null, InternalSyntax.SyntaxList.List(_nodes[0]!, _nodes[1]!), 0, 0);
case 3:
Debug.Assert(_nodes[0] is object);
Debug.Assert(_nodes[1] is object);
Debug.Assert(_nodes[2] is object);
return new SyntaxTokenList(null, InternalSyntax.SyntaxList.List(_nodes[0]!, _nodes[1]!, _nodes[2]!), 0, 0);
default:
return new SyntaxTokenList(null, InternalSyntax.SyntaxList.List(_nodes, _count), 0, 0);
}
}
else
{
return default(SyntaxTokenList);
}
}
public static implicit operator SyntaxTokenList(SyntaxTokenListBuilder builder)
{
return builder.ToList();
}
}
}
|