initial commit
This commit is contained in:
+221
@@ -0,0 +1,221 @@
|
||||
namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax;
|
||||
|
||||
internal struct ChildSyntaxList
|
||||
{
|
||||
internal struct Enumerator
|
||||
{
|
||||
private readonly GreenNode? _node;
|
||||
|
||||
private int _childIndex;
|
||||
|
||||
private GreenNode? _list;
|
||||
|
||||
private int _listIndex;
|
||||
|
||||
private GreenNode? _currentChild;
|
||||
|
||||
public GreenNode Current => _currentChild;
|
||||
|
||||
internal Enumerator(GreenNode? node)
|
||||
{
|
||||
_node = node;
|
||||
_childIndex = -1;
|
||||
_listIndex = -1;
|
||||
_list = null;
|
||||
_currentChild = null;
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (_node != null)
|
||||
{
|
||||
if (_list != null)
|
||||
{
|
||||
_listIndex++;
|
||||
if (_listIndex < _list.SlotCount)
|
||||
{
|
||||
_currentChild = _list.GetSlot(_listIndex);
|
||||
return true;
|
||||
}
|
||||
_list = null;
|
||||
_listIndex = -1;
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
_childIndex++;
|
||||
if (_childIndex == _node.SlotCount)
|
||||
{
|
||||
break;
|
||||
}
|
||||
GreenNode slot = _node.GetSlot(_childIndex);
|
||||
if (slot != null)
|
||||
{
|
||||
if (slot.RawKind != 1)
|
||||
{
|
||||
_currentChild = slot;
|
||||
return true;
|
||||
}
|
||||
_list = slot;
|
||||
_listIndex++;
|
||||
if (_listIndex < _list.SlotCount)
|
||||
{
|
||||
_currentChild = _list.GetSlot(_listIndex);
|
||||
return true;
|
||||
}
|
||||
_list = null;
|
||||
_listIndex = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
_currentChild = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal readonly struct Reversed
|
||||
{
|
||||
internal struct Enumerator
|
||||
{
|
||||
private readonly GreenNode? _node;
|
||||
|
||||
private int _childIndex;
|
||||
|
||||
private GreenNode? _list;
|
||||
|
||||
private int _listIndex;
|
||||
|
||||
private GreenNode? _currentChild;
|
||||
|
||||
public GreenNode Current => _currentChild;
|
||||
|
||||
internal Enumerator(GreenNode? node)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
_node = node;
|
||||
_childIndex = node.SlotCount;
|
||||
_listIndex = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_node = null;
|
||||
_childIndex = 0;
|
||||
_listIndex = -1;
|
||||
}
|
||||
_list = null;
|
||||
_currentChild = null;
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (_node != null)
|
||||
{
|
||||
if (_list != null)
|
||||
{
|
||||
if (--_listIndex >= 0)
|
||||
{
|
||||
_currentChild = _list.GetSlot(_listIndex);
|
||||
return true;
|
||||
}
|
||||
_list = null;
|
||||
_listIndex = -1;
|
||||
}
|
||||
while (--_childIndex >= 0)
|
||||
{
|
||||
GreenNode slot = _node.GetSlot(_childIndex);
|
||||
if (slot != null)
|
||||
{
|
||||
if (!slot.IsList)
|
||||
{
|
||||
_currentChild = slot;
|
||||
return true;
|
||||
}
|
||||
_list = slot;
|
||||
_listIndex = _list.SlotCount;
|
||||
if (--_listIndex >= 0)
|
||||
{
|
||||
_currentChild = _list.GetSlot(_listIndex);
|
||||
return true;
|
||||
}
|
||||
_list = null;
|
||||
_listIndex = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
_currentChild = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly GreenNode? _node;
|
||||
|
||||
internal Reversed(GreenNode? node)
|
||||
{
|
||||
_node = node;
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(_node);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly GreenNode? _node;
|
||||
|
||||
private int _count;
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_count == -1)
|
||||
{
|
||||
_count = CountNodes();
|
||||
}
|
||||
return _count;
|
||||
}
|
||||
}
|
||||
|
||||
private GreenNode[] Nodes
|
||||
{
|
||||
get
|
||||
{
|
||||
GreenNode[] array = new GreenNode[Count];
|
||||
int num = 0;
|
||||
Enumerator enumerator = GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
GreenNode current = enumerator.Current;
|
||||
array[num++] = current;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
internal ChildSyntaxList(GreenNode node)
|
||||
{
|
||||
_node = node;
|
||||
_count = -1;
|
||||
}
|
||||
|
||||
private int CountNodes()
|
||||
{
|
||||
int num = 0;
|
||||
Enumerator enumerator = GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
num++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(_node);
|
||||
}
|
||||
|
||||
public Reversed Reverse()
|
||||
{
|
||||
return new Reversed(_node);
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax;
|
||||
|
||||
internal static class GreenNodeExtensions
|
||||
{
|
||||
internal static SyntaxList<T> ToGreenList<T>(this SyntaxNode? node) where T : GreenNode
|
||||
{
|
||||
return node?.Green.ToGreenList<T>() ?? default(SyntaxList<T>);
|
||||
}
|
||||
|
||||
internal static SeparatedSyntaxList<T> ToGreenSeparatedList<T>(this SyntaxNode? node) where T : GreenNode
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
return default(SeparatedSyntaxList<T>);
|
||||
}
|
||||
return new SeparatedSyntaxList<T>(node.Green.ToGreenList<T>());
|
||||
}
|
||||
|
||||
internal static SyntaxList<T> ToGreenList<T>(this GreenNode? node) where T : GreenNode
|
||||
{
|
||||
return new SyntaxList<T>(node);
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax;
|
||||
|
||||
internal class GreenStats
|
||||
{
|
||||
internal static void NoteGreen(GreenNode _)
|
||||
{
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
internal static void ItemAdded()
|
||||
{
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
internal static void ItemCacheable()
|
||||
{
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
internal static void CacheHit()
|
||||
{
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax;
|
||||
|
||||
internal readonly struct SeparatedSyntaxList<TNode> : IEquatable<SeparatedSyntaxList<TNode>> where TNode : GreenNode
|
||||
{
|
||||
private readonly SyntaxList<GreenNode> _list;
|
||||
|
||||
internal GreenNode? Node => _list.Node;
|
||||
|
||||
public int Count => _list.Count + 1 >> 1;
|
||||
|
||||
public int SeparatorCount => _list.Count >> 1;
|
||||
|
||||
public TNode? this[int index] => (TNode)_list[index << 1];
|
||||
|
||||
internal SeparatedSyntaxList(SyntaxList<GreenNode> list)
|
||||
{
|
||||
_list = list;
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private static void Validate(SyntaxList<GreenNode> list)
|
||||
{
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
list.GetRequiredItem(i);
|
||||
_ = i & 1;
|
||||
}
|
||||
}
|
||||
|
||||
public GreenNode? GetSeparator(int index)
|
||||
{
|
||||
return _list[(index << 1) + 1];
|
||||
}
|
||||
|
||||
public SyntaxList<GreenNode> GetWithSeparators()
|
||||
{
|
||||
return _list;
|
||||
}
|
||||
|
||||
public static bool operator ==(in SeparatedSyntaxList<TNode> left, in SeparatedSyntaxList<TNode> right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(in SeparatedSyntaxList<TNode> left, in SeparatedSyntaxList<TNode> right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
public bool Equals(SeparatedSyntaxList<TNode> other)
|
||||
{
|
||||
return _list == other._list;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is SeparatedSyntaxList<TNode>)
|
||||
{
|
||||
return Equals((SeparatedSyntaxList<TNode>)obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _list.GetHashCode();
|
||||
}
|
||||
|
||||
public static implicit operator SeparatedSyntaxList<GreenNode>(SeparatedSyntaxList<TNode> list)
|
||||
{
|
||||
return new SeparatedSyntaxList<GreenNode>(list.GetWithSeparators());
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax;
|
||||
|
||||
internal readonly struct SeparatedSyntaxListBuilder<TNode> where TNode : GreenNode
|
||||
{
|
||||
private readonly SyntaxListBuilder? _builder;
|
||||
|
||||
public bool IsNull => _builder == null;
|
||||
|
||||
public int Count => _builder.Count;
|
||||
|
||||
public GreenNode? this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _builder[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
_builder[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal SyntaxListBuilder? UnderlyingBuilder => _builder;
|
||||
|
||||
public SeparatedSyntaxListBuilder(int size)
|
||||
: this(new SyntaxListBuilder(size))
|
||||
{
|
||||
}
|
||||
|
||||
public static SeparatedSyntaxListBuilder<TNode> Create()
|
||||
{
|
||||
return new SeparatedSyntaxListBuilder<TNode>(8);
|
||||
}
|
||||
|
||||
internal SeparatedSyntaxListBuilder(SyntaxListBuilder builder)
|
||||
{
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_builder.Clear();
|
||||
}
|
||||
|
||||
public void RemoveLast()
|
||||
{
|
||||
_builder.RemoveLast();
|
||||
}
|
||||
|
||||
public SeparatedSyntaxListBuilder<TNode> Add(TNode node)
|
||||
{
|
||||
_builder.Add(node);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void AddSeparator(GreenNode separatorToken)
|
||||
{
|
||||
_builder.Add(separatorToken);
|
||||
}
|
||||
|
||||
public void AddRange(TNode[] items, int offset, int length)
|
||||
{
|
||||
_builder.AddRange(items, offset, length);
|
||||
}
|
||||
|
||||
public void AddRange(in SeparatedSyntaxList<TNode> nodes)
|
||||
{
|
||||
_builder.AddRange(nodes.GetWithSeparators());
|
||||
}
|
||||
|
||||
public void AddRange(in SeparatedSyntaxList<TNode> nodes, int count)
|
||||
{
|
||||
SyntaxList<GreenNode> withSeparators = nodes.GetWithSeparators();
|
||||
_builder.AddRange(withSeparators, Count, Math.Min(count * 2, withSeparators.Count));
|
||||
}
|
||||
|
||||
public bool Any(int kind)
|
||||
{
|
||||
return _builder.Any(kind);
|
||||
}
|
||||
|
||||
public SeparatedSyntaxList<TNode> ToList()
|
||||
{
|
||||
if (_builder != null)
|
||||
{
|
||||
return new SeparatedSyntaxList<TNode>(new SyntaxList<GreenNode>(_builder.ToListNode()));
|
||||
}
|
||||
return default(SeparatedSyntaxList<TNode>);
|
||||
}
|
||||
|
||||
public static implicit operator SeparatedSyntaxList<TNode>(in SeparatedSyntaxListBuilder<TNode> builder)
|
||||
{
|
||||
return builder.ToList();
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxListBuilder?(in SeparatedSyntaxListBuilder<TNode> builder)
|
||||
{
|
||||
return builder._builder;
|
||||
}
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax;
|
||||
|
||||
internal readonly struct SyntaxDiagnosticInfoList
|
||||
{
|
||||
public struct Enumerator
|
||||
{
|
||||
private struct NodeIteration
|
||||
{
|
||||
internal readonly GreenNode Node;
|
||||
|
||||
internal int DiagnosticIndex;
|
||||
|
||||
internal int SlotIndex;
|
||||
|
||||
internal NodeIteration(GreenNode node)
|
||||
{
|
||||
Node = node;
|
||||
SlotIndex = -1;
|
||||
DiagnosticIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private NodeIteration[]? _stack = null;
|
||||
|
||||
private int _count = 0;
|
||||
|
||||
public DiagnosticInfo Current { get; private set; } = null;
|
||||
|
||||
internal Enumerator(GreenNode node)
|
||||
{
|
||||
if (node != null && node.ContainsDiagnostics)
|
||||
{
|
||||
_stack = new NodeIteration[8];
|
||||
PushNodeOrToken(node);
|
||||
}
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
while (_count > 0)
|
||||
{
|
||||
int diagnosticIndex = _stack[_count - 1].DiagnosticIndex;
|
||||
GreenNode node = _stack[_count - 1].Node;
|
||||
DiagnosticInfo[] diagnostics = node.GetDiagnostics();
|
||||
if (diagnosticIndex < diagnostics.Length - 1)
|
||||
{
|
||||
diagnosticIndex++;
|
||||
Current = diagnostics[diagnosticIndex];
|
||||
_stack[_count - 1].DiagnosticIndex = diagnosticIndex;
|
||||
return true;
|
||||
}
|
||||
int num = _stack[_count - 1].SlotIndex;
|
||||
while (true)
|
||||
{
|
||||
if (num < node.SlotCount - 1)
|
||||
{
|
||||
num++;
|
||||
GreenNode slot = node.GetSlot(num);
|
||||
if (slot != null && slot.ContainsDiagnostics)
|
||||
{
|
||||
_stack[_count - 1].SlotIndex = num;
|
||||
PushNodeOrToken(slot);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Pop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void PushNodeOrToken(GreenNode node)
|
||||
{
|
||||
if (node.IsToken)
|
||||
{
|
||||
PushToken(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
Push(node);
|
||||
}
|
||||
}
|
||||
|
||||
private void PushToken(GreenNode token)
|
||||
{
|
||||
GreenNode trailingTriviaCore = token.GetTrailingTriviaCore();
|
||||
if (trailingTriviaCore != null)
|
||||
{
|
||||
Push(trailingTriviaCore);
|
||||
}
|
||||
Push(token);
|
||||
GreenNode leadingTriviaCore = token.GetLeadingTriviaCore();
|
||||
if (leadingTriviaCore != null)
|
||||
{
|
||||
Push(leadingTriviaCore);
|
||||
}
|
||||
}
|
||||
|
||||
private void Push(GreenNode node)
|
||||
{
|
||||
if (_count >= _stack.Length)
|
||||
{
|
||||
NodeIteration[] array = new NodeIteration[_stack.Length * 2];
|
||||
Array.Copy(_stack, array, _stack.Length);
|
||||
_stack = array;
|
||||
}
|
||||
_stack[_count] = new NodeIteration(node);
|
||||
_count++;
|
||||
}
|
||||
|
||||
private void Pop()
|
||||
{
|
||||
_count--;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly GreenNode _node;
|
||||
|
||||
internal SyntaxDiagnosticInfoList(GreenNode node)
|
||||
{
|
||||
_node = node;
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(_node);
|
||||
}
|
||||
|
||||
internal bool Any(Func<DiagnosticInfo, bool> predicate)
|
||||
{
|
||||
Enumerator enumerator = GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (predicate(enumerator.Current))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+721
@@ -0,0 +1,721 @@
|
||||
using System;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax;
|
||||
|
||||
internal abstract class SyntaxList : GreenNode
|
||||
{
|
||||
internal sealed class WithLotsOfChildren : WithManyChildrenBase
|
||||
{
|
||||
private readonly int[] _childOffsets;
|
||||
|
||||
static WithLotsOfChildren()
|
||||
{
|
||||
ObjectBinder.RegisterTypeReader(typeof(WithLotsOfChildren), (ObjectReader r) => new WithLotsOfChildren(r));
|
||||
}
|
||||
|
||||
internal WithLotsOfChildren(ArrayElement<GreenNode>[] children)
|
||||
: base(children)
|
||||
{
|
||||
_childOffsets = CalculateOffsets(children);
|
||||
}
|
||||
|
||||
internal WithLotsOfChildren(DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations, ArrayElement<GreenNode>[] children, int[] childOffsets)
|
||||
: base(diagnostics, annotations, children)
|
||||
{
|
||||
_childOffsets = childOffsets;
|
||||
}
|
||||
|
||||
internal WithLotsOfChildren(ObjectReader reader)
|
||||
: base(reader)
|
||||
{
|
||||
_childOffsets = CalculateOffsets(children);
|
||||
}
|
||||
|
||||
internal override void WriteTo(ObjectWriter writer)
|
||||
{
|
||||
base.WriteTo(writer);
|
||||
}
|
||||
|
||||
public override int GetSlotOffset(int index)
|
||||
{
|
||||
return _childOffsets[index];
|
||||
}
|
||||
|
||||
public override int FindSlotIndexContainingOffset(int offset)
|
||||
{
|
||||
return _childOffsets.BinarySearchUpperBound(offset) - 1;
|
||||
}
|
||||
|
||||
private static int[] CalculateOffsets(ArrayElement<GreenNode>[] children)
|
||||
{
|
||||
int num = children.Length;
|
||||
int[] array = new int[num];
|
||||
int num2 = 0;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
array[i] = num2;
|
||||
num2 += children[i].Value.FullWidth;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(DiagnosticInfo[]? errors)
|
||||
{
|
||||
return new WithLotsOfChildren(errors, GetAnnotations(), children, _childOffsets);
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations)
|
||||
{
|
||||
return new WithLotsOfChildren(GetDiagnostics(), annotations, children, _childOffsets);
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class WithManyChildrenBase : SyntaxList
|
||||
{
|
||||
internal readonly ArrayElement<GreenNode>[] children;
|
||||
|
||||
internal WithManyChildrenBase(ArrayElement<GreenNode>[] children)
|
||||
{
|
||||
this.children = children;
|
||||
InitializeChildren();
|
||||
}
|
||||
|
||||
internal WithManyChildrenBase(DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations, ArrayElement<GreenNode>[] children)
|
||||
: base(diagnostics, annotations)
|
||||
{
|
||||
this.children = children;
|
||||
InitializeChildren();
|
||||
}
|
||||
|
||||
private void InitializeChildren()
|
||||
{
|
||||
int num = children.Length;
|
||||
if (num < 255)
|
||||
{
|
||||
base.SlotCount = (byte)num;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.SlotCount = 255;
|
||||
}
|
||||
for (int i = 0; i < children.Length; i++)
|
||||
{
|
||||
AdjustFlagsAndWidth(children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
internal WithManyChildrenBase(ObjectReader reader)
|
||||
: base(reader)
|
||||
{
|
||||
int num = reader.ReadInt32();
|
||||
children = new ArrayElement<GreenNode>[num];
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
children[i].Value = (GreenNode)reader.ReadValue();
|
||||
}
|
||||
InitializeChildren();
|
||||
}
|
||||
|
||||
internal override void WriteTo(ObjectWriter writer)
|
||||
{
|
||||
base.WriteTo(writer);
|
||||
writer.WriteInt32(children.Length);
|
||||
for (int i = 0; i < children.Length; i++)
|
||||
{
|
||||
writer.WriteValue(children[i].Value);
|
||||
}
|
||||
}
|
||||
|
||||
protected override int GetSlotCount()
|
||||
{
|
||||
return children.Length;
|
||||
}
|
||||
|
||||
internal override GreenNode GetSlot(int index)
|
||||
{
|
||||
return children[index];
|
||||
}
|
||||
|
||||
internal override void CopyTo(ArrayElement<GreenNode>[] array, int offset)
|
||||
{
|
||||
Array.Copy(children, 0, array, offset, children.Length);
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode? parent, int position)
|
||||
{
|
||||
bool flag = base.SlotCount > 1 && HasNodeTokenPattern();
|
||||
if (parent != null && parent.ShouldCreateWeakList())
|
||||
{
|
||||
if (!flag)
|
||||
{
|
||||
return new Microsoft.CodeAnalysis.Syntax.SyntaxList.WithManyWeakChildren(this, parent, position);
|
||||
}
|
||||
return new Microsoft.CodeAnalysis.Syntax.SyntaxList.SeparatedWithManyWeakChildren(this, parent, position);
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
return new Microsoft.CodeAnalysis.Syntax.SyntaxList.WithManyChildren(this, parent, position);
|
||||
}
|
||||
return new Microsoft.CodeAnalysis.Syntax.SyntaxList.SeparatedWithManyChildren(this, parent, position);
|
||||
}
|
||||
|
||||
private bool HasNodeTokenPattern()
|
||||
{
|
||||
for (int i = 0; i < base.SlotCount; i++)
|
||||
{
|
||||
if (GetSlot(i).IsToken == ((i & 1) == 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class WithManyChildren : WithManyChildrenBase
|
||||
{
|
||||
static WithManyChildren()
|
||||
{
|
||||
ObjectBinder.RegisterTypeReader(typeof(WithManyChildren), (ObjectReader r) => new WithManyChildren(r));
|
||||
}
|
||||
|
||||
internal WithManyChildren(ArrayElement<GreenNode>[] children)
|
||||
: base(children)
|
||||
{
|
||||
}
|
||||
|
||||
internal WithManyChildren(DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations, ArrayElement<GreenNode>[] children)
|
||||
: base(diagnostics, annotations, children)
|
||||
{
|
||||
}
|
||||
|
||||
internal WithManyChildren(ObjectReader reader)
|
||||
: base(reader)
|
||||
{
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(DiagnosticInfo[]? errors)
|
||||
{
|
||||
return new WithManyChildren(errors, GetAnnotations(), children);
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations)
|
||||
{
|
||||
return new WithManyChildren(GetDiagnostics(), annotations, children);
|
||||
}
|
||||
}
|
||||
|
||||
internal class WithThreeChildren : SyntaxList
|
||||
{
|
||||
private readonly GreenNode _child0;
|
||||
|
||||
private readonly GreenNode _child1;
|
||||
|
||||
private readonly GreenNode _child2;
|
||||
|
||||
static WithThreeChildren()
|
||||
{
|
||||
ObjectBinder.RegisterTypeReader(typeof(WithThreeChildren), (ObjectReader r) => new WithThreeChildren(r));
|
||||
}
|
||||
|
||||
internal WithThreeChildren(GreenNode child0, GreenNode child1, GreenNode child2)
|
||||
{
|
||||
base.SlotCount = 3;
|
||||
AdjustFlagsAndWidth(child0);
|
||||
_child0 = child0;
|
||||
AdjustFlagsAndWidth(child1);
|
||||
_child1 = child1;
|
||||
AdjustFlagsAndWidth(child2);
|
||||
_child2 = child2;
|
||||
}
|
||||
|
||||
internal WithThreeChildren(DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations, GreenNode child0, GreenNode child1, GreenNode child2)
|
||||
: base(diagnostics, annotations)
|
||||
{
|
||||
base.SlotCount = 3;
|
||||
AdjustFlagsAndWidth(child0);
|
||||
_child0 = child0;
|
||||
AdjustFlagsAndWidth(child1);
|
||||
_child1 = child1;
|
||||
AdjustFlagsAndWidth(child2);
|
||||
_child2 = child2;
|
||||
}
|
||||
|
||||
internal WithThreeChildren(ObjectReader reader)
|
||||
: base(reader)
|
||||
{
|
||||
base.SlotCount = 3;
|
||||
_child0 = (GreenNode)reader.ReadValue();
|
||||
AdjustFlagsAndWidth(_child0);
|
||||
_child1 = (GreenNode)reader.ReadValue();
|
||||
AdjustFlagsAndWidth(_child1);
|
||||
_child2 = (GreenNode)reader.ReadValue();
|
||||
AdjustFlagsAndWidth(_child2);
|
||||
}
|
||||
|
||||
internal override void WriteTo(ObjectWriter writer)
|
||||
{
|
||||
base.WriteTo(writer);
|
||||
writer.WriteValue(_child0);
|
||||
writer.WriteValue(_child1);
|
||||
writer.WriteValue(_child2);
|
||||
}
|
||||
|
||||
internal override GreenNode? GetSlot(int index)
|
||||
{
|
||||
return index switch
|
||||
{
|
||||
0 => _child0,
|
||||
1 => _child1,
|
||||
2 => _child2,
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
internal override void CopyTo(ArrayElement<GreenNode>[] array, int offset)
|
||||
{
|
||||
array[offset].Value = _child0;
|
||||
array[offset + 1].Value = _child1;
|
||||
array[offset + 2].Value = _child2;
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode? parent, int position)
|
||||
{
|
||||
return new Microsoft.CodeAnalysis.Syntax.SyntaxList.WithThreeChildren(this, parent, position);
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(DiagnosticInfo[]? errors)
|
||||
{
|
||||
return new WithThreeChildren(errors, GetAnnotations(), _child0, _child1, _child2);
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations)
|
||||
{
|
||||
return new WithThreeChildren(GetDiagnostics(), annotations, _child0, _child1, _child2);
|
||||
}
|
||||
}
|
||||
|
||||
internal class WithTwoChildren : SyntaxList
|
||||
{
|
||||
private readonly GreenNode _child0;
|
||||
|
||||
private readonly GreenNode _child1;
|
||||
|
||||
static WithTwoChildren()
|
||||
{
|
||||
ObjectBinder.RegisterTypeReader(typeof(WithTwoChildren), (ObjectReader r) => new WithTwoChildren(r));
|
||||
}
|
||||
|
||||
internal WithTwoChildren(GreenNode child0, GreenNode child1)
|
||||
{
|
||||
base.SlotCount = 2;
|
||||
AdjustFlagsAndWidth(child0);
|
||||
_child0 = child0;
|
||||
AdjustFlagsAndWidth(child1);
|
||||
_child1 = child1;
|
||||
}
|
||||
|
||||
internal WithTwoChildren(DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations, GreenNode child0, GreenNode child1)
|
||||
: base(diagnostics, annotations)
|
||||
{
|
||||
base.SlotCount = 2;
|
||||
AdjustFlagsAndWidth(child0);
|
||||
_child0 = child0;
|
||||
AdjustFlagsAndWidth(child1);
|
||||
_child1 = child1;
|
||||
}
|
||||
|
||||
internal WithTwoChildren(ObjectReader reader)
|
||||
: base(reader)
|
||||
{
|
||||
base.SlotCount = 2;
|
||||
_child0 = (GreenNode)reader.ReadValue();
|
||||
AdjustFlagsAndWidth(_child0);
|
||||
_child1 = (GreenNode)reader.ReadValue();
|
||||
AdjustFlagsAndWidth(_child1);
|
||||
}
|
||||
|
||||
internal override void WriteTo(ObjectWriter writer)
|
||||
{
|
||||
base.WriteTo(writer);
|
||||
writer.WriteValue(_child0);
|
||||
writer.WriteValue(_child1);
|
||||
}
|
||||
|
||||
internal override GreenNode? GetSlot(int index)
|
||||
{
|
||||
return index switch
|
||||
{
|
||||
0 => _child0,
|
||||
1 => _child1,
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
internal override void CopyTo(ArrayElement<GreenNode>[] array, int offset)
|
||||
{
|
||||
array[offset].Value = _child0;
|
||||
array[offset + 1].Value = _child1;
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode? parent, int position)
|
||||
{
|
||||
return new Microsoft.CodeAnalysis.Syntax.SyntaxList.WithTwoChildren(this, parent, position);
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(DiagnosticInfo[]? errors)
|
||||
{
|
||||
return new WithTwoChildren(errors, GetAnnotations(), _child0, _child1);
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations)
|
||||
{
|
||||
return new WithTwoChildren(GetDiagnostics(), annotations, _child0, _child1);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override string Language
|
||||
{
|
||||
get
|
||||
{
|
||||
throw ExceptionUtilities.Unreachable("/_/src/Compilers/Core/Portable/Syntax/InternalSyntax/SyntaxList.cs", 153);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override string KindText
|
||||
{
|
||||
get
|
||||
{
|
||||
throw ExceptionUtilities.Unreachable("/_/src/Compilers/Core/Portable/Syntax/InternalSyntax/SyntaxList.cs", 161);
|
||||
}
|
||||
}
|
||||
|
||||
internal SyntaxList()
|
||||
: base(1)
|
||||
{
|
||||
}
|
||||
|
||||
internal SyntaxList(DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations)
|
||||
: base(1, diagnostics, annotations)
|
||||
{
|
||||
}
|
||||
|
||||
internal SyntaxList(ObjectReader reader)
|
||||
: base(reader)
|
||||
{
|
||||
}
|
||||
|
||||
internal static GreenNode List(GreenNode child)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
|
||||
internal static WithTwoChildren List(GreenNode child0, GreenNode child1)
|
||||
{
|
||||
int hash;
|
||||
GreenNode greenNode = SyntaxNodeCache.TryGetNode(1, child0, child1, out hash);
|
||||
if (greenNode != null)
|
||||
{
|
||||
return (WithTwoChildren)greenNode;
|
||||
}
|
||||
WithTwoChildren withTwoChildren = new WithTwoChildren(child0, child1);
|
||||
if (hash >= 0)
|
||||
{
|
||||
SyntaxNodeCache.AddNode(withTwoChildren, hash);
|
||||
}
|
||||
return withTwoChildren;
|
||||
}
|
||||
|
||||
internal static WithThreeChildren List(GreenNode child0, GreenNode child1, GreenNode child2)
|
||||
{
|
||||
int hash;
|
||||
GreenNode greenNode = SyntaxNodeCache.TryGetNode(1, child0, child1, child2, out hash);
|
||||
if (greenNode != null)
|
||||
{
|
||||
return (WithThreeChildren)greenNode;
|
||||
}
|
||||
WithThreeChildren withThreeChildren = new WithThreeChildren(child0, child1, child2);
|
||||
if (hash >= 0)
|
||||
{
|
||||
SyntaxNodeCache.AddNode(withThreeChildren, hash);
|
||||
}
|
||||
return withThreeChildren;
|
||||
}
|
||||
|
||||
internal static GreenNode List(GreenNode?[] nodes)
|
||||
{
|
||||
return List(nodes, nodes.Length);
|
||||
}
|
||||
|
||||
internal static GreenNode List(GreenNode?[] nodes, int count)
|
||||
{
|
||||
ArrayElement<GreenNode>[] array = new ArrayElement<GreenNode>[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
GreenNode value = nodes[i];
|
||||
array[i].Value = value;
|
||||
}
|
||||
return List(array);
|
||||
}
|
||||
|
||||
internal static SyntaxList List(ArrayElement<GreenNode>[] children)
|
||||
{
|
||||
if (children.Length < 10)
|
||||
{
|
||||
return new WithManyChildren(children);
|
||||
}
|
||||
return new WithLotsOfChildren(children);
|
||||
}
|
||||
|
||||
internal abstract void CopyTo(ArrayElement<GreenNode>[] array, int offset);
|
||||
|
||||
internal static GreenNode? Concat(GreenNode? left, GreenNode? right)
|
||||
{
|
||||
if (left == null)
|
||||
{
|
||||
return right;
|
||||
}
|
||||
if (right == null)
|
||||
{
|
||||
return left;
|
||||
}
|
||||
SyntaxList syntaxList = left as SyntaxList;
|
||||
SyntaxList syntaxList2 = right as SyntaxList;
|
||||
if (syntaxList != null)
|
||||
{
|
||||
if (syntaxList2 != null)
|
||||
{
|
||||
ArrayElement<GreenNode>[] array = new ArrayElement<GreenNode>[left.SlotCount + right.SlotCount];
|
||||
syntaxList.CopyTo(array, 0);
|
||||
syntaxList2.CopyTo(array, left.SlotCount);
|
||||
return List(array);
|
||||
}
|
||||
ArrayElement<GreenNode>[] array2 = new ArrayElement<GreenNode>[left.SlotCount + 1];
|
||||
syntaxList.CopyTo(array2, 0);
|
||||
array2[left.SlotCount].Value = right;
|
||||
return List(array2);
|
||||
}
|
||||
if (syntaxList2 != null)
|
||||
{
|
||||
ArrayElement<GreenNode>[] array3 = new ArrayElement<GreenNode>[syntaxList2.SlotCount + 1];
|
||||
array3[0].Value = left;
|
||||
syntaxList2.CopyTo(array3, 1);
|
||||
return List(array3);
|
||||
}
|
||||
return List(left, right);
|
||||
}
|
||||
|
||||
public sealed override SyntaxNode GetStructure(SyntaxTrivia parentTrivia)
|
||||
{
|
||||
throw ExceptionUtilities.Unreachable("/_/src/Compilers/Core/Portable/Syntax/InternalSyntax/SyntaxList.cs", 167);
|
||||
}
|
||||
|
||||
public sealed override SyntaxToken CreateSeparator<TNode>(SyntaxNode element)
|
||||
{
|
||||
throw ExceptionUtilities.Unreachable("/_/src/Compilers/Core/Portable/Syntax/InternalSyntax/SyntaxList.cs", 172);
|
||||
}
|
||||
|
||||
public sealed override bool IsTriviaWithEndOfLine()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
internal readonly struct SyntaxList<TNode> : IEquatable<SyntaxList<TNode>> where TNode : GreenNode
|
||||
{
|
||||
internal struct Enumerator
|
||||
{
|
||||
private readonly SyntaxList<TNode> _list;
|
||||
|
||||
private int _index;
|
||||
|
||||
public TNode Current => _list[_index];
|
||||
|
||||
internal Enumerator(SyntaxList<TNode> list)
|
||||
{
|
||||
_list = list;
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
int num = _index + 1;
|
||||
if (num < _list.Count)
|
||||
{
|
||||
_index = num;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly GreenNode? _node;
|
||||
|
||||
internal GreenNode? Node => _node;
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_node != null)
|
||||
{
|
||||
if (!_node.IsList)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return _node.SlotCount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public TNode? this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_node == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (_node.IsList)
|
||||
{
|
||||
return (TNode)_node.GetSlot(index);
|
||||
}
|
||||
if (index == 0)
|
||||
{
|
||||
return (TNode)_node;
|
||||
}
|
||||
throw ExceptionUtilities.Unreachable("/_/src/Compilers/Core/Portable/Syntax/InternalSyntax/SyntaxList`1.cs", 52);
|
||||
}
|
||||
}
|
||||
|
||||
internal TNode[] Nodes
|
||||
{
|
||||
get
|
||||
{
|
||||
TNode[] array = new TNode[Count];
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
array[i] = GetRequiredItem(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
public TNode? Last
|
||||
{
|
||||
get
|
||||
{
|
||||
GreenNode node = _node;
|
||||
if (node.IsList)
|
||||
{
|
||||
return (TNode)node.GetSlot(node.SlotCount - 1);
|
||||
}
|
||||
return (TNode)node;
|
||||
}
|
||||
}
|
||||
|
||||
internal SyntaxList(GreenNode? node)
|
||||
{
|
||||
_node = node;
|
||||
}
|
||||
|
||||
internal TNode GetRequiredItem(int index)
|
||||
{
|
||||
return this[index];
|
||||
}
|
||||
|
||||
internal GreenNode? ItemUntyped(int index)
|
||||
{
|
||||
GreenNode node = _node;
|
||||
if (node.IsList)
|
||||
{
|
||||
return node.GetSlot(index);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public bool Any()
|
||||
{
|
||||
return _node != null;
|
||||
}
|
||||
|
||||
public bool Any(int kind)
|
||||
{
|
||||
Enumerator enumerator = GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (enumerator.Current.RawKind == kind)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
internal void CopyTo(int offset, ArrayElement<GreenNode>[] array, int arrayOffset, int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
array[arrayOffset + i].Value = GetRequiredItem(i + offset);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator ==(SyntaxList<TNode> left, SyntaxList<TNode> right)
|
||||
{
|
||||
return left._node == right._node;
|
||||
}
|
||||
|
||||
public static bool operator !=(SyntaxList<TNode> left, SyntaxList<TNode> right)
|
||||
{
|
||||
return left._node != right._node;
|
||||
}
|
||||
|
||||
public bool Equals(SyntaxList<TNode> other)
|
||||
{
|
||||
return _node == other._node;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is SyntaxList<TNode>)
|
||||
{
|
||||
return Equals((SyntaxList<TNode>)obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (_node == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return _node.GetHashCode();
|
||||
}
|
||||
|
||||
public SeparatedSyntaxList<TOther> AsSeparatedList<TOther>() where TOther : GreenNode
|
||||
{
|
||||
return new SeparatedSyntaxList<TOther>(this);
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxList<TNode>(TNode node)
|
||||
{
|
||||
return new SyntaxList<TNode>(node);
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxList<TNode>(SyntaxList<GreenNode> nodes)
|
||||
{
|
||||
return new SyntaxList<TNode>(nodes._node);
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxList<GreenNode>(SyntaxList<TNode> nodes)
|
||||
{
|
||||
return new SyntaxList<GreenNode>(nodes.Node);
|
||||
}
|
||||
}
|
||||
+273
@@ -0,0 +1,273 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax;
|
||||
|
||||
internal class SyntaxListBuilder
|
||||
{
|
||||
private ArrayElement<GreenNode?>[] _nodes;
|
||||
|
||||
public int Count { get; private set; }
|
||||
|
||||
public GreenNode? this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _nodes[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
_nodes[index].Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SyntaxListBuilder(int size)
|
||||
{
|
||||
_nodes = new ArrayElement<GreenNode>[size];
|
||||
}
|
||||
|
||||
public static SyntaxListBuilder Create()
|
||||
{
|
||||
return new SyntaxListBuilder(8);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
public void Add(GreenNode? item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (item.IsList)
|
||||
{
|
||||
int slotCount = item.SlotCount;
|
||||
EnsureAdditionalCapacity(slotCount);
|
||||
for (int i = 0; i < slotCount; i++)
|
||||
{
|
||||
Add(item.GetSlot(i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EnsureAdditionalCapacity(1);
|
||||
_nodes[Count++].Value = item;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange(GreenNode[] items)
|
||||
{
|
||||
AddRange(items, 0, items.Length);
|
||||
}
|
||||
|
||||
public void AddRange(GreenNode[] items, int offset, int length)
|
||||
{
|
||||
EnsureAdditionalCapacity(length - offset);
|
||||
_ = Count;
|
||||
for (int i = offset; i < length; i++)
|
||||
{
|
||||
Add(items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void Validate(int start, int end)
|
||||
{
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<GreenNode> list)
|
||||
{
|
||||
AddRange(list, 0, list.Count);
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<GreenNode> list, int offset, int length)
|
||||
{
|
||||
EnsureAdditionalCapacity(length - offset);
|
||||
_ = Count;
|
||||
for (int i = offset; i < length; i++)
|
||||
{
|
||||
Add(list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange<TNode>(SyntaxList<TNode> list) where TNode : GreenNode
|
||||
{
|
||||
AddRange(list, 0, list.Count);
|
||||
}
|
||||
|
||||
public void AddRange<TNode>(SyntaxList<TNode> list, int offset, int length) where TNode : GreenNode
|
||||
{
|
||||
AddRange(new SyntaxList<GreenNode>(list.Node), offset, length);
|
||||
}
|
||||
|
||||
public void RemoveLast()
|
||||
{
|
||||
Count--;
|
||||
_nodes[Count].Value = null;
|
||||
}
|
||||
|
||||
private void EnsureAdditionalCapacity(int additionalCount)
|
||||
{
|
||||
int num = _nodes.Length;
|
||||
int num2 = Count + additionalCount;
|
||||
if (num2 > num)
|
||||
{
|
||||
int newSize = ((num2 < 8) ? 8 : ((num2 >= 1073741823) ? int.MaxValue : Math.Max(num2, num * 2)));
|
||||
Array.Resize(ref _nodes, newSize);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Any(int kind)
|
||||
{
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
if (_nodes[i].Value.RawKind == kind)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public GreenNode[] ToArray()
|
||||
{
|
||||
GreenNode[] array = new GreenNode[Count];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
array[i] = _nodes[i];
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
internal GreenNode? ToListNode()
|
||||
{
|
||||
switch (Count)
|
||||
{
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
return _nodes[0];
|
||||
case 2:
|
||||
return SyntaxList.List(_nodes[0], _nodes[1]);
|
||||
case 3:
|
||||
return SyntaxList.List(_nodes[0], _nodes[1], _nodes[2]);
|
||||
default:
|
||||
{
|
||||
ArrayElement<GreenNode>[] array = new ArrayElement<GreenNode>[Count];
|
||||
Array.Copy(_nodes, array, Count);
|
||||
return SyntaxList.List(array);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SyntaxList<GreenNode> ToList()
|
||||
{
|
||||
return new SyntaxList<GreenNode>(ToListNode());
|
||||
}
|
||||
|
||||
public SyntaxList<TNode> ToList<TNode>() where TNode : GreenNode
|
||||
{
|
||||
return new SyntaxList<TNode>(ToListNode());
|
||||
}
|
||||
}
|
||||
internal readonly struct SyntaxListBuilder<TNode> where TNode : GreenNode
|
||||
{
|
||||
private readonly SyntaxListBuilder _builder;
|
||||
|
||||
public bool IsNull => _builder == null;
|
||||
|
||||
public int Count => _builder.Count;
|
||||
|
||||
public TNode this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return (TNode)_builder[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
_builder[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SyntaxListBuilder(int size)
|
||||
: this(new SyntaxListBuilder(size))
|
||||
{
|
||||
}
|
||||
|
||||
public static SyntaxListBuilder<TNode> Create()
|
||||
{
|
||||
return new SyntaxListBuilder<TNode>(8);
|
||||
}
|
||||
|
||||
internal SyntaxListBuilder(SyntaxListBuilder builder)
|
||||
{
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_builder.Clear();
|
||||
}
|
||||
|
||||
public SyntaxListBuilder<TNode> Add(TNode? node)
|
||||
{
|
||||
_builder.Add(node);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void AddRange(TNode[] items, int offset, int length)
|
||||
{
|
||||
_builder.AddRange(items, offset, length);
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<TNode> nodes)
|
||||
{
|
||||
_builder.AddRange(nodes);
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<TNode> nodes, int offset, int length)
|
||||
{
|
||||
_builder.AddRange(nodes, offset, length);
|
||||
}
|
||||
|
||||
public bool Any(int kind)
|
||||
{
|
||||
return _builder.Any(kind);
|
||||
}
|
||||
|
||||
public SyntaxList<TNode> ToList()
|
||||
{
|
||||
return _builder.ToList();
|
||||
}
|
||||
|
||||
public GreenNode? ToListNode()
|
||||
{
|
||||
return _builder.ToListNode();
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxListBuilder(SyntaxListBuilder<TNode> builder)
|
||||
{
|
||||
return builder._builder;
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxList<TNode>(SyntaxListBuilder<TNode> builder)
|
||||
{
|
||||
if (builder._builder != null)
|
||||
{
|
||||
return builder.ToList();
|
||||
}
|
||||
return default(SyntaxList<TNode>);
|
||||
}
|
||||
|
||||
public SyntaxList<TDerived> ToList<TDerived>() where TDerived : GreenNode
|
||||
{
|
||||
return new SyntaxList<TDerived>(ToListNode());
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax;
|
||||
|
||||
internal static class SyntaxListBuilderExtensions
|
||||
{
|
||||
public static SyntaxList<GreenNode> ToList(this SyntaxListBuilder? builder)
|
||||
{
|
||||
return ToList<GreenNode>(builder);
|
||||
}
|
||||
|
||||
public static SyntaxList<TNode> ToList<TNode>(this SyntaxListBuilder? builder) where TNode : GreenNode
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
return default(SyntaxList<GreenNode>);
|
||||
}
|
||||
return new SyntaxList<TNode>(builder.ToListNode());
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax;
|
||||
|
||||
internal class SyntaxListPool
|
||||
{
|
||||
private ArrayElement<SyntaxListBuilder?>[] _freeList = new ArrayElement<SyntaxListBuilder>[10];
|
||||
|
||||
private int _freeIndex;
|
||||
|
||||
internal SyntaxListPool()
|
||||
{
|
||||
}
|
||||
|
||||
internal SyntaxListBuilder Allocate()
|
||||
{
|
||||
SyntaxListBuilder result;
|
||||
if (_freeIndex > 0)
|
||||
{
|
||||
_freeIndex--;
|
||||
result = _freeList[_freeIndex].Value;
|
||||
_freeList[_freeIndex].Value = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new SyntaxListBuilder(10);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal SyntaxListBuilder<TNode> Allocate<TNode>() where TNode : GreenNode
|
||||
{
|
||||
return new SyntaxListBuilder<TNode>(Allocate());
|
||||
}
|
||||
|
||||
internal SeparatedSyntaxListBuilder<TNode> AllocateSeparated<TNode>() where TNode : GreenNode
|
||||
{
|
||||
return new SeparatedSyntaxListBuilder<TNode>(Allocate());
|
||||
}
|
||||
|
||||
internal void Free<TNode>(in SeparatedSyntaxListBuilder<TNode> item) where TNode : GreenNode
|
||||
{
|
||||
Free(item.UnderlyingBuilder);
|
||||
}
|
||||
|
||||
internal void Free(SyntaxListBuilder? item)
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
item.Clear();
|
||||
if (_freeIndex >= _freeList.Length)
|
||||
{
|
||||
Grow();
|
||||
}
|
||||
_freeList[_freeIndex].Value = item;
|
||||
_freeIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
private void Grow()
|
||||
{
|
||||
ArrayElement<SyntaxListBuilder>[] array = new ArrayElement<SyntaxListBuilder>[_freeList.Length * 2];
|
||||
Array.Copy(_freeList, array, _freeList.Length);
|
||||
_freeList = array;
|
||||
}
|
||||
|
||||
public SyntaxList<TNode> ToListAndFree<TNode>(SyntaxListBuilder<TNode> item) where TNode : GreenNode
|
||||
{
|
||||
if (item.IsNull)
|
||||
{
|
||||
return default(SyntaxList<TNode>);
|
||||
}
|
||||
SyntaxList<TNode> result = item.ToList();
|
||||
Free(item);
|
||||
return result;
|
||||
}
|
||||
|
||||
public SeparatedSyntaxList<TNode> ToListAndFree<TNode>(in SeparatedSyntaxListBuilder<TNode> item) where TNode : GreenNode
|
||||
{
|
||||
SeparatedSyntaxList<TNode> result = item.ToList();
|
||||
Free(in item);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using Roslyn.Utilities;
|
||||
|
||||
namespace Microsoft.CodeAnalysis.Syntax.InternalSyntax;
|
||||
|
||||
internal static class SyntaxNodeCache
|
||||
{
|
||||
private readonly struct Entry
|
||||
{
|
||||
public readonly int hash;
|
||||
|
||||
public readonly GreenNode? node;
|
||||
|
||||
internal Entry(int hash, GreenNode node)
|
||||
{
|
||||
this.hash = hash;
|
||||
this.node = node;
|
||||
}
|
||||
}
|
||||
|
||||
private const int CacheSizeBits = 16;
|
||||
|
||||
private const int CacheSize = 65536;
|
||||
|
||||
private const int CacheMask = 65535;
|
||||
|
||||
private static readonly Entry[] s_cache = new Entry[65536];
|
||||
|
||||
internal static void AddNode(GreenNode node, int hash)
|
||||
{
|
||||
if (AllChildrenInCache(node) && !node.IsMissing)
|
||||
{
|
||||
int num = hash & 0xFFFF;
|
||||
s_cache[num] = new Entry(hash, node);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CanBeCached(GreenNode? child1)
|
||||
{
|
||||
return child1?.IsCacheable ?? true;
|
||||
}
|
||||
|
||||
private static bool CanBeCached(GreenNode? child1, GreenNode? child2)
|
||||
{
|
||||
if (CanBeCached(child1))
|
||||
{
|
||||
return CanBeCached(child2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool CanBeCached(GreenNode? child1, GreenNode? child2, GreenNode? child3)
|
||||
{
|
||||
if (CanBeCached(child1) && CanBeCached(child2))
|
||||
{
|
||||
return CanBeCached(child3);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool ChildInCache(GreenNode? child)
|
||||
{
|
||||
if (child == null || child.SlotCount == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int num = child.GetCacheHash() & 0xFFFF;
|
||||
return s_cache[num].node == child;
|
||||
}
|
||||
|
||||
private static bool AllChildrenInCache(GreenNode node)
|
||||
{
|
||||
int slotCount = node.SlotCount;
|
||||
for (int i = 0; i < slotCount; i++)
|
||||
{
|
||||
if (!ChildInCache(node.GetSlot(i)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static GreenNode? TryGetNode(int kind, GreenNode? child1, out int hash)
|
||||
{
|
||||
return TryGetNode(kind, child1, GetDefaultNodeFlags(), out hash);
|
||||
}
|
||||
|
||||
internal static GreenNode? TryGetNode(int kind, GreenNode? child1, GreenNode.NodeFlags flags, out int hash)
|
||||
{
|
||||
if (CanBeCached(child1))
|
||||
{
|
||||
int num = (hash = GetCacheHash(kind, flags, child1));
|
||||
int num2 = num & 0xFFFF;
|
||||
Entry entry = s_cache[num2];
|
||||
if (entry.hash == num && entry.node != null && entry.node.IsCacheEquivalent(kind, flags, child1))
|
||||
{
|
||||
return entry.node;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hash = -1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static GreenNode? TryGetNode(int kind, GreenNode? child1, GreenNode? child2, out int hash)
|
||||
{
|
||||
return TryGetNode(kind, child1, child2, GetDefaultNodeFlags(), out hash);
|
||||
}
|
||||
|
||||
internal static GreenNode? TryGetNode(int kind, GreenNode? child1, GreenNode? child2, GreenNode.NodeFlags flags, out int hash)
|
||||
{
|
||||
if (CanBeCached(child1, child2))
|
||||
{
|
||||
int num = (hash = GetCacheHash(kind, flags, child1, child2));
|
||||
int num2 = num & 0xFFFF;
|
||||
Entry entry = s_cache[num2];
|
||||
if (entry.hash == num && entry.node != null && entry.node.IsCacheEquivalent(kind, flags, child1, child2))
|
||||
{
|
||||
return entry.node;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hash = -1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static GreenNode? TryGetNode(int kind, GreenNode? child1, GreenNode? child2, GreenNode? child3, out int hash)
|
||||
{
|
||||
return TryGetNode(kind, child1, child2, child3, GetDefaultNodeFlags(), out hash);
|
||||
}
|
||||
|
||||
internal static GreenNode? TryGetNode(int kind, GreenNode? child1, GreenNode? child2, GreenNode? child3, GreenNode.NodeFlags flags, out int hash)
|
||||
{
|
||||
if (CanBeCached(child1, child2, child3))
|
||||
{
|
||||
int num = (hash = GetCacheHash(kind, flags, child1, child2, child3));
|
||||
int num2 = num & 0xFFFF;
|
||||
Entry entry = s_cache[num2];
|
||||
if (entry.hash == num && entry.node != null && entry.node.IsCacheEquivalent(kind, flags, child1, child2, child3))
|
||||
{
|
||||
return entry.node;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hash = -1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static GreenNode.NodeFlags GetDefaultNodeFlags()
|
||||
{
|
||||
return GreenNode.NodeFlags.IsNotMissing;
|
||||
}
|
||||
|
||||
private static int GetCacheHash(int kind, GreenNode.NodeFlags flags, GreenNode? child1)
|
||||
{
|
||||
int currentKey = (int)flags ^ kind;
|
||||
currentKey = Hash.Combine(RuntimeHelpers.GetHashCode(child1), currentKey);
|
||||
return currentKey & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
private static int GetCacheHash(int kind, GreenNode.NodeFlags flags, GreenNode? child1, GreenNode? child2)
|
||||
{
|
||||
int num = (int)flags ^ kind;
|
||||
if (child1 != null)
|
||||
{
|
||||
num = Hash.Combine(RuntimeHelpers.GetHashCode(child1), num);
|
||||
}
|
||||
if (child2 != null)
|
||||
{
|
||||
num = Hash.Combine(RuntimeHelpers.GetHashCode(child2), num);
|
||||
}
|
||||
return num & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
private static int GetCacheHash(int kind, GreenNode.NodeFlags flags, GreenNode? child1, GreenNode? child2, GreenNode? child3)
|
||||
{
|
||||
int num = (int)flags ^ kind;
|
||||
if (child1 != null)
|
||||
{
|
||||
num = Hash.Combine(RuntimeHelpers.GetHashCode(child1), num);
|
||||
}
|
||||
if (child2 != null)
|
||||
{
|
||||
num = Hash.Combine(RuntimeHelpers.GetHashCode(child2), num);
|
||||
}
|
||||
if (child3 != null)
|
||||
{
|
||||
num = Hash.Combine(RuntimeHelpers.GetHashCode(child3), num);
|
||||
}
|
||||
return num & 0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user