Skip to content

Commit befe848

Browse files
committed
Cleaned up and refactored ParseTreeView code
Also added FindTreeNode method.
1 parent c3ba0ee commit befe848

1 file changed

Lines changed: 74 additions & 22 deletions

File tree

ParserTreeView/ParserTreeView.cs

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Windows.Forms;
34
using Antlr4.Runtime.Tree;
45
using Org.Edgerunner.ANTLR4.Tools.Testing.Grammar;
@@ -28,7 +29,7 @@ private void ParserTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs
2829
for (var i = 0; i < tree.ChildCount; i++)
2930
{
3031
var child = tree.GetChild(i);
31-
AddChildNode(e.Node, child);
32+
AddChildNodeAndLeaves(e.Node, child);
3233
}
3334
}
3435
}
@@ -46,7 +47,7 @@ private void ParserTreeView_BeforeSelect(object sender, TreeViewCancelEventArgs
4647
for (var i = 0; i < tree.ChildCount; i++)
4748
{
4849
var child = tree.GetChild(i);
49-
AddChildNode(e.Node, child);
50+
AddChildNodeAndLeaves(e.Node, child);
5051
}
5152
}
5253
}
@@ -58,23 +59,45 @@ private void ParserTreeView_BeforeSelect(object sender, TreeViewCancelEventArgs
5859
/// <param name="grammar">The <see cref="GrammarReference"/> instance to use.</param>
5960
public void LoadParseTree(ITree parseTree, GrammarReference grammar)
6061
{
62+
if (parseTree == null) throw new ArgumentNullException(nameof(parseTree));
63+
if (grammar == null) throw new ArgumentNullException(nameof(grammar));
64+
6165
ActiveNodes.Clear();
6266
Nodes.Clear();
6367
ParseTree = parseTree;
6468
Grammar = grammar;
65-
AddChildNode(null, parseTree);
69+
AddChildNodeAndLeaves(null, parseTree);
6670
}
6771

6872
/// <summary>
6973
/// Selects the tree node corresponding to the specified <see cref="ITree"/> instance.
7074
/// </summary>
71-
/// <param name="tree">The <see cref="ITree"/> instance.</param>
72-
public void SelectTreeNode(ITree tree)
75+
/// <param name="tree">The <see cref="ITree"/> instance to use.</param>
76+
/// <returns>The selected <see cref="TreeNode"/> or null if not found.</returns>
77+
public TreeNode SelectTreeNode(ITree tree)
7378
{
79+
if (tree == null) throw new ArgumentNullException(nameof(tree));
80+
7481
var treeNode = AddBranchesTillLeaf(tree);
75-
SelectedNode = treeNode;
76-
TopNode = treeNode;
77-
treeNode.EnsureVisible();
82+
if (treeNode != null)
83+
{
84+
SelectedNode = treeNode;
85+
TopNode = treeNode;
86+
treeNode.EnsureVisible();
87+
}
88+
return treeNode;
89+
}
90+
91+
/// <summary>
92+
/// Finds the tree node corresponding to the specified <see cref="ITree"/> instance.
93+
/// </summary>
94+
/// <param name="tree">The <see cref="ITree"/> node to use.</param>
95+
/// <returns>The corresponding <see cref="TreeNode"/> instance or null if not found.</returns>
96+
public TreeNode FindTreeNode(ITree tree)
97+
{
98+
if (tree == null) throw new ArgumentNullException(nameof(tree));
99+
100+
return AddBranchesTillLeaf(tree);
78101
}
79102

80103
/// <summary>
@@ -84,8 +107,6 @@ public void SelectTreeNode(ITree tree)
84107
/// <returns>The final leaf <see cref="TreeNode"/> instance that was created.</returns>
85108
private TreeNode AddBranchesTillLeaf(ITree tree)
86109
{
87-
// TODO: Find and fix the bug in this method's logic
88-
89110
// fetch our unique ID for the tree instance and then check if it already exists in active nodes
90111
// if so, we return the existing tree node since nothing more needs to be done
91112
var nodeName = tree.GetHashCode().ToString();
@@ -94,10 +115,30 @@ private TreeNode AddBranchesTillLeaf(ITree tree)
94115

95116
// Now we create a stack of ITree instances and begin walking our way up the parentage and pushing them onto the stack
96117
var stack = new Stack<ITree>();
97-
var workingChildren = new List<ITree>();
118+
119+
if (!BuildBranchStackFromTreeNode(tree, stack, out var parentTree))
120+
return null;
121+
122+
// Now that we built our stack of nodes that need to be created, and we have our starting parent TreeNode
123+
// We begin popping off ITree instances and creating the nodes.
124+
parentTree = CreateBranchNodesAndLeavesFromStack(stack, parentTree);
125+
126+
// Now we return the final leaf that was created on the branch
127+
return parentTree;
128+
}
129+
130+
/// <summary>
131+
/// Builds the branch stack from specified tree node.
132+
/// </summary>
133+
/// <param name="tree">The destination node we wish to build the intervening branch and leaves for.</param>
134+
/// <param name="stack">The stack to add prospective nodes to.</param>
135+
/// <param name="parentTree">The parent tree node to build the branch and leaves off of.</param>
136+
/// <returns><c>true</c> if successful, <c>false</c> otherwise.</returns>
137+
private bool BuildBranchStackFromTreeNode(ITree tree, Stack<ITree> stack, out TreeNode parentTree)
138+
{
98139
stack.Push(tree);
99140
var work = tree.Parent;
100-
nodeName = work.GetHashCode().ToString();
141+
var nodeName = work.GetHashCode().ToString();
101142
while (!ActiveNodes.ContainsKey(nodeName))
102143
{
103144
stack.Push(work);
@@ -107,23 +148,35 @@ private TreeNode AddBranchesTillLeaf(ITree tree)
107148
nodeName = work.GetHashCode().ToString();
108149
}
109150

110-
TreeNode parentTree;
111151
if (work.Parent == null)
112152
{
113153
if (this.Nodes.Count == 0)
114-
return null;
154+
{
155+
parentTree = null;
156+
return false;
157+
}
115158

116159
parentTree = this.Nodes[0];
117160
}
118161
else
119162
parentTree = ActiveNodes[nodeName];
120163

121-
// Now that we built our stack of nodes that need to be created, and we have our starting parent TreeNode
122-
// We begin popping off ITree instances and creating the nodes.
164+
return true;
165+
}
166+
167+
/// <summary>
168+
/// Creates the branch nodes and leaves from stack.
169+
/// </summary>
170+
/// <param name="stack">The stack to use.</param>
171+
/// <param name="parentTree">The parent tree node to build on.</param>
172+
/// <returns>Returns a <see cref="TreeNode"/> representing our final leaf.</returns>
173+
private TreeNode CreateBranchNodesAndLeavesFromStack(Stack<ITree> stack, TreeNode parentTree)
174+
{
175+
var workingChildren = new List<ITree>();
123176
while (stack.Count > 0)
124177
{
125178
// pop our first work item
126-
work = stack.Pop();
179+
var work = stack.Pop();
127180
// clear our working children list
128181
workingChildren.Clear();
129182
// our working parent should never be null and if it is, something has gone HORRIBLY wrong, we will leave it to error in that case
@@ -137,17 +190,16 @@ private TreeNode AddBranchesTillLeaf(ITree tree)
137190

138191
// now we add our extra working children from our list
139192
foreach (var child in workingChildren)
140-
AddChildNode(parentTree, child);
193+
AddChildNodeAndLeaves(parentTree, child);
141194

142195
// now we add the child that is part of our branch being traversed and set it as the new parent for the branch we are building
143-
parentTree = AddChildNode(parentTree, work);
196+
parentTree = AddChildNodeAndLeaves(parentTree, work);
144197
}
145198

146-
// Now we return the final leaf that was created on the branch
147199
return parentTree;
148200
}
149201

150-
private TreeNode AddChildNode(TreeNode root, ITree tree)
202+
private TreeNode AddChildNodeAndLeaves(TreeNode root, ITree tree)
151203
{
152204
// Add the child node
153205
var nodeName = tree.GetHashCode().ToString();

0 commit comments

Comments
 (0)