move_syn/functions/
signature.rs1use std::collections::HashMap;
2
3use unsynn::*;
4
5use crate::{Generics, HasGenerics, ItemKind, MaybeRefType, Typed, kw, mutate_delimited_vec};
6
7unsynn! {
8 pub(super) struct Arguments(ParenthesisGroupContaining<CommaDelimitedVec<FunctionArg>>);
9
10 pub struct FunctionArg {
12 mut_: Option<kw::Mut>,
13 ident: Ident,
14 colon: Colon,
15 type_: MaybeRefType,
16 }
17
18 pub(super) struct Returns {
20 colon: Colon,
21 type_: ReturnType,
22 }
23
24 pub(super) enum ReturnType {
25 One(MaybeRefType),
26 Many(ParenthesisGroupContaining<CommaDelimitedVec<MaybeRefType>>),
27 }
28}
29
30impl crate::Module {
31 pub fn fully_qualify_fun_signature_types(&mut self) -> &mut Self {
33 let imports: HashMap<_, _> = self
35 .items()
36 .filter_map(|item| match &item.kind {
37 ItemKind::Import(import) => Some(import),
38 _ => None,
39 })
40 .flat_map(|import| import.flatten())
41 .collect();
42
43 for item in &mut self.contents.content {
45 match &mut item.kind {
46 ItemKind::Function(fun) => {
47 let generics = &fun.type_param_idents();
48 fun.map_types(|ty| ty.resolve(&imports, generics));
49 }
50 ItemKind::NativeFun(native) => {
51 let generics = &native.type_param_idents();
52 native.map_types(|ty| ty.resolve(&imports, generics));
53 }
54 _ => (),
55 }
56 }
57
58 self
59 }
60}
61
62impl HasGenerics for super::Function {
63 fn generics(&self) -> Option<&Generics> {
64 self.generics.as_ref()
65 }
66}
67
68impl HasGenerics for super::NativeFun {
69 fn generics(&self) -> Option<&Generics> {
70 self.generics.as_ref()
71 }
72}
73
74impl Typed for super::Function {
75 fn map_types(&mut self, mut f: impl FnMut(&mut crate::Type)) {
76 mutate_delimited_vec(&mut self.args.0.content, |arg| f(&mut arg.type_.r#type));
77 if let Some(ret) = self.ret.as_mut() {
78 ret.map_types(f);
79 }
80 }
81}
82
83impl Typed for super::NativeFun {
84 fn map_types(&mut self, mut f: impl FnMut(&mut crate::Type)) {
85 mutate_delimited_vec(&mut self.args.0.content, |arg| f(&mut arg.type_.r#type));
86 if let Some(ret) = self.ret.as_mut() {
87 ret.map_types(f);
88 }
89 }
90}
91
92impl Typed for Returns {
93 fn map_types(&mut self, mut f: impl FnMut(&mut crate::Type)) {
94 match &mut self.type_ {
95 ReturnType::One(maybe_ref_type) => f(&mut maybe_ref_type.r#type),
96 ReturnType::Many(parenthesis_group) => {
97 mutate_delimited_vec(&mut parenthesis_group.content, |maybe_ref_type| {
98 f(&mut maybe_ref_type.r#type)
99 })
100 }
101 }
102 }
103}
104
105impl super::Function {
106 pub fn arguments(&self) -> impl ExactSizeIterator<Item = &FunctionArg> {
108 self.args.0.content.iter().map(|d| &d.value)
109 }
110
111 pub fn returns(&self) -> impl ExactSizeIterator<Item = &MaybeRefType> {
113 MaybeRefTypeIter::new(self.ret.as_ref())
114 }
115}
116
117impl super::NativeFun {
118 pub fn arguments(&self) -> impl ExactSizeIterator<Item = &FunctionArg> {
120 self.args.0.content.iter().map(|d| &d.value)
121 }
122
123 pub fn returns(&self) -> impl ExactSizeIterator<Item = &MaybeRefType> {
125 MaybeRefTypeIter::new(self.ret.as_ref())
126 }
127}
128
129impl FunctionArg {
130 pub const fn ident(&self) -> &Ident {
131 &self.ident
132 }
133
134 pub const fn type_(&self) -> &MaybeRefType {
135 &self.type_
136 }
137}
138
139struct MaybeRefTypeIter<'a> {
140 inner: Option<&'a Returns>,
141 idx: usize,
142}
143
144impl<'a> MaybeRefTypeIter<'a> {
145 const fn new(inner: Option<&'a Returns>) -> Self {
146 Self { inner, idx: 0 }
147 }
148}
149
150impl<'a> Iterator for MaybeRefTypeIter<'a> {
151 type Item = &'a MaybeRefType;
152
153 fn next(&mut self) -> Option<Self::Item> {
154 match &self.inner {
155 None => None,
156 Some(Returns {
157 type_: ReturnType::One(maybe_ref_type),
158 ..
159 }) if self.idx == 0 => {
160 self.idx += 1;
161 Some(maybe_ref_type)
162 }
163 Some(Returns {
164 type_: ReturnType::One(_),
165 ..
166 }) => None,
167 Some(Returns {
168 type_: ReturnType::Many(parenthesis_group),
169 ..
170 }) if self.idx < parenthesis_group.content.len() => {
171 let item = &parenthesis_group.content[self.idx].value;
172 self.idx += 1;
173 Some(item)
174 }
175 Some(Returns {
176 type_: ReturnType::Many(_),
177 ..
178 }) => None,
179 }
180 }
181}
182
183impl<'a> ExactSizeIterator for MaybeRefTypeIter<'a> {
184 fn len(&self) -> usize {
185 match &self.inner {
186 None => 0,
187 Some(Returns {
188 type_: ReturnType::One(_),
189 ..
190 }) => 1,
191 Some(Returns {
192 type_: ReturnType::Many(parenthesis_group),
193 ..
194 }) => parenthesis_group.content.len(),
195 }
196 }
197}