Skip to content

Commit ff8b7cf

Browse files
committed
Initial refactor to use ParserRuleContextExtension exclusively
1 parent f4cf930 commit ff8b7cf

File tree

4 files changed

+439
-102
lines changed

4 files changed

+439
-102
lines changed

Rubberduck.Parsing/ParserRuleContextExtensions.cs

Lines changed: 208 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using Antlr4.Runtime.Tree;
44
using Rubberduck.Parsing.Grammar;
55
using Rubberduck.VBEditor;
6+
using System.Linq;
7+
using Antlr4.Runtime.Misc;
68

79
namespace Rubberduck.Parsing
810
{
@@ -40,7 +42,212 @@ private static Selection GetProcedureContextSelection(ParserRuleContext context)
4042
endContext.Start.Column + 1);
4143
}
4244

43-
public static IEnumerable<TContext> FindChildren<TContext>(this ParserRuleContext context) where TContext : ParserRuleContext
45+
//public static IEnumerable<TContext> FindChildrenX<TContext>(this ParserRuleContext context) where TContext : ParserRuleContext
46+
//{
47+
// var walker = new ParseTreeWalker();
48+
// var listener = new ChildNodeListener<TContext>();
49+
// walker.Walk(listener, context);
50+
// return listener.Matches;
51+
//}
52+
53+
public static IEnumerable<IToken> GetTokens(this ParserRuleContext context, CommonTokenStream tokenStream)
54+
{
55+
var sourceInterval = context.SourceInterval;
56+
if (sourceInterval.Equals(Interval.Invalid) || sourceInterval.b < sourceInterval.a)
57+
{
58+
return new List<IToken>();
59+
}
60+
// Gets the tokens belonging to the context from the token stream.
61+
return tokenStream.GetTokens(sourceInterval.a, sourceInterval.b);
62+
}
63+
64+
public static string GetText(this ParserRuleContext context, ICharStream stream)
65+
{
66+
// Can be null if the input is empty it seems.
67+
if (context.Stop == null)
68+
{
69+
return string.Empty;
70+
}
71+
// Gets the original source, without "synthetic" text such as "<EOF>".
72+
return stream.GetText(new Interval(context.Start.StartIndex, context.Stop.StopIndex));
73+
}
74+
75+
public static T GetChild<T>(this ParserRuleContext context)
76+
{
77+
if (context == null)
78+
{
79+
return default;
80+
}
81+
82+
for (var index = 0; index < context.ChildCount; index++)
83+
{
84+
var child = context.GetChild(index);
85+
if (context.GetChild(index) is T)
86+
{
87+
return (T)child;
88+
}
89+
}
90+
91+
return default;
92+
}
93+
94+
//public static IEnumerable<T> GetChildren<T>(this RuleContext context)
95+
//{
96+
// if (context == null)
97+
// {
98+
// yield break;
99+
// }
100+
101+
// for (var index = 0; index < context.ChildCount; index++)
102+
// {
103+
// var child = context.GetChild(index);
104+
// if (child is T)
105+
// {
106+
// yield return (T)child;
107+
// }
108+
// }
109+
//}
110+
111+
public static T GetParent<T>(this ParserRuleContext context)
112+
{
113+
if (context == null)
114+
{
115+
return default;
116+
}
117+
if (context is T)
118+
{
119+
return (T)System.Convert.ChangeType(context, typeof(T));
120+
}
121+
//return GetMyParent<T>(context); //.Parent);
122+
return GetParent<T>((ParserRuleContext)context.Parent);
123+
}
124+
125+
//private static T GetMyParent<T>(ParserRuleContext context)
126+
//{
127+
// if (context == null)
128+
// {
129+
// return default;
130+
// }
131+
// if (context is T)
132+
// {
133+
// return (T)System.Convert.ChangeType(context, typeof(T));
134+
// }
135+
// return GetMyParent<T>((ParserRuleContext)context.Parent);
136+
//}
137+
138+
public static bool HasParent<TContext>(this ParserRuleContext context)
139+
{
140+
//return TryGetAncestor(context, out TContext _);
141+
return GetParent<TContext>(context) != null;
142+
}
143+
144+
public static bool HasParent(this ParserRuleContext context, IParseTree parent)
145+
{
146+
return HasParent((IParseTree)context, parent);
147+
//if (TryGetAncestor(context, out IParseTree ancestor))
148+
//{
149+
// if (ancestor == parent)
150+
// {
151+
// return true;
152+
// }
153+
//}
154+
//return HasParent(ancestor, parent);
155+
}
156+
157+
private static bool HasParent(this IParseTree context, IParseTree targetParent)
158+
{
159+
if (context == null)
160+
{
161+
return false;
162+
}
163+
if (context == targetParent)
164+
{
165+
return true;
166+
}
167+
return HasParent(context.Parent, targetParent);
168+
}
169+
170+
private static bool TryGetAncestor<TContext>(this ParserRuleContext context, out TContext ancestor)
171+
{
172+
ancestor = GetParent<TContext>(context);
173+
return ancestor != null;
174+
}
175+
176+
public static TContext FindChild<TContext>(this ParserRuleContext context) where TContext : ParserRuleContext
177+
{
178+
if (context == null)
179+
{
180+
return default;
181+
}
182+
183+
for (var index = 0; index < context.ChildCount; index++)
184+
{
185+
var child = context.GetChild(index);
186+
if (context.GetChild(index) is TContext)
187+
{
188+
return (TContext)child;
189+
}
190+
}
191+
return default;
192+
}
193+
194+
//public static bool HasChildToken(this IParseTree context, string token)
195+
//{
196+
// for (var index = 0; index < context.ChildCount; index++)
197+
// {
198+
// var child = context.GetChild(index);
199+
// if (context.GetChild(index).GetText().Equals(token))
200+
// {
201+
// return true;
202+
// }
203+
// }
204+
// return false;
205+
//}
206+
207+
public static bool HasChildToken(this ParserRuleContext context, string token)
208+
{
209+
return context.children.Any(ch => ch.GetText().Equals(token));
210+
//for (var index = 0; index < context.ChildCount; index++)
211+
//{
212+
// var child = context.GetChild(index);
213+
// if (context.GetChild(index).GetText().Equals(token))
214+
// {
215+
// return true;
216+
// }
217+
//}
218+
//return false;
219+
}
220+
221+
public static T GetDescendent<T>(this ParserRuleContext context)
222+
{
223+
return GetDescendent<T>((IParseTree)context);
224+
}
225+
226+
private static T GetDescendent<T>(this IParseTree context)
227+
{
228+
if (context == null)
229+
{
230+
return default;
231+
}
232+
233+
for (var index = 0; index < context.ChildCount; index++)
234+
{
235+
var child = context.GetChild(index);
236+
if (context.GetChild(index) is T)
237+
{
238+
return (T)child;
239+
}
240+
241+
var descendent = child.GetDescendent<T>();
242+
if (descendent != null)
243+
{
244+
return descendent;
245+
}
246+
}
247+
248+
return default;
249+
}
250+
44251
{
45252
var walker = new ParseTreeWalker();
46253
var listener = new ChildNodeListener<TContext>();

0 commit comments

Comments
 (0)