-
Notifications
You must be signed in to change notification settings - Fork 10
/
LuaSyntaxWalker.cs
132 lines (119 loc) · 3.99 KB
/
LuaSyntaxWalker.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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Loretta.CodeAnalysis.Lua
{
/// <summary>
/// Represents a <see cref="LuaSyntaxVisitor"/> that descends an entire <see cref="LuaSyntaxNode"/> graph
/// visiting each LuaSyntaxNode and its child SyntaxNodes and <see cref="SyntaxToken"/>s in depth-first order.
/// </summary>
public abstract class LuaSyntaxWalker : LuaSyntaxVisitor
{
/// <summary>
/// The depth up to which the walker should go into.
/// </summary>
protected SyntaxWalkerDepth Depth { get; }
/// <summary>
/// Initializes the syntax walker with hte provided depth.
/// </summary>
/// <param name="depth"></param>
protected LuaSyntaxWalker(SyntaxWalkerDepth depth = SyntaxWalkerDepth.Node)
{
Depth = depth;
}
private int _recursionDepth;
/// <summary>
/// Called when the syntax walker visits a node.
/// </summary>
/// <param name="node"></param>
public override void Visit(SyntaxNode? node)
{
if (node != null)
{
_recursionDepth++;
StackGuard.EnsureSufficientExecutionStack(_recursionDepth);
((LuaSyntaxNode) node).Accept(this);
_recursionDepth--;
}
}
/// <summary>
/// Called when the walker walks into a node.
/// </summary>
/// <param name="node"></param>
public override void DefaultVisit(SyntaxNode node)
{
var childCnt = node.ChildNodesAndTokens().Count;
var i = 0;
while (i < childCnt)
{
var child = ChildSyntaxList.ItemInternal((LuaSyntaxNode) node, i);
i++;
var asNode = child.AsNode();
if (asNode != null)
{
if (Depth >= SyntaxWalkerDepth.Node)
{
Visit(asNode);
}
}
else
{
if (Depth >= SyntaxWalkerDepth.Token)
{
VisitToken(child.AsToken());
}
}
}
}
/// <summary>
/// Called when the walker visits a token.
/// </summary>
/// <param name="token"></param>
public virtual void VisitToken(SyntaxToken token)
{
if (Depth >= SyntaxWalkerDepth.Trivia)
{
VisitLeadingTrivia(token);
VisitTrailingTrivia(token);
}
}
/// <summary>
/// Called when the walker should visit the leading trivia of a token.
/// </summary>
/// <param name="token"></param>
public virtual void VisitLeadingTrivia(SyntaxToken token)
{
if (token.HasLeadingTrivia)
{
foreach (var tr in token.LeadingTrivia)
{
VisitTrivia(tr);
}
}
}
/// <summary>
/// Called when the walker should visit the trailing trivia of a token.
/// </summary>
/// <param name="token"></param>
public virtual void VisitTrailingTrivia(SyntaxToken token)
{
if (token.HasTrailingTrivia)
{
foreach (var tr in token.TrailingTrivia)
{
VisitTrivia(tr);
}
}
}
/// <summary>
/// Called when the walker visits a trivia.
/// </summary>
/// <param name="trivia"></param>
public virtual void VisitTrivia(SyntaxTrivia trivia)
{
if (Depth >= SyntaxWalkerDepth.StructuredTrivia && trivia.HasStructure)
{
Visit((LuaSyntaxNode) trivia.GetStructure()!);
}
}
}
}