1#![allow(clippy::derive_partial_eq_without_eq)]
2pub use crate::{builtin::*, text_size::TextSize, ConversionFlag, Node};
3use std::fmt::{Debug, Display, Formatter};
4use std::marker::PhantomData;
5
6pub type Suite<R = TextRange> = Vec<Stmt<R>>;
7
8#[cfg(feature = "all-nodes-with-ranges")]
9pub type OptionalRange<R> = R;
10
11#[cfg(not(feature = "all-nodes-with-ranges"))]
12pub type OptionalRange<R> = EmptyRange<R>;
13
14#[cfg(not(feature = "all-nodes-with-ranges"))]
15impl<R> From<R> for OptionalRange<R> {
16 fn from(_: R) -> Self {
17 Self {
18 phantom: PhantomData,
19 }
20 }
21}
22
23#[derive(Eq, PartialEq, Hash, Copy, Clone)]
24pub struct EmptyRange<R> {
25 phantom: PhantomData<R>,
26}
27
28impl<R> EmptyRange<R> {
29 #[inline(always)]
30 pub fn new(_start: TextSize, _end: TextSize) -> Self {
31 Self {
32 phantom: PhantomData,
33 }
34 }
35}
36
37impl<R> Display for EmptyRange<R> {
38 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
39 f.write_str("()")
40 }
41}
42
43impl<R> Debug for EmptyRange<R> {
44 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
45 Display::fmt(self, f)
46 }
47}
48
49impl<R> Default for EmptyRange<R> {
50 fn default() -> Self {
51 EmptyRange {
52 phantom: PhantomData,
53 }
54 }
55}
56
57impl CmpOp {
58 pub fn as_str(&self) -> &'static str {
59 match self {
60 CmpOp::Eq => "==",
61 CmpOp::NotEq => "!=",
62 CmpOp::Lt => "<",
63 CmpOp::LtE => "<=",
64 CmpOp::Gt => ">",
65 CmpOp::GtE => ">=",
66 CmpOp::Is => "is",
67 CmpOp::IsNot => "is not",
68 CmpOp::In => "in",
69 CmpOp::NotIn => "not in",
70 }
71 }
72}
73
74impl<R> Arguments<R> {
75 pub fn empty(range: OptionalRange<R>) -> Self {
76 Self {
77 range,
78 posonlyargs: Vec::new(),
79 args: Vec::new(),
80 vararg: None,
81 kwonlyargs: Vec::new(),
82 kwarg: None,
83 }
84 }
85}
86
87#[allow(clippy::borrowed_box)] fn clone_boxed_expr<R: Clone>(expr: &Box<Expr<R>>) -> Box<Expr<R>> {
89 let expr: &Expr<_> = expr.as_ref();
90 Box::new(expr.clone())
91}
92
93impl<R> ArgWithDefault<R> {
94 pub fn from_arg(def: Arg<R>, default: Option<Expr<R>>) -> Self
95 where
96 R: Clone,
97 {
98 let range = {
99 if cfg!(feature = "all-nodes-with-ranges") {
100 todo!("range recovery is not implemented yet") } else {
102 #[allow(clippy::useless_conversion)] OptionalRange::from(def.range.clone())
104 }
105 };
106 Self {
107 range,
108 def,
109 default: default.map(Box::new),
110 }
111 }
112
113 pub fn as_arg(&self) -> &Arg<R> {
114 &self.def
115 }
116
117 pub fn to_arg(&self) -> (Arg<R>, Option<Box<Expr<R>>>)
118 where
119 R: Clone,
120 {
121 let ArgWithDefault {
122 range: _,
123 def,
124 default,
125 } = self;
126 (def.clone(), default.as_ref().map(clone_boxed_expr))
127 }
128 pub fn into_arg(self) -> (Arg<R>, Option<Box<Expr<R>>>) {
129 let ArgWithDefault {
130 range: _,
131 def,
132 default,
133 } = self;
134 (def, default)
135 }
136}
137
138impl<R> Arguments<R> {
139 pub fn defaults(&self) -> impl std::iter::Iterator<Item = &Expr<R>> {
140 self.posonlyargs
141 .iter()
142 .chain(self.args.iter())
143 .filter_map(|arg| arg.default.as_ref().map(|e| e.as_ref()))
144 }
145
146 #[allow(clippy::type_complexity)]
147 pub fn split_kwonlyargs(&self) -> (Vec<&Arg<R>>, Vec<(&Arg<R>, &Expr<R>)>) {
148 let mut args = Vec::new();
149 let mut with_defaults = Vec::new();
150 for arg in self.kwonlyargs.iter() {
151 if let Some(ref default) = arg.default {
152 with_defaults.push((arg.as_arg(), &**default));
153 } else {
154 args.push(arg.as_arg());
155 }
156 }
157 (args, with_defaults)
158 }
159
160 pub fn to_python_arguments(&self) -> PythonArguments<R>
161 where
162 R: Clone,
163 {
164 let Arguments {
165 range,
166 posonlyargs,
167 args,
168 vararg,
169 kwonlyargs,
170 kwarg,
171 } = self;
172
173 let mut pos_only = Vec::with_capacity(posonlyargs.len());
174 let mut pos_args = Vec::with_capacity(args.len());
175 let mut defaults = Vec::new();
176 for arg in posonlyargs {
177 let (arg, default) = arg.to_arg();
178 if let Some(default) = default {
179 defaults.push(*default);
180 }
181 pos_only.push(arg);
182 }
183 for arg in args {
184 let (arg, default) = arg.to_arg();
185 if let Some(default) = default {
186 defaults.push(*default);
187 }
188 pos_args.push(arg);
189 }
190
191 let mut kw_only = Vec::with_capacity(kwonlyargs.len());
192 let mut kw_defaults = Vec::new();
193 for arg in kwonlyargs {
194 let (arg, default) = arg.to_arg();
195 if let Some(default) = default {
196 kw_defaults.push(*default);
197 }
198 kw_only.push(arg);
199 }
200
201 PythonArguments {
202 range: range.clone(),
203 posonlyargs: pos_only,
204 args: pos_args,
205 defaults,
206 vararg: vararg.clone(),
207 kwonlyargs: kw_only,
208 kw_defaults,
209 kwarg: kwarg.clone(),
210 }
211 }
212
213 pub fn into_python_arguments(self) -> PythonArguments<R> {
214 let Arguments {
215 range,
216 posonlyargs,
217 args,
218 vararg,
219 kwonlyargs,
220 kwarg,
221 } = self;
222
223 let mut pos_only = Vec::with_capacity(posonlyargs.len());
224 let mut pos_args = Vec::with_capacity(args.len());
225 let mut defaults = Vec::new();
226 for arg in posonlyargs {
227 let (arg, default) = arg.into_arg();
228 if let Some(default) = default {
229 defaults.push(*default);
230 }
231 pos_only.push(arg);
232 }
233 for arg in args {
234 let (arg, default) = arg.into_arg();
235 if let Some(default) = default {
236 defaults.push(*default);
237 }
238 pos_args.push(arg);
239 }
240
241 let mut kw_only = Vec::with_capacity(kwonlyargs.len());
242 let mut kw_defaults = Vec::new();
243 for arg in kwonlyargs {
244 let (arg, default) = arg.into_arg();
245 if let Some(default) = default {
246 kw_defaults.push(*default);
247 }
248 kw_only.push(arg);
249 }
250
251 PythonArguments {
252 range,
253 posonlyargs: pos_only,
254 args: pos_args,
255 defaults,
256 vararg,
257 kwonlyargs: kw_only,
258 kw_defaults,
259 kwarg,
260 }
261 }
262}
263
264impl<R> PythonArguments<R> {
265 pub fn into_arguments(self) -> Arguments<R>
266 where
267 R: Clone,
268 {
269 let PythonArguments {
270 range,
271 posonlyargs,
272 args,
273 defaults,
274 vararg,
275 kwonlyargs,
276 kw_defaults,
277 kwarg,
278 } = self;
279
280 let mut pos_only = Vec::with_capacity(posonlyargs.len());
281 let mut pos_args = Vec::with_capacity(args.len());
282 let args_len = posonlyargs.len() + args.len();
283 let mut defaults: Vec<_> = std::iter::repeat_with(|| None)
285 .take(args_len - defaults.len())
286 .chain(defaults.into_iter().map(Some))
287 .collect();
288 debug_assert_eq!(args_len, defaults.len());
289
290 for (arg, default) in std::iter::zip(args, defaults.drain(posonlyargs.len()..)) {
291 let arg = ArgWithDefault::from_arg(arg, default);
292 pos_args.push(arg);
293 }
294
295 for (arg, default) in std::iter::zip(posonlyargs, defaults.drain(..)) {
296 let arg = ArgWithDefault::from_arg(arg, default);
297 pos_only.push(arg);
298 }
299
300 let mut kw_only = Vec::with_capacity(kwonlyargs.len());
301 let kw_defaults: Vec<_> = std::iter::repeat_with(|| None)
302 .take(kw_only.len().saturating_sub(kw_defaults.len()))
303 .chain(kw_defaults.into_iter().map(Some))
304 .collect();
305 for (arg, default) in std::iter::zip(kwonlyargs, kw_defaults) {
306 let arg = ArgWithDefault::from_arg(arg, default);
307 kw_only.push(arg);
308 }
309
310 Arguments {
311 range,
312 posonlyargs: pos_only,
313 args: pos_args,
314 vararg,
315 kwonlyargs: kw_only,
316 kwarg,
317 }
318 }
319}
320
321impl<R> From<Arguments<R>> for PythonArguments<R> {
322 fn from(arguments: Arguments<R>) -> Self {
323 arguments.into_python_arguments()
324 }
325}
326
327include!("gen/generic.rs");