dry4rust/rust/normalizer/
normalize.rs1use crate::node::{NodeKind, NormalizedNode, PlaceholderKind};
7use crate::normalization_context::NormalizationContext;
8
9use syn::Block;
10use syn::ExprClosure;
11use syn::ImplItemFn;
12use syn::ItemFn;
13use syn::ItemImpl;
14use syn::Signature;
15
16impl NormalizationContext {
17 pub fn normalize_signature(&mut self, sig: &Signature) -> NormalizedNode {
18 let return_type = match &sig.output {
20 syn::ReturnType::Default => NormalizedNode::none(),
21 syn::ReturnType::Type(_, ty) => self.normalize_type(ty),
22 };
23 let mut children = vec![return_type];
24 children.extend(sig.inputs.iter().map(|arg| match arg {
25 syn::FnArg::Receiver(r) => {
26 let idx = self.placeholder("self", PlaceholderKind::Variable);
27 let self_node =
28 NormalizedNode::leaf(NodeKind::Placeholder(PlaceholderKind::Variable, idx));
29 if r.reference.is_some() {
30 NormalizedNode::with_children(
31 NodeKind::Reference {
32 mutable: r.mutability.is_some(),
33 },
34 vec![self_node],
35 )
36 } else {
37 self_node
38 }
39 }
40 syn::FnArg::Typed(pt) => {
41 let pat = self.normalize_pat(&pt.pat);
42 let ty = self.normalize_type(&pt.ty);
43 NormalizedNode::with_children(NodeKind::FieldValue, vec![pat, ty])
44 }
45 }));
46 NormalizedNode::with_children(NodeKind::FnSignature, children)
47 }
48}
49
50fn normalize_fn_parts(sig: &Signature, block: &Block) -> (NormalizedNode, NormalizedNode) {
53 let mut ctx = NormalizationContext::new();
54 let sig = ctx.normalize_signature(sig);
55 let body = ctx.normalize_block(block);
56 (sig, body)
57}
58
59#[must_use]
61pub fn normalize_item_fn(func: &ItemFn) -> (NormalizedNode, NormalizedNode) {
62 normalize_fn_parts(&func.sig, &func.block)
63}
64
65#[must_use]
67pub fn normalize_impl_item_fn(method: &ImplItemFn) -> (NormalizedNode, NormalizedNode) {
68 normalize_fn_parts(&method.sig, &method.block)
69}
70
71#[must_use]
73pub fn normalize_closure_expr(closure: &ExprClosure) -> NormalizedNode {
74 let mut ctx = NormalizationContext::new();
75 let mut children = vec![ctx.normalize_expr(&closure.body)];
76 children.extend(closure.inputs.iter().map(|p| ctx.normalize_pat(p)));
77 NormalizedNode::with_children(NodeKind::Closure, children)
78}
79
80#[must_use]
82pub fn normalize_impl_block(imp: &ItemImpl) -> Vec<(String, NormalizedNode, NormalizedNode)> {
83 imp.items
84 .iter()
85 .filter_map(|item| {
86 if let syn::ImplItem::Fn(method) = item {
87 let name = method.sig.ident.to_string();
88 let (sig, body) = normalize_impl_item_fn(method);
89 Some((name, sig, body))
90 } else {
91 None
92 }
93 })
94 .collect()
95}