1use crate::parser::{Argument, AstNode, Modifiers, Span};
7
8pub trait AstVisitor {
10 fn visit_program(&mut self, body: &[AstNode], _span: Span) {
12 for node in body {
13 self.visit(node);
14 }
15 }
16
17 fn visit_text(&mut self, content: &str, span: Span) {
19 let _ = (content, span);
20 }
21
22 fn visit_function_call(
24 &mut self,
25 name: &str,
26 args: Option<&Vec<Argument>>,
27 modifiers: &Modifiers,
28 span: Span,
29 ) {
30 let _ = (name, modifiers, span);
31 if let Some(args) = args {
32 for arg in args {
33 self.visit_argument(arg);
34 }
35 }
36 }
37
38 fn visit_argument(&mut self, arg: &Argument) {
40 for part in &arg.parts {
41 self.visit(part);
42 }
43 }
44
45 fn visit_javascript(&mut self, code: &str, span: Span) {
47 let _ = (code, span);
48 }
49
50 fn visit_escaped(&mut self, content: &str, span: Span) {
52 let _ = (content, span);
53 }
54
55 fn visit(&mut self, node: &AstNode) {
57 match node {
58 AstNode::Program { body, span } => self.visit_program(body, *span),
59 AstNode::Text { content, span } => self.visit_text(content, *span),
60 AstNode::FunctionCall {
61 name,
62 args,
63 modifiers,
64 span,
65 } => self.visit_function_call(name, args.as_ref(), modifiers, *span),
66 AstNode::JavaScript { code, span } => self.visit_javascript(code, *span),
67 AstNode::Escaped { content, span } => self.visit_escaped(content, *span),
68 }
69 }
70}
71
72pub struct FunctionCollector {
74 pub functions: Vec<String>,
75}
76
77impl FunctionCollector {
78 pub fn new() -> Self {
79 Self {
80 functions: Vec::new(),
81 }
82 }
83}
84
85impl AstVisitor for FunctionCollector {
86 fn visit_function_call(
87 &mut self,
88 name: &str,
89 args: Option<&Vec<Argument>>,
90 modifiers: &Modifiers,
91 span: Span,
92 ) {
93 self.functions.push(name.to_string());
94
95 let _ = (modifiers, span);
97 if let Some(args) = args {
98 for arg in args {
99 self.visit_argument(arg);
100 }
101 }
102 }
103}
104
105#[derive(Default)]
107pub struct NodeCounter {
108 pub text_nodes: usize,
109 pub function_nodes: usize,
110 pub javascript_nodes: usize,
111 pub escaped_nodes: usize,
112}
113
114impl AstVisitor for NodeCounter {
115 fn visit_text(&mut self, _content: &str, _span: Span) {
116 self.text_nodes += 1;
117 }
118
119 fn visit_function_call(
120 &mut self,
121 _name: &str,
122 args: Option<&Vec<Argument>>,
123 _modifiers: &Modifiers,
124 _span: Span,
125 ) {
126 self.function_nodes += 1;
127 if let Some(args) = args {
128 for arg in args {
129 self.visit_argument(arg);
130 }
131 }
132 }
133
134 fn visit_javascript(&mut self, _code: &str, _span: Span) {
135 self.javascript_nodes += 1;
136 }
137
138 fn visit_escaped(&mut self, _content: &str, _span: Span) {
139 self.escaped_nodes += 1;
140 }
141}
142
143pub trait AstVisitorMut {
145 fn visit_mut(&mut self, node: &mut AstNode) {
147 match node {
148 AstNode::Program { body, span } => self.visit_program_mut(body, *span),
149 AstNode::Text { content, span } => self.visit_text_mut(content, *span),
150 AstNode::FunctionCall {
151 name,
152 args,
153 modifiers,
154 span,
155 } => self.visit_function_call_mut(name, args, modifiers, *span),
156 AstNode::JavaScript { code, span } => self.visit_javascript_mut(code, *span),
157 AstNode::Escaped { content, span } => self.visit_escaped_mut(content, *span),
158 }
159 }
160
161 fn visit_program_mut(&mut self, body: &mut [AstNode], span: Span) {
162 let _ = span;
163 for node in body {
164 self.visit_mut(node);
165 }
166 }
167
168 fn visit_text_mut(&mut self, content: &mut String, span: Span) {
169 let _ = (content, span);
170 }
171
172 fn visit_function_call_mut(
173 &mut self,
174 name: &mut String,
175 args: &mut Option<Vec<Argument>>,
176 modifiers: &mut Modifiers,
177 span: Span,
178 ) {
179 let _ = (name, modifiers, span);
180 if let Some(args) = args {
181 for arg in args {
182 for part in &mut arg.parts {
183 self.visit_mut(part);
184 }
185 }
186 }
187 }
188
189 fn visit_javascript_mut(&mut self, code: &mut String, span: Span) {
190 let _ = (code, span);
191 }
192
193 fn visit_escaped_mut(&mut self, content: &mut String, span: Span) {
194 let _ = (content, span);
195 }
196}