Skip to main content

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