dry4rust/rust/normalizer/
expr.rs1use crate::node::{NodeKind, NormalizedNode, PlaceholderKind};
7use crate::normalization_context::NormalizationContext;
8
9use super::helpers::{member_to_string, normalize_bin_op, normalize_lit, normalize_un_op};
10use syn::Block;
11use syn::Expr;
12use syn::Stmt;
13
14impl NormalizationContext {
15 #[allow(clippy::too_many_lines)]
16 pub fn normalize_expr(&mut self, expr: &Expr) -> NormalizedNode {
17 match expr {
18 Expr::Lit(el) => normalize_lit(&el.lit),
19 Expr::Path(ep) => {
20 if ep.path.segments.len() == 1 {
21 let seg = &ep.path.segments[0];
22 let ident = seg.ident.to_string();
23 let kind = if ident.chars().next().is_some_and(char::is_uppercase) {
24 PlaceholderKind::Type
25 } else {
26 PlaceholderKind::Variable
27 };
28 let idx = self.placeholder(&ident, kind);
29 NormalizedNode::leaf(NodeKind::Placeholder(kind, idx))
30 } else {
31 let segments: Vec<NormalizedNode> = ep
32 .path
33 .segments
34 .iter()
35 .map(|seg| {
36 let ident = seg.ident.to_string();
37 let kind = if ident.chars().next().is_some_and(char::is_uppercase) {
38 PlaceholderKind::Type
39 } else {
40 PlaceholderKind::Variable
41 };
42 let idx = self.placeholder(&ident, kind);
43 NormalizedNode::leaf(NodeKind::Placeholder(kind, idx))
44 })
45 .collect();
46 NormalizedNode::with_children(NodeKind::Path, segments)
47 }
48 }
49 Expr::Binary(eb) => NormalizedNode::with_children(
51 NodeKind::BinaryOp(normalize_bin_op(&eb.op)),
52 vec![
53 self.normalize_expr(&eb.left),
54 self.normalize_expr(&eb.right),
55 ],
56 ),
57 Expr::Unary(eu) => NormalizedNode::with_children(
59 NodeKind::UnaryOp(normalize_un_op(&eu.op)),
60 vec![self.normalize_expr(&eu.expr)],
61 ),
62 Expr::Call(ec) => {
64 let mut children = vec![self.normalize_expr(&ec.func)];
65 children.extend(ec.args.iter().map(|a| self.normalize_expr(a)));
66 NormalizedNode::with_children(NodeKind::Call, children)
67 }
68 Expr::MethodCall(emc) => {
70 let method_idx =
71 self.placeholder(&emc.method.to_string(), PlaceholderKind::Function);
72 let mut children = vec![
73 self.normalize_expr(&emc.receiver),
74 NormalizedNode::leaf(NodeKind::Placeholder(
75 PlaceholderKind::Function,
76 method_idx,
77 )),
78 ];
79 children.extend(emc.args.iter().map(|a| self.normalize_expr(a)));
80 NormalizedNode::with_children(NodeKind::MethodCall, children)
81 }
82 Expr::Field(ef) => {
84 let field_idx =
85 self.placeholder(&member_to_string(&ef.member), PlaceholderKind::Variable);
86 NormalizedNode::with_children(
87 NodeKind::FieldAccess,
88 vec![
89 self.normalize_expr(&ef.base),
90 NormalizedNode::leaf(NodeKind::Placeholder(
91 PlaceholderKind::Variable,
92 field_idx,
93 )),
94 ],
95 )
96 }
97 Expr::Index(ei) => NormalizedNode::with_children(
99 NodeKind::Index,
100 vec![
101 self.normalize_expr(&ei.expr),
102 self.normalize_expr(&ei.index),
103 ],
104 ),
105 Expr::Closure(ec) => {
107 let mut children = vec![self.normalize_expr(&ec.body)];
108 children.extend(ec.inputs.iter().map(|p| self.normalize_pat(p)));
109 NormalizedNode::with_children(NodeKind::Closure, children)
110 }
111 Expr::Return(er) => {
113 let children: Vec<_> = er
114 .expr
115 .as_ref()
116 .map(|e| vec![self.normalize_expr(e)])
117 .unwrap_or_default();
118 NormalizedNode::with_children(NodeKind::Return, children)
119 }
120 Expr::Break(eb) => {
122 let children: Vec<_> = eb
123 .expr
124 .as_ref()
125 .map(|e| vec![self.normalize_expr(e)])
126 .unwrap_or_default();
127 NormalizedNode::with_children(NodeKind::Break, children)
128 }
129 Expr::Continue(_) => NormalizedNode::leaf(NodeKind::Continue),
130 Expr::Assign(ea) => NormalizedNode::with_children(
132 NodeKind::Assign,
133 vec![
134 self.normalize_expr(&ea.left),
135 self.normalize_expr(&ea.right),
136 ],
137 ),
138 Expr::Reference(er) => NormalizedNode::with_children(
140 NodeKind::Reference {
141 mutable: er.mutability.is_some(),
142 },
143 vec![self.normalize_expr(&er.expr)],
144 ),
145 Expr::Tuple(et) => NormalizedNode::with_children(
146 NodeKind::Tuple,
147 et.elems.iter().map(|e| self.normalize_expr(e)).collect(),
148 ),
149 Expr::Array(ea) => NormalizedNode::with_children(
150 NodeKind::Array,
151 ea.elems.iter().map(|e| self.normalize_expr(e)).collect(),
152 ),
153 Expr::Repeat(er) => NormalizedNode::with_children(
155 NodeKind::Repeat,
156 vec![self.normalize_expr(&er.expr), self.normalize_expr(&er.len)],
157 ),
158 Expr::Cast(ec) => NormalizedNode::with_children(
160 NodeKind::Cast,
161 vec![self.normalize_expr(&ec.expr), self.normalize_type(&ec.ty)],
162 ),
163 Expr::Struct(es) => {
165 let mut children = vec![NormalizedNode::opt(
166 es.rest.as_ref().map(|e| self.normalize_expr(e)),
167 )];
168 children.extend(es.fields.iter().map(|f| {
169 let field_idx =
170 self.placeholder(&member_to_string(&f.member), PlaceholderKind::Variable);
171 NormalizedNode::with_children(
172 NodeKind::FieldValue,
173 vec![
174 NormalizedNode::leaf(NodeKind::Placeholder(
175 PlaceholderKind::Variable,
176 field_idx,
177 )),
178 self.normalize_expr(&f.expr),
179 ],
180 )
181 }));
182 NormalizedNode::with_children(NodeKind::StructInit, children)
183 }
184 Expr::Await(ea) => {
186 NormalizedNode::with_children(NodeKind::Await, vec![self.normalize_expr(&ea.base)])
187 }
188 Expr::Try(et) => {
190 NormalizedNode::with_children(NodeKind::Try, vec![self.normalize_expr(&et.expr)])
191 }
192 Expr::If(ei) => NormalizedNode::with_children(
194 NodeKind::If,
195 vec![
196 self.normalize_expr(&ei.cond),
197 self.normalize_block(&ei.then_branch),
198 NormalizedNode::opt(
199 ei.else_branch.as_ref().map(|(_, e)| self.normalize_expr(e)),
200 ),
201 ],
202 ),
203 Expr::Match(em) => {
206 let mut children = vec![self.normalize_expr(&em.expr)];
207 children.extend(em.arms.iter().map(|arm| {
208 NormalizedNode::with_children(
209 NodeKind::MatchArm,
210 vec![
211 self.normalize_pat(&arm.pat),
212 NormalizedNode::opt(
213 arm.guard.as_ref().map(|(_, g)| self.normalize_expr(g)),
214 ),
215 self.normalize_expr(&arm.body),
216 ],
217 )
218 }));
219 NormalizedNode::with_children(NodeKind::Match, children)
220 }
221 Expr::Loop(el) => {
223 NormalizedNode::with_children(NodeKind::Loop, vec![self.normalize_block(&el.body)])
224 }
225 Expr::While(ew) => NormalizedNode::with_children(
227 NodeKind::While,
228 vec![
229 self.normalize_expr(&ew.cond),
230 self.normalize_block(&ew.body),
231 ],
232 ),
233 Expr::ForLoop(ef) => NormalizedNode::with_children(
235 NodeKind::ForLoop,
236 vec![
237 self.normalize_pat(&ef.pat),
238 self.normalize_expr(&ef.expr),
239 self.normalize_block(&ef.body),
240 ],
241 ),
242 Expr::Block(eb) => self.normalize_block(&eb.block),
243 Expr::Paren(ep) => {
245 NormalizedNode::with_children(NodeKind::Paren, vec![self.normalize_expr(&ep.expr)])
246 }
247 Expr::Range(er) => NormalizedNode::with_children(
249 NodeKind::Range,
250 vec![
251 NormalizedNode::opt(er.start.as_ref().map(|e| self.normalize_expr(e))),
252 NormalizedNode::opt(er.end.as_ref().map(|e| self.normalize_expr(e))),
253 ],
254 ),
255 Expr::Let(el) => NormalizedNode::with_children(
257 NodeKind::LetExpr,
258 vec![self.normalize_pat(&el.pat), self.normalize_expr(&el.expr)],
259 ),
260 Expr::Macro(em) => self.normalize_macro(&em.mac),
261 Expr::Group(eg) => self.normalize_expr(&eg.expr),
262 Expr::Unsafe(eu) => self.normalize_block(&eu.block),
263 Expr::Const(ec) => self.normalize_block(&ec.block),
264 _ => NormalizedNode::leaf(NodeKind::Opaque),
265 }
266 }
267
268 pub fn normalize_stmt(&mut self, stmt: &Stmt) -> NormalizedNode {
269 match stmt {
270 Stmt::Local(local) => NormalizedNode::with_children(
272 NodeKind::LetBinding,
273 vec![
274 self.normalize_pat(&local.pat),
275 NormalizedNode::none(), NormalizedNode::opt(
277 local
278 .init
279 .as_ref()
280 .map(|init| self.normalize_expr(&init.expr)),
281 ),
282 NormalizedNode::opt(
283 local
284 .init
285 .as_ref()
286 .and_then(|init| init.diverge.as_ref())
287 .map(|(_, expr)| self.normalize_expr(expr)),
288 ),
289 ],
290 ),
291 Stmt::Expr(expr, semi) => {
292 let normalized = self.normalize_expr(expr);
293 if semi.is_some() {
294 NormalizedNode::with_children(NodeKind::Semi, vec![normalized])
295 } else {
296 normalized
297 }
298 }
299 Stmt::Item(_) => NormalizedNode::leaf(NodeKind::Opaque),
300 Stmt::Macro(sm) => {
301 let normalized = self.normalize_macro(&sm.mac);
302 if sm.semi_token.is_some() {
303 NormalizedNode::with_children(NodeKind::Semi, vec![normalized])
304 } else {
305 normalized
306 }
307 }
308 }
309 }
310
311 pub fn normalize_block(&mut self, block: &Block) -> NormalizedNode {
312 NormalizedNode::with_children(
313 NodeKind::Block,
314 block.stmts.iter().map(|s| self.normalize_stmt(s)).collect(),
315 )
316 }
317}