1- using System . Collections . Generic ;
1+ using System ;
2+ using System . Collections . Generic ;
23using System . Windows . Forms ;
34using Antlr4 . Runtime . Tree ;
45using 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