lib_ruby_parser_ast/traverse/finder/pattern/
item.rs

1use crate::traverse::finder::PatternError;
2
3/// Enum of all types of parent->child transitions during traversing
4#[derive(Clone, Debug, PartialEq, Eq, Copy)]
5pub enum Item {
6    /// Root transition
7    Root,
8
9    /// Transition into `.recv` from:
10    ///
11    /// + `Send`
12    /// + `CSend`
13    /// + `Index`
14    /// + `IndexAsgn`
15    /// + `OpAsgn`
16    /// + `OrAsgn`
17    /// + `AndAsgn`
18    Recv,
19
20    /// Transition into `.lhs` from:
21    ///
22    /// + `And`
23    /// + `Masgn`
24    /// + `MatchAlt`
25    /// + `Or`
26    Lhs,
27
28    /// Transition into `.rhs` from:
29    ///
30    /// + `And`
31    /// + `Masgn`
32    /// + `MatchAlt`
33    /// + `Or`
34    Rhs,
35
36    /// Transition into `.value` from:
37    ///
38    /// + `AndAsgn`
39    /// + `BlockPass`
40    /// + `Casgn`
41    /// + `Cvasgn`
42    /// + `Defined`
43    /// + `Gvasgn`
44    /// + `MatchPattern`
45    /// + `MatchPattern`
46    /// + `IndexAsgn`
47    /// + `Ivasgn`
48    /// + `Kwsplat`
49    /// + `Lvasgn`
50    /// + `MatchAs`
51    /// + `MatchWithLvasgn`
52    /// + `OpAsgn`
53    /// + `OrAsgn`
54    /// + `Pair`
55    /// + `Splat`
56    Value,
57
58    /// Transitions into `.call` from:
59    ///
60    /// + `Block`
61    /// + `Numblock`
62    MethodCall,
63
64    /// Transitions into `.body` from:
65    ///
66    /// + `Block`
67    /// + `Class`
68    /// + `Def`
69    /// + `Defs`
70    /// + `Ensure`
71    /// + `For`
72    /// + `InPattern`
73    /// + `Module`
74    /// + `Numblock`
75    /// + `Postexe`
76    /// + `Preexe`
77    /// + `Rescue`
78    /// + `RescueBody`
79    /// + `Sclass`
80    /// + `Until`
81    /// + `UntilPost`
82    /// + `When`
83    /// + `While`
84    /// + `WhilePost`
85    Body,
86
87    /// Transitions into `.args` from:
88    ///
89    /// + `Block`
90    /// + `Break`
91    /// + `Csend`
92    /// + `Def`
93    /// + `Defs`
94    /// + `Next`
95    /// + `Return`
96    /// + `Send`
97    /// + `Super`
98    /// + `Undef`
99    /// + `When`
100    /// + `Yield`
101    Args,
102
103    /// Transitions into `.expr` from:
104    ///
105    /// + `Case`
106    /// + `CaseMatch`
107    /// + `Sclass`
108    Expr,
109
110    /// Transitions into `.else_body` from:
111    ///
112    /// + `Case`
113    /// + `CaseMatch`
114    /// + `Rescue`
115    ElseBody,
116
117    /// Transitions into `.scope` from:
118    ///
119    /// + `Casgn`
120    /// + `Const`
121    Scope,
122
123    /// Transitions into `.name` from:
124    ///
125    /// + `Class`
126    /// + `MatchRest`
127    /// + `Module`
128    Name,
129
130    /// Transitions into `.superclass` from:
131    ///
132    /// + `Class`
133    Superclass,
134
135    /// Transitions into `.const` from:
136    ///
137    /// + `ConstPattern`
138    Const,
139
140    /// Transitions into `.definee` from:
141    ///
142    /// + `Defs`
143    Definee,
144
145    /// Transitions into `.iterator` from:
146    ///
147    /// + `For`
148    Iterator,
149
150    /// Transitions into `.iteratee` from:
151    ///
152    /// + `For`
153    Iteratee,
154
155    /// Transitions into `.pattern` from:
156    ///
157    /// + `ConstPattern`
158    /// + `MatchPattern`
159    /// + `MatchPatternP`
160    /// + `InPattern`
161    Pattern,
162
163    /// Transitions into `.left` from:
164    ///
165    /// + `EFlipFlop`
166    /// + `Erange`
167    /// + `IFlipFlop`
168    /// + `Irange`
169    Left,
170
171    /// Transitions into `.right` from:
172    ///
173    /// + `EFlipFlop`
174    /// + `Erange`
175    /// + `IFlipFlop`
176    /// + `Irange`
177    Right,
178
179    /// Transitions into `.if_true` from:
180    ///
181    /// + `If`
182    /// + `IfMod`
183    /// + `IfTernary`
184    IfTrue,
185
186    /// Transitions into `.if_false` from:
187    ///
188    /// + `If`
189    /// + `IfMod`
190    /// + `IfTernary`
191    IfFalse,
192
193    /// Transitions into `.cond` from:
194    ///
195    /// + `If`
196    /// + `IfGuard`
197    /// + `IfMod`
198    /// + `IfTernary`
199    /// + `UnlessGuard`
200    /// + `Until`
201    /// + `UntilPost`
202    /// + `While`
203    /// + `WhilePost`
204    Cond,
205
206    /// Transitions into `.default` from:
207    ///
208    /// + `Kwoptarg`
209    /// + `Optarg`
210    DefaultValue,
211
212    /// Transitions into `.ensure` from:
213    ///
214    /// + `Ensure`
215    Ensure,
216
217    /// Transitions into `.guard` from:
218    ///
219    /// + `InPattern`
220    Guard,
221
222    /// Transitions into `.as` from:
223    ///
224    /// + `MatchAs`
225    As,
226
227    /// Transitions into `.re` from:
228    ///
229    /// + `MatchCurrentLine`
230    /// + `MatchWithLvasgn`
231    Re,
232
233    /// Transitions into `.key` from:
234    ///
235    /// + `Pair`
236    Key,
237
238    /// Transitions into `.exc_list` from:
239    ///
240    /// + `RescueBody`
241    ExcList,
242
243    /// Transitions into `.exc_var` from:
244    ///
245    /// + `RescueBody`
246    ExcVar,
247
248    /// Transitions into `.var` from:
249    ///
250    /// + `Pin`
251    Var,
252
253    /// Transitions into `.options` from:
254    ///
255    /// + `Regexp`
256    Options,
257
258    /// Transitions into `.to` from:
259    ///
260    /// + `Alias`
261    To,
262
263    /// Transitions into `.from` from:
264    ///
265    /// + `Alias`
266    From,
267
268    // -- arrays --
269    /// Transitions into `.items` from:
270    ///
271    /// + `Mlhs`
272    MlhsItems,
273
274    /// Transitions into `.args` from:
275    ///
276    /// + `Args`
277    /// + `Procarg0`
278    Arglist,
279
280    /// Transitions into `.elements` from:
281    ///
282    /// + `Array`
283    /// + `ArrayPattern`
284    /// + `ArrayPatternWithTail`
285    /// + `FindPattern`
286    /// + `HashPattern`
287    Elements,
288
289    /// Transitions into `.statements` from:
290    ///
291    /// + `Begin`
292    /// + `KwBegin`
293    Stmts,
294
295    /// Transitions into `.when_bodies` from:
296    ///
297    /// + `Case`
298    WhenBodies,
299
300    /// Transitions into `.in_bodies` from:
301    ///
302    /// + `CaseMatch`
303    InBodies,
304
305    /// Transitions into `.parts` from:
306    ///
307    /// + `Dstr`
308    /// + `Dsym`
309    /// + `Heredoc`
310    /// + `Regexp`
311    /// + `XHeredoc`
312    /// + `Xstr`
313    Parts,
314
315    /// Transitions into `.indexes` from:
316    ///
317    /// + `Index`
318    /// + `IndexAsgn`
319    Indexes,
320
321    /// Transitions into `.pairs` from:
322    ///
323    /// + `Hash`
324    /// + `Kwargs`
325    Pairs,
326
327    /// Transitions into `.rescue_bodies` from:
328    ///
329    /// + `Rescue`
330    RescueBodies,
331
332    /// Transitions into any element of `Vec<Node>
333    Idx(usize),
334}
335
336#[derive(Debug)]
337pub(crate) struct ItemFromStringError {
338    unknown_pattern: String,
339}
340
341impl std::fmt::Display for ItemFromStringError {
342    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
343        write!(f, "unknown pattern {}", self.unknown_pattern)
344    }
345}
346
347impl Item {
348    pub(crate) fn from_string(s: &str) -> Result<Self, ItemFromStringError> {
349        let result = match s {
350            "root" => Self::Root,
351
352            "recv" => Self::Recv,
353            "lhs" => Self::Lhs,
354            "rhs" => Self::Rhs,
355            "value" => Self::Value,
356            "method_call" => Self::MethodCall,
357            "body" => Self::Body,
358            "args" => Self::Args,
359            "expr" => Self::Expr,
360            "else_body" => Self::ElseBody,
361            "scope" => Self::Scope,
362            "name" => Self::Name,
363            "superclass" => Self::Superclass,
364            "const" => Self::Const,
365            "definee" => Self::Definee,
366            "iterator" => Self::Iterator,
367            "iteratee" => Self::Iteratee,
368            "pattern" => Self::Pattern,
369            "left" => Self::Left,
370            "right" => Self::Right,
371            "if_true" => Self::IfTrue,
372            "if_false" => Self::IfFalse,
373            "cond" => Self::Cond,
374            "default_value" => Self::DefaultValue,
375            "ensure" => Self::Ensure,
376            "guard" => Self::Guard,
377            "as" => Self::As,
378            "re" => Self::Re,
379            "key" => Self::Key,
380            "exc_list" => Self::ExcList,
381            "exc_var" => Self::ExcVar,
382            "var" => Self::Var,
383            "options" => Self::Options,
384            "to" => Self::To,
385            "from" => Self::From,
386
387            "mlhs_items" => Self::MlhsItems,
388            "arglist" => Self::Arglist,
389            "elements" => Self::Elements,
390            "stmts" => Self::Stmts,
391            "when_bodies" => Self::WhenBodies,
392            "in_bodies" => Self::InBodies,
393            "parts" => Self::Parts,
394            "indexes" => Self::Indexes,
395            "pairs" => Self::Pairs,
396            "rescue_bodies" => Self::RescueBodies,
397
398            other if other.parse::<usize>().is_ok() => {
399                let idx = other.parse::<usize>().unwrap();
400                Self::Idx(idx)
401            }
402
403            unknown_pattern => {
404                return Err(ItemFromStringError {
405                    unknown_pattern: unknown_pattern.to_string(),
406                })
407            }
408        };
409        Ok(result)
410    }
411}
412
413impl Item {
414    /// Parses given string slice and constructs an `Item` (if possible)
415    pub fn new(s: &str) -> Result<Self, PatternError> {
416        Item::from_string(s).map_err(|e| PatternError {
417            pattern: e.to_string(),
418        })
419    }
420}