/
ChildSyntaxList.Enumerator.cs
149 lines (130 loc) · 5.08 KB
/
ChildSyntaxList.Enumerator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis
{
public partial struct ChildSyntaxList
{
/// <summary>Enumerates the elements of a <see cref="ChildSyntaxList" />.</summary>
public struct Enumerator
{
private SyntaxNode _node;
private int _count;
private int _childIndex;
internal Enumerator(SyntaxNode node, int count)
{
_node = node;
_count = count;
_childIndex = -1;
}
// PERF: Initialize an Enumerator directly from a SyntaxNode without going
// via ChildNodesAndTokens. This saves constructing an intermediate ChildSyntaxList
internal void InitializeFrom(SyntaxNode node)
{
_node = node;
_count = CountNodes(node.Green);
_childIndex = -1;
}
/// <summary>Advances the enumerator to the next element of the <see cref="ChildSyntaxList" />.</summary>
/// <returns>true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.</returns>
public bool MoveNext()
{
var newIndex = _childIndex + 1;
if (newIndex < _count)
{
_childIndex = newIndex;
return true;
}
return false;
}
/// <summary>Gets the element at the current position of the enumerator.</summary>
/// <returns>The element in the <see cref="ChildSyntaxList" /> at the current position of the enumerator.</returns>
public SyntaxNodeOrToken Current
{
get
{
return ItemInternal(_node, _childIndex);
}
}
/// <summary>Sets the enumerator to its initial position, which is before the first element in the collection.</summary>
public void Reset()
{
_childIndex = -1;
}
internal bool TryMoveNextAndGetCurrent(out SyntaxNodeOrToken current)
{
if (!MoveNext())
{
current = default;
return false;
}
current = ItemInternal(_node, _childIndex);
return true;
}
internal SyntaxNode TryMoveNextAndGetCurrentAsNode()
{
while (MoveNext())
{
var nodeValue = ItemInternalAsNode(_node, _childIndex);
if (nodeValue != null)
{
return nodeValue;
}
}
return null;
}
}
private class EnumeratorImpl : IEnumerator<SyntaxNodeOrToken>
{
private Enumerator _enumerator;
internal EnumeratorImpl(SyntaxNode node, int count)
{
_enumerator = new Enumerator(node, count);
}
/// <summary>
/// Gets the element in the collection at the current position of the enumerator.
/// </summary>
/// <returns>
/// The element in the collection at the current position of the enumerator.
/// </returns>
public SyntaxNodeOrToken Current
{
get { return _enumerator.Current; }
}
/// <summary>
/// Gets the element in the collection at the current position of the enumerator.
/// </summary>
/// <returns>
/// The element in the collection at the current position of the enumerator.
/// </returns>
object IEnumerator.Current
{
get { return _enumerator.Current; }
}
/// <summary>
/// Advances the enumerator to the next element of the collection.
/// </summary>
/// <returns>
/// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
/// </returns>
public bool MoveNext()
{
return _enumerator.MoveNext();
}
/// <summary>
/// Sets the enumerator to its initial position, which is before the first element in the collection.
/// </summary>
public void Reset()
{
_enumerator.Reset();
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{ }
}
}
}