libcst_native/nodes/
expression.rs

1// Copyright (c) Meta Platforms, Inc. and affiliates.
2//
3// This source code is licensed under the MIT license found in the
4// LICENSE file in the root directory of this source tree.
5
6use std::mem::swap;
7
8use crate::{
9    inflate_helpers::adjust_parameters_trailing_whitespace,
10    nodes::{
11        op::*,
12        statement::*,
13        traits::{Inflate, ParenthesizedDeflatedNode, ParenthesizedNode, Result, WithComma},
14        whitespace::ParenthesizableWhitespace,
15        Annotation, AssignEqual, AssignTargetExpression, BinaryOp, BooleanOp, Codegen,
16        CodegenState, Colon, Comma, CompOp, Dot, UnaryOp,
17    },
18    tokenizer::{
19        whitespace_parser::{parse_parenthesizable_whitespace, Config},
20        Token,
21    },
22};
23#[cfg(feature = "py")]
24use libcst_derive::TryIntoPy;
25use libcst_derive::{cst_node, Codegen, Inflate, ParenthesizedDeflatedNode, ParenthesizedNode};
26
27type TokenRef<'r, 'a> = &'r Token<'a>;
28
29#[cst_node(Default)]
30pub struct Parameters<'a> {
31    pub params: Vec<Param<'a>>,
32    pub star_arg: Option<StarArg<'a>>,
33    pub kwonly_params: Vec<Param<'a>>,
34    pub star_kwarg: Option<Param<'a>>,
35    pub posonly_params: Vec<Param<'a>>,
36    pub posonly_ind: Option<ParamSlash<'a>>,
37}
38
39impl<'a> Parameters<'a> {
40    pub fn is_empty(&self) -> bool {
41        self.params.is_empty()
42            && self.star_arg.is_none()
43            && self.kwonly_params.is_empty()
44            && self.star_kwarg.is_none()
45            && self.posonly_params.is_empty()
46            && self.posonly_ind.is_none()
47    }
48}
49
50impl<'r, 'a> DeflatedParameters<'r, 'a> {
51    pub fn is_empty(&self) -> bool {
52        self.params.is_empty()
53            && self.star_arg.is_none()
54            && self.kwonly_params.is_empty()
55            && self.star_kwarg.is_none()
56            && self.posonly_params.is_empty()
57            && self.posonly_ind.is_none()
58    }
59}
60
61impl<'r, 'a> Inflate<'a> for DeflatedParameters<'r, 'a> {
62    type Inflated = Parameters<'a>;
63    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
64        let posonly_params = self.posonly_params.inflate(config)?;
65        let posonly_ind = self.posonly_ind.inflate(config)?;
66        let params = self.params.inflate(config)?;
67        let star_arg = self.star_arg.inflate(config)?;
68        let kwonly_params = self.kwonly_params.inflate(config)?;
69        let star_kwarg = self.star_kwarg.inflate(config)?;
70        Ok(Self::Inflated {
71            params,
72            star_arg,
73            kwonly_params,
74            star_kwarg,
75            posonly_params,
76            posonly_ind,
77        })
78    }
79}
80
81#[cst_node(Inflate)]
82pub enum StarArg<'a> {
83    Star(Box<ParamStar<'a>>),
84    Param(Box<Param<'a>>),
85}
86
87impl<'a> Codegen<'a> for Parameters<'a> {
88    fn codegen(&self, state: &mut CodegenState<'a>) {
89        let params_after_kwonly = self.star_kwarg.is_some();
90        let params_after_regular = !self.kwonly_params.is_empty() || params_after_kwonly;
91        let params_after_posonly = !self.params.is_empty() || params_after_regular;
92        let star_included = self.star_arg.is_some() || !self.kwonly_params.is_empty();
93
94        for p in &self.posonly_params {
95            p.codegen(state, None, true);
96        }
97
98        match &self.posonly_ind {
99            Some(ind) => ind.codegen(state, params_after_posonly),
100            _ => {
101                if !self.posonly_params.is_empty() {
102                    if params_after_posonly {
103                        state.add_token("/, ");
104                    } else {
105                        state.add_token("/");
106                    }
107                }
108            }
109        }
110
111        let param_size = self.params.len();
112        for (i, p) in self.params.iter().enumerate() {
113            p.codegen(state, None, params_after_regular || i < param_size - 1);
114        }
115
116        let kwonly_size = self.kwonly_params.len();
117        match &self.star_arg {
118            None => {
119                if star_included {
120                    state.add_token("*, ")
121                }
122            }
123            Some(StarArg::Param(p)) => p.codegen(
124                state,
125                Some("*"),
126                kwonly_size > 0 || self.star_kwarg.is_some(),
127            ),
128            Some(StarArg::Star(s)) => s.codegen(state),
129        }
130
131        for (i, p) in self.kwonly_params.iter().enumerate() {
132            p.codegen(state, None, params_after_kwonly || i < kwonly_size - 1);
133        }
134
135        if let Some(star) = &self.star_kwarg {
136            star.codegen(state, Some("**"), false)
137        }
138    }
139}
140
141#[cst_node]
142pub struct ParamSlash<'a> {
143    pub comma: Option<Comma<'a>>,
144    pub whitespace_after: ParenthesizableWhitespace<'a>,
145
146    pub(crate) tok: TokenRef<'a>,
147}
148
149impl<'a> ParamSlash<'a> {
150    fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) {
151        state.add_token("/");
152        self.whitespace_after.codegen(state);
153        match (&self.comma, default_comma) {
154            (Some(comma), _) => comma.codegen(state),
155            (None, true) => state.add_token(", "),
156            _ => {}
157        }
158    }
159}
160
161impl<'r, 'a> Inflate<'a> for DeflatedParamSlash<'r, 'a> {
162    type Inflated = ParamSlash<'a>;
163    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
164        let whitespace_after =
165            parse_parenthesizable_whitespace(config, &mut self.tok.whitespace_after.borrow_mut())?;
166        let comma = self.comma.inflate(config)?;
167        Ok(Self::Inflated {
168            comma,
169            whitespace_after,
170        })
171    }
172}
173
174#[cst_node]
175pub struct ParamStar<'a> {
176    pub comma: Comma<'a>,
177}
178
179impl<'a> Codegen<'a> for ParamStar<'a> {
180    fn codegen(&self, state: &mut CodegenState<'a>) {
181        state.add_token("*");
182        self.comma.codegen(state);
183    }
184}
185
186impl<'r, 'a> Inflate<'a> for DeflatedParamStar<'r, 'a> {
187    type Inflated = ParamStar<'a>;
188    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
189        let comma = self.comma.inflate(config)?;
190        Ok(Self::Inflated { comma })
191    }
192}
193
194#[cst_node(ParenthesizedNode, Default)]
195pub struct Name<'a> {
196    pub value: &'a str,
197    pub lpar: Vec<LeftParen<'a>>,
198    pub rpar: Vec<RightParen<'a>>,
199}
200
201impl<'r, 'a> Inflate<'a> for DeflatedName<'r, 'a> {
202    type Inflated = Name<'a>;
203    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
204        let lpar = self.lpar.inflate(config)?;
205        let rpar = self.rpar.inflate(config)?;
206        Ok(Self::Inflated {
207            value: self.value,
208            lpar,
209            rpar,
210        })
211    }
212}
213
214impl<'a> Codegen<'a> for Name<'a> {
215    fn codegen(&self, state: &mut CodegenState<'a>) {
216        self.parenthesize(state, |state| {
217            state.add_token(self.value);
218        });
219    }
220}
221
222#[cst_node]
223pub struct Param<'a> {
224    pub name: Name<'a>,
225    pub annotation: Option<Annotation<'a>>,
226    pub equal: Option<AssignEqual<'a>>,
227    pub default: Option<Expression<'a>>,
228
229    pub comma: Option<Comma<'a>>,
230
231    pub star: Option<&'a str>,
232
233    pub whitespace_after_star: ParenthesizableWhitespace<'a>,
234    pub whitespace_after_param: ParenthesizableWhitespace<'a>,
235
236    pub(crate) star_tok: Option<TokenRef<'a>>,
237}
238
239impl<'r, 'a> Inflate<'a> for DeflatedParam<'r, 'a> {
240    type Inflated = Param<'a>;
241    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
242        let name = self.name.inflate(config)?;
243        let annotation = self.annotation.inflate(config)?;
244        let equal = self.equal.inflate(config)?;
245        let default = self.default.inflate(config)?;
246        let comma = self.comma.inflate(config)?;
247        let whitespace_after_star = if let Some(star_tok) = self.star_tok.as_mut() {
248            parse_parenthesizable_whitespace(config, &mut star_tok.whitespace_after.borrow_mut())?
249        } else {
250            Default::default()
251        };
252        let whitespace_after_param = Default::default(); // TODO
253        Ok(Self::Inflated {
254            name,
255            annotation,
256            equal,
257            default,
258            comma,
259            star: self.star,
260            whitespace_after_star,
261            whitespace_after_param,
262        })
263    }
264}
265
266impl<'r, 'a> Default for DeflatedParam<'r, 'a> {
267    fn default() -> Self {
268        Self {
269            name: Default::default(),
270            annotation: None,
271            equal: None,
272            default: None,
273            comma: None,
274            star: Some(""), // Note: this preserves a quirk of the pure python parser
275            star_tok: None,
276        }
277    }
278}
279
280impl<'a> Param<'a> {
281    fn codegen(
282        &self,
283        state: &mut CodegenState<'a>,
284        default_star: Option<&'a str>,
285        default_comma: bool,
286    ) {
287        match (self.star, default_star) {
288            (Some(star), _) => state.add_token(star),
289            (None, Some(star)) => state.add_token(star),
290            _ => {}
291        }
292        self.whitespace_after_star.codegen(state);
293        self.name.codegen(state);
294
295        if let Some(ann) = &self.annotation {
296            ann.codegen(state, ":");
297        }
298
299        match (&self.equal, &self.default) {
300            (Some(equal), Some(def)) => {
301                equal.codegen(state);
302                def.codegen(state);
303            }
304            (None, Some(def)) => {
305                state.add_token(" = ");
306                def.codegen(state);
307            }
308            _ => {}
309        }
310
311        match &self.comma {
312            Some(comma) => comma.codegen(state),
313            None if default_comma => state.add_token(", "),
314            _ => {}
315        }
316
317        self.whitespace_after_param.codegen(state);
318    }
319}
320
321#[cst_node]
322pub struct Arg<'a> {
323    pub value: Expression<'a>,
324    pub keyword: Option<Name<'a>>,
325    pub equal: Option<AssignEqual<'a>>,
326    pub comma: Option<Comma<'a>>,
327    pub star: &'a str,
328    pub whitespace_after_star: ParenthesizableWhitespace<'a>,
329    pub whitespace_after_arg: ParenthesizableWhitespace<'a>,
330
331    pub(crate) star_tok: Option<TokenRef<'a>>,
332}
333
334impl<'r, 'a> Inflate<'a> for DeflatedArg<'r, 'a> {
335    type Inflated = Arg<'a>;
336    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
337        let whitespace_after_star = if let Some(star_tok) = self.star_tok.as_mut() {
338            parse_parenthesizable_whitespace(config, &mut star_tok.whitespace_after.borrow_mut())?
339        } else {
340            Default::default()
341        };
342        let keyword = self.keyword.inflate(config)?;
343        let equal = self.equal.inflate(config)?;
344        let value = self.value.inflate(config)?;
345        let comma = self.comma.inflate(config)?;
346        // whitespace_after_arg is handled in Call
347        let whitespace_after_arg = Default::default();
348        Ok(Self::Inflated {
349            value,
350            keyword,
351            equal,
352            comma,
353            star: self.star,
354            whitespace_after_star,
355            whitespace_after_arg,
356        })
357    }
358}
359
360impl<'a> Arg<'a> {
361    pub fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) {
362        state.add_token(self.star);
363        self.whitespace_after_star.codegen(state);
364        if let Some(kw) = &self.keyword {
365            kw.codegen(state);
366        }
367        if let Some(eq) = &self.equal {
368            eq.codegen(state);
369        } else if self.keyword.is_some() {
370            state.add_token(" = ");
371        }
372        self.value.codegen(state);
373
374        if let Some(comma) = &self.comma {
375            comma.codegen(state);
376        } else if default_comma {
377            state.add_token(", ");
378        }
379
380        self.whitespace_after_arg.codegen(state);
381    }
382}
383
384impl<'r, 'a> WithComma<'r, 'a> for DeflatedArg<'r, 'a> {
385    fn with_comma(self, c: DeflatedComma<'r, 'a>) -> Self {
386        Self {
387            comma: Some(c),
388            ..self
389        }
390    }
391}
392
393#[cst_node]
394#[derive(Default)]
395pub struct LeftParen<'a> {
396    /// Any space that appears directly after this left parenthesis.
397    pub whitespace_after: ParenthesizableWhitespace<'a>,
398
399    pub(crate) lpar_tok: TokenRef<'a>,
400}
401
402impl<'a> Codegen<'a> for LeftParen<'a> {
403    fn codegen(&self, state: &mut CodegenState<'a>) {
404        state.add_token("(");
405        self.whitespace_after.codegen(state);
406    }
407}
408
409impl<'r, 'a> Inflate<'a> for DeflatedLeftParen<'r, 'a> {
410    type Inflated = LeftParen<'a>;
411    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
412        let whitespace_after = parse_parenthesizable_whitespace(
413            config,
414            &mut (*self.lpar_tok).whitespace_after.borrow_mut(),
415        )?;
416        Ok(Self::Inflated { whitespace_after })
417    }
418}
419
420#[cst_node]
421#[derive(Default)]
422pub struct RightParen<'a> {
423    /// Any space that appears directly before this right parenthesis.
424    pub whitespace_before: ParenthesizableWhitespace<'a>,
425
426    pub(crate) rpar_tok: TokenRef<'a>,
427}
428
429impl<'a> Codegen<'a> for RightParen<'a> {
430    fn codegen(&self, state: &mut CodegenState<'a>) {
431        self.whitespace_before.codegen(state);
432        state.add_token(")");
433    }
434}
435
436impl<'r, 'a> Inflate<'a> for DeflatedRightParen<'r, 'a> {
437    type Inflated = RightParen<'a>;
438    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
439        let whitespace_before = parse_parenthesizable_whitespace(
440            config,
441            &mut (*self.rpar_tok).whitespace_before.borrow_mut(),
442        )?;
443        Ok(Self::Inflated { whitespace_before })
444    }
445}
446
447#[cst_node(ParenthesizedNode, Codegen, Inflate)]
448pub enum Expression<'a> {
449    Name(Box<Name<'a>>),
450    Ellipsis(Box<Ellipsis<'a>>),
451    Integer(Box<Integer<'a>>),
452    Float(Box<Float<'a>>),
453    Imaginary(Box<Imaginary<'a>>),
454    Comparison(Box<Comparison<'a>>),
455    UnaryOperation(Box<UnaryOperation<'a>>),
456    BinaryOperation(Box<BinaryOperation<'a>>),
457    BooleanOperation(Box<BooleanOperation<'a>>),
458    Attribute(Box<Attribute<'a>>),
459    Tuple(Box<Tuple<'a>>),
460    Call(Box<Call<'a>>),
461    GeneratorExp(Box<GeneratorExp<'a>>),
462    ListComp(Box<ListComp<'a>>),
463    SetComp(Box<SetComp<'a>>),
464    DictComp(Box<DictComp<'a>>),
465    List(Box<List<'a>>),
466    Set(Box<Set<'a>>),
467    Dict(Box<Dict<'a>>),
468    Subscript(Box<Subscript<'a>>),
469    StarredElement(Box<StarredElement<'a>>),
470    IfExp(Box<IfExp<'a>>),
471    Lambda(Box<Lambda<'a>>),
472    Yield(Box<Yield<'a>>),
473    Await(Box<Await<'a>>),
474    SimpleString(Box<SimpleString<'a>>),
475    ConcatenatedString(Box<ConcatenatedString<'a>>),
476    FormattedString(Box<FormattedString<'a>>),
477    TemplatedString(Box<TemplatedString<'a>>),
478    NamedExpr(Box<NamedExpr<'a>>),
479}
480
481#[cst_node(ParenthesizedNode)]
482pub struct Ellipsis<'a> {
483    pub lpar: Vec<LeftParen<'a>>,
484    pub rpar: Vec<RightParen<'a>>,
485}
486
487impl<'a> Codegen<'a> for Ellipsis<'a> {
488    fn codegen(&self, state: &mut CodegenState<'a>) {
489        self.parenthesize(state, |state| {
490            state.add_token("...");
491        })
492    }
493}
494impl<'r, 'a> Inflate<'a> for DeflatedEllipsis<'r, 'a> {
495    type Inflated = Ellipsis<'a>;
496    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
497        let lpar = self.lpar.inflate(config)?;
498        let rpar = self.rpar.inflate(config)?;
499        Ok(Self::Inflated { lpar, rpar })
500    }
501}
502
503#[cst_node(ParenthesizedNode)]
504pub struct Integer<'a> {
505    /// A string representation of the integer, such as ``"100000"`` or
506    /// ``"100_000"``.
507    pub value: &'a str,
508    pub lpar: Vec<LeftParen<'a>>,
509    pub rpar: Vec<RightParen<'a>>,
510}
511
512impl<'a> Codegen<'a> for Integer<'a> {
513    fn codegen(&self, state: &mut CodegenState<'a>) {
514        self.parenthesize(state, |state| {
515            state.add_token(self.value);
516        })
517    }
518}
519
520impl<'r, 'a> Inflate<'a> for DeflatedInteger<'r, 'a> {
521    type Inflated = Integer<'a>;
522    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
523        let lpar = self.lpar.inflate(config)?;
524        let rpar = self.rpar.inflate(config)?;
525        Ok(Self::Inflated {
526            value: self.value,
527            lpar,
528            rpar,
529        })
530    }
531}
532
533#[cst_node(ParenthesizedNode)]
534pub struct Float<'a> {
535    /// A string representation of the floating point number, such as ```"0.05"``,
536    /// ``".050"``, or ``"5e-2"``.
537    pub value: &'a str,
538    pub lpar: Vec<LeftParen<'a>>,
539    pub rpar: Vec<RightParen<'a>>,
540}
541
542impl<'a> Codegen<'a> for Float<'a> {
543    fn codegen(&self, state: &mut CodegenState<'a>) {
544        self.parenthesize(state, |state| {
545            state.add_token(self.value);
546        })
547    }
548}
549
550impl<'r, 'a> Inflate<'a> for DeflatedFloat<'r, 'a> {
551    type Inflated = Float<'a>;
552    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
553        let lpar = self.lpar.inflate(config)?;
554        let rpar = self.rpar.inflate(config)?;
555        Ok(Self::Inflated {
556            value: self.value,
557            lpar,
558            rpar,
559        })
560    }
561}
562
563#[cst_node(ParenthesizedNode)]
564pub struct Imaginary<'a> {
565    /// A string representation of the complex number, such as ``"2j"``
566    pub value: &'a str,
567    pub lpar: Vec<LeftParen<'a>>,
568    pub rpar: Vec<RightParen<'a>>,
569}
570
571impl<'a> Codegen<'a> for Imaginary<'a> {
572    fn codegen(&self, state: &mut CodegenState<'a>) {
573        self.parenthesize(state, |state| {
574            state.add_token(self.value);
575        })
576    }
577}
578
579impl<'r, 'a> Inflate<'a> for DeflatedImaginary<'r, 'a> {
580    type Inflated = Imaginary<'a>;
581    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
582        let lpar = self.lpar.inflate(config)?;
583        let rpar = self.rpar.inflate(config)?;
584        Ok(Self::Inflated {
585            value: self.value,
586            lpar,
587            rpar,
588        })
589    }
590}
591
592#[cst_node(ParenthesizedNode)]
593pub struct Comparison<'a> {
594    pub left: Box<Expression<'a>>,
595    pub comparisons: Vec<ComparisonTarget<'a>>,
596    pub lpar: Vec<LeftParen<'a>>,
597    pub rpar: Vec<RightParen<'a>>,
598}
599
600impl<'a> Codegen<'a> for Comparison<'a> {
601    fn codegen(&self, state: &mut CodegenState<'a>) {
602        self.parenthesize(state, |state| {
603            self.left.codegen(state);
604            for comp in &self.comparisons {
605                comp.codegen(state);
606            }
607        })
608    }
609}
610impl<'r, 'a> Inflate<'a> for DeflatedComparison<'r, 'a> {
611    type Inflated = Comparison<'a>;
612    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
613        let lpar = self.lpar.inflate(config)?;
614        let left = self.left.inflate(config)?;
615        let comparisons = self.comparisons.inflate(config)?;
616        let rpar = self.rpar.inflate(config)?;
617        Ok(Self::Inflated {
618            left,
619            comparisons,
620            lpar,
621            rpar,
622        })
623    }
624}
625
626#[cst_node(ParenthesizedNode)]
627pub struct UnaryOperation<'a> {
628    pub operator: UnaryOp<'a>,
629    pub expression: Box<Expression<'a>>,
630    pub lpar: Vec<LeftParen<'a>>,
631    pub rpar: Vec<RightParen<'a>>,
632}
633
634impl<'a> Codegen<'a> for UnaryOperation<'a> {
635    fn codegen(&self, state: &mut CodegenState<'a>) {
636        self.parenthesize(state, |state| {
637            self.operator.codegen(state);
638            self.expression.codegen(state);
639        })
640    }
641}
642
643impl<'r, 'a> Inflate<'a> for DeflatedUnaryOperation<'r, 'a> {
644    type Inflated = UnaryOperation<'a>;
645    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
646        let lpar = self.lpar.inflate(config)?;
647        let operator = self.operator.inflate(config)?;
648        let expression = self.expression.inflate(config)?;
649        let rpar = self.rpar.inflate(config)?;
650        Ok(Self::Inflated {
651            operator,
652            expression,
653            lpar,
654            rpar,
655        })
656    }
657}
658
659#[cst_node(ParenthesizedNode)]
660pub struct BinaryOperation<'a> {
661    pub left: Box<Expression<'a>>,
662    pub operator: BinaryOp<'a>,
663    pub right: Box<Expression<'a>>,
664    pub lpar: Vec<LeftParen<'a>>,
665    pub rpar: Vec<RightParen<'a>>,
666}
667
668impl<'a> Codegen<'a> for BinaryOperation<'a> {
669    fn codegen(&self, state: &mut CodegenState<'a>) {
670        self.parenthesize(state, |state| {
671            self.left.codegen(state);
672            self.operator.codegen(state);
673            self.right.codegen(state);
674        })
675    }
676}
677
678impl<'r, 'a> Inflate<'a> for DeflatedBinaryOperation<'r, 'a> {
679    type Inflated = BinaryOperation<'a>;
680    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
681        let lpar = self.lpar.inflate(config)?;
682        let left = self.left.inflate(config)?;
683        let operator = self.operator.inflate(config)?;
684        let right = self.right.inflate(config)?;
685        let rpar = self.rpar.inflate(config)?;
686        Ok(Self::Inflated {
687            left,
688            operator,
689            right,
690            lpar,
691            rpar,
692        })
693    }
694}
695
696#[cst_node(ParenthesizedNode)]
697pub struct BooleanOperation<'a> {
698    pub left: Box<Expression<'a>>,
699    pub operator: BooleanOp<'a>,
700    pub right: Box<Expression<'a>>,
701    pub lpar: Vec<LeftParen<'a>>,
702    pub rpar: Vec<RightParen<'a>>,
703}
704
705impl<'a> Codegen<'a> for BooleanOperation<'a> {
706    fn codegen(&self, state: &mut CodegenState<'a>) {
707        self.parenthesize(state, |state| {
708            self.left.codegen(state);
709            self.operator.codegen(state);
710            self.right.codegen(state);
711        })
712    }
713}
714
715impl<'r, 'a> Inflate<'a> for DeflatedBooleanOperation<'r, 'a> {
716    type Inflated = BooleanOperation<'a>;
717    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
718        let lpar = self.lpar.inflate(config)?;
719        let left = self.left.inflate(config)?;
720        let operator = self.operator.inflate(config)?;
721        let right = self.right.inflate(config)?;
722        let rpar = self.rpar.inflate(config)?;
723        Ok(Self::Inflated {
724            left,
725            operator,
726            right,
727            lpar,
728            rpar,
729        })
730    }
731}
732
733#[cst_node(ParenthesizedNode)]
734pub struct Call<'a> {
735    pub func: Box<Expression<'a>>,
736    pub args: Vec<Arg<'a>>,
737    pub lpar: Vec<LeftParen<'a>>,
738    pub rpar: Vec<RightParen<'a>>,
739    pub whitespace_after_func: ParenthesizableWhitespace<'a>,
740    pub whitespace_before_args: ParenthesizableWhitespace<'a>,
741
742    pub(crate) lpar_tok: TokenRef<'a>,
743    pub(crate) rpar_tok: TokenRef<'a>,
744}
745
746impl<'r, 'a> Inflate<'a> for DeflatedCall<'r, 'a> {
747    type Inflated = Call<'a>;
748    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
749        let lpar = self.lpar.inflate(config)?;
750        let func = self.func.inflate(config)?;
751        let whitespace_after_func = parse_parenthesizable_whitespace(
752            config,
753            &mut (*self.lpar_tok).whitespace_before.borrow_mut(),
754        )?;
755        let whitespace_before_args = parse_parenthesizable_whitespace(
756            config,
757            &mut (*self.lpar_tok).whitespace_after.borrow_mut(),
758        )?;
759        let mut args = self.args.inflate(config)?;
760
761        if let Some(arg) = args.last_mut() {
762            if arg.comma.is_none() {
763                arg.whitespace_after_arg = parse_parenthesizable_whitespace(
764                    config,
765                    &mut (*self.rpar_tok).whitespace_before.borrow_mut(),
766                )?;
767            }
768        }
769        let rpar = self.rpar.inflate(config)?;
770
771        Ok(Self::Inflated {
772            func,
773            args,
774            lpar,
775            rpar,
776            whitespace_after_func,
777            whitespace_before_args,
778        })
779    }
780}
781
782impl<'a> Codegen<'a> for Call<'a> {
783    fn codegen(&self, state: &mut CodegenState<'a>) {
784        self.parenthesize(state, |state| {
785            self.func.codegen(state);
786            self.whitespace_after_func.codegen(state);
787            state.add_token("(");
788            self.whitespace_before_args.codegen(state);
789            let arg_len = self.args.len();
790            for (i, arg) in self.args.iter().enumerate() {
791                arg.codegen(state, i + 1 < arg_len);
792            }
793            state.add_token(")");
794        })
795    }
796}
797
798#[cst_node(ParenthesizedNode)]
799pub struct Attribute<'a> {
800    pub value: Box<Expression<'a>>,
801    pub attr: Name<'a>,
802    pub dot: Dot<'a>,
803    pub lpar: Vec<LeftParen<'a>>,
804    pub rpar: Vec<RightParen<'a>>,
805}
806
807impl<'r, 'a> Inflate<'a> for DeflatedAttribute<'r, 'a> {
808    type Inflated = Attribute<'a>;
809    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
810        let lpar = self.lpar.inflate(config)?;
811        let value = self.value.inflate(config)?;
812        let dot = self.dot.inflate(config)?;
813        let attr = self.attr.inflate(config)?;
814        let rpar = self.rpar.inflate(config)?;
815        Ok(Self::Inflated {
816            value,
817            attr,
818            dot,
819            lpar,
820            rpar,
821        })
822    }
823}
824
825impl<'a> Codegen<'a> for Attribute<'a> {
826    fn codegen(&self, state: &mut CodegenState<'a>) {
827        self.parenthesize(state, |state| {
828            self.value.codegen(state);
829            self.dot.codegen(state);
830            self.attr.codegen(state);
831        })
832    }
833}
834
835#[cst_node(Codegen, Inflate)]
836pub enum NameOrAttribute<'a> {
837    N(Box<Name<'a>>),
838    A(Box<Attribute<'a>>),
839}
840
841impl<'r, 'a> std::convert::From<DeflatedNameOrAttribute<'r, 'a>> for DeflatedExpression<'r, 'a> {
842    fn from(x: DeflatedNameOrAttribute<'r, 'a>) -> Self {
843        match x {
844            DeflatedNameOrAttribute::N(n) => Self::Name(n),
845            DeflatedNameOrAttribute::A(a) => Self::Attribute(a),
846        }
847    }
848}
849
850#[cst_node]
851pub struct ComparisonTarget<'a> {
852    pub operator: CompOp<'a>,
853    pub comparator: Expression<'a>,
854}
855
856impl<'a> Codegen<'a> for ComparisonTarget<'a> {
857    fn codegen(&self, state: &mut CodegenState<'a>) {
858        self.operator.codegen(state);
859        self.comparator.codegen(state);
860    }
861}
862
863impl<'r, 'a> Inflate<'a> for DeflatedComparisonTarget<'r, 'a> {
864    type Inflated = ComparisonTarget<'a>;
865    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
866        let operator = self.operator.inflate(config)?;
867        let comparator = self.comparator.inflate(config)?;
868        Ok(Self::Inflated {
869            operator,
870            comparator,
871        })
872    }
873}
874
875#[cst_node(ParenthesizedNode)]
876pub struct StarredElement<'a> {
877    pub value: Box<Expression<'a>>,
878    pub comma: Option<Comma<'a>>,
879    pub lpar: Vec<LeftParen<'a>>,
880    pub rpar: Vec<RightParen<'a>>,
881    pub whitespace_before_value: ParenthesizableWhitespace<'a>,
882
883    pub(crate) star_tok: TokenRef<'a>,
884}
885
886impl<'r, 'a> DeflatedStarredElement<'r, 'a> {
887    pub fn inflate_element(self, config: &Config<'a>, is_last: bool) -> Result<StarredElement<'a>> {
888        let lpar = self.lpar.inflate(config)?;
889        let whitespace_before_value = parse_parenthesizable_whitespace(
890            config,
891            &mut (*self.star_tok).whitespace_after.borrow_mut(),
892        )?;
893        let value = self.value.inflate(config)?;
894        let rpar = self.rpar.inflate(config)?;
895        let comma = if is_last {
896            self.comma.map(|c| c.inflate_before(config)).transpose()
897        } else {
898            self.comma.inflate(config)
899        }?;
900        Ok(StarredElement {
901            value,
902            comma,
903            lpar,
904            rpar,
905            whitespace_before_value,
906        })
907    }
908}
909
910impl<'r, 'a> Inflate<'a> for DeflatedStarredElement<'r, 'a> {
911    type Inflated = StarredElement<'a>;
912    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
913        self.inflate_element(config, false)
914    }
915}
916
917impl<'a> Codegen<'a> for StarredElement<'a> {
918    fn codegen(&self, state: &mut CodegenState<'a>) {
919        self.parenthesize(state, |state| {
920            state.add_token("*");
921            self.whitespace_before_value.codegen(state);
922            self.value.codegen(state);
923        });
924        if let Some(comma) = &self.comma {
925            comma.codegen(state);
926        }
927    }
928}
929
930#[allow(clippy::large_enum_variant)]
931#[cst_node(NoIntoPy)]
932pub enum Element<'a> {
933    Simple {
934        value: Expression<'a>,
935        comma: Option<Comma<'a>>,
936    },
937    Starred(Box<StarredElement<'a>>),
938}
939
940impl<'a> Element<'a> {
941    pub fn codegen(
942        &self,
943        state: &mut CodegenState<'a>,
944        default_comma: bool,
945        default_comma_whitespace: bool,
946    ) {
947        match self {
948            Self::Simple { value, comma } => {
949                value.codegen(state);
950                if let Some(comma) = comma {
951                    comma.codegen(state)
952                }
953            }
954            Self::Starred(s) => s.codegen(state),
955        }
956        let maybe_comma = match self {
957            Self::Simple { comma, .. } => comma,
958            Self::Starred(s) => &s.comma,
959        };
960        if maybe_comma.is_none() && default_comma {
961            state.add_token(if default_comma_whitespace { ", " } else { "," });
962        }
963    }
964}
965impl<'r, 'a> DeflatedElement<'r, 'a> {
966    pub fn inflate_element(self, config: &Config<'a>, is_last: bool) -> Result<Element<'a>> {
967        Ok(match self {
968            Self::Starred(s) => Element::Starred(Box::new(s.inflate_element(config, is_last)?)),
969            Self::Simple { value, comma } => Element::Simple {
970                value: value.inflate(config)?,
971                comma: if is_last {
972                    comma.map(|c| c.inflate_before(config)).transpose()?
973                } else {
974                    comma.inflate(config)?
975                },
976            },
977        })
978    }
979}
980
981impl<'r, 'a> WithComma<'r, 'a> for DeflatedElement<'r, 'a> {
982    fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
983        let comma = Some(comma);
984        match self {
985            Self::Simple { value, .. } => Self::Simple { comma, value },
986            Self::Starred(mut s) => {
987                s.comma = comma;
988                Self::Starred(s)
989            }
990        }
991    }
992}
993impl<'r, 'a> std::convert::From<DeflatedExpression<'r, 'a>> for DeflatedElement<'r, 'a> {
994    fn from(e: DeflatedExpression<'r, 'a>) -> Self {
995        match e {
996            DeflatedExpression::StarredElement(e) => Self::Starred(e),
997            value => Self::Simple { value, comma: None },
998        }
999    }
1000}
1001
1002#[cst_node(ParenthesizedNode, Default)]
1003pub struct Tuple<'a> {
1004    pub elements: Vec<Element<'a>>,
1005    pub lpar: Vec<LeftParen<'a>>,
1006    pub rpar: Vec<RightParen<'a>>,
1007}
1008
1009impl<'r, 'a> Inflate<'a> for DeflatedTuple<'r, 'a> {
1010    type Inflated = Tuple<'a>;
1011    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1012        let lpar = self.lpar.inflate(config)?;
1013        let len = self.elements.len();
1014        let elements = self
1015            .elements
1016            .into_iter()
1017            .enumerate()
1018            .map(|(idx, el)| el.inflate_element(config, idx + 1 == len))
1019            .collect::<Result<Vec<_>>>()?;
1020        let rpar = self.rpar.inflate(config)?;
1021        Ok(Self::Inflated {
1022            elements,
1023            lpar,
1024            rpar,
1025        })
1026    }
1027}
1028
1029impl<'a> Codegen<'a> for Tuple<'a> {
1030    fn codegen(&self, state: &mut CodegenState<'a>) {
1031        self.parenthesize(state, |state| {
1032            let len = self.elements.len();
1033            if len == 1 {
1034                self.elements.first().unwrap().codegen(state, true, false);
1035            } else {
1036                for (idx, el) in self.elements.iter().enumerate() {
1037                    el.codegen(state, idx < len - 1, true);
1038                }
1039            }
1040        });
1041    }
1042}
1043
1044#[cst_node(ParenthesizedNode)]
1045pub struct GeneratorExp<'a> {
1046    pub elt: Box<Expression<'a>>,
1047    pub for_in: Box<CompFor<'a>>,
1048    pub lpar: Vec<LeftParen<'a>>,
1049    pub rpar: Vec<RightParen<'a>>,
1050}
1051
1052impl<'a> Codegen<'a> for GeneratorExp<'a> {
1053    fn codegen(&self, state: &mut CodegenState<'a>) {
1054        self.parenthesize(state, |state| {
1055            self.elt.codegen(state);
1056            self.for_in.codegen(state);
1057        })
1058    }
1059}
1060
1061impl<'r, 'a> Inflate<'a> for DeflatedGeneratorExp<'r, 'a> {
1062    type Inflated = GeneratorExp<'a>;
1063    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1064        let lpar = self.lpar.inflate(config)?;
1065        let elt = self.elt.inflate(config)?;
1066        let for_in = self.for_in.inflate(config)?;
1067        let rpar = self.rpar.inflate(config)?;
1068        Ok(Self::Inflated {
1069            elt,
1070            for_in,
1071            lpar,
1072            rpar,
1073        })
1074    }
1075}
1076
1077#[cst_node(ParenthesizedNode)]
1078pub struct ListComp<'a> {
1079    pub elt: Box<Expression<'a>>,
1080    pub for_in: Box<CompFor<'a>>,
1081    pub lbracket: LeftSquareBracket<'a>,
1082    pub rbracket: RightSquareBracket<'a>,
1083    pub lpar: Vec<LeftParen<'a>>,
1084    pub rpar: Vec<RightParen<'a>>,
1085}
1086
1087impl<'a> Codegen<'a> for ListComp<'a> {
1088    fn codegen(&self, state: &mut CodegenState<'a>) {
1089        self.parenthesize(state, |state| {
1090            self.lbracket.codegen(state);
1091            self.elt.codegen(state);
1092            self.for_in.codegen(state);
1093            self.rbracket.codegen(state);
1094        })
1095    }
1096}
1097
1098impl<'r, 'a> Inflate<'a> for DeflatedListComp<'r, 'a> {
1099    type Inflated = ListComp<'a>;
1100    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1101        let lpar = self.lpar.inflate(config)?;
1102        let lbracket = self.lbracket.inflate(config)?;
1103        let elt = self.elt.inflate(config)?;
1104        let for_in = self.for_in.inflate(config)?;
1105        let rbracket = self.rbracket.inflate(config)?;
1106        let rpar = self.rpar.inflate(config)?;
1107        Ok(Self::Inflated {
1108            elt,
1109            for_in,
1110            lbracket,
1111            rbracket,
1112            lpar,
1113            rpar,
1114        })
1115    }
1116}
1117
1118#[cst_node]
1119#[derive(Default)]
1120pub struct LeftSquareBracket<'a> {
1121    pub whitespace_after: ParenthesizableWhitespace<'a>,
1122    pub(crate) tok: TokenRef<'a>,
1123}
1124
1125impl<'a> Codegen<'a> for LeftSquareBracket<'a> {
1126    fn codegen(&self, state: &mut CodegenState<'a>) {
1127        state.add_token("[");
1128        self.whitespace_after.codegen(state);
1129    }
1130}
1131
1132impl<'r, 'a> Inflate<'a> for DeflatedLeftSquareBracket<'r, 'a> {
1133    type Inflated = LeftSquareBracket<'a>;
1134    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1135        let whitespace_after = parse_parenthesizable_whitespace(
1136            config,
1137            &mut (*self.tok).whitespace_after.borrow_mut(),
1138        )?;
1139        Ok(Self::Inflated { whitespace_after })
1140    }
1141}
1142
1143#[cst_node]
1144#[derive(Default)]
1145pub struct RightSquareBracket<'a> {
1146    pub whitespace_before: ParenthesizableWhitespace<'a>,
1147    pub(crate) tok: TokenRef<'a>,
1148}
1149
1150impl<'a> Codegen<'a> for RightSquareBracket<'a> {
1151    fn codegen(&self, state: &mut CodegenState<'a>) {
1152        self.whitespace_before.codegen(state);
1153        state.add_token("]");
1154    }
1155}
1156
1157impl<'r, 'a> Inflate<'a> for DeflatedRightSquareBracket<'r, 'a> {
1158    type Inflated = RightSquareBracket<'a>;
1159    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1160        let whitespace_before = parse_parenthesizable_whitespace(
1161            config,
1162            &mut (*self.tok).whitespace_before.borrow_mut(),
1163        )?;
1164        Ok(Self::Inflated { whitespace_before })
1165    }
1166}
1167
1168#[cst_node(ParenthesizedNode)]
1169pub struct SetComp<'a> {
1170    pub elt: Box<Expression<'a>>,
1171    pub for_in: Box<CompFor<'a>>,
1172    pub lbrace: LeftCurlyBrace<'a>,
1173    pub rbrace: RightCurlyBrace<'a>,
1174    pub lpar: Vec<LeftParen<'a>>,
1175    pub rpar: Vec<RightParen<'a>>,
1176}
1177
1178impl<'r, 'a> Inflate<'a> for DeflatedSetComp<'r, 'a> {
1179    type Inflated = SetComp<'a>;
1180    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1181        let lpar = self.lpar.inflate(config)?;
1182        let lbrace = self.lbrace.inflate(config)?;
1183        let elt = self.elt.inflate(config)?;
1184        let for_in = self.for_in.inflate(config)?;
1185        let rbrace = self.rbrace.inflate(config)?;
1186        let rpar = self.rpar.inflate(config)?;
1187        Ok(Self::Inflated {
1188            elt,
1189            for_in,
1190            lbrace,
1191            rbrace,
1192            lpar,
1193            rpar,
1194        })
1195    }
1196}
1197
1198impl<'a> Codegen<'a> for SetComp<'a> {
1199    fn codegen(&self, state: &mut CodegenState<'a>) {
1200        self.parenthesize(state, |state| {
1201            self.lbrace.codegen(state);
1202            self.elt.codegen(state);
1203            self.for_in.codegen(state);
1204            self.rbrace.codegen(state);
1205        })
1206    }
1207}
1208
1209#[cst_node(ParenthesizedNode)]
1210pub struct DictComp<'a> {
1211    pub key: Box<Expression<'a>>,
1212    pub value: Box<Expression<'a>>,
1213    pub for_in: Box<CompFor<'a>>,
1214    pub lbrace: LeftCurlyBrace<'a>,
1215    pub rbrace: RightCurlyBrace<'a>,
1216    pub lpar: Vec<LeftParen<'a>>,
1217    pub rpar: Vec<RightParen<'a>>,
1218    pub whitespace_before_colon: ParenthesizableWhitespace<'a>,
1219    pub whitespace_after_colon: ParenthesizableWhitespace<'a>,
1220
1221    pub(crate) colon_tok: TokenRef<'a>,
1222}
1223
1224impl<'r, 'a> Inflate<'a> for DeflatedDictComp<'r, 'a> {
1225    type Inflated = DictComp<'a>;
1226    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1227        let lpar = self.lpar.inflate(config)?;
1228        let lbrace = self.lbrace.inflate(config)?;
1229        let key = self.key.inflate(config)?;
1230        let whitespace_before_colon = parse_parenthesizable_whitespace(
1231            config,
1232            &mut (*self.colon_tok).whitespace_before.borrow_mut(),
1233        )?;
1234        let whitespace_after_colon = parse_parenthesizable_whitespace(
1235            config,
1236            &mut (*self.colon_tok).whitespace_after.borrow_mut(),
1237        )?;
1238        let value = self.value.inflate(config)?;
1239        let for_in = self.for_in.inflate(config)?;
1240        let rbrace = self.rbrace.inflate(config)?;
1241        let rpar = self.rpar.inflate(config)?;
1242        Ok(Self::Inflated {
1243            key,
1244            value,
1245            for_in,
1246            lbrace,
1247            rbrace,
1248            lpar,
1249            rpar,
1250            whitespace_before_colon,
1251            whitespace_after_colon,
1252        })
1253    }
1254}
1255
1256impl<'a> Codegen<'a> for DictComp<'a> {
1257    fn codegen(&self, state: &mut CodegenState<'a>) {
1258        self.parenthesize(state, |state| {
1259            self.lbrace.codegen(state);
1260            self.key.codegen(state);
1261            self.whitespace_before_colon.codegen(state);
1262            state.add_token(":");
1263            self.whitespace_after_colon.codegen(state);
1264            self.value.codegen(state);
1265            self.for_in.codegen(state);
1266            self.rbrace.codegen(state);
1267        })
1268    }
1269}
1270
1271#[cst_node]
1272pub struct LeftCurlyBrace<'a> {
1273    pub whitespace_after: ParenthesizableWhitespace<'a>,
1274    pub(crate) tok: TokenRef<'a>,
1275}
1276
1277impl<'a> Default for LeftCurlyBrace<'a> {
1278    fn default() -> Self {
1279        Self {
1280            whitespace_after: Default::default(),
1281        }
1282    }
1283}
1284
1285impl<'r, 'a> Inflate<'a> for DeflatedLeftCurlyBrace<'r, 'a> {
1286    type Inflated = LeftCurlyBrace<'a>;
1287    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1288        let whitespace_after = parse_parenthesizable_whitespace(
1289            config,
1290            &mut (*self.tok).whitespace_after.borrow_mut(),
1291        )?;
1292        Ok(Self::Inflated { whitespace_after })
1293    }
1294}
1295
1296impl<'a> Codegen<'a> for LeftCurlyBrace<'a> {
1297    fn codegen(&self, state: &mut CodegenState<'a>) {
1298        state.add_token("{");
1299        self.whitespace_after.codegen(state);
1300    }
1301}
1302
1303#[cst_node]
1304pub struct RightCurlyBrace<'a> {
1305    pub whitespace_before: ParenthesizableWhitespace<'a>,
1306    pub(crate) tok: TokenRef<'a>,
1307}
1308
1309impl<'a> Default for RightCurlyBrace<'a> {
1310    fn default() -> Self {
1311        Self {
1312            whitespace_before: Default::default(),
1313        }
1314    }
1315}
1316
1317impl<'r, 'a> Inflate<'a> for DeflatedRightCurlyBrace<'r, 'a> {
1318    type Inflated = RightCurlyBrace<'a>;
1319    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1320        let whitespace_before = parse_parenthesizable_whitespace(
1321            config,
1322            &mut (*self.tok).whitespace_before.borrow_mut(),
1323        )?;
1324        Ok(Self::Inflated { whitespace_before })
1325    }
1326}
1327
1328impl<'a> Codegen<'a> for RightCurlyBrace<'a> {
1329    fn codegen(&self, state: &mut CodegenState<'a>) {
1330        self.whitespace_before.codegen(state);
1331        state.add_token("}");
1332    }
1333}
1334
1335#[cst_node]
1336pub struct CompFor<'a> {
1337    pub target: AssignTargetExpression<'a>,
1338    pub iter: Expression<'a>,
1339    pub ifs: Vec<CompIf<'a>>,
1340    pub inner_for_in: Option<Box<CompFor<'a>>>,
1341    pub asynchronous: Option<Asynchronous<'a>>,
1342    pub whitespace_before: ParenthesizableWhitespace<'a>,
1343    pub whitespace_after_for: ParenthesizableWhitespace<'a>,
1344    pub whitespace_before_in: ParenthesizableWhitespace<'a>,
1345    pub whitespace_after_in: ParenthesizableWhitespace<'a>,
1346
1347    pub(crate) async_tok: Option<TokenRef<'a>>,
1348    pub(crate) for_tok: TokenRef<'a>,
1349    pub(crate) in_tok: TokenRef<'a>,
1350}
1351
1352impl<'a> Codegen<'a> for CompFor<'a> {
1353    fn codegen(&self, state: &mut CodegenState<'a>) {
1354        self.whitespace_before.codegen(state);
1355        if let Some(asynchronous) = &self.asynchronous {
1356            asynchronous.codegen(state);
1357        }
1358        state.add_token("for");
1359        self.whitespace_after_for.codegen(state);
1360        self.target.codegen(state);
1361        self.whitespace_before_in.codegen(state);
1362        state.add_token("in");
1363        self.whitespace_after_in.codegen(state);
1364        self.iter.codegen(state);
1365        for if_ in &self.ifs {
1366            if_.codegen(state);
1367        }
1368        if let Some(inner) = &self.inner_for_in {
1369            inner.codegen(state);
1370        }
1371    }
1372}
1373
1374impl<'r, 'a> Inflate<'a> for DeflatedCompFor<'r, 'a> {
1375    type Inflated = CompFor<'a>;
1376    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
1377        let mut whitespace_before = parse_parenthesizable_whitespace(
1378            config,
1379            &mut (*self.for_tok).whitespace_before.borrow_mut(),
1380        )?;
1381        let asynchronous = if let Some(asy_tok) = self.async_tok.as_mut() {
1382            // If there is an async keyword, the start of the CompFor expression is
1383            // considered to be this keyword, so whitespace_before needs to adjust but
1384            // Asynchronous will own the whitespace before the for token.
1385            let mut asy_whitespace_after = parse_parenthesizable_whitespace(
1386                config,
1387                &mut asy_tok.whitespace_before.borrow_mut(),
1388            )?;
1389            swap(&mut asy_whitespace_after, &mut whitespace_before);
1390            Some(Asynchronous {
1391                whitespace_after: asy_whitespace_after,
1392            })
1393        } else {
1394            None
1395        };
1396        let whitespace_after_for = parse_parenthesizable_whitespace(
1397            config,
1398            &mut (*self.for_tok).whitespace_after.borrow_mut(),
1399        )?;
1400        let target = self.target.inflate(config)?;
1401        let whitespace_before_in = parse_parenthesizable_whitespace(
1402            config,
1403            &mut (*self.in_tok).whitespace_before.borrow_mut(),
1404        )?;
1405        let whitespace_after_in = parse_parenthesizable_whitespace(
1406            config,
1407            &mut (*self.in_tok).whitespace_after.borrow_mut(),
1408        )?;
1409        let iter = self.iter.inflate(config)?;
1410        let ifs = self.ifs.inflate(config)?;
1411        let inner_for_in = self.inner_for_in.inflate(config)?;
1412        Ok(Self::Inflated {
1413            target,
1414            iter,
1415            ifs,
1416            inner_for_in,
1417            asynchronous,
1418            whitespace_before,
1419            whitespace_after_for,
1420            whitespace_before_in,
1421            whitespace_after_in,
1422        })
1423    }
1424}
1425
1426#[cst_node]
1427pub struct Asynchronous<'a> {
1428    pub whitespace_after: ParenthesizableWhitespace<'a>,
1429}
1430
1431impl<'a> Codegen<'a> for Asynchronous<'a> {
1432    fn codegen(&self, state: &mut CodegenState<'a>) {
1433        state.add_token("async");
1434        self.whitespace_after.codegen(state);
1435    }
1436}
1437
1438pub(crate) fn make_async<'r, 'a>() -> DeflatedAsynchronous<'r, 'a> {
1439    DeflatedAsynchronous {
1440        _phantom: Default::default(),
1441    }
1442}
1443
1444#[cst_node]
1445pub struct CompIf<'a> {
1446    pub test: Expression<'a>,
1447    pub whitespace_before: ParenthesizableWhitespace<'a>,
1448    pub whitespace_before_test: ParenthesizableWhitespace<'a>,
1449
1450    pub(crate) if_tok: TokenRef<'a>,
1451}
1452
1453impl<'a> Codegen<'a> for CompIf<'a> {
1454    fn codegen(&self, state: &mut CodegenState<'a>) {
1455        self.whitespace_before.codegen(state);
1456        state.add_token("if");
1457        self.whitespace_before_test.codegen(state);
1458        self.test.codegen(state);
1459    }
1460}
1461
1462impl<'r, 'a> Inflate<'a> for DeflatedCompIf<'r, 'a> {
1463    type Inflated = CompIf<'a>;
1464    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1465        let whitespace_before = parse_parenthesizable_whitespace(
1466            config,
1467            &mut (*self.if_tok).whitespace_before.borrow_mut(),
1468        )?;
1469        let whitespace_before_test = parse_parenthesizable_whitespace(
1470            config,
1471            &mut (*self.if_tok).whitespace_after.borrow_mut(),
1472        )?;
1473        let test = self.test.inflate(config)?;
1474        Ok(Self::Inflated {
1475            test,
1476            whitespace_before,
1477            whitespace_before_test,
1478        })
1479    }
1480}
1481
1482#[cst_node(ParenthesizedNode)]
1483pub struct List<'a> {
1484    pub elements: Vec<Element<'a>>,
1485    pub lbracket: LeftSquareBracket<'a>,
1486    pub rbracket: RightSquareBracket<'a>,
1487    pub lpar: Vec<LeftParen<'a>>,
1488    pub rpar: Vec<RightParen<'a>>,
1489}
1490
1491impl<'r, 'a> Inflate<'a> for DeflatedList<'r, 'a> {
1492    type Inflated = List<'a>;
1493    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1494        let lpar = self.lpar.inflate(config)?;
1495        let lbracket = self.lbracket.inflate(config)?;
1496        let len = self.elements.len();
1497        let elements = self
1498            .elements
1499            .into_iter()
1500            .enumerate()
1501            .map(|(idx, el)| el.inflate_element(config, idx + 1 == len))
1502            .collect::<Result<Vec<_>>>()?;
1503        let rbracket = if !elements.is_empty() {
1504            // lbracket owns all the whitespace if there are no elements
1505            self.rbracket.inflate(config)?
1506        } else {
1507            Default::default()
1508        };
1509        let rpar = self.rpar.inflate(config)?;
1510        Ok(Self::Inflated {
1511            elements,
1512            lbracket,
1513            rbracket,
1514            lpar,
1515            rpar,
1516        })
1517    }
1518}
1519
1520impl<'a> Codegen<'a> for List<'a> {
1521    fn codegen(&self, state: &mut CodegenState<'a>) {
1522        self.parenthesize(state, |state| {
1523            self.lbracket.codegen(state);
1524            let len = self.elements.len();
1525            for (idx, el) in self.elements.iter().enumerate() {
1526                el.codegen(state, idx < len - 1, true);
1527            }
1528            self.rbracket.codegen(state);
1529        })
1530    }
1531}
1532
1533#[cst_node(ParenthesizedNode)]
1534pub struct Set<'a> {
1535    pub elements: Vec<Element<'a>>,
1536    pub lbrace: LeftCurlyBrace<'a>,
1537    pub rbrace: RightCurlyBrace<'a>,
1538    pub lpar: Vec<LeftParen<'a>>,
1539    pub rpar: Vec<RightParen<'a>>,
1540}
1541
1542impl<'r, 'a> Inflate<'a> for DeflatedSet<'r, 'a> {
1543    type Inflated = Set<'a>;
1544    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1545        let lpar = self.lpar.inflate(config)?;
1546        let lbrace = self.lbrace.inflate(config)?;
1547        let len = self.elements.len();
1548        let elements = self
1549            .elements
1550            .into_iter()
1551            .enumerate()
1552            .map(|(idx, el)| el.inflate_element(config, idx + 1 == len))
1553            .collect::<Result<Vec<_>>>()?;
1554        let rbrace = if !elements.is_empty() {
1555            self.rbrace.inflate(config)?
1556        } else {
1557            Default::default()
1558        };
1559        let rpar = self.rpar.inflate(config)?;
1560        Ok(Self::Inflated {
1561            elements,
1562            lbrace,
1563            rbrace,
1564            lpar,
1565            rpar,
1566        })
1567    }
1568}
1569
1570impl<'a> Codegen<'a> for Set<'a> {
1571    fn codegen(&self, state: &mut CodegenState<'a>) {
1572        self.parenthesize(state, |state| {
1573            self.lbrace.codegen(state);
1574            let len = self.elements.len();
1575            for (idx, el) in self.elements.iter().enumerate() {
1576                el.codegen(state, idx < len - 1, true);
1577            }
1578            self.rbrace.codegen(state);
1579        })
1580    }
1581}
1582
1583#[cst_node(ParenthesizedNode)]
1584pub struct Dict<'a> {
1585    pub elements: Vec<DictElement<'a>>,
1586    pub lbrace: LeftCurlyBrace<'a>,
1587    pub rbrace: RightCurlyBrace<'a>,
1588    pub lpar: Vec<LeftParen<'a>>,
1589    pub rpar: Vec<RightParen<'a>>,
1590}
1591
1592impl<'r, 'a> Inflate<'a> for DeflatedDict<'r, 'a> {
1593    type Inflated = Dict<'a>;
1594    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1595        let lpar = self.lpar.inflate(config)?;
1596        let lbrace = self.lbrace.inflate(config)?;
1597        let len = self.elements.len();
1598        let elements = self
1599            .elements
1600            .into_iter()
1601            .enumerate()
1602            .map(|(idx, el)| el.inflate_element(config, idx + 1 == len))
1603            .collect::<Result<Vec<_>>>()?;
1604        let rbrace = if !elements.is_empty() {
1605            self.rbrace.inflate(config)?
1606        } else {
1607            Default::default()
1608        };
1609        let rpar = self.rpar.inflate(config)?;
1610        Ok(Self::Inflated {
1611            elements,
1612            lbrace,
1613            rbrace,
1614            lpar,
1615            rpar,
1616        })
1617    }
1618}
1619
1620impl<'a> Codegen<'a> for Dict<'a> {
1621    fn codegen(&self, state: &mut CodegenState<'a>) {
1622        self.parenthesize(state, |state| {
1623            self.lbrace.codegen(state);
1624            let len = self.elements.len();
1625            for (idx, el) in self.elements.iter().enumerate() {
1626                el.codegen(state, idx < len - 1, true);
1627            }
1628            self.rbrace.codegen(state);
1629        })
1630    }
1631}
1632
1633#[cst_node(NoIntoPy)]
1634pub enum DictElement<'a> {
1635    Simple {
1636        key: Expression<'a>,
1637        value: Expression<'a>,
1638        comma: Option<Comma<'a>>,
1639        whitespace_before_colon: ParenthesizableWhitespace<'a>,
1640        whitespace_after_colon: ParenthesizableWhitespace<'a>,
1641        colon_tok: TokenRef<'a>,
1642    },
1643    Starred(StarredDictElement<'a>),
1644}
1645
1646impl<'r, 'a> DeflatedDictElement<'r, 'a> {
1647    pub fn inflate_element(
1648        self,
1649        config: &Config<'a>,
1650        last_element: bool,
1651    ) -> Result<DictElement<'a>> {
1652        Ok(match self {
1653            Self::Starred(s) => DictElement::Starred(s.inflate_element(config, last_element)?),
1654            Self::Simple {
1655                key,
1656                value,
1657                comma,
1658                colon_tok,
1659                ..
1660            } => {
1661                let whitespace_before_colon = parse_parenthesizable_whitespace(
1662                    config,
1663                    &mut colon_tok.whitespace_before.borrow_mut(),
1664                )?;
1665                let whitespace_after_colon = parse_parenthesizable_whitespace(
1666                    config,
1667                    &mut colon_tok.whitespace_after.borrow_mut(),
1668                )?;
1669                DictElement::Simple {
1670                    key: key.inflate(config)?,
1671                    whitespace_before_colon,
1672                    whitespace_after_colon,
1673                    value: value.inflate(config)?,
1674                    comma: if last_element {
1675                        comma.map(|c| c.inflate_before(config)).transpose()
1676                    } else {
1677                        comma.inflate(config)
1678                    }?,
1679                }
1680            }
1681        })
1682    }
1683}
1684
1685impl<'a> DictElement<'a> {
1686    fn codegen(
1687        &self,
1688        state: &mut CodegenState<'a>,
1689        default_comma: bool,
1690        default_comma_whitespace: bool,
1691    ) {
1692        match self {
1693            Self::Simple {
1694                key,
1695                value,
1696                comma,
1697                whitespace_before_colon,
1698                whitespace_after_colon,
1699                ..
1700            } => {
1701                key.codegen(state);
1702                whitespace_before_colon.codegen(state);
1703                state.add_token(":");
1704                whitespace_after_colon.codegen(state);
1705                value.codegen(state);
1706                if let Some(comma) = comma {
1707                    comma.codegen(state)
1708                }
1709            }
1710            Self::Starred(s) => s.codegen(state),
1711        }
1712        let maybe_comma = match self {
1713            Self::Simple { comma, .. } => comma,
1714            Self::Starred(s) => &s.comma,
1715        };
1716        if maybe_comma.is_none() && default_comma {
1717            state.add_token(if default_comma_whitespace { ", " } else { "," });
1718        }
1719    }
1720}
1721
1722impl<'r, 'a> WithComma<'r, 'a> for DeflatedDictElement<'r, 'a> {
1723    fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
1724        let comma = Some(comma);
1725        match self {
1726            Self::Starred(s) => Self::Starred(DeflatedStarredDictElement { comma, ..s }),
1727            Self::Simple {
1728                key,
1729                value,
1730                colon_tok,
1731                ..
1732            } => Self::Simple {
1733                comma,
1734                key,
1735                value,
1736                colon_tok,
1737            },
1738        }
1739    }
1740}
1741
1742#[cst_node]
1743pub struct StarredDictElement<'a> {
1744    pub value: Expression<'a>,
1745    pub comma: Option<Comma<'a>>,
1746    pub whitespace_before_value: ParenthesizableWhitespace<'a>,
1747
1748    pub(crate) star_tok: TokenRef<'a>,
1749}
1750
1751impl<'r, 'a> DeflatedStarredDictElement<'r, 'a> {
1752    fn inflate_element(
1753        self,
1754        config: &Config<'a>,
1755        last_element: bool,
1756    ) -> Result<StarredDictElement<'a>> {
1757        let whitespace_before_value = parse_parenthesizable_whitespace(
1758            config,
1759            &mut (*self.star_tok).whitespace_after.borrow_mut(),
1760        )?;
1761        let value = self.value.inflate(config)?;
1762        let comma = if last_element {
1763            self.comma.map(|c| c.inflate_before(config)).transpose()
1764        } else {
1765            self.comma.inflate(config)
1766        }?;
1767        Ok(StarredDictElement {
1768            value,
1769            comma,
1770            whitespace_before_value,
1771        })
1772    }
1773}
1774
1775impl<'a> Codegen<'a> for StarredDictElement<'a> {
1776    fn codegen(&self, state: &mut CodegenState<'a>) {
1777        state.add_token("**");
1778        self.whitespace_before_value.codegen(state);
1779        self.value.codegen(state);
1780        if let Some(comma) = &self.comma {
1781            comma.codegen(state);
1782        }
1783    }
1784}
1785
1786#[cst_node(Codegen, Inflate)]
1787pub enum BaseSlice<'a> {
1788    Index(Box<Index<'a>>),
1789    Slice(Box<Slice<'a>>),
1790}
1791
1792#[cst_node]
1793pub struct Index<'a> {
1794    pub value: Expression<'a>,
1795    pub star: Option<&'a str>,
1796    pub whitespace_after_star: Option<ParenthesizableWhitespace<'a>>,
1797
1798    pub(crate) star_tok: Option<TokenRef<'a>>,
1799}
1800
1801impl<'r, 'a> Inflate<'a> for DeflatedIndex<'r, 'a> {
1802    type Inflated = Index<'a>;
1803    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
1804        let (star, whitespace_after_star) = if let Some(star_tok) = self.star_tok.as_mut() {
1805            (
1806                Some(star_tok.string),
1807                Some(parse_parenthesizable_whitespace(
1808                    config,
1809                    &mut star_tok.whitespace_after.borrow_mut(),
1810                )?),
1811            )
1812        } else {
1813            (None, None)
1814        };
1815        let value = self.value.inflate(config)?;
1816        Ok(Self::Inflated {
1817            value,
1818            star,
1819            whitespace_after_star,
1820        })
1821    }
1822}
1823
1824impl<'a> Codegen<'a> for Index<'a> {
1825    fn codegen(&self, state: &mut CodegenState<'a>) {
1826        if let Some(star) = self.star {
1827            state.add_token(star);
1828        }
1829        self.whitespace_after_star.codegen(state);
1830        self.value.codegen(state);
1831    }
1832}
1833
1834#[cst_node]
1835pub struct Slice<'a> {
1836    #[cfg_attr(feature = "py", no_py_default)]
1837    pub lower: Option<Expression<'a>>,
1838    #[cfg_attr(feature = "py", no_py_default)]
1839    pub upper: Option<Expression<'a>>,
1840    pub step: Option<Expression<'a>>,
1841    pub first_colon: Colon<'a>,
1842    pub second_colon: Option<Colon<'a>>,
1843}
1844
1845impl<'r, 'a> Inflate<'a> for DeflatedSlice<'r, 'a> {
1846    type Inflated = Slice<'a>;
1847    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1848        let lower = self.lower.inflate(config)?;
1849        let first_colon = self.first_colon.inflate(config)?;
1850        let upper = self.upper.inflate(config)?;
1851        let second_colon = self.second_colon.inflate(config)?;
1852        let step = self.step.inflate(config)?;
1853        Ok(Self::Inflated {
1854            lower,
1855            upper,
1856            step,
1857            first_colon,
1858            second_colon,
1859        })
1860    }
1861}
1862
1863impl<'a> Codegen<'a> for Slice<'a> {
1864    fn codegen(&self, state: &mut CodegenState<'a>) {
1865        if let Some(lower) = &self.lower {
1866            lower.codegen(state);
1867        }
1868        self.first_colon.codegen(state);
1869        if let Some(upper) = &self.upper {
1870            upper.codegen(state);
1871        }
1872        if let Some(second_colon) = &self.second_colon {
1873            second_colon.codegen(state);
1874        } else if self.step.is_some() {
1875            state.add_token(";");
1876        }
1877        if let Some(step) = &self.step {
1878            step.codegen(state);
1879        }
1880    }
1881}
1882
1883#[cst_node]
1884pub struct SubscriptElement<'a> {
1885    pub slice: BaseSlice<'a>,
1886    pub comma: Option<Comma<'a>>,
1887}
1888
1889impl<'r, 'a> Inflate<'a> for DeflatedSubscriptElement<'r, 'a> {
1890    type Inflated = SubscriptElement<'a>;
1891    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1892        let slice = self.slice.inflate(config)?;
1893        let comma = self.comma.inflate(config)?;
1894        Ok(Self::Inflated { slice, comma })
1895    }
1896}
1897
1898impl<'a> Codegen<'a> for SubscriptElement<'a> {
1899    fn codegen(&self, state: &mut CodegenState<'a>) {
1900        self.slice.codegen(state);
1901        if let Some(comma) = &self.comma {
1902            comma.codegen(state);
1903        }
1904    }
1905}
1906
1907#[cst_node(ParenthesizedNode)]
1908pub struct Subscript<'a> {
1909    pub value: Box<Expression<'a>>,
1910    pub slice: Vec<SubscriptElement<'a>>,
1911    pub lbracket: LeftSquareBracket<'a>,
1912    pub rbracket: RightSquareBracket<'a>,
1913    pub lpar: Vec<LeftParen<'a>>,
1914    pub rpar: Vec<RightParen<'a>>,
1915    pub whitespace_after_value: ParenthesizableWhitespace<'a>,
1916}
1917
1918impl<'r, 'a> Inflate<'a> for DeflatedSubscript<'r, 'a> {
1919    type Inflated = Subscript<'a>;
1920    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1921        let lpar = self.lpar.inflate(config)?;
1922        let value = self.value.inflate(config)?;
1923        let whitespace_after_value = parse_parenthesizable_whitespace(
1924            config,
1925            &mut self.lbracket.tok.whitespace_before.borrow_mut(),
1926        )?;
1927        let lbracket = self.lbracket.inflate(config)?;
1928        let slice = self.slice.inflate(config)?;
1929        let rbracket = self.rbracket.inflate(config)?;
1930        let rpar = self.rpar.inflate(config)?;
1931        Ok(Self::Inflated {
1932            value,
1933            slice,
1934            lbracket,
1935            rbracket,
1936            lpar,
1937            rpar,
1938            whitespace_after_value,
1939        })
1940    }
1941}
1942
1943impl<'a> Codegen<'a> for Subscript<'a> {
1944    fn codegen(&self, state: &mut CodegenState<'a>) {
1945        self.parenthesize(state, |state| {
1946            self.value.codegen(state);
1947            self.whitespace_after_value.codegen(state);
1948            self.lbracket.codegen(state);
1949            let len = self.slice.len();
1950            for (i, slice) in self.slice.iter().enumerate() {
1951                slice.codegen(state);
1952                if slice.comma.is_none() && i + 1 < len {
1953                    state.add_token(", ")
1954                }
1955            }
1956            self.rbracket.codegen(state);
1957        })
1958    }
1959}
1960
1961#[cst_node(ParenthesizedNode)]
1962pub struct IfExp<'a> {
1963    pub test: Box<Expression<'a>>,
1964    pub body: Box<Expression<'a>>,
1965    pub orelse: Box<Expression<'a>>,
1966    pub lpar: Vec<LeftParen<'a>>,
1967    pub rpar: Vec<RightParen<'a>>,
1968    pub whitespace_before_if: ParenthesizableWhitespace<'a>,
1969    pub whitespace_after_if: ParenthesizableWhitespace<'a>,
1970    pub whitespace_before_else: ParenthesizableWhitespace<'a>,
1971    pub whitespace_after_else: ParenthesizableWhitespace<'a>,
1972
1973    pub(crate) if_tok: TokenRef<'a>,
1974    pub(crate) else_tok: TokenRef<'a>,
1975}
1976
1977impl<'r, 'a> Inflate<'a> for DeflatedIfExp<'r, 'a> {
1978    type Inflated = IfExp<'a>;
1979    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1980        let lpar = self.lpar.inflate(config)?;
1981        let body = self.body.inflate(config)?;
1982        let whitespace_before_if = parse_parenthesizable_whitespace(
1983            config,
1984            &mut (*self.if_tok).whitespace_before.borrow_mut(),
1985        )?;
1986        let whitespace_after_if = parse_parenthesizable_whitespace(
1987            config,
1988            &mut (*self.if_tok).whitespace_after.borrow_mut(),
1989        )?;
1990        let test = self.test.inflate(config)?;
1991        let whitespace_before_else = parse_parenthesizable_whitespace(
1992            config,
1993            &mut (*self.else_tok).whitespace_before.borrow_mut(),
1994        )?;
1995        let whitespace_after_else = parse_parenthesizable_whitespace(
1996            config,
1997            &mut (*self.else_tok).whitespace_after.borrow_mut(),
1998        )?;
1999        let orelse = self.orelse.inflate(config)?;
2000        let rpar = self.rpar.inflate(config)?;
2001        Ok(Self::Inflated {
2002            test,
2003            body,
2004            orelse,
2005            lpar,
2006            rpar,
2007            whitespace_before_if,
2008            whitespace_after_if,
2009            whitespace_before_else,
2010            whitespace_after_else,
2011        })
2012    }
2013}
2014
2015impl<'a> Codegen<'a> for IfExp<'a> {
2016    fn codegen(&self, state: &mut CodegenState<'a>) {
2017        self.parenthesize(state, |state| {
2018            self.body.codegen(state);
2019            self.whitespace_before_if.codegen(state);
2020            state.add_token("if");
2021            self.whitespace_after_if.codegen(state);
2022            self.test.codegen(state);
2023            self.whitespace_before_else.codegen(state);
2024            state.add_token("else");
2025            self.whitespace_after_else.codegen(state);
2026            self.orelse.codegen(state);
2027        })
2028    }
2029}
2030
2031#[cst_node(ParenthesizedNode)]
2032pub struct Lambda<'a> {
2033    pub params: Box<Parameters<'a>>,
2034    pub body: Box<Expression<'a>>,
2035    pub colon: Colon<'a>,
2036    pub lpar: Vec<LeftParen<'a>>,
2037    pub rpar: Vec<RightParen<'a>>,
2038    pub whitespace_after_lambda: Option<ParenthesizableWhitespace<'a>>,
2039
2040    pub(crate) lambda_tok: TokenRef<'a>,
2041}
2042
2043impl<'r, 'a> Inflate<'a> for DeflatedLambda<'r, 'a> {
2044    type Inflated = Lambda<'a>;
2045    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2046        let lpar = self.lpar.inflate(config)?;
2047        let whitespace_after_lambda = if !self.params.is_empty() {
2048            Some(parse_parenthesizable_whitespace(
2049                config,
2050                &mut (*self.lambda_tok).whitespace_after.borrow_mut(),
2051            )?)
2052        } else {
2053            Default::default()
2054        };
2055        let mut params = self.params.inflate(config)?;
2056        adjust_parameters_trailing_whitespace(config, &mut params, &self.colon.tok)?;
2057        let colon = self.colon.inflate(config)?;
2058        let body = self.body.inflate(config)?;
2059        let rpar = self.rpar.inflate(config)?;
2060        Ok(Self::Inflated {
2061            params,
2062            body,
2063            colon,
2064            lpar,
2065            rpar,
2066            whitespace_after_lambda,
2067        })
2068    }
2069}
2070
2071impl<'a> Codegen<'a> for Lambda<'a> {
2072    fn codegen(&self, state: &mut CodegenState<'a>) {
2073        self.parenthesize(state, |state| {
2074            state.add_token("lambda");
2075            if let Some(ws) = &self.whitespace_after_lambda {
2076                ws.codegen(state);
2077            } else if !self.params.is_empty() {
2078                // there's one or more params, add a space
2079                state.add_token(" ")
2080            }
2081            self.params.codegen(state);
2082            self.colon.codegen(state);
2083            self.body.codegen(state);
2084        })
2085    }
2086}
2087
2088#[cst_node]
2089pub struct From<'a> {
2090    pub item: Expression<'a>,
2091    pub whitespace_before_from: Option<ParenthesizableWhitespace<'a>>,
2092    pub whitespace_after_from: ParenthesizableWhitespace<'a>,
2093
2094    pub(crate) tok: TokenRef<'a>,
2095}
2096
2097impl<'a> From<'a> {
2098    pub fn codegen(&self, state: &mut CodegenState<'a>, default_space: &'a str) {
2099        if let Some(ws) = &self.whitespace_before_from {
2100            ws.codegen(state);
2101        } else {
2102            state.add_token(default_space);
2103        }
2104        state.add_token("from");
2105        self.whitespace_after_from.codegen(state);
2106        self.item.codegen(state);
2107    }
2108}
2109
2110impl<'r, 'a> Inflate<'a> for DeflatedFrom<'r, 'a> {
2111    type Inflated = From<'a>;
2112    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2113        let whitespace_before_from = Some(parse_parenthesizable_whitespace(
2114            config,
2115            &mut (*self.tok).whitespace_before.borrow_mut(),
2116        )?);
2117        let whitespace_after_from = parse_parenthesizable_whitespace(
2118            config,
2119            &mut (*self.tok).whitespace_after.borrow_mut(),
2120        )?;
2121        let item = self.item.inflate(config)?;
2122        Ok(Self::Inflated {
2123            item,
2124            whitespace_before_from,
2125            whitespace_after_from,
2126        })
2127    }
2128}
2129
2130#[cst_node]
2131pub enum YieldValue<'a> {
2132    Expression(Box<Expression<'a>>),
2133    From(Box<From<'a>>),
2134}
2135
2136impl<'r, 'a> Inflate<'a> for DeflatedYieldValue<'r, 'a> {
2137    type Inflated = YieldValue<'a>;
2138    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2139        Ok(match self {
2140            Self::Expression(e) => Self::Inflated::Expression(e.inflate(config)?),
2141            Self::From(e) => {
2142                let mut e = e.inflate(config)?;
2143                e.whitespace_before_from = None;
2144                Self::Inflated::From(e)
2145            }
2146        })
2147    }
2148}
2149
2150impl<'a> YieldValue<'a> {
2151    fn codegen(&self, state: &mut CodegenState<'a>, default_space: &'a str) {
2152        match self {
2153            Self::Expression(e) => e.codegen(state),
2154            Self::From(f) => f.codegen(state, default_space),
2155        }
2156    }
2157}
2158
2159#[cst_node(ParenthesizedNode)]
2160pub struct Yield<'a> {
2161    pub value: Option<Box<YieldValue<'a>>>,
2162    pub lpar: Vec<LeftParen<'a>>,
2163    pub rpar: Vec<RightParen<'a>>,
2164    pub whitespace_after_yield: Option<ParenthesizableWhitespace<'a>>,
2165
2166    pub(crate) yield_tok: TokenRef<'a>,
2167}
2168
2169impl<'r, 'a> Inflate<'a> for DeflatedYield<'r, 'a> {
2170    type Inflated = Yield<'a>;
2171    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2172        let lpar = self.lpar.inflate(config)?;
2173        let whitespace_after_yield = if self.value.is_some() {
2174            Some(parse_parenthesizable_whitespace(
2175                config,
2176                &mut (*self.yield_tok).whitespace_after.borrow_mut(),
2177            )?)
2178        } else {
2179            Default::default()
2180        };
2181        let value = self.value.inflate(config)?;
2182        let rpar = self.rpar.inflate(config)?;
2183        Ok(Self::Inflated {
2184            value,
2185            lpar,
2186            rpar,
2187            whitespace_after_yield,
2188        })
2189    }
2190}
2191
2192impl<'a> Codegen<'a> for Yield<'a> {
2193    fn codegen(&self, state: &mut CodegenState<'a>) {
2194        self.parenthesize(state, |state| {
2195            state.add_token("yield");
2196            if let Some(ws) = &self.whitespace_after_yield {
2197                ws.codegen(state);
2198            } else if self.value.is_some() {
2199                state.add_token(" ");
2200            }
2201
2202            if let Some(val) = &self.value {
2203                val.codegen(state, "")
2204            }
2205        })
2206    }
2207}
2208
2209#[cst_node(ParenthesizedNode)]
2210pub struct Await<'a> {
2211    pub expression: Box<Expression<'a>>,
2212    pub lpar: Vec<LeftParen<'a>>,
2213    pub rpar: Vec<RightParen<'a>>,
2214    pub whitespace_after_await: ParenthesizableWhitespace<'a>,
2215
2216    pub(crate) await_tok: TokenRef<'a>,
2217}
2218
2219impl<'r, 'a> Inflate<'a> for DeflatedAwait<'r, 'a> {
2220    type Inflated = Await<'a>;
2221    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2222        let lpar = self.lpar.inflate(config)?;
2223        let whitespace_after_await = parse_parenthesizable_whitespace(
2224            config,
2225            &mut (*self.await_tok).whitespace_after.borrow_mut(),
2226        )?;
2227        let expression = self.expression.inflate(config)?;
2228        let rpar = self.rpar.inflate(config)?;
2229        Ok(Self::Inflated {
2230            expression,
2231            lpar,
2232            rpar,
2233            whitespace_after_await,
2234        })
2235    }
2236}
2237
2238impl<'a> Codegen<'a> for Await<'a> {
2239    fn codegen(&self, state: &mut CodegenState<'a>) {
2240        self.parenthesize(state, |state| {
2241            state.add_token("await");
2242            self.whitespace_after_await.codegen(state);
2243            self.expression.codegen(state);
2244        })
2245    }
2246}
2247
2248#[cst_node(Codegen, Inflate)]
2249pub enum String<'a> {
2250    Simple(SimpleString<'a>),
2251    Concatenated(ConcatenatedString<'a>),
2252    Formatted(FormattedString<'a>),
2253    Templated(TemplatedString<'a>),
2254}
2255
2256impl<'r, 'a> std::convert::From<DeflatedString<'r, 'a>> for DeflatedExpression<'r, 'a> {
2257    fn from(s: DeflatedString<'r, 'a>) -> Self {
2258        match s {
2259            DeflatedString::Simple(s) => Self::SimpleString(Box::new(s)),
2260            DeflatedString::Concatenated(s) => Self::ConcatenatedString(Box::new(s)),
2261            DeflatedString::Formatted(s) => Self::FormattedString(Box::new(s)),
2262            DeflatedString::Templated(s) => Self::TemplatedString(Box::new(s)),
2263        }
2264    }
2265}
2266
2267#[cst_node(ParenthesizedNode)]
2268pub struct ConcatenatedString<'a> {
2269    pub left: Box<String<'a>>,
2270    pub right: Box<String<'a>>,
2271    pub lpar: Vec<LeftParen<'a>>,
2272    pub rpar: Vec<RightParen<'a>>,
2273    pub whitespace_between: ParenthesizableWhitespace<'a>,
2274
2275    // we capture the next token after each string piece so Inflate can extract the
2276    // whitespace between individual pieces
2277    pub(crate) right_tok: TokenRef<'a>,
2278}
2279
2280impl<'r, 'a> Inflate<'a> for DeflatedConcatenatedString<'r, 'a> {
2281    type Inflated = ConcatenatedString<'a>;
2282    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2283        let lpar = self.lpar.inflate(config)?;
2284        let left = self.left.inflate(config)?;
2285        let whitespace_between = parse_parenthesizable_whitespace(
2286            config,
2287            &mut (*self.right_tok).whitespace_before.borrow_mut(),
2288        )?;
2289        let right = self.right.inflate(config)?;
2290        let rpar = self.rpar.inflate(config)?;
2291        Ok(Self::Inflated {
2292            left,
2293            right,
2294            lpar,
2295            rpar,
2296            whitespace_between,
2297        })
2298    }
2299}
2300
2301impl<'a> Codegen<'a> for ConcatenatedString<'a> {
2302    fn codegen(&self, state: &mut CodegenState<'a>) {
2303        self.parenthesize(state, |state| {
2304            self.left.codegen(state);
2305            self.whitespace_between.codegen(state);
2306            self.right.codegen(state);
2307        })
2308    }
2309}
2310
2311#[cst_node(ParenthesizedNode, Default)]
2312pub struct SimpleString<'a> {
2313    /// The texual representation of the string, including quotes, prefix
2314    /// characters, and any escape characters present in the original source code,
2315    /// such as ``r"my string\n"``.
2316    pub value: &'a str,
2317    pub lpar: Vec<LeftParen<'a>>,
2318    pub rpar: Vec<RightParen<'a>>,
2319}
2320
2321impl<'r, 'a> Inflate<'a> for DeflatedSimpleString<'r, 'a> {
2322    type Inflated = SimpleString<'a>;
2323    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2324        let lpar = self.lpar.inflate(config)?;
2325        let rpar = self.rpar.inflate(config)?;
2326        Ok(Self::Inflated {
2327            value: self.value,
2328            lpar,
2329            rpar,
2330        })
2331    }
2332}
2333
2334impl<'a> Codegen<'a> for SimpleString<'a> {
2335    fn codegen(&self, state: &mut CodegenState<'a>) {
2336        self.parenthesize(state, |state| state.add_token(self.value))
2337    }
2338}
2339
2340#[cst_node]
2341pub struct TemplatedStringText<'a> {
2342    pub value: &'a str,
2343}
2344
2345impl<'r, 'a> Inflate<'a> for DeflatedTemplatedStringText<'r, 'a> {
2346    type Inflated = TemplatedStringText<'a>;
2347    fn inflate(self, _config: &Config<'a>) -> Result<Self::Inflated> {
2348        Ok(Self::Inflated { value: self.value })
2349    }
2350}
2351
2352impl<'a> Codegen<'a> for TemplatedStringText<'a> {
2353    fn codegen(&self, state: &mut CodegenState<'a>) {
2354        state.add_token(self.value);
2355    }
2356}
2357
2358pub(crate) fn make_tstringtext<'r, 'a>(value: &'a str) -> DeflatedTemplatedStringText<'r, 'a> {
2359    DeflatedTemplatedStringText {
2360        value,
2361        _phantom: Default::default(),
2362    }
2363}
2364
2365#[cst_node]
2366pub struct TemplatedStringExpression<'a> {
2367    // This represents the part of a t-string that is insde the brackets '{' and '}'.
2368    pub expression: Expression<'a>,
2369    pub conversion: Option<&'a str>,
2370    pub format_spec: Option<Vec<TemplatedStringContent<'a>>>,
2371    pub whitespace_before_expression: ParenthesizableWhitespace<'a>,
2372    pub whitespace_after_expression: ParenthesizableWhitespace<'a>,
2373    pub equal: Option<AssignEqual<'a>>,
2374
2375    pub(crate) lbrace_tok: TokenRef<'a>,
2376    // This is None if there's an equal sign, otherwise it's the first token of
2377    // (conversion, format spec, right brace) in that order
2378    pub(crate) after_expr_tok: Option<TokenRef<'a>>,
2379}
2380
2381impl<'r, 'a> Inflate<'a> for DeflatedTemplatedStringExpression<'r, 'a> {
2382    type Inflated = TemplatedStringExpression<'a>;
2383    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
2384        let whitespace_before_expression = parse_parenthesizable_whitespace(
2385            config,
2386            &mut (*self.lbrace_tok).whitespace_after.borrow_mut(),
2387        )?;
2388        let expression = self.expression.inflate(config)?;
2389        let equal = self.equal.inflate(config)?;
2390        let whitespace_after_expression = if let Some(after_expr_tok) = self.after_expr_tok.as_mut()
2391        {
2392            parse_parenthesizable_whitespace(
2393                config,
2394                &mut after_expr_tok.whitespace_before.borrow_mut(),
2395            )?
2396        } else {
2397            Default::default()
2398        };
2399        let format_spec = self.format_spec.inflate(config)?;
2400        Ok(Self::Inflated {
2401            expression,
2402            conversion: self.conversion,
2403            format_spec,
2404            whitespace_before_expression,
2405            whitespace_after_expression,
2406            equal,
2407        })
2408    }
2409}
2410
2411impl<'a> Codegen<'a> for TemplatedStringExpression<'a> {
2412    fn codegen(&self, state: &mut CodegenState<'a>) {
2413        state.add_token("{");
2414        self.whitespace_before_expression.codegen(state);
2415        self.expression.codegen(state);
2416        if let Some(eq) = &self.equal {
2417            eq.codegen(state);
2418        }
2419        self.whitespace_after_expression.codegen(state);
2420        if let Some(conv) = &self.conversion {
2421            state.add_token("!");
2422            state.add_token(conv);
2423        }
2424        if let Some(specs) = &self.format_spec {
2425            state.add_token(":");
2426            for spec in specs {
2427                spec.codegen(state);
2428            }
2429        }
2430        state.add_token("}");
2431    }
2432}
2433
2434#[cst_node(ParenthesizedNode)]
2435pub struct TemplatedString<'a> {
2436    pub parts: Vec<TemplatedStringContent<'a>>,
2437    pub start: &'a str,
2438    pub end: &'a str,
2439    pub lpar: Vec<LeftParen<'a>>,
2440    pub rpar: Vec<RightParen<'a>>,
2441}
2442
2443impl<'r, 'a> Inflate<'a> for DeflatedTemplatedString<'r, 'a> {
2444    type Inflated = TemplatedString<'a>;
2445    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2446        let lpar = self.lpar.inflate(config)?;
2447        let parts = self.parts.inflate(config)?;
2448        let rpar = self.rpar.inflate(config)?;
2449        Ok(Self::Inflated {
2450            parts,
2451            start: self.start,
2452            end: self.end,
2453            lpar,
2454            rpar,
2455        })
2456    }
2457}
2458
2459impl<'a> Codegen<'a> for TemplatedString<'a> {
2460    fn codegen(&self, state: &mut CodegenState<'a>) {
2461        self.parenthesize(state, |state| {
2462            state.add_token(self.start);
2463            for part in &self.parts {
2464                part.codegen(state);
2465            }
2466            state.add_token(self.end);
2467        })
2468    }
2469}
2470
2471#[cst_node(Codegen, Inflate)]
2472pub enum TemplatedStringContent<'a> {
2473    Text(TemplatedStringText<'a>),
2474    Expression(Box<TemplatedStringExpression<'a>>),
2475}
2476#[cst_node]
2477pub struct FormattedStringText<'a> {
2478    pub value: &'a str,
2479}
2480
2481impl<'r, 'a> Inflate<'a> for DeflatedFormattedStringText<'r, 'a> {
2482    type Inflated = FormattedStringText<'a>;
2483    fn inflate(self, _config: &Config<'a>) -> Result<Self::Inflated> {
2484        Ok(Self::Inflated { value: self.value })
2485    }
2486}
2487
2488impl<'a> Codegen<'a> for FormattedStringText<'a> {
2489    fn codegen(&self, state: &mut CodegenState<'a>) {
2490        state.add_token(self.value);
2491    }
2492}
2493
2494pub(crate) fn make_fstringtext<'r, 'a>(value: &'a str) -> DeflatedFormattedStringText<'r, 'a> {
2495    DeflatedFormattedStringText {
2496        value,
2497        _phantom: Default::default(),
2498    }
2499}
2500
2501#[cst_node]
2502pub struct FormattedStringExpression<'a> {
2503    pub expression: Expression<'a>,
2504    pub conversion: Option<&'a str>,
2505    pub format_spec: Option<Vec<FormattedStringContent<'a>>>,
2506    pub whitespace_before_expression: ParenthesizableWhitespace<'a>,
2507    pub whitespace_after_expression: ParenthesizableWhitespace<'a>,
2508    pub equal: Option<AssignEqual<'a>>,
2509
2510    pub(crate) lbrace_tok: TokenRef<'a>,
2511    // This is None if there's an equal sign, otherwise it's the first token of
2512    // (conversion, format spec, right brace) in that order
2513    pub(crate) after_expr_tok: Option<TokenRef<'a>>,
2514}
2515
2516impl<'r, 'a> Inflate<'a> for DeflatedFormattedStringExpression<'r, 'a> {
2517    type Inflated = FormattedStringExpression<'a>;
2518    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
2519        let whitespace_before_expression = parse_parenthesizable_whitespace(
2520            config,
2521            &mut (*self.lbrace_tok).whitespace_after.borrow_mut(),
2522        )?;
2523        let expression = self.expression.inflate(config)?;
2524        let equal = self.equal.inflate(config)?;
2525        let whitespace_after_expression = if let Some(after_expr_tok) = self.after_expr_tok.as_mut()
2526        {
2527            parse_parenthesizable_whitespace(
2528                config,
2529                &mut after_expr_tok.whitespace_before.borrow_mut(),
2530            )?
2531        } else {
2532            Default::default()
2533        };
2534        let format_spec = self.format_spec.inflate(config)?;
2535        Ok(Self::Inflated {
2536            expression,
2537            conversion: self.conversion,
2538            format_spec,
2539            whitespace_before_expression,
2540            whitespace_after_expression,
2541            equal,
2542        })
2543    }
2544}
2545
2546impl<'a> Codegen<'a> for FormattedStringExpression<'a> {
2547    fn codegen(&self, state: &mut CodegenState<'a>) {
2548        state.add_token("{");
2549        self.whitespace_before_expression.codegen(state);
2550        self.expression.codegen(state);
2551        if let Some(eq) = &self.equal {
2552            eq.codegen(state);
2553        }
2554        self.whitespace_after_expression.codegen(state);
2555        if let Some(conv) = &self.conversion {
2556            state.add_token("!");
2557            state.add_token(conv);
2558        }
2559        if let Some(specs) = &self.format_spec {
2560            state.add_token(":");
2561            for spec in specs {
2562                spec.codegen(state);
2563            }
2564        }
2565        state.add_token("}");
2566    }
2567}
2568
2569#[cst_node(Codegen, Inflate)]
2570pub enum FormattedStringContent<'a> {
2571    Text(FormattedStringText<'a>),
2572    Expression(Box<FormattedStringExpression<'a>>),
2573}
2574
2575#[cst_node(ParenthesizedNode)]
2576pub struct FormattedString<'a> {
2577    pub parts: Vec<FormattedStringContent<'a>>,
2578    pub start: &'a str,
2579    pub end: &'a str,
2580    pub lpar: Vec<LeftParen<'a>>,
2581    pub rpar: Vec<RightParen<'a>>,
2582}
2583
2584impl<'r, 'a> Inflate<'a> for DeflatedFormattedString<'r, 'a> {
2585    type Inflated = FormattedString<'a>;
2586    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2587        let lpar = self.lpar.inflate(config)?;
2588        let parts = self.parts.inflate(config)?;
2589        let rpar = self.rpar.inflate(config)?;
2590        Ok(Self::Inflated {
2591            parts,
2592            start: self.start,
2593            end: self.end,
2594            lpar,
2595            rpar,
2596        })
2597    }
2598}
2599
2600impl<'a> Codegen<'a> for FormattedString<'a> {
2601    fn codegen(&self, state: &mut CodegenState<'a>) {
2602        self.parenthesize(state, |state| {
2603            state.add_token(self.start);
2604            for part in &self.parts {
2605                part.codegen(state);
2606            }
2607            state.add_token(self.end);
2608        })
2609    }
2610}
2611
2612#[cst_node(ParenthesizedNode)]
2613pub struct NamedExpr<'a> {
2614    pub target: Box<Expression<'a>>,
2615    pub value: Box<Expression<'a>>,
2616    pub lpar: Vec<LeftParen<'a>>,
2617    pub rpar: Vec<RightParen<'a>>,
2618
2619    pub whitespace_before_walrus: ParenthesizableWhitespace<'a>,
2620    pub whitespace_after_walrus: ParenthesizableWhitespace<'a>,
2621
2622    pub(crate) walrus_tok: TokenRef<'a>,
2623}
2624
2625impl<'a> Codegen<'a> for NamedExpr<'a> {
2626    fn codegen(&self, state: &mut CodegenState<'a>) {
2627        self.parenthesize(state, |state| {
2628            self.target.codegen(state);
2629            self.whitespace_before_walrus.codegen(state);
2630            state.add_token(":=");
2631            self.whitespace_after_walrus.codegen(state);
2632            self.value.codegen(state);
2633        })
2634    }
2635}
2636
2637impl<'r, 'a> Inflate<'a> for DeflatedNamedExpr<'r, 'a> {
2638    type Inflated = NamedExpr<'a>;
2639    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2640        let lpar = self.lpar.inflate(config)?;
2641        let target = self.target.inflate(config)?;
2642        let whitespace_before_walrus = parse_parenthesizable_whitespace(
2643            config,
2644            &mut self.walrus_tok.whitespace_before.borrow_mut(),
2645        )?;
2646        let whitespace_after_walrus = parse_parenthesizable_whitespace(
2647            config,
2648            &mut self.walrus_tok.whitespace_after.borrow_mut(),
2649        )?;
2650        let value = self.value.inflate(config)?;
2651        let rpar = self.rpar.inflate(config)?;
2652        Ok(Self::Inflated {
2653            target,
2654            value,
2655            lpar,
2656            rpar,
2657            whitespace_before_walrus,
2658            whitespace_after_walrus,
2659        })
2660    }
2661}
2662
2663#[cfg(feature = "py")]
2664mod py {
2665
2666    use pyo3::types::PyAnyMethods;
2667    use pyo3::types::PyModule;
2668
2669    use super::*;
2670    use crate::nodes::traits::py::TryIntoPy;
2671
2672    // TODO: this could be a derive helper attribute to override the python class name
2673    impl<'a> TryIntoPy<pyo3::Py<pyo3::PyAny>> for Element<'a> {
2674        fn try_into_py(self, py: pyo3::Python) -> pyo3::PyResult<pyo3::Py<pyo3::PyAny>> {
2675            match self {
2676                Self::Starred(s) => s.try_into_py(py),
2677                Self::Simple { value, comma } => {
2678                    let libcst = PyModule::import(py, "libcst")?;
2679                    let kwargs = [
2680                        Some(("value", value.try_into_py(py)?)),
2681                        comma
2682                            .map(|x| x.try_into_py(py))
2683                            .transpose()?
2684                            .map(|x| ("comma", x)),
2685                    ]
2686                    .iter()
2687                    .filter(|x| x.is_some())
2688                    .map(|x| x.as_ref().unwrap())
2689                    .collect::<Vec<_>>()
2690                    .into_py_dict(py)?;
2691                    Ok(libcst
2692                        .getattr("Element")
2693                        .expect("no Element found in libcst")
2694                        .call((), Some(&kwargs))?
2695                        .into())
2696                }
2697            }
2698        }
2699    }
2700
2701    // TODO: this could be a derive helper attribute to override the python class name
2702    impl<'a> TryIntoPy<pyo3::Py<pyo3::PyAny>> for DictElement<'a> {
2703        fn try_into_py(self, py: pyo3::Python) -> pyo3::PyResult<pyo3::Py<pyo3::PyAny>> {
2704            match self {
2705                Self::Starred(s) => s.try_into_py(py),
2706                Self::Simple {
2707                    key,
2708                    value,
2709                    comma,
2710                    whitespace_after_colon,
2711                    whitespace_before_colon,
2712                    ..
2713                } => {
2714                    let libcst = PyModule::import(py, "libcst")?;
2715                    let kwargs = [
2716                        Some(("key", key.try_into_py(py)?)),
2717                        Some(("value", value.try_into_py(py)?)),
2718                        Some((
2719                            "whitespace_before_colon",
2720                            whitespace_before_colon.try_into_py(py)?,
2721                        )),
2722                        Some((
2723                            "whitespace_after_colon",
2724                            whitespace_after_colon.try_into_py(py)?,
2725                        )),
2726                        comma
2727                            .map(|x| x.try_into_py(py))
2728                            .transpose()?
2729                            .map(|x| ("comma", x)),
2730                    ]
2731                    .iter()
2732                    .filter(|x| x.is_some())
2733                    .map(|x| x.as_ref().unwrap())
2734                    .collect::<Vec<_>>()
2735                    .into_py_dict(py)?;
2736                    Ok(libcst
2737                        .getattr("DictElement")
2738                        .expect("no Element found in libcst")
2739                        .call((), Some(&kwargs))?
2740                        .into())
2741                }
2742            }
2743        }
2744    }
2745}