yog_script_analyze/ast/
walk.rs1use super::{Decl, DeclKind, Element, Expr, ExprKind, Name, Pattern, StrSeg};
5
6impl Expr {
7 pub fn each_child<'e>(&'e self, mut f: impl FnMut(&'e Expr)) {
10 match &self.kind {
11 ExprKind::Str(segs) => segs.iter().for_each(|s| {
12 if let StrSeg::Expr(e) = s {
13 f(e);
14 }
15 }),
16 ExprKind::Tuple(items) | ExprKind::Macro { args: items, .. } => {
17 items.iter().for_each(f)
18 }
19 ExprKind::Collection(items) => items.iter().for_each(|i| match i {
20 Element::Item(e) | Element::Spread(e) => f(e),
21 Element::Entry(k, v) => {
22 f(k);
23 f(v);
24 }
25 }),
26 ExprKind::New { args, init, .. } => {
27 args.iter().flatten().for_each(|a| f(&a.value));
28 init.iter().for_each(|(_, v)| f(v));
29 }
30 ExprKind::Call { callee, args } => {
31 f(callee);
32 args.iter().for_each(|a| f(&a.value));
33 }
34 ExprKind::Binary { left, right, .. } => {
35 f(left);
36 f(right);
37 }
38 ExprKind::Range { from, to, .. } => {
39 f(from);
40 f(to);
41 }
42 ExprKind::Index { expr, index } => {
43 f(expr);
44 f(index);
45 }
46 ExprKind::Conditional {
47 cond,
48 then,
49 otherwise,
50 } => {
51 f(cond);
52 f(then);
53 f(otherwise);
54 }
55 ExprKind::Switch { expr, arms } => {
56 f(expr);
57 for arm in arms {
58 arm.guard.iter().for_each(&mut f);
59 f(&arm.value);
60 }
61 }
62 _ => self.each_wrapped(f),
63 }
64 }
65
66 fn each_wrapped<'e>(&'e self, mut f: impl FnMut(&'e Expr)) {
68 match &self.kind {
69 ExprKind::NameOf(e)
70 | ExprKind::NotNull(e)
71 | ExprKind::Move(e)
72 | ExprKind::Unary { expr: e, .. }
73 | ExprKind::Cast { expr: e, .. }
74 | ExprKind::Is { expr: e, .. }
75 | ExprKind::As { expr: e, .. }
76 | ExprKind::Has { expr: e, .. }
77 | ExprKind::TypeArgs { expr: e, .. }
78 | ExprKind::Member { expr: e, .. } => f(e),
79 _ => {}
80 }
81 }
82}
83
84impl DeclKind {
85 pub fn members(&self) -> &[Decl] {
88 match self {
89 DeclKind::Namespace {
90 body: Some(body), ..
91 }
92 | DeclKind::Mod { body, .. }
93 | DeclKind::Type { body, .. }
94 | DeclKind::Enum { body, .. }
95 | DeclKind::Content { body, .. }
96 | DeclKind::Component { body, .. }
97 | DeclKind::Extend { body, .. }
98 | DeclKind::Screen { body, .. }
99 | DeclKind::Command { body, .. } => body,
100 _ => &[],
101 }
102 }
103}
104
105impl Pattern {
106 pub fn each_binding<'p>(&'p self, f: &mut impl FnMut(&'p Name)) {
108 match self {
109 Pattern::Let(n) | Pattern::Type { bind: Some(n), .. } => f(n),
110 Pattern::Variant { args: all, .. } | Pattern::Tuple(all) => {
111 all.iter().for_each(|p| p.each_binding(f));
112 }
113 Pattern::Property { fields, .. } => fields.iter().for_each(|(_, p)| p.each_binding(f)),
114 Pattern::Or(a, b) | Pattern::And(a, b) => {
115 a.each_binding(f);
116 b.each_binding(f);
117 }
118 Pattern::Not(p) => p.each_binding(f),
119 _ => {}
120 }
121 }
122}