/
Walker.cs
92 lines (84 loc) · 2.93 KB
/
Walker.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
using Antlr4.Runtime.Tree;
using Rubberduck.Inspections.CodePathAnalysis.Nodes;
using Rubberduck.Parsing.Grammar;
using Rubberduck.Parsing.Symbols;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
namespace Rubberduck.Inspections.CodePathAnalysis
{
public class Walker
{
public INode GenerateTree(IParseTree tree, Declaration declaration)
{
INode node = default;
switch (tree)
{
case VBAParser.ForNextStmtContext _:
case VBAParser.ForEachStmtContext _:
case VBAParser.WhileWendStmtContext _:
case VBAParser.DoLoopStmtContext _:
node = new LoopNode(tree);
break;
case VBAParser.IfStmtContext _:
case VBAParser.ElseBlockContext _:
case VBAParser.ElseIfBlockContext _:
case VBAParser.SingleLineIfStmtContext _:
case VBAParser.SingleLineElseClauseContext _:
case VBAParser.CaseClauseContext _:
case VBAParser.CaseElseClauseContext _:
node = new BranchNode(tree);
break;
case VBAParser.BlockContext _:
node = new BlockNode(tree);
break;
case VBAParser.LetStmtContext _:
case VBAParser.SetStmtContext _:
node = new AssignmentExpressionNode(tree);
break;
}
if (declaration.Context == tree)
{
node = new DeclarationNode(tree)
{
Declaration = declaration
};
}
var reference = declaration.References.SingleOrDefault(w => w.Context == tree);
if (reference != null)
{
if (reference.IsAssignment)
{
node = new AssignmentNode(tree)
{
Reference = reference
};
}
else
{
node = new ReferenceNode(tree)
{
Reference = reference
};
}
}
if (node == null)
{
node = new GenericNode(tree);
}
var children = new List<INode>();
for (var i = 0; i < tree.ChildCount; i++)
{
var nextChild = GenerateTree(tree.GetChild(i), declaration);
nextChild.SortOrder = i;
nextChild.Parent = node;
if (nextChild.Children.Any() || nextChild.GetType() != typeof(GenericNode))
{
children.Add(nextChild);
}
}
node.Children = children.ToImmutableList();
return node;
}
}
}