Skip to main content

libcst_native/nodes/
statement.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 super::{
9    inflate_helpers::adjust_parameters_trailing_whitespace, Attribute, Codegen, CodegenState,
10    Comma, Dot, EmptyLine, Expression, From, ImportStar, LeftParen, List, Name, NameOrAttribute,
11    Parameters, ParenthesizableWhitespace, RightParen, Semicolon, SimpleWhitespace, StarredElement,
12    Subscript, TrailingWhitespace, Tuple,
13};
14use crate::{
15    nodes::{
16        expression::*,
17        op::*,
18        traits::{
19            Inflate, ParenthesizedDeflatedNode, ParenthesizedNode, Result, WithComma,
20            WithLeadingLines,
21        },
22    },
23    tokenizer::{
24        whitespace_parser::{
25            parse_empty_lines, parse_parenthesizable_whitespace, parse_simple_whitespace,
26            parse_trailing_whitespace, Config,
27        },
28        Token,
29    },
30    LeftCurlyBrace, LeftSquareBracket, RightCurlyBrace, RightSquareBracket,
31};
32#[cfg(feature = "py")]
33use libcst_derive::TryIntoPy;
34use libcst_derive::{cst_node, Codegen, Inflate, ParenthesizedDeflatedNode, ParenthesizedNode};
35
36type TokenRef<'r, 'a> = &'r Token<'a>;
37
38#[allow(clippy::large_enum_variant)]
39#[cst_node(Inflate, Codegen)]
40pub enum Statement<'a> {
41    Simple(SimpleStatementLine<'a>),
42    Compound(CompoundStatement<'a>),
43}
44
45impl<'a> WithLeadingLines<'a> for Statement<'a> {
46    fn leading_lines(&mut self) -> &mut Vec<EmptyLine<'a>> {
47        match self {
48            Self::Simple(s) => &mut s.leading_lines,
49            Self::Compound(c) => c.leading_lines(),
50        }
51    }
52}
53
54#[allow(clippy::large_enum_variant)]
55#[cst_node(Inflate, Codegen)]
56pub enum CompoundStatement<'a> {
57    FunctionDef(FunctionDef<'a>),
58    If(If<'a>),
59    For(For<'a>),
60    While(While<'a>),
61    ClassDef(ClassDef<'a>),
62    Try(Try<'a>),
63    TryStar(TryStar<'a>),
64    With(With<'a>),
65    Match(Match<'a>),
66}
67
68impl<'a> WithLeadingLines<'a> for CompoundStatement<'a> {
69    fn leading_lines(&mut self) -> &mut Vec<EmptyLine<'a>> {
70        match self {
71            Self::FunctionDef(f) => &mut f.leading_lines,
72            Self::If(f) => &mut f.leading_lines,
73            Self::For(f) => &mut f.leading_lines,
74            Self::While(f) => &mut f.leading_lines,
75            Self::ClassDef(c) => &mut c.leading_lines,
76            Self::Try(t) => &mut t.leading_lines,
77            Self::TryStar(t) => &mut t.leading_lines,
78            Self::With(w) => &mut w.leading_lines,
79            Self::Match(m) => &mut m.leading_lines,
80        }
81    }
82}
83
84#[cst_node(Inflate, Codegen)]
85pub enum Suite<'a> {
86    IndentedBlock(IndentedBlock<'a>),
87    SimpleStatementSuite(SimpleStatementSuite<'a>),
88}
89
90#[cst_node]
91pub struct IndentedBlock<'a> {
92    /// Sequence of statements belonging to this indented block.
93    pub body: Vec<Statement<'a>>,
94    /// Any optional trailing comment and the final ``NEWLINE`` at the end of the line.
95    pub header: TrailingWhitespace<'a>,
96    /// A string represents a specific indentation. A ``None`` value uses the modules's
97    /// default indentation. This is included because indentation is allowed to be
98    /// inconsistent across a file, just not ambiguously.
99    pub indent: Option<&'a str>,
100    /// Any trailing comments or lines after the dedent that are owned by this indented
101    /// block. Statements own preceeding and same-line trailing comments, but not
102    /// trailing lines, so it falls on :class:`IndentedBlock` to own it. In the case
103    /// that a statement follows an :class:`IndentedBlock`, that statement will own the
104    /// comments and lines that are at the same indent as the statement, and this
105    /// :class:`IndentedBlock` will own the comments and lines that are indented
106    /// further.
107    pub footer: Vec<EmptyLine<'a>>,
108
109    pub(crate) newline_tok: TokenRef<'a>,
110    pub(crate) indent_tok: TokenRef<'a>,
111    pub(crate) dedent_tok: TokenRef<'a>,
112}
113
114impl<'a> Codegen<'a> for IndentedBlock<'a> {
115    fn codegen(&self, state: &mut CodegenState<'a>) {
116        self.header.codegen(state);
117
118        let indent = match self.indent {
119            Some(i) => i,
120            None => state.default_indent,
121        };
122        state.indent(indent);
123
124        if self.body.is_empty() {
125            // Empty indented blocks are not syntactically valid in Python unless they
126            // contain a 'pass' statement, so add one here.
127            state.add_indent();
128            state.add_token("pass");
129            state.add_token(state.default_newline);
130        } else {
131            for stmt in &self.body {
132                // IndentedBlock is responsible for adjusting the current indentation
133                // level, but its children are responsible for actually adding that
134                // indentation to the token list.
135                stmt.codegen(state);
136            }
137        }
138
139        for f in &self.footer {
140            f.codegen(state);
141        }
142
143        state.dedent();
144    }
145}
146
147impl<'r, 'a> Inflate<'a> for DeflatedIndentedBlock<'r, 'a> {
148    type Inflated = IndentedBlock<'a>;
149    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
150        let body = self.body.inflate(config)?;
151        // We want to be able to only keep comments in the footer that are actually for
152        // this IndentedBlock. We do so by assuming that lines which are indented to the
153        // same level as the block itself are comments that go at the footer of the
154        // block. Comments that are indented to less than this indent are assumed to
155        // belong to the next line of code. We override the indent here because the
156        // dedent node's absolute indent is the resulting indentation after the dedent
157        // is performed. Its this way because the whitespace state for both the dedent's
158        // whitespace_after and the next BaseCompoundStatement's whitespace_before is
159        // shared. This allows us to partially parse here and parse the rest of the
160        // whitespace and comments on the next line, effectively making sure that
161        // comments are attached to the correct node.
162        let footer = parse_empty_lines(
163            config,
164            &mut (*self.dedent_tok).whitespace_after.borrow_mut(),
165            Some(self.indent_tok.whitespace_before.borrow().absolute_indent),
166        )?;
167        let header = parse_trailing_whitespace(
168            config,
169            &mut (*self.newline_tok).whitespace_before.borrow_mut(),
170        )?;
171        let mut indent = self.indent_tok.relative_indent;
172        if indent == Some(config.default_indent) {
173            indent = None;
174        }
175        Ok(Self::Inflated {
176            body,
177            header,
178            indent,
179            footer,
180        })
181    }
182}
183
184#[cst_node]
185pub struct SimpleStatementSuite<'a> {
186    /// Sequence of small statements. All but the last statement are required to have
187    /// a semicolon.
188    pub body: Vec<SmallStatement<'a>>,
189
190    /// The whitespace between the colon in the parent statement and the body.
191    pub leading_whitespace: SimpleWhitespace<'a>,
192    /// Any optional trailing comment and the final ``NEWLINE`` at the end of the line.
193    pub trailing_whitespace: TrailingWhitespace<'a>,
194
195    pub(crate) first_tok: TokenRef<'a>,
196    pub(crate) newline_tok: TokenRef<'a>,
197}
198
199impl<'r, 'a> Inflate<'a> for DeflatedSimpleStatementSuite<'r, 'a> {
200    type Inflated = SimpleStatementSuite<'a>;
201    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
202        let leading_whitespace = parse_simple_whitespace(
203            config,
204            &mut (*self.first_tok).whitespace_before.borrow_mut(),
205        )?;
206        let body = self.body.inflate(config)?;
207        let trailing_whitespace = parse_trailing_whitespace(
208            config,
209            &mut (*self.newline_tok).whitespace_before.borrow_mut(),
210        )?;
211        Ok(Self::Inflated {
212            body,
213            leading_whitespace,
214            trailing_whitespace,
215        })
216    }
217}
218
219fn _simple_statement_codegen<'a>(
220    body: &[SmallStatement<'a>],
221    trailing_whitespace: &TrailingWhitespace<'a>,
222    state: &mut CodegenState<'a>,
223) {
224    for stmt in body {
225        stmt.codegen(state);
226        // TODO: semicolon
227    }
228    if body.is_empty() {
229        // Empty simple statement blocks are not syntactically valid in Python
230        // unless they contain a 'pass' statement, so add one here.
231        state.add_token("pass")
232    }
233    trailing_whitespace.codegen(state);
234}
235
236impl<'a> Codegen<'a> for SimpleStatementSuite<'a> {
237    fn codegen(&self, state: &mut CodegenState<'a>) {
238        self.leading_whitespace.codegen(state);
239        _simple_statement_codegen(&self.body, &self.trailing_whitespace, state);
240    }
241}
242
243#[cst_node]
244pub struct SimpleStatementLine<'a> {
245    /// Sequence of small statements. All but the last statement are required to have
246    /// a semicolon.
247    pub body: Vec<SmallStatement<'a>>,
248
249    /// Sequence of empty lines appearing before this simple statement line.
250    pub leading_lines: Vec<EmptyLine<'a>>,
251    /// Any optional trailing comment and the final ``NEWLINE`` at the end of the line.
252    pub trailing_whitespace: TrailingWhitespace<'a>,
253
254    pub(crate) first_tok: TokenRef<'a>,
255    pub(crate) newline_tok: TokenRef<'a>,
256}
257
258impl<'a> Codegen<'a> for SimpleStatementLine<'a> {
259    fn codegen(&self, state: &mut CodegenState<'a>) {
260        for line in &self.leading_lines {
261            line.codegen(state);
262        }
263        state.add_indent();
264        _simple_statement_codegen(&self.body, &self.trailing_whitespace, state);
265    }
266}
267
268impl<'r, 'a> Inflate<'a> for DeflatedSimpleStatementLine<'r, 'a> {
269    type Inflated = SimpleStatementLine<'a>;
270    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
271        let leading_lines = parse_empty_lines(
272            config,
273            &mut (*self.first_tok).whitespace_before.borrow_mut(),
274            None,
275        )?;
276        let body = self.body.inflate(config)?;
277        let trailing_whitespace = parse_trailing_whitespace(
278            config,
279            &mut (*self.newline_tok).whitespace_before.borrow_mut(),
280        )?;
281        Ok(Self::Inflated {
282            body,
283            leading_lines,
284            trailing_whitespace,
285        })
286    }
287}
288
289#[allow(dead_code, clippy::large_enum_variant)]
290#[cst_node(Codegen, Inflate)]
291pub enum SmallStatement<'a> {
292    Pass(Pass<'a>),
293    Break(Break<'a>),
294    Continue(Continue<'a>),
295    Return(Return<'a>),
296    Expr(Expr<'a>),
297    Assert(Assert<'a>),
298    Import(Import<'a>),
299    ImportFrom(ImportFrom<'a>),
300    LazyImport(LazyImport<'a>),
301    LazyImportFrom(LazyImportFrom<'a>),
302    Assign(Assign<'a>),
303    AnnAssign(AnnAssign<'a>),
304    Raise(Raise<'a>),
305    Global(Global<'a>),
306    Nonlocal(Nonlocal<'a>),
307    AugAssign(AugAssign<'a>),
308    Del(Del<'a>),
309    TypeAlias(TypeAlias<'a>),
310}
311
312impl<'r, 'a> DeflatedSmallStatement<'r, 'a> {
313    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
314        match self {
315            Self::Pass(p) => Self::Pass(p.with_semicolon(semicolon)),
316            Self::Break(p) => Self::Break(p.with_semicolon(semicolon)),
317            Self::Continue(p) => Self::Continue(p.with_semicolon(semicolon)),
318            Self::Expr(p) => Self::Expr(p.with_semicolon(semicolon)),
319            Self::Import(i) => Self::Import(i.with_semicolon(semicolon)),
320            Self::ImportFrom(i) => Self::ImportFrom(i.with_semicolon(semicolon)),
321            Self::LazyImport(i) => Self::LazyImport(i.with_semicolon(semicolon)),
322            Self::LazyImportFrom(i) => Self::LazyImportFrom(i.with_semicolon(semicolon)),
323            Self::Assign(a) => Self::Assign(a.with_semicolon(semicolon)),
324            Self::AnnAssign(a) => Self::AnnAssign(a.with_semicolon(semicolon)),
325            Self::Return(r) => Self::Return(r.with_semicolon(semicolon)),
326            Self::Assert(a) => Self::Assert(a.with_semicolon(semicolon)),
327            Self::Raise(r) => Self::Raise(r.with_semicolon(semicolon)),
328            Self::Global(g) => Self::Global(g.with_semicolon(semicolon)),
329            Self::Nonlocal(l) => Self::Nonlocal(l.with_semicolon(semicolon)),
330            Self::AugAssign(a) => Self::AugAssign(a.with_semicolon(semicolon)),
331            Self::Del(d) => Self::Del(d.with_semicolon(semicolon)),
332            Self::TypeAlias(t) => Self::TypeAlias(t.with_semicolon(semicolon)),
333        }
334    }
335}
336
337#[cst_node]
338pub struct Pass<'a> {
339    pub semicolon: Option<Semicolon<'a>>,
340}
341impl<'r, 'a> DeflatedPass<'r, 'a> {
342    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
343        Self { semicolon }
344    }
345}
346impl<'a> Codegen<'a> for Pass<'a> {
347    fn codegen(&self, state: &mut CodegenState<'a>) {
348        state.add_token("pass");
349        self.semicolon.codegen(state);
350    }
351}
352impl<'r, 'a> Inflate<'a> for DeflatedPass<'r, 'a> {
353    type Inflated = Pass<'a>;
354    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
355        let semicolon = self.semicolon.inflate(config)?;
356        Ok(Self::Inflated { semicolon })
357    }
358}
359
360#[cst_node]
361pub struct Break<'a> {
362    pub semicolon: Option<Semicolon<'a>>,
363}
364impl<'r, 'a> DeflatedBreak<'r, 'a> {
365    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
366        Self { semicolon }
367    }
368}
369impl<'a> Codegen<'a> for Break<'a> {
370    fn codegen(&self, state: &mut CodegenState<'a>) {
371        state.add_token("break");
372        self.semicolon.codegen(state);
373    }
374}
375impl<'r, 'a> Inflate<'a> for DeflatedBreak<'r, 'a> {
376    type Inflated = Break<'a>;
377    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
378        let semicolon = self.semicolon.inflate(config)?;
379        Ok(Self::Inflated { semicolon })
380    }
381}
382
383#[cst_node]
384pub struct Continue<'a> {
385    pub semicolon: Option<Semicolon<'a>>,
386}
387impl<'r, 'a> DeflatedContinue<'r, 'a> {
388    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
389        Self { semicolon }
390    }
391}
392impl<'a> Codegen<'a> for Continue<'a> {
393    fn codegen(&self, state: &mut CodegenState<'a>) {
394        state.add_token("continue");
395        self.semicolon.codegen(state);
396    }
397}
398impl<'r, 'a> Inflate<'a> for DeflatedContinue<'r, 'a> {
399    type Inflated = Continue<'a>;
400    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
401        let semicolon = self.semicolon.inflate(config)?;
402        Ok(Self::Inflated { semicolon })
403    }
404}
405
406#[cst_node]
407pub struct Expr<'a> {
408    pub value: Expression<'a>,
409    pub semicolon: Option<Semicolon<'a>>,
410}
411impl<'r, 'a> DeflatedExpr<'r, 'a> {
412    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
413        Self { semicolon, ..self }
414    }
415}
416impl<'a> Codegen<'a> for Expr<'a> {
417    fn codegen(&self, state: &mut CodegenState<'a>) {
418        self.value.codegen(state);
419        self.semicolon.codegen(state);
420    }
421}
422impl<'r, 'a> Inflate<'a> for DeflatedExpr<'r, 'a> {
423    type Inflated = Expr<'a>;
424    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
425        let value = self.value.inflate(config)?;
426        let semicolon = self.semicolon.inflate(config)?;
427        Ok(Self::Inflated { value, semicolon })
428    }
429}
430
431#[cst_node]
432pub struct Assign<'a> {
433    pub targets: Vec<AssignTarget<'a>>,
434    pub value: Expression<'a>,
435    pub semicolon: Option<Semicolon<'a>>,
436}
437
438impl<'a> Codegen<'a> for Assign<'a> {
439    fn codegen(&self, state: &mut CodegenState<'a>) {
440        for target in &self.targets {
441            target.codegen(state);
442        }
443        self.value.codegen(state);
444        if let Some(semi) = &self.semicolon {
445            semi.codegen(state);
446        }
447    }
448}
449
450impl<'r, 'a> Inflate<'a> for DeflatedAssign<'r, 'a> {
451    type Inflated = Assign<'a>;
452    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
453        let targets = self.targets.inflate(config)?;
454        let value = self.value.inflate(config)?;
455        let semicolon = self.semicolon.inflate(config)?;
456        Ok(Self::Inflated {
457            targets,
458            value,
459            semicolon,
460        })
461    }
462}
463
464impl<'r, 'a> DeflatedAssign<'r, 'a> {
465    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
466        Self { semicolon, ..self }
467    }
468}
469
470#[cst_node]
471pub struct AssignTarget<'a> {
472    pub target: AssignTargetExpression<'a>,
473    pub whitespace_before_equal: SimpleWhitespace<'a>,
474    pub whitespace_after_equal: SimpleWhitespace<'a>,
475
476    pub(crate) equal_tok: TokenRef<'a>,
477}
478
479impl<'a> Codegen<'a> for AssignTarget<'a> {
480    fn codegen(&self, state: &mut CodegenState<'a>) {
481        self.target.codegen(state);
482        self.whitespace_before_equal.codegen(state);
483        state.add_token("=");
484        self.whitespace_after_equal.codegen(state);
485    }
486}
487
488impl<'r, 'a> Inflate<'a> for DeflatedAssignTarget<'r, 'a> {
489    type Inflated = AssignTarget<'a>;
490    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
491        let target = self.target.inflate(config)?;
492        let whitespace_before_equal = parse_simple_whitespace(
493            config,
494            &mut (*self.equal_tok).whitespace_before.borrow_mut(),
495        )?;
496        let whitespace_after_equal =
497            parse_simple_whitespace(config, &mut (*self.equal_tok).whitespace_after.borrow_mut())?;
498        Ok(Self::Inflated {
499            target,
500            whitespace_before_equal,
501            whitespace_after_equal,
502        })
503    }
504}
505
506#[allow(clippy::large_enum_variant)]
507#[cst_node(Codegen, ParenthesizedNode, Inflate)]
508pub enum AssignTargetExpression<'a> {
509    Name(Box<Name<'a>>),
510    Attribute(Box<Attribute<'a>>),
511    StarredElement(Box<StarredElement<'a>>),
512    Tuple(Box<Tuple<'a>>),
513    List(Box<List<'a>>),
514    Subscript(Box<Subscript<'a>>),
515}
516
517#[cst_node]
518pub struct Import<'a> {
519    pub names: Vec<ImportAlias<'a>>,
520    pub semicolon: Option<Semicolon<'a>>,
521    pub whitespace_after_import: SimpleWhitespace<'a>,
522
523    pub(crate) import_tok: TokenRef<'a>,
524}
525
526impl<'a> Codegen<'a> for Import<'a> {
527    fn codegen(&self, state: &mut CodegenState<'a>) {
528        state.add_token("import");
529        self.whitespace_after_import.codegen(state);
530        for (i, name) in self.names.iter().enumerate() {
531            name.codegen(state);
532            if name.comma.is_none() && i < self.names.len() - 1 {
533                state.add_token(", ");
534            }
535        }
536        if let Some(semi) = &self.semicolon {
537            semi.codegen(state);
538        }
539    }
540}
541
542impl<'r, 'a> Inflate<'a> for DeflatedImport<'r, 'a> {
543    type Inflated = Import<'a>;
544    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
545        let whitespace_after_import = parse_simple_whitespace(
546            config,
547            &mut (*self.import_tok).whitespace_after.borrow_mut(),
548        )?;
549        let names = self.names.inflate(config)?;
550        let semicolon = self.semicolon.inflate(config)?;
551        Ok(Self::Inflated {
552            names,
553            semicolon,
554            whitespace_after_import,
555        })
556    }
557}
558
559impl<'r, 'a> DeflatedImport<'r, 'a> {
560    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
561        Self { semicolon, ..self }
562    }
563}
564
565#[cst_node]
566pub struct ImportFrom<'a> {
567    #[cfg_attr(feature = "py", no_py_default)]
568    pub module: Option<NameOrAttribute<'a>>,
569    pub names: ImportNames<'a>,
570    pub relative: Vec<Dot<'a>>,
571    pub lpar: Option<LeftParen<'a>>,
572    pub rpar: Option<RightParen<'a>>,
573    pub semicolon: Option<Semicolon<'a>>,
574    pub whitespace_after_from: SimpleWhitespace<'a>,
575    pub whitespace_before_import: SimpleWhitespace<'a>,
576    pub whitespace_after_import: SimpleWhitespace<'a>,
577
578    pub(crate) from_tok: TokenRef<'a>,
579    pub(crate) import_tok: TokenRef<'a>,
580}
581
582impl<'a> Codegen<'a> for ImportFrom<'a> {
583    fn codegen(&self, state: &mut CodegenState<'a>) {
584        state.add_token("from");
585        self.whitespace_after_from.codegen(state);
586        for dot in &self.relative {
587            dot.codegen(state);
588        }
589        if let Some(module) = &self.module {
590            module.codegen(state);
591        }
592        self.whitespace_before_import.codegen(state);
593        state.add_token("import");
594        self.whitespace_after_import.codegen(state);
595        if let Some(lpar) = &self.lpar {
596            lpar.codegen(state);
597        }
598        self.names.codegen(state);
599        if let Some(rpar) = &self.rpar {
600            rpar.codegen(state);
601        }
602
603        if let Some(semi) = &self.semicolon {
604            semi.codegen(state);
605        }
606    }
607}
608
609impl<'r, 'a> Inflate<'a> for DeflatedImportFrom<'r, 'a> {
610    type Inflated = ImportFrom<'a>;
611    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
612        let whitespace_after_from =
613            parse_simple_whitespace(config, &mut (*self.from_tok).whitespace_after.borrow_mut())?;
614
615        let module = self.module.inflate(config)?;
616
617        let whitespace_after_import = parse_simple_whitespace(
618            config,
619            &mut (*self.import_tok).whitespace_after.borrow_mut(),
620        )?;
621
622        let mut relative = inflate_dots(self.relative, config)?;
623        let mut whitespace_before_import = Default::default();
624
625        if !relative.is_empty() && module.is_none() {
626            // For relative-only imports relocate the space after the final dot to be owned
627            // by the import token.
628            if let Some(Dot {
629                whitespace_after: ParenthesizableWhitespace::SimpleWhitespace(dot_ws),
630                ..
631            }) = relative.last_mut()
632            {
633                swap(dot_ws, &mut whitespace_before_import);
634            }
635        } else {
636            whitespace_before_import = parse_simple_whitespace(
637                config,
638                &mut (*self.import_tok).whitespace_before.borrow_mut(),
639            )?;
640        }
641
642        let lpar = self.lpar.inflate(config)?;
643        let names = self.names.inflate(config)?;
644        let rpar = self.rpar.inflate(config)?;
645
646        let semicolon = self.semicolon.inflate(config)?;
647
648        Ok(Self::Inflated {
649            module,
650            names,
651            relative,
652            lpar,
653            rpar,
654            semicolon,
655            whitespace_after_from,
656            whitespace_before_import,
657            whitespace_after_import,
658        })
659    }
660}
661
662fn inflate_dots<'r, 'a>(
663    dots: Vec<DeflatedDot<'r, 'a>>,
664    config: &Config<'a>,
665) -> Result<Vec<Dot<'a>>> {
666    let mut ret: Vec<Dot<'a>> = vec![];
667    let mut last_tok: Option<TokenRef<'r, 'a>> = None;
668    for dot in dots {
669        if let Some(last_tokref) = &last_tok {
670            // Consecutive dots having the same Token can only happen if `...` was
671            // parsed as a single ELLIPSIS token. In this case the token's
672            // whitespace_before belongs to the first dot, but the whitespace_after is
673            // moved to the 3rd dot (by swapping it twice)
674            if last_tokref.start_pos == dot.tok.start_pos {
675                let mut subsequent_dot = Dot {
676                    whitespace_before: Default::default(),
677                    whitespace_after: Default::default(),
678                };
679                swap(
680                    &mut ret.last_mut().unwrap().whitespace_after,
681                    &mut subsequent_dot.whitespace_after,
682                );
683                ret.push(subsequent_dot);
684                continue;
685            }
686        }
687        last_tok = Some(dot.tok);
688        ret.push(dot.inflate(config)?);
689    }
690    Ok(ret)
691}
692
693impl<'r, 'a> DeflatedImportFrom<'r, 'a> {
694    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
695        Self { semicolon, ..self }
696    }
697}
698
699// ---------------------------------------------------------------------------
700// PEP 810 – lazy import statements
701// ---------------------------------------------------------------------------
702
703/// A ``lazy import x`` statement (PEP 810).
704#[cst_node]
705pub struct LazyImport<'a> {
706    pub names: Vec<ImportAlias<'a>>,
707    pub semicolon: Option<Semicolon<'a>>,
708    pub whitespace_after_lazy: SimpleWhitespace<'a>,
709    pub whitespace_after_import: SimpleWhitespace<'a>,
710
711    pub(crate) lazy_tok: TokenRef<'a>,
712    pub(crate) import_tok: TokenRef<'a>,
713}
714
715impl<'a> Codegen<'a> for LazyImport<'a> {
716    fn codegen(&self, state: &mut CodegenState<'a>) {
717        state.add_token("lazy");
718        self.whitespace_after_lazy.codegen(state);
719        state.add_token("import");
720        self.whitespace_after_import.codegen(state);
721        for (i, name) in self.names.iter().enumerate() {
722            name.codegen(state);
723            if name.comma.is_none() && i < self.names.len() - 1 {
724                state.add_token(", ");
725            }
726        }
727        if let Some(semi) = &self.semicolon {
728            semi.codegen(state);
729        }
730    }
731}
732
733impl<'r, 'a> Inflate<'a> for DeflatedLazyImport<'r, 'a> {
734    type Inflated = LazyImport<'a>;
735    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
736        let whitespace_after_lazy =
737            parse_simple_whitespace(config, &mut (*self.lazy_tok).whitespace_after.borrow_mut())?;
738        let whitespace_after_import = parse_simple_whitespace(
739            config,
740            &mut (*self.import_tok).whitespace_after.borrow_mut(),
741        )?;
742        let names = self.names.inflate(config)?;
743        let semicolon = self.semicolon.inflate(config)?;
744        Ok(Self::Inflated {
745            names,
746            semicolon,
747            whitespace_after_lazy,
748            whitespace_after_import,
749        })
750    }
751}
752
753impl<'r, 'a> DeflatedLazyImport<'r, 'a> {
754    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
755        Self { semicolon, ..self }
756    }
757}
758
759/// A ``lazy from x import y`` statement (PEP 810).
760#[cst_node]
761pub struct LazyImportFrom<'a> {
762    #[cfg_attr(feature = "py", no_py_default)]
763    pub module: Option<NameOrAttribute<'a>>,
764    pub names: ImportNames<'a>,
765    pub relative: Vec<Dot<'a>>,
766    pub lpar: Option<LeftParen<'a>>,
767    pub rpar: Option<RightParen<'a>>,
768    pub semicolon: Option<Semicolon<'a>>,
769    pub whitespace_after_lazy: SimpleWhitespace<'a>,
770    pub whitespace_after_from: SimpleWhitespace<'a>,
771    pub whitespace_before_import: SimpleWhitespace<'a>,
772    pub whitespace_after_import: SimpleWhitespace<'a>,
773
774    pub(crate) lazy_tok: TokenRef<'a>,
775    pub(crate) from_tok: TokenRef<'a>,
776    pub(crate) import_tok: TokenRef<'a>,
777}
778
779impl<'a> Codegen<'a> for LazyImportFrom<'a> {
780    fn codegen(&self, state: &mut CodegenState<'a>) {
781        state.add_token("lazy");
782        self.whitespace_after_lazy.codegen(state);
783        state.add_token("from");
784        self.whitespace_after_from.codegen(state);
785        for dot in &self.relative {
786            dot.codegen(state);
787        }
788        if let Some(module) = &self.module {
789            module.codegen(state);
790        }
791        self.whitespace_before_import.codegen(state);
792        state.add_token("import");
793        self.whitespace_after_import.codegen(state);
794        if let Some(lpar) = &self.lpar {
795            lpar.codegen(state);
796        }
797        self.names.codegen(state);
798        if let Some(rpar) = &self.rpar {
799            rpar.codegen(state);
800        }
801        if let Some(semi) = &self.semicolon {
802            semi.codegen(state);
803        }
804    }
805}
806
807impl<'r, 'a> Inflate<'a> for DeflatedLazyImportFrom<'r, 'a> {
808    type Inflated = LazyImportFrom<'a>;
809    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
810        let whitespace_after_lazy =
811            parse_simple_whitespace(config, &mut (*self.lazy_tok).whitespace_after.borrow_mut())?;
812        let whitespace_after_from =
813            parse_simple_whitespace(config, &mut (*self.from_tok).whitespace_after.borrow_mut())?;
814        let module = self.module.inflate(config)?;
815        let whitespace_after_import = parse_simple_whitespace(
816            config,
817            &mut (*self.import_tok).whitespace_after.borrow_mut(),
818        )?;
819        let mut relative = inflate_dots(self.relative, config)?;
820        let mut whitespace_before_import = Default::default();
821        if !relative.is_empty() && module.is_none() {
822            if let Some(Dot {
823                whitespace_after: ParenthesizableWhitespace::SimpleWhitespace(dot_ws),
824                ..
825            }) = relative.last_mut()
826            {
827                swap(dot_ws, &mut whitespace_before_import);
828            }
829        } else {
830            whitespace_before_import = parse_simple_whitespace(
831                config,
832                &mut (*self.import_tok).whitespace_before.borrow_mut(),
833            )?;
834        }
835        let lpar = self.lpar.inflate(config)?;
836        let names = self.names.inflate(config)?;
837        let rpar = self.rpar.inflate(config)?;
838        let semicolon = self.semicolon.inflate(config)?;
839        Ok(Self::Inflated {
840            module,
841            names,
842            relative,
843            lpar,
844            rpar,
845            semicolon,
846            whitespace_after_lazy,
847            whitespace_after_from,
848            whitespace_before_import,
849            whitespace_after_import,
850        })
851    }
852}
853
854impl<'r, 'a> DeflatedLazyImportFrom<'r, 'a> {
855    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
856        Self { semicolon, ..self }
857    }
858}
859
860#[cst_node]
861pub struct ImportAlias<'a> {
862    pub name: NameOrAttribute<'a>,
863    pub asname: Option<AsName<'a>>,
864    pub comma: Option<Comma<'a>>,
865}
866
867impl<'r, 'a> Inflate<'a> for DeflatedImportAlias<'r, 'a> {
868    type Inflated = ImportAlias<'a>;
869    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
870        let name = self.name.inflate(config)?;
871        let asname = self.asname.inflate(config)?;
872        let comma = self.comma.inflate(config)?;
873        Ok(Self::Inflated {
874            name,
875            asname,
876            comma,
877        })
878    }
879}
880
881impl<'r, 'a> WithComma<'r, 'a> for DeflatedImportAlias<'r, 'a> {
882    fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
883        let comma = Some(comma);
884        Self { comma, ..self }
885    }
886}
887
888impl<'a> Codegen<'a> for ImportAlias<'a> {
889    fn codegen(&self, state: &mut CodegenState<'a>) {
890        self.name.codegen(state);
891        if let Some(asname) = &self.asname {
892            asname.codegen(state);
893        }
894        if let Some(comma) = &self.comma {
895            comma.codegen(state);
896        }
897    }
898}
899
900#[cst_node]
901pub struct AsName<'a> {
902    pub name: AssignTargetExpression<'a>,
903    pub whitespace_before_as: ParenthesizableWhitespace<'a>,
904    pub whitespace_after_as: ParenthesizableWhitespace<'a>,
905
906    pub(crate) as_tok: TokenRef<'a>,
907}
908
909impl<'a> Codegen<'a> for AsName<'a> {
910    fn codegen(&self, state: &mut CodegenState<'a>) {
911        self.whitespace_before_as.codegen(state);
912        state.add_token("as");
913        self.whitespace_after_as.codegen(state);
914        self.name.codegen(state);
915    }
916}
917
918impl<'r, 'a> Inflate<'a> for DeflatedAsName<'r, 'a> {
919    type Inflated = AsName<'a>;
920    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
921        let whitespace_before_as = parse_parenthesizable_whitespace(
922            config,
923            &mut (*self.as_tok).whitespace_before.borrow_mut(),
924        )?;
925        let whitespace_after_as = parse_parenthesizable_whitespace(
926            config,
927            &mut (*self.as_tok).whitespace_after.borrow_mut(),
928        )?;
929        let name = self.name.inflate(config)?;
930        Ok(Self::Inflated {
931            name,
932            whitespace_before_as,
933            whitespace_after_as,
934        })
935    }
936}
937
938#[cst_node(Inflate)]
939pub enum ImportNames<'a> {
940    Star(ImportStar),
941    Aliases(Vec<ImportAlias<'a>>),
942}
943
944impl<'a> Codegen<'a> for ImportNames<'a> {
945    fn codegen(&self, state: &mut CodegenState<'a>) {
946        match self {
947            Self::Star(s) => s.codegen(state),
948            Self::Aliases(aliases) => {
949                for (i, alias) in aliases.iter().enumerate() {
950                    alias.codegen(state);
951                    if alias.comma.is_none() && i < aliases.len() - 1 {
952                        state.add_token(", ");
953                    }
954                }
955            }
956        }
957    }
958}
959
960#[cst_node]
961pub struct FunctionDef<'a> {
962    pub name: Name<'a>,
963    pub type_parameters: Option<TypeParameters<'a>>,
964    pub params: Parameters<'a>,
965    pub body: Suite<'a>,
966    pub decorators: Vec<Decorator<'a>>,
967    pub returns: Option<Annotation<'a>>,
968    pub asynchronous: Option<Asynchronous<'a>>,
969    pub leading_lines: Vec<EmptyLine<'a>>,
970    pub lines_after_decorators: Vec<EmptyLine<'a>>,
971    pub whitespace_after_def: SimpleWhitespace<'a>,
972    pub whitespace_after_name: SimpleWhitespace<'a>,
973    pub whitespace_after_type_parameters: SimpleWhitespace<'a>,
974    pub whitespace_before_params: ParenthesizableWhitespace<'a>,
975    pub whitespace_before_colon: SimpleWhitespace<'a>,
976
977    pub(crate) async_tok: Option<TokenRef<'a>>,
978    pub(crate) def_tok: TokenRef<'a>,
979    pub(crate) open_paren_tok: TokenRef<'a>,
980    pub(crate) close_paren_tok: TokenRef<'a>,
981    pub(crate) colon_tok: TokenRef<'a>,
982}
983
984impl<'r, 'a> DeflatedFunctionDef<'r, 'a> {
985    pub fn with_decorators(self, decorators: Vec<DeflatedDecorator<'r, 'a>>) -> Self {
986        Self { decorators, ..self }
987    }
988}
989
990impl<'a> Codegen<'a> for FunctionDef<'a> {
991    fn codegen(&self, state: &mut CodegenState<'a>) {
992        for l in &self.leading_lines {
993            l.codegen(state);
994        }
995        for dec in self.decorators.iter() {
996            dec.codegen(state);
997        }
998        for l in &self.lines_after_decorators {
999            l.codegen(state);
1000        }
1001        state.add_indent();
1002
1003        if let Some(asy) = &self.asynchronous {
1004            asy.codegen(state);
1005        }
1006        state.add_token("def");
1007        self.whitespace_after_def.codegen(state);
1008        self.name.codegen(state);
1009        self.whitespace_after_name.codegen(state);
1010
1011        if let Some(tp) = &self.type_parameters {
1012            tp.codegen(state);
1013            self.whitespace_after_type_parameters.codegen(state);
1014        }
1015
1016        state.add_token("(");
1017        self.whitespace_before_params.codegen(state);
1018        self.params.codegen(state);
1019        state.add_token(")");
1020
1021        if let Some(ann) = &self.returns {
1022            ann.codegen(state, "->");
1023        }
1024
1025        self.whitespace_before_colon.codegen(state);
1026        state.add_token(":");
1027        self.body.codegen(state);
1028    }
1029}
1030
1031impl<'r, 'a> Inflate<'a> for DeflatedFunctionDef<'r, 'a> {
1032    type Inflated = FunctionDef<'a>;
1033    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
1034        let mut decorators = self.decorators.inflate(config)?;
1035        let (asynchronous, leading_lines) = if let Some(asy) = self.async_tok.as_mut() {
1036            let whitespace_after =
1037                parse_parenthesizable_whitespace(config, &mut asy.whitespace_after.borrow_mut())?;
1038            (
1039                Some(Asynchronous { whitespace_after }),
1040                Some(parse_empty_lines(
1041                    config,
1042                    &mut asy.whitespace_before.borrow_mut(),
1043                    None,
1044                )?),
1045            )
1046        } else {
1047            (None, None)
1048        };
1049
1050        let mut leading_lines = if let Some(ll) = leading_lines {
1051            ll
1052        } else {
1053            parse_empty_lines(
1054                config,
1055                &mut (*self.def_tok).whitespace_before.borrow_mut(),
1056                None,
1057            )?
1058        };
1059
1060        let mut lines_after_decorators = Default::default();
1061
1062        if let Some(dec) = decorators.first_mut() {
1063            swap(&mut lines_after_decorators, &mut leading_lines);
1064            swap(&mut dec.leading_lines, &mut leading_lines);
1065        }
1066
1067        let whitespace_after_def =
1068            parse_simple_whitespace(config, &mut (*self.def_tok).whitespace_after.borrow_mut())?;
1069
1070        let name = self.name.inflate(config)?;
1071
1072        let whitespace_after_name;
1073        let mut type_parameters = Default::default();
1074        let mut whitespace_after_type_parameters = Default::default();
1075
1076        if let Some(tp) = self.type_parameters {
1077            let rbracket_tok = tp.rbracket.tok.clone();
1078            whitespace_after_name = parse_simple_whitespace(
1079                config,
1080                &mut tp.lbracket.tok.whitespace_before.borrow_mut(),
1081            )?;
1082            type_parameters = Some(tp.inflate(config)?);
1083            whitespace_after_type_parameters =
1084                parse_simple_whitespace(config, &mut rbracket_tok.whitespace_after.borrow_mut())?;
1085        } else {
1086            whitespace_after_name = parse_simple_whitespace(
1087                config,
1088                &mut self.open_paren_tok.whitespace_before.borrow_mut(),
1089            )?;
1090        }
1091
1092        let whitespace_before_params = parse_parenthesizable_whitespace(
1093            config,
1094            &mut (*self.open_paren_tok).whitespace_after.borrow_mut(),
1095        )?;
1096        let mut params = self.params.inflate(config)?;
1097        adjust_parameters_trailing_whitespace(config, &mut params, &self.close_paren_tok)?;
1098
1099        let returns = self.returns.inflate(config)?;
1100        let whitespace_before_colon = parse_simple_whitespace(
1101            config,
1102            &mut (*self.colon_tok).whitespace_before.borrow_mut(),
1103        )?;
1104
1105        let body = self.body.inflate(config)?;
1106        Ok(Self::Inflated {
1107            name,
1108            type_parameters,
1109            params,
1110            body,
1111            decorators,
1112            returns,
1113            asynchronous,
1114            leading_lines,
1115            lines_after_decorators,
1116            whitespace_after_def,
1117            whitespace_after_name,
1118            whitespace_after_type_parameters,
1119            whitespace_before_params,
1120            whitespace_before_colon,
1121        })
1122    }
1123}
1124
1125#[cst_node]
1126pub struct Decorator<'a> {
1127    pub decorator: Expression<'a>,
1128    pub leading_lines: Vec<EmptyLine<'a>>,
1129    pub whitespace_after_at: SimpleWhitespace<'a>,
1130    pub trailing_whitespace: TrailingWhitespace<'a>,
1131
1132    pub(crate) at_tok: TokenRef<'a>,
1133    pub(crate) newline_tok: TokenRef<'a>,
1134}
1135
1136impl<'a> Codegen<'a> for Decorator<'a> {
1137    fn codegen(&self, state: &mut CodegenState<'a>) {
1138        for ll in self.leading_lines.iter() {
1139            ll.codegen(state);
1140        }
1141        state.add_indent();
1142        state.add_token("@");
1143        self.whitespace_after_at.codegen(state);
1144        self.decorator.codegen(state);
1145        self.trailing_whitespace.codegen(state);
1146    }
1147}
1148
1149impl<'r, 'a> Inflate<'a> for DeflatedDecorator<'r, 'a> {
1150    type Inflated = Decorator<'a>;
1151    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1152        let leading_lines = parse_empty_lines(
1153            config,
1154            &mut (*self.at_tok).whitespace_before.borrow_mut(),
1155            None,
1156        )?;
1157        let whitespace_after_at =
1158            parse_simple_whitespace(config, &mut (*self.at_tok).whitespace_after.borrow_mut())?;
1159        let decorator = self.decorator.inflate(config)?;
1160        let trailing_whitespace = parse_trailing_whitespace(
1161            config,
1162            &mut (*self.newline_tok).whitespace_before.borrow_mut(),
1163        )?;
1164        Ok(Self::Inflated {
1165            decorator,
1166            leading_lines,
1167            whitespace_after_at,
1168            trailing_whitespace,
1169        })
1170    }
1171}
1172
1173#[cst_node]
1174pub struct If<'a> {
1175    /// The expression that, when evaluated, should give us a truthy value
1176    pub test: Expression<'a>,
1177    // The body of this compound statement.
1178    pub body: Suite<'a>,
1179
1180    /// An optional ``elif`` or ``else`` clause. ``If`` signifies an ``elif`` block.
1181    pub orelse: Option<Box<OrElse<'a>>>,
1182
1183    /// Sequence of empty lines appearing before this compound statement line.
1184    pub leading_lines: Vec<EmptyLine<'a>>,
1185
1186    /// The whitespace appearing after the ``if`` keyword but before the test
1187    /// expression.
1188    pub whitespace_before_test: SimpleWhitespace<'a>,
1189
1190    /// The whitespace appearing after the test expression but before the colon.
1191    pub whitespace_after_test: SimpleWhitespace<'a>,
1192
1193    /// Signifies if this instance represents an ``elif`` or an ``if`` block.
1194    #[cfg_attr(feature = "py", skip_py)]
1195    pub is_elif: bool,
1196
1197    pub(crate) if_tok: TokenRef<'a>,
1198    pub(crate) colon_tok: TokenRef<'a>,
1199}
1200
1201impl<'a> Codegen<'a> for If<'a> {
1202    fn codegen(&self, state: &mut CodegenState<'a>) {
1203        for l in &self.leading_lines {
1204            l.codegen(state);
1205        }
1206        state.add_indent();
1207
1208        state.add_token(if self.is_elif { "elif" } else { "if" });
1209        self.whitespace_before_test.codegen(state);
1210        self.test.codegen(state);
1211        self.whitespace_after_test.codegen(state);
1212        state.add_token(":");
1213        self.body.codegen(state);
1214        if let Some(orelse) = &self.orelse {
1215            orelse.codegen(state)
1216        }
1217    }
1218}
1219
1220impl<'r, 'a> Inflate<'a> for DeflatedIf<'r, 'a> {
1221    type Inflated = If<'a>;
1222    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1223        let leading_lines = parse_empty_lines(
1224            config,
1225            &mut (*self.if_tok).whitespace_before.borrow_mut(),
1226            None,
1227        )?;
1228        let whitespace_before_test =
1229            parse_simple_whitespace(config, &mut (*self.if_tok).whitespace_after.borrow_mut())?;
1230        let test = self.test.inflate(config)?;
1231        let whitespace_after_test = parse_simple_whitespace(
1232            config,
1233            &mut (*self.colon_tok).whitespace_before.borrow_mut(),
1234        )?;
1235        let body = self.body.inflate(config)?;
1236        let orelse = self.orelse.inflate(config)?;
1237
1238        Ok(Self::Inflated {
1239            test,
1240            body,
1241            orelse,
1242            leading_lines,
1243            whitespace_before_test,
1244            whitespace_after_test,
1245            is_elif: self.is_elif,
1246        })
1247    }
1248}
1249
1250#[allow(clippy::large_enum_variant)]
1251#[cst_node(Inflate, Codegen)]
1252pub enum OrElse<'a> {
1253    Elif(If<'a>),
1254    Else(Else<'a>),
1255}
1256
1257#[cst_node]
1258pub struct Else<'a> {
1259    pub body: Suite<'a>,
1260    /// Sequence of empty lines appearing before this compound statement line.
1261    pub leading_lines: Vec<EmptyLine<'a>>,
1262    /// The whitespace appearing after the ``else`` keyword but before the colon.
1263    pub whitespace_before_colon: SimpleWhitespace<'a>,
1264
1265    pub(crate) else_tok: TokenRef<'a>,
1266    pub(crate) colon_tok: TokenRef<'a>,
1267}
1268
1269impl<'a> Codegen<'a> for Else<'a> {
1270    fn codegen(&self, state: &mut CodegenState<'a>) {
1271        for l in &self.leading_lines {
1272            l.codegen(state);
1273        }
1274        state.add_indent();
1275
1276        state.add_token("else");
1277        self.whitespace_before_colon.codegen(state);
1278        state.add_token(":");
1279        self.body.codegen(state);
1280    }
1281}
1282
1283impl<'r, 'a> Inflate<'a> for DeflatedElse<'r, 'a> {
1284    type Inflated = Else<'a>;
1285    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1286        let leading_lines = parse_empty_lines(
1287            config,
1288            &mut (*self.else_tok).whitespace_before.borrow_mut(),
1289            None,
1290        )?;
1291        let whitespace_before_colon = parse_simple_whitespace(
1292            config,
1293            &mut (*self.colon_tok).whitespace_before.borrow_mut(),
1294        )?;
1295        let body = self.body.inflate(config)?;
1296
1297        Ok(Self::Inflated {
1298            body,
1299            leading_lines,
1300            whitespace_before_colon,
1301        })
1302    }
1303}
1304
1305#[cst_node]
1306pub struct Annotation<'a> {
1307    pub annotation: Expression<'a>,
1308    pub whitespace_before_indicator: Option<ParenthesizableWhitespace<'a>>,
1309    pub whitespace_after_indicator: ParenthesizableWhitespace<'a>,
1310
1311    pub(crate) tok: TokenRef<'a>,
1312}
1313
1314impl<'a> Annotation<'a> {
1315    pub fn codegen(&self, state: &mut CodegenState<'a>, default_indicator: &'a str) {
1316        if let Some(ws) = &self.whitespace_before_indicator {
1317            ws.codegen(state);
1318        } else if default_indicator == "->" {
1319            state.add_token(" ");
1320        } else {
1321            panic!("Variable annotation but whitespace is None");
1322        }
1323
1324        state.add_token(default_indicator);
1325        self.whitespace_after_indicator.codegen(state);
1326        self.annotation.codegen(state);
1327    }
1328}
1329
1330impl<'r, 'a> Inflate<'a> for DeflatedAnnotation<'r, 'a> {
1331    type Inflated = Annotation<'a>;
1332    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1333        let whitespace_before_indicator = Some(parse_parenthesizable_whitespace(
1334            config,
1335            &mut (*self.tok).whitespace_before.borrow_mut(),
1336        )?);
1337        let whitespace_after_indicator = parse_parenthesizable_whitespace(
1338            config,
1339            &mut (*self.tok).whitespace_after.borrow_mut(),
1340        )?;
1341        let annotation = self.annotation.inflate(config)?;
1342        Ok(Self::Inflated {
1343            annotation,
1344            whitespace_before_indicator,
1345            whitespace_after_indicator,
1346        })
1347    }
1348}
1349
1350#[cst_node]
1351pub struct AnnAssign<'a> {
1352    pub target: AssignTargetExpression<'a>,
1353    pub annotation: Annotation<'a>,
1354    pub value: Option<Expression<'a>>,
1355    pub equal: Option<AssignEqual<'a>>,
1356    pub semicolon: Option<Semicolon<'a>>,
1357}
1358
1359impl<'a> Codegen<'a> for AnnAssign<'a> {
1360    fn codegen(&self, state: &mut CodegenState<'a>) {
1361        self.target.codegen(state);
1362        self.annotation.codegen(state, ":");
1363        if let Some(eq) = &self.equal {
1364            eq.codegen(state);
1365        } else if self.value.is_some() {
1366            state.add_token(" = ");
1367        }
1368        if let Some(value) = &self.value {
1369            value.codegen(state);
1370        }
1371
1372        if let Some(semi) = &self.semicolon {
1373            semi.codegen(state);
1374        }
1375    }
1376}
1377
1378impl<'r, 'a> Inflate<'a> for DeflatedAnnAssign<'r, 'a> {
1379    type Inflated = AnnAssign<'a>;
1380    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1381        let target = self.target.inflate(config)?;
1382        let annotation = self.annotation.inflate(config)?;
1383        let value = self.value.inflate(config)?;
1384        let equal = self.equal.inflate(config)?;
1385        let semicolon = self.semicolon.inflate(config)?;
1386        Ok(Self::Inflated {
1387            target,
1388            annotation,
1389            value,
1390            equal,
1391            semicolon,
1392        })
1393    }
1394}
1395
1396impl<'r, 'a> DeflatedAnnAssign<'r, 'a> {
1397    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
1398        Self { semicolon, ..self }
1399    }
1400}
1401
1402#[cst_node]
1403pub struct Return<'a> {
1404    pub value: Option<Expression<'a>>,
1405    pub whitespace_after_return: Option<SimpleWhitespace<'a>>,
1406    pub semicolon: Option<Semicolon<'a>>,
1407
1408    pub(crate) return_tok: TokenRef<'a>,
1409}
1410
1411impl<'a> Codegen<'a> for Return<'a> {
1412    fn codegen(&self, state: &mut CodegenState<'a>) {
1413        state.add_token("return");
1414        if let Some(ws) = &self.whitespace_after_return {
1415            ws.codegen(state);
1416        } else if self.value.is_some() {
1417            state.add_token(" ");
1418        }
1419
1420        if let Some(val) = &self.value {
1421            val.codegen(state);
1422        }
1423        if let Some(semi) = &self.semicolon {
1424            semi.codegen(state);
1425        }
1426    }
1427}
1428
1429impl<'r, 'a> Inflate<'a> for DeflatedReturn<'r, 'a> {
1430    type Inflated = Return<'a>;
1431    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1432        let whitespace_after_return = if self.value.is_some() {
1433            Some(parse_simple_whitespace(
1434                config,
1435                &mut (*self.return_tok).whitespace_after.borrow_mut(),
1436            )?)
1437        } else {
1438            // otherwise space is owned by semicolon or small statement
1439            // whitespace is not None to preserve a quirk of the pure python parser
1440            Some(Default::default())
1441        };
1442        let value = self.value.inflate(config)?;
1443        let semicolon = self.semicolon.inflate(config)?;
1444        Ok(Self::Inflated {
1445            value,
1446            whitespace_after_return,
1447            semicolon,
1448        })
1449    }
1450}
1451
1452impl<'r, 'a> DeflatedReturn<'r, 'a> {
1453    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
1454        Self { semicolon, ..self }
1455    }
1456}
1457
1458#[cst_node]
1459pub struct Assert<'a> {
1460    pub test: Expression<'a>,
1461    pub msg: Option<Expression<'a>>,
1462    pub comma: Option<Comma<'a>>,
1463    pub whitespace_after_assert: SimpleWhitespace<'a>,
1464    pub semicolon: Option<Semicolon<'a>>,
1465
1466    pub(crate) assert_tok: TokenRef<'a>,
1467}
1468
1469impl<'a> Codegen<'a> for Assert<'a> {
1470    fn codegen(&self, state: &mut CodegenState<'a>) {
1471        state.add_token("assert");
1472        self.whitespace_after_assert.codegen(state);
1473        self.test.codegen(state);
1474        if let Some(comma) = &self.comma {
1475            comma.codegen(state);
1476        } else if self.msg.is_some() {
1477            state.add_token(", ");
1478        }
1479        if let Some(msg) = &self.msg {
1480            msg.codegen(state);
1481        }
1482        if let Some(semi) = &self.semicolon {
1483            semi.codegen(state);
1484        }
1485    }
1486}
1487impl<'r, 'a> Inflate<'a> for DeflatedAssert<'r, 'a> {
1488    type Inflated = Assert<'a>;
1489    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1490        let whitespace_after_assert = parse_simple_whitespace(
1491            config,
1492            &mut (*self.assert_tok).whitespace_after.borrow_mut(),
1493        )?;
1494
1495        let test = self.test.inflate(config)?;
1496        let comma = self.comma.inflate(config)?;
1497        let msg = self.msg.inflate(config)?;
1498
1499        let semicolon = self.semicolon.inflate(config)?;
1500        Ok(Self::Inflated {
1501            test,
1502            msg,
1503            comma,
1504            whitespace_after_assert,
1505            semicolon,
1506        })
1507    }
1508}
1509
1510impl<'r, 'a> DeflatedAssert<'r, 'a> {
1511    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
1512        Self { semicolon, ..self }
1513    }
1514}
1515
1516#[cst_node]
1517pub struct Raise<'a> {
1518    pub exc: Option<Expression<'a>>,
1519    pub cause: Option<From<'a>>,
1520    pub whitespace_after_raise: Option<SimpleWhitespace<'a>>,
1521    pub semicolon: Option<Semicolon<'a>>,
1522
1523    pub(crate) raise_tok: TokenRef<'a>,
1524}
1525
1526impl<'r, 'a> Inflate<'a> for DeflatedRaise<'r, 'a> {
1527    type Inflated = Raise<'a>;
1528    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1529        let whitespace_after_raise = if self.exc.is_some() {
1530            Some(parse_simple_whitespace(
1531                config,
1532                &mut (*self.raise_tok).whitespace_after.borrow_mut(),
1533            )?)
1534        } else {
1535            Default::default()
1536        };
1537
1538        let exc = self.exc.inflate(config)?;
1539        let mut cause = self.cause.inflate(config)?;
1540        if exc.is_none() {
1541            if let Some(cause) = cause.as_mut() {
1542                // in `raise from`, `raise` owns the shared whitespace
1543                cause.whitespace_before_from = None;
1544            }
1545        }
1546        let semicolon = self.semicolon.inflate(config)?;
1547
1548        Ok(Self::Inflated {
1549            exc,
1550            cause,
1551            whitespace_after_raise,
1552            semicolon,
1553        })
1554    }
1555}
1556
1557impl<'a> Codegen<'a> for Raise<'a> {
1558    fn codegen(&self, state: &mut CodegenState<'a>) {
1559        state.add_token("raise");
1560        if let Some(ws) = &self.whitespace_after_raise {
1561            ws.codegen(state);
1562        } else if self.exc.is_some() {
1563            state.add_token(" ");
1564        }
1565
1566        if let Some(exc) = &self.exc {
1567            exc.codegen(state);
1568        }
1569
1570        if let Some(cause) = &self.cause {
1571            cause.codegen(state, " ");
1572        }
1573
1574        if let Some(semi) = &self.semicolon {
1575            semi.codegen(state);
1576        }
1577    }
1578}
1579
1580impl<'r, 'a> DeflatedRaise<'r, 'a> {
1581    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
1582        Self { semicolon, ..self }
1583    }
1584}
1585
1586#[cst_node]
1587pub struct NameItem<'a> {
1588    pub name: Name<'a>,
1589    pub comma: Option<Comma<'a>>,
1590}
1591
1592impl<'r, 'a> Inflate<'a> for DeflatedNameItem<'r, 'a> {
1593    type Inflated = NameItem<'a>;
1594    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1595        let name = self.name.inflate(config)?;
1596        let comma = self.comma.inflate(config)?;
1597        Ok(Self::Inflated { name, comma })
1598    }
1599}
1600
1601impl<'a> NameItem<'a> {
1602    fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) {
1603        self.name.codegen(state);
1604        if let Some(comma) = &self.comma {
1605            comma.codegen(state);
1606        } else if default_comma {
1607            state.add_token(", ");
1608        }
1609    }
1610}
1611
1612#[cst_node]
1613pub struct Global<'a> {
1614    pub names: Vec<NameItem<'a>>,
1615    pub whitespace_after_global: SimpleWhitespace<'a>,
1616    pub semicolon: Option<Semicolon<'a>>,
1617
1618    pub(crate) tok: TokenRef<'a>,
1619}
1620
1621impl<'r, 'a> Inflate<'a> for DeflatedGlobal<'r, 'a> {
1622    type Inflated = Global<'a>;
1623    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1624        let whitespace_after_global =
1625            parse_simple_whitespace(config, &mut (*self.tok).whitespace_after.borrow_mut())?;
1626        let names = self.names.inflate(config)?;
1627        let semicolon = self.semicolon.inflate(config)?;
1628        Ok(Self::Inflated {
1629            names,
1630            whitespace_after_global,
1631            semicolon,
1632        })
1633    }
1634}
1635
1636impl<'a> Codegen<'a> for Global<'a> {
1637    fn codegen(&self, state: &mut CodegenState<'a>) {
1638        state.add_token("global");
1639        self.whitespace_after_global.codegen(state);
1640        let len = self.names.len();
1641        for (i, name) in self.names.iter().enumerate() {
1642            name.codegen(state, i + 1 != len);
1643        }
1644
1645        if let Some(semicolon) = &self.semicolon {
1646            semicolon.codegen(state);
1647        }
1648    }
1649}
1650
1651impl<'r, 'a> DeflatedGlobal<'r, 'a> {
1652    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
1653        Self { semicolon, ..self }
1654    }
1655}
1656
1657#[cst_node]
1658pub struct Nonlocal<'a> {
1659    pub names: Vec<NameItem<'a>>,
1660    pub whitespace_after_nonlocal: SimpleWhitespace<'a>,
1661    pub semicolon: Option<Semicolon<'a>>,
1662
1663    pub(crate) tok: TokenRef<'a>,
1664}
1665
1666impl<'r, 'a> Inflate<'a> for DeflatedNonlocal<'r, 'a> {
1667    type Inflated = Nonlocal<'a>;
1668    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1669        let whitespace_after_nonlocal =
1670            parse_simple_whitespace(config, &mut (*self.tok).whitespace_after.borrow_mut())?;
1671        let names = self.names.inflate(config)?;
1672        let semicolon = self.semicolon.inflate(config)?;
1673        Ok(Self::Inflated {
1674            names,
1675            whitespace_after_nonlocal,
1676            semicolon,
1677        })
1678    }
1679}
1680
1681impl<'a> Codegen<'a> for Nonlocal<'a> {
1682    fn codegen(&self, state: &mut CodegenState<'a>) {
1683        state.add_token("nonlocal");
1684        self.whitespace_after_nonlocal.codegen(state);
1685        let len = self.names.len();
1686        for (i, name) in self.names.iter().enumerate() {
1687            name.codegen(state, i + 1 != len);
1688        }
1689
1690        if let Some(semicolon) = &self.semicolon {
1691            semicolon.codegen(state);
1692        }
1693    }
1694}
1695
1696impl<'r, 'a> DeflatedNonlocal<'r, 'a> {
1697    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
1698        Self { semicolon, ..self }
1699    }
1700}
1701
1702#[cst_node]
1703pub struct For<'a> {
1704    pub target: AssignTargetExpression<'a>,
1705    pub iter: Expression<'a>,
1706    pub body: Suite<'a>,
1707    pub orelse: Option<Else<'a>>,
1708    pub asynchronous: Option<Asynchronous<'a>>,
1709
1710    pub leading_lines: Vec<EmptyLine<'a>>,
1711    pub whitespace_after_for: SimpleWhitespace<'a>,
1712    pub whitespace_before_in: SimpleWhitespace<'a>,
1713    pub whitespace_after_in: SimpleWhitespace<'a>,
1714    pub whitespace_before_colon: SimpleWhitespace<'a>,
1715
1716    pub(crate) async_tok: Option<TokenRef<'a>>,
1717    pub(crate) for_tok: TokenRef<'a>,
1718    pub(crate) in_tok: TokenRef<'a>,
1719    pub(crate) colon_tok: TokenRef<'a>,
1720}
1721
1722impl<'a> Codegen<'a> for For<'a> {
1723    fn codegen(&self, state: &mut CodegenState<'a>) {
1724        for ll in &self.leading_lines {
1725            ll.codegen(state);
1726        }
1727        state.add_indent();
1728
1729        if let Some(asy) = &self.asynchronous {
1730            asy.codegen(state);
1731        }
1732        state.add_token("for");
1733        self.whitespace_after_for.codegen(state);
1734        self.target.codegen(state);
1735        self.whitespace_before_in.codegen(state);
1736        state.add_token("in");
1737        self.whitespace_after_in.codegen(state);
1738        self.iter.codegen(state);
1739        self.whitespace_before_colon.codegen(state);
1740        state.add_token(":");
1741        self.body.codegen(state);
1742        if let Some(e) = &self.orelse {
1743            e.codegen(state);
1744        }
1745    }
1746}
1747
1748impl<'r, 'a> Inflate<'a> for DeflatedFor<'r, 'a> {
1749    type Inflated = For<'a>;
1750    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
1751        let (asynchronous, leading_lines) = if let Some(asy) = self.async_tok.as_mut() {
1752            let whitespace_after =
1753                parse_parenthesizable_whitespace(config, &mut asy.whitespace_after.borrow_mut())?;
1754            (
1755                Some(Asynchronous { whitespace_after }),
1756                Some(parse_empty_lines(
1757                    config,
1758                    &mut asy.whitespace_before.borrow_mut(),
1759                    None,
1760                )?),
1761            )
1762        } else {
1763            (None, None)
1764        };
1765        let leading_lines = if let Some(ll) = leading_lines {
1766            ll
1767        } else {
1768            parse_empty_lines(
1769                config,
1770                &mut (*self.for_tok).whitespace_before.borrow_mut(),
1771                None,
1772            )?
1773        };
1774        let whitespace_after_for =
1775            parse_simple_whitespace(config, &mut (*self.for_tok).whitespace_after.borrow_mut())?;
1776        let target = self.target.inflate(config)?;
1777        let whitespace_before_in =
1778            parse_simple_whitespace(config, &mut (*self.in_tok).whitespace_before.borrow_mut())?;
1779        let whitespace_after_in =
1780            parse_simple_whitespace(config, &mut (*self.in_tok).whitespace_after.borrow_mut())?;
1781        let iter = self.iter.inflate(config)?;
1782        let whitespace_before_colon = parse_simple_whitespace(
1783            config,
1784            &mut (*self.colon_tok).whitespace_before.borrow_mut(),
1785        )?;
1786
1787        let body = self.body.inflate(config)?;
1788        let orelse = self.orelse.inflate(config)?;
1789
1790        Ok(Self::Inflated {
1791            target,
1792            iter,
1793            body,
1794            orelse,
1795            asynchronous,
1796            leading_lines,
1797            whitespace_after_for,
1798            whitespace_before_in,
1799            whitespace_after_in,
1800            whitespace_before_colon,
1801        })
1802    }
1803}
1804
1805#[cst_node]
1806pub struct While<'a> {
1807    pub test: Expression<'a>,
1808    pub body: Suite<'a>,
1809    pub orelse: Option<Else<'a>>,
1810    pub leading_lines: Vec<EmptyLine<'a>>,
1811    pub whitespace_after_while: SimpleWhitespace<'a>,
1812    pub whitespace_before_colon: SimpleWhitespace<'a>,
1813
1814    pub(crate) while_tok: TokenRef<'a>,
1815    pub(crate) colon_tok: TokenRef<'a>,
1816}
1817
1818impl<'a> Codegen<'a> for While<'a> {
1819    fn codegen(&self, state: &mut CodegenState<'a>) {
1820        for ll in &self.leading_lines {
1821            ll.codegen(state);
1822        }
1823        state.add_indent();
1824
1825        state.add_token("while");
1826        self.whitespace_after_while.codegen(state);
1827        self.test.codegen(state);
1828        self.whitespace_before_colon.codegen(state);
1829        state.add_token(":");
1830        self.body.codegen(state);
1831        if let Some(orelse) = &self.orelse {
1832            orelse.codegen(state);
1833        }
1834    }
1835}
1836
1837impl<'r, 'a> Inflate<'a> for DeflatedWhile<'r, 'a> {
1838    type Inflated = While<'a>;
1839    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1840        let leading_lines = parse_empty_lines(
1841            config,
1842            &mut (*self.while_tok).whitespace_before.borrow_mut(),
1843            None,
1844        )?;
1845        let whitespace_after_while =
1846            parse_simple_whitespace(config, &mut (*self.while_tok).whitespace_after.borrow_mut())?;
1847        let test = self.test.inflate(config)?;
1848        let whitespace_before_colon = parse_simple_whitespace(
1849            config,
1850            &mut (*self.colon_tok).whitespace_before.borrow_mut(),
1851        )?;
1852        let body = self.body.inflate(config)?;
1853        let orelse = self.orelse.inflate(config)?;
1854
1855        Ok(Self::Inflated {
1856            test,
1857            body,
1858            orelse,
1859            leading_lines,
1860            whitespace_after_while,
1861            whitespace_before_colon,
1862        })
1863    }
1864}
1865
1866#[cst_node]
1867pub struct ClassDef<'a> {
1868    pub name: Name<'a>,
1869    pub type_parameters: Option<TypeParameters<'a>>,
1870    pub body: Suite<'a>,
1871    pub bases: Vec<Arg<'a>>,
1872    pub keywords: Vec<Arg<'a>>,
1873    pub decorators: Vec<Decorator<'a>>,
1874    pub lpar: Option<LeftParen<'a>>,
1875    pub rpar: Option<RightParen<'a>>,
1876    pub leading_lines: Vec<EmptyLine<'a>>,
1877    pub lines_after_decorators: Vec<EmptyLine<'a>>,
1878    pub whitespace_after_class: SimpleWhitespace<'a>,
1879    pub whitespace_after_name: SimpleWhitespace<'a>,
1880    pub whitespace_after_type_parameters: SimpleWhitespace<'a>,
1881    pub whitespace_before_colon: SimpleWhitespace<'a>,
1882
1883    pub(crate) class_tok: TokenRef<'a>,
1884    pub(crate) lpar_tok: Option<TokenRef<'a>>,
1885    pub(crate) rpar_tok: Option<TokenRef<'a>>,
1886    pub(crate) colon_tok: TokenRef<'a>,
1887}
1888
1889impl<'a> Codegen<'a> for ClassDef<'a> {
1890    fn codegen(&self, state: &mut CodegenState<'a>) {
1891        for ll in &self.leading_lines {
1892            ll.codegen(state);
1893        }
1894        for dec in &self.decorators {
1895            dec.codegen(state);
1896        }
1897        for lad in &self.lines_after_decorators {
1898            lad.codegen(state);
1899        }
1900        state.add_indent();
1901
1902        state.add_token("class");
1903        self.whitespace_after_class.codegen(state);
1904        self.name.codegen(state);
1905        self.whitespace_after_name.codegen(state);
1906
1907        if let Some(tp) = &self.type_parameters {
1908            tp.codegen(state);
1909            self.whitespace_after_type_parameters.codegen(state);
1910        }
1911
1912        let need_parens = !self.bases.is_empty() || !self.keywords.is_empty();
1913
1914        if let Some(lpar) = &self.lpar {
1915            lpar.codegen(state);
1916        } else if need_parens {
1917            state.add_token("(");
1918        }
1919        let args = self.bases.iter().chain(self.keywords.iter());
1920        let len = self.bases.len() + self.keywords.len();
1921        for (i, arg) in args.enumerate() {
1922            arg.codegen(state, i + 1 < len);
1923        }
1924
1925        if let Some(rpar) = &self.rpar {
1926            rpar.codegen(state);
1927        } else if need_parens {
1928            state.add_token(")");
1929        }
1930
1931        self.whitespace_before_colon.codegen(state);
1932        state.add_token(":");
1933        self.body.codegen(state);
1934    }
1935}
1936
1937impl<'r, 'a> Inflate<'a> for DeflatedClassDef<'r, 'a> {
1938    type Inflated = ClassDef<'a>;
1939    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
1940        let mut leading_lines = parse_empty_lines(
1941            config,
1942            &mut (*self.class_tok).whitespace_before.borrow_mut(),
1943            None,
1944        )?;
1945        let mut decorators = self.decorators.inflate(config)?;
1946        let mut lines_after_decorators = Default::default();
1947        if let Some(dec) = decorators.first_mut() {
1948            swap(&mut lines_after_decorators, &mut leading_lines);
1949            swap(&mut dec.leading_lines, &mut leading_lines);
1950        }
1951
1952        let whitespace_after_class =
1953            parse_simple_whitespace(config, &mut (*self.class_tok).whitespace_after.borrow_mut())?;
1954        let name = self.name.inflate(config)?;
1955
1956        let (mut whitespace_after_name, mut type_parameters, mut whitespace_after_type_parameters) =
1957            Default::default();
1958
1959        if let Some(tparams) = self.type_parameters {
1960            let rbracket_tok = tparams.rbracket.tok.clone();
1961            whitespace_after_name = parse_simple_whitespace(
1962                config,
1963                &mut tparams.lbracket.tok.whitespace_before.borrow_mut(),
1964            )?;
1965            type_parameters = Some(tparams.inflate(config)?);
1966            whitespace_after_type_parameters =
1967                parse_simple_whitespace(config, &mut rbracket_tok.whitespace_after.borrow_mut())?;
1968        } else if let Some(lpar_tok) = self.lpar_tok.as_mut() {
1969            whitespace_after_name =
1970                parse_simple_whitespace(config, &mut lpar_tok.whitespace_before.borrow_mut())?;
1971        }
1972
1973        let lpar = self.lpar.inflate(config)?;
1974        let bases = self.bases.inflate(config)?;
1975        let keywords = self.keywords.inflate(config)?;
1976        let rpar = self.rpar.inflate(config)?;
1977
1978        let whitespace_before_colon = parse_simple_whitespace(
1979            config,
1980            &mut (*self.colon_tok).whitespace_before.borrow_mut(),
1981        )?;
1982        let body = self.body.inflate(config)?;
1983
1984        Ok(Self::Inflated {
1985            name,
1986            type_parameters,
1987            body,
1988            bases,
1989            keywords,
1990            decorators,
1991            lpar,
1992            rpar,
1993            leading_lines,
1994            lines_after_decorators,
1995            whitespace_after_class,
1996            whitespace_after_type_parameters,
1997            whitespace_after_name,
1998            whitespace_before_colon,
1999        })
2000    }
2001}
2002
2003impl<'r, 'a> DeflatedClassDef<'r, 'a> {
2004    pub fn with_decorators(self, decorators: Vec<DeflatedDecorator<'r, 'a>>) -> Self {
2005        Self { decorators, ..self }
2006    }
2007}
2008
2009#[cst_node]
2010pub struct Finally<'a> {
2011    pub body: Suite<'a>,
2012    pub leading_lines: Vec<EmptyLine<'a>>,
2013    pub whitespace_before_colon: SimpleWhitespace<'a>,
2014
2015    pub(crate) finally_tok: TokenRef<'a>,
2016    pub(crate) colon_tok: TokenRef<'a>,
2017}
2018
2019impl<'a> Codegen<'a> for Finally<'a> {
2020    fn codegen(&self, state: &mut CodegenState<'a>) {
2021        for ll in &self.leading_lines {
2022            ll.codegen(state);
2023        }
2024        state.add_indent();
2025
2026        state.add_token("finally");
2027        self.whitespace_before_colon.codegen(state);
2028        state.add_token(":");
2029        self.body.codegen(state);
2030    }
2031}
2032
2033impl<'r, 'a> Inflate<'a> for DeflatedFinally<'r, 'a> {
2034    type Inflated = Finally<'a>;
2035    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2036        let leading_lines = parse_empty_lines(
2037            config,
2038            &mut (*self.finally_tok).whitespace_before.borrow_mut(),
2039            None,
2040        )?;
2041        let whitespace_before_colon = parse_simple_whitespace(
2042            config,
2043            &mut (*self.colon_tok).whitespace_before.borrow_mut(),
2044        )?;
2045        let body = self.body.inflate(config)?;
2046        Ok(Self::Inflated {
2047            body,
2048            leading_lines,
2049            whitespace_before_colon,
2050        })
2051    }
2052}
2053
2054#[cst_node]
2055pub struct ExceptHandler<'a> {
2056    pub body: Suite<'a>,
2057    pub r#type: Option<Expression<'a>>,
2058    pub name: Option<AsName<'a>>,
2059    pub leading_lines: Vec<EmptyLine<'a>>,
2060    pub whitespace_after_except: SimpleWhitespace<'a>,
2061    pub whitespace_before_colon: SimpleWhitespace<'a>,
2062
2063    pub(crate) except_tok: TokenRef<'a>,
2064    pub(crate) colon_tok: TokenRef<'a>,
2065}
2066
2067impl<'a> Codegen<'a> for ExceptHandler<'a> {
2068    fn codegen(&self, state: &mut CodegenState<'a>) {
2069        for ll in &self.leading_lines {
2070            ll.codegen(state);
2071        }
2072        state.add_indent();
2073
2074        state.add_token("except");
2075        self.whitespace_after_except.codegen(state);
2076        if let Some(t) = &self.r#type {
2077            t.codegen(state);
2078        }
2079        if let Some(n) = &self.name {
2080            n.codegen(state);
2081        }
2082        self.whitespace_before_colon.codegen(state);
2083        state.add_token(":");
2084        self.body.codegen(state);
2085    }
2086}
2087
2088impl<'r, 'a> Inflate<'a> for DeflatedExceptHandler<'r, 'a> {
2089    type Inflated = ExceptHandler<'a>;
2090    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2091        let leading_lines = parse_empty_lines(
2092            config,
2093            &mut (*self.except_tok).whitespace_before.borrow_mut(),
2094            None,
2095        )?;
2096        let whitespace_after_except = parse_simple_whitespace(
2097            config,
2098            &mut (*self.except_tok).whitespace_after.borrow_mut(),
2099        )?;
2100
2101        let r#type = self.r#type.inflate(config)?;
2102        let name = self.name.inflate(config)?;
2103        let whitespace_before_colon = if name.is_some() {
2104            parse_simple_whitespace(
2105                config,
2106                &mut (*self.colon_tok).whitespace_before.borrow_mut(),
2107            )?
2108        } else {
2109            Default::default()
2110        };
2111
2112        let body = self.body.inflate(config)?;
2113        Ok(Self::Inflated {
2114            body,
2115            r#type,
2116            name,
2117            leading_lines,
2118            whitespace_after_except,
2119            whitespace_before_colon,
2120        })
2121    }
2122}
2123
2124#[cst_node]
2125pub struct ExceptStarHandler<'a> {
2126    pub body: Suite<'a>,
2127    pub r#type: Expression<'a>,
2128    pub name: Option<AsName<'a>>,
2129    pub leading_lines: Vec<EmptyLine<'a>>,
2130    pub whitespace_after_except: SimpleWhitespace<'a>,
2131    pub whitespace_after_star: SimpleWhitespace<'a>,
2132    pub whitespace_before_colon: SimpleWhitespace<'a>,
2133
2134    pub(crate) except_tok: TokenRef<'a>,
2135    pub(crate) star_tok: TokenRef<'a>,
2136    pub(crate) colon_tok: TokenRef<'a>,
2137}
2138
2139impl<'a> Codegen<'a> for ExceptStarHandler<'a> {
2140    fn codegen(&self, state: &mut CodegenState<'a>) {
2141        for ll in &self.leading_lines {
2142            ll.codegen(state);
2143        }
2144        state.add_indent();
2145
2146        state.add_token("except");
2147        self.whitespace_after_except.codegen(state);
2148        state.add_token("*");
2149        self.whitespace_after_star.codegen(state);
2150        self.r#type.codegen(state);
2151        if let Some(n) = &self.name {
2152            n.codegen(state);
2153        }
2154        self.whitespace_before_colon.codegen(state);
2155        state.add_token(":");
2156        self.body.codegen(state);
2157    }
2158}
2159
2160impl<'r, 'a> Inflate<'a> for DeflatedExceptStarHandler<'r, 'a> {
2161    type Inflated = ExceptStarHandler<'a>;
2162    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2163        let leading_lines = parse_empty_lines(
2164            config,
2165            &mut self.except_tok.whitespace_before.borrow_mut(),
2166            None,
2167        )?;
2168        let whitespace_after_except =
2169            parse_simple_whitespace(config, &mut self.except_tok.whitespace_after.borrow_mut())?;
2170        let whitespace_after_star =
2171            parse_simple_whitespace(config, &mut self.star_tok.whitespace_after.borrow_mut())?;
2172
2173        let r#type = self.r#type.inflate(config)?;
2174        let name = self.name.inflate(config)?;
2175        let whitespace_before_colon = if name.is_some() {
2176            parse_simple_whitespace(config, &mut self.colon_tok.whitespace_before.borrow_mut())?
2177        } else {
2178            Default::default()
2179        };
2180
2181        let body = self.body.inflate(config)?;
2182        Ok(Self::Inflated {
2183            body,
2184            r#type,
2185            name,
2186            leading_lines,
2187            whitespace_after_except,
2188            whitespace_after_star,
2189            whitespace_before_colon,
2190        })
2191    }
2192}
2193
2194#[cst_node]
2195pub struct Try<'a> {
2196    pub body: Suite<'a>,
2197    pub handlers: Vec<ExceptHandler<'a>>,
2198    pub orelse: Option<Else<'a>>,
2199    pub finalbody: Option<Finally<'a>>,
2200    pub leading_lines: Vec<EmptyLine<'a>>,
2201    pub whitespace_before_colon: SimpleWhitespace<'a>,
2202
2203    pub(crate) try_tok: TokenRef<'a>,
2204    // colon_tok unnecessary
2205}
2206
2207impl<'a> Codegen<'a> for Try<'a> {
2208    fn codegen(&self, state: &mut CodegenState<'a>) {
2209        for ll in &self.leading_lines {
2210            ll.codegen(state);
2211        }
2212        state.add_indent();
2213        state.add_token("try");
2214        self.whitespace_before_colon.codegen(state);
2215        state.add_token(":");
2216        self.body.codegen(state);
2217        for h in &self.handlers {
2218            h.codegen(state);
2219        }
2220        if let Some(e) = &self.orelse {
2221            e.codegen(state);
2222        }
2223        if let Some(f) = &self.finalbody {
2224            f.codegen(state);
2225        }
2226    }
2227}
2228
2229impl<'r, 'a> Inflate<'a> for DeflatedTry<'r, 'a> {
2230    type Inflated = Try<'a>;
2231    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2232        let leading_lines = parse_empty_lines(
2233            config,
2234            &mut (*self.try_tok).whitespace_before.borrow_mut(),
2235            None,
2236        )?;
2237        let whitespace_before_colon =
2238            parse_simple_whitespace(config, &mut (*self.try_tok).whitespace_after.borrow_mut())?;
2239        let body = self.body.inflate(config)?;
2240        let handlers = self.handlers.inflate(config)?;
2241        let orelse = self.orelse.inflate(config)?;
2242        let finalbody = self.finalbody.inflate(config)?;
2243        Ok(Self::Inflated {
2244            body,
2245            handlers,
2246            orelse,
2247            finalbody,
2248            leading_lines,
2249            whitespace_before_colon,
2250        })
2251    }
2252}
2253
2254#[cst_node]
2255pub struct TryStar<'a> {
2256    pub body: Suite<'a>,
2257    pub handlers: Vec<ExceptStarHandler<'a>>,
2258    pub orelse: Option<Else<'a>>,
2259    pub finalbody: Option<Finally<'a>>,
2260    pub leading_lines: Vec<EmptyLine<'a>>,
2261    pub whitespace_before_colon: SimpleWhitespace<'a>,
2262
2263    pub(crate) try_tok: TokenRef<'a>,
2264    // colon_tok unnecessary
2265}
2266
2267impl<'a> Codegen<'a> for TryStar<'a> {
2268    fn codegen(&self, state: &mut CodegenState<'a>) {
2269        for ll in &self.leading_lines {
2270            ll.codegen(state);
2271        }
2272        state.add_indent();
2273        state.add_token("try");
2274        self.whitespace_before_colon.codegen(state);
2275        state.add_token(":");
2276        self.body.codegen(state);
2277        for h in &self.handlers {
2278            h.codegen(state);
2279        }
2280        if let Some(e) = &self.orelse {
2281            e.codegen(state);
2282        }
2283        if let Some(f) = &self.finalbody {
2284            f.codegen(state);
2285        }
2286    }
2287}
2288
2289impl<'r, 'a> Inflate<'a> for DeflatedTryStar<'r, 'a> {
2290    type Inflated = TryStar<'a>;
2291    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2292        let leading_lines = parse_empty_lines(
2293            config,
2294            &mut (*self.try_tok).whitespace_before.borrow_mut(),
2295            None,
2296        )?;
2297        let whitespace_before_colon =
2298            parse_simple_whitespace(config, &mut (*self.try_tok).whitespace_after.borrow_mut())?;
2299        let body = self.body.inflate(config)?;
2300        let handlers = self.handlers.inflate(config)?;
2301        let orelse = self.orelse.inflate(config)?;
2302        let finalbody = self.finalbody.inflate(config)?;
2303        Ok(Self::Inflated {
2304            body,
2305            handlers,
2306            orelse,
2307            finalbody,
2308            leading_lines,
2309            whitespace_before_colon,
2310        })
2311    }
2312}
2313
2314#[cst_node]
2315pub struct AugAssign<'a> {
2316    pub target: AssignTargetExpression<'a>,
2317    pub operator: AugOp<'a>,
2318    pub value: Expression<'a>,
2319    pub semicolon: Option<Semicolon<'a>>,
2320}
2321
2322impl<'r, 'a> Inflate<'a> for DeflatedAugAssign<'r, 'a> {
2323    type Inflated = AugAssign<'a>;
2324    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2325        let target = self.target.inflate(config)?;
2326        let operator = self.operator.inflate(config)?;
2327        let value = self.value.inflate(config)?;
2328        let semicolon = self.semicolon.inflate(config)?;
2329        Ok(Self::Inflated {
2330            target,
2331            operator,
2332            value,
2333            semicolon,
2334        })
2335    }
2336}
2337
2338impl<'a> Codegen<'a> for AugAssign<'a> {
2339    fn codegen(&self, state: &mut CodegenState<'a>) {
2340        self.target.codegen(state);
2341        self.operator.codegen(state);
2342        self.value.codegen(state);
2343
2344        if let Some(s) = &self.semicolon {
2345            s.codegen(state);
2346        }
2347    }
2348}
2349
2350impl<'r, 'a> DeflatedAugAssign<'r, 'a> {
2351    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
2352        Self { semicolon, ..self }
2353    }
2354}
2355
2356#[cst_node]
2357pub struct WithItem<'a> {
2358    pub item: Expression<'a>,
2359    pub asname: Option<AsName<'a>>,
2360    pub comma: Option<Comma<'a>>,
2361}
2362
2363impl<'r, 'a> DeflatedWithItem<'r, 'a> {
2364    fn inflate_withitem(self, config: &Config<'a>, is_last: bool) -> Result<WithItem<'a>> {
2365        let item = self.item.inflate(config)?;
2366        let asname = self.asname.inflate(config)?;
2367        let comma = if is_last {
2368            self.comma.map(|c| c.inflate_before(config)).transpose()?
2369        } else {
2370            self.comma.map(|c| c.inflate(config)).transpose()?
2371        };
2372        Ok(WithItem {
2373            item,
2374            asname,
2375            comma,
2376        })
2377    }
2378}
2379
2380impl<'a> Codegen<'a> for WithItem<'a> {
2381    fn codegen(&self, state: &mut CodegenState<'a>) {
2382        self.item.codegen(state);
2383        if let Some(n) = &self.asname {
2384            n.codegen(state);
2385        }
2386        if let Some(c) = &self.comma {
2387            c.codegen(state);
2388        }
2389    }
2390}
2391
2392impl<'r, 'a> WithComma<'r, 'a> for DeflatedWithItem<'r, 'a> {
2393    fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
2394        Self {
2395            comma: Some(comma),
2396            ..self
2397        }
2398    }
2399}
2400
2401#[cst_node]
2402pub struct With<'a> {
2403    pub items: Vec<WithItem<'a>>,
2404    pub body: Suite<'a>,
2405    pub asynchronous: Option<Asynchronous<'a>>,
2406    pub leading_lines: Vec<EmptyLine<'a>>,
2407    pub lpar: Option<LeftParen<'a>>,
2408    pub rpar: Option<RightParen<'a>>,
2409    pub whitespace_after_with: SimpleWhitespace<'a>,
2410    pub whitespace_before_colon: SimpleWhitespace<'a>,
2411
2412    pub(crate) async_tok: Option<TokenRef<'a>>,
2413    pub(crate) with_tok: TokenRef<'a>,
2414    pub(crate) colon_tok: TokenRef<'a>,
2415}
2416
2417impl<'a> Codegen<'a> for With<'a> {
2418    fn codegen(&self, state: &mut CodegenState<'a>) {
2419        for ll in &self.leading_lines {
2420            ll.codegen(state);
2421        }
2422        state.add_indent();
2423
2424        if let Some(asy) = &self.asynchronous {
2425            asy.codegen(state);
2426        }
2427        state.add_token("with");
2428        self.whitespace_after_with.codegen(state);
2429
2430        // TODO: Force parens whenever there are newlines in
2431        // the commas of self.items.
2432        //
2433        // For now, only the python API does this.
2434        let need_parens = false;
2435        if let Some(lpar) = &self.lpar {
2436            lpar.codegen(state);
2437        } else if need_parens {
2438            state.add_token("(");
2439        }
2440
2441        let len = self.items.len();
2442        for (i, item) in self.items.iter().enumerate() {
2443            item.codegen(state);
2444            if item.comma.is_none() && i + 1 < len {
2445                state.add_token(", ");
2446            }
2447        }
2448
2449        if let Some(rpar) = &self.rpar {
2450            rpar.codegen(state);
2451        } else if need_parens {
2452            state.add_token(")");
2453        }
2454
2455        self.whitespace_before_colon.codegen(state);
2456        state.add_token(":");
2457        self.body.codegen(state);
2458    }
2459}
2460
2461impl<'r, 'a> Inflate<'a> for DeflatedWith<'r, 'a> {
2462    type Inflated = With<'a>;
2463    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
2464        let (asynchronous, leading_lines) = if let Some(asy) = self.async_tok.as_mut() {
2465            let whitespace_after =
2466                parse_parenthesizable_whitespace(config, &mut asy.whitespace_after.borrow_mut())?;
2467            (
2468                Some(Asynchronous { whitespace_after }),
2469                Some(parse_empty_lines(
2470                    config,
2471                    &mut asy.whitespace_before.borrow_mut(),
2472                    None,
2473                )?),
2474            )
2475        } else {
2476            (None, None)
2477        };
2478
2479        let leading_lines = if let Some(ll) = leading_lines {
2480            ll
2481        } else {
2482            parse_empty_lines(
2483                config,
2484                &mut (*self.with_tok).whitespace_before.borrow_mut(),
2485                None,
2486            )?
2487        };
2488
2489        let whitespace_after_with =
2490            parse_simple_whitespace(config, &mut (*self.with_tok).whitespace_after.borrow_mut())?;
2491        let lpar = self.lpar.map(|lpar| lpar.inflate(config)).transpose()?;
2492        let len = self.items.len();
2493        let items = self
2494            .items
2495            .into_iter()
2496            .enumerate()
2497            .map(|(idx, el)| el.inflate_withitem(config, idx + 1 == len))
2498            .collect::<Result<Vec<_>>>()?;
2499        let rpar = if !items.is_empty() {
2500            // rpar only has whitespace if items is non empty
2501            self.rpar.map(|rpar| rpar.inflate(config)).transpose()?
2502        } else {
2503            Default::default()
2504        };
2505        let whitespace_before_colon = parse_simple_whitespace(
2506            config,
2507            &mut (*self.colon_tok).whitespace_before.borrow_mut(),
2508        )?;
2509        let body = self.body.inflate(config)?;
2510
2511        Ok(Self::Inflated {
2512            items,
2513            body,
2514            asynchronous,
2515            leading_lines,
2516            lpar,
2517            rpar,
2518            whitespace_after_with,
2519            whitespace_before_colon,
2520        })
2521    }
2522}
2523
2524#[cst_node(Codegen, ParenthesizedNode, Inflate)]
2525pub enum DelTargetExpression<'a> {
2526    Name(Box<Name<'a>>),
2527    Attribute(Box<Attribute<'a>>),
2528    Tuple(Box<Tuple<'a>>),
2529    List(Box<List<'a>>),
2530    Subscript(Box<Subscript<'a>>),
2531}
2532
2533impl<'r, 'a> std::convert::From<DeflatedDelTargetExpression<'r, 'a>>
2534    for DeflatedExpression<'r, 'a>
2535{
2536    fn from(d: DeflatedDelTargetExpression<'r, 'a>) -> Self {
2537        match d {
2538            DeflatedDelTargetExpression::Attribute(a) => Self::Attribute(a),
2539            DeflatedDelTargetExpression::List(l) => Self::List(l),
2540            DeflatedDelTargetExpression::Name(n) => Self::Name(n),
2541            DeflatedDelTargetExpression::Subscript(s) => Self::Subscript(s),
2542            DeflatedDelTargetExpression::Tuple(t) => Self::Tuple(t),
2543        }
2544    }
2545}
2546impl<'r, 'a> std::convert::From<DeflatedDelTargetExpression<'r, 'a>> for DeflatedElement<'r, 'a> {
2547    fn from(d: DeflatedDelTargetExpression<'r, 'a>) -> Self {
2548        Self::Simple {
2549            value: d.into(),
2550            comma: None,
2551        }
2552    }
2553}
2554
2555#[cst_node]
2556pub struct Del<'a> {
2557    pub target: DelTargetExpression<'a>,
2558    pub whitespace_after_del: SimpleWhitespace<'a>,
2559    pub semicolon: Option<Semicolon<'a>>,
2560
2561    pub(crate) tok: TokenRef<'a>,
2562}
2563
2564impl<'r, 'a> Inflate<'a> for DeflatedDel<'r, 'a> {
2565    type Inflated = Del<'a>;
2566    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2567        let whitespace_after_del =
2568            parse_simple_whitespace(config, &mut (*self.tok).whitespace_after.borrow_mut())?;
2569        let target = self.target.inflate(config)?;
2570        let semicolon = self.semicolon.inflate(config)?;
2571        Ok(Self::Inflated {
2572            target,
2573            whitespace_after_del,
2574            semicolon,
2575        })
2576    }
2577}
2578
2579impl<'a> Codegen<'a> for Del<'a> {
2580    fn codegen(&self, state: &mut CodegenState<'a>) {
2581        state.add_token("del");
2582        self.whitespace_after_del.codegen(state);
2583        self.target.codegen(state);
2584        if let Some(semi) = &self.semicolon {
2585            semi.codegen(state);
2586        }
2587    }
2588}
2589
2590impl<'r, 'a> DeflatedDel<'r, 'a> {
2591    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
2592        Self { semicolon, ..self }
2593    }
2594}
2595
2596#[cst_node]
2597pub struct Match<'a> {
2598    pub subject: Expression<'a>,
2599    pub cases: Vec<MatchCase<'a>>,
2600
2601    pub leading_lines: Vec<EmptyLine<'a>>,
2602    pub whitespace_after_match: SimpleWhitespace<'a>,
2603    pub whitespace_before_colon: SimpleWhitespace<'a>,
2604    pub whitespace_after_colon: TrailingWhitespace<'a>,
2605    pub indent: Option<&'a str>,
2606    pub footer: Vec<EmptyLine<'a>>,
2607
2608    pub(crate) match_tok: TokenRef<'a>,
2609    pub(crate) colon_tok: TokenRef<'a>,
2610    pub(crate) indent_tok: TokenRef<'a>,
2611    pub(crate) dedent_tok: TokenRef<'a>,
2612}
2613
2614impl<'a> Codegen<'a> for Match<'a> {
2615    fn codegen(&self, state: &mut CodegenState<'a>) {
2616        for l in &self.leading_lines {
2617            l.codegen(state);
2618        }
2619        state.add_indent();
2620        state.add_token("match");
2621        self.whitespace_after_match.codegen(state);
2622        self.subject.codegen(state);
2623        self.whitespace_before_colon.codegen(state);
2624        state.add_token(":");
2625        self.whitespace_after_colon.codegen(state);
2626
2627        let indent = self.indent.unwrap_or(state.default_indent);
2628        state.indent(indent);
2629
2630        // Note: empty cases is a syntax error
2631        for c in &self.cases {
2632            c.codegen(state);
2633        }
2634
2635        for f in &self.footer {
2636            f.codegen(state);
2637        }
2638        state.dedent();
2639    }
2640}
2641
2642impl<'r, 'a> Inflate<'a> for DeflatedMatch<'r, 'a> {
2643    type Inflated = Match<'a>;
2644    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2645        let leading_lines = parse_empty_lines(
2646            config,
2647            &mut self.match_tok.whitespace_before.borrow_mut(),
2648            None,
2649        )?;
2650        let whitespace_after_match =
2651            parse_simple_whitespace(config, &mut self.match_tok.whitespace_after.borrow_mut())?;
2652        let subject = self.subject.inflate(config)?;
2653        let whitespace_before_colon =
2654            parse_simple_whitespace(config, &mut self.colon_tok.whitespace_before.borrow_mut())?;
2655        let whitespace_after_colon =
2656            parse_trailing_whitespace(config, &mut self.colon_tok.whitespace_after.borrow_mut())?;
2657        let mut indent = self.indent_tok.relative_indent;
2658        if indent == Some(config.default_indent) {
2659            indent = None;
2660        }
2661        let cases = self.cases.inflate(config)?;
2662        // See note about footers in `IndentedBlock`'s inflate fn
2663        let footer = parse_empty_lines(
2664            config,
2665            &mut self.dedent_tok.whitespace_after.borrow_mut(),
2666            Some(self.indent_tok.whitespace_before.borrow().absolute_indent),
2667        )?;
2668        Ok(Self::Inflated {
2669            subject,
2670            cases,
2671            leading_lines,
2672            whitespace_after_match,
2673            whitespace_before_colon,
2674            whitespace_after_colon,
2675            indent,
2676            footer,
2677        })
2678    }
2679}
2680
2681#[cst_node]
2682pub struct MatchCase<'a> {
2683    pub pattern: MatchPattern<'a>,
2684    pub guard: Option<Expression<'a>>,
2685    pub body: Suite<'a>,
2686
2687    pub leading_lines: Vec<EmptyLine<'a>>,
2688    pub whitespace_after_case: SimpleWhitespace<'a>,
2689    pub whitespace_before_if: SimpleWhitespace<'a>,
2690    pub whitespace_after_if: SimpleWhitespace<'a>,
2691    pub whitespace_before_colon: SimpleWhitespace<'a>,
2692
2693    pub(crate) case_tok: TokenRef<'a>,
2694    pub(crate) if_tok: Option<TokenRef<'a>>,
2695    pub(crate) colon_tok: TokenRef<'a>,
2696}
2697
2698impl<'a> Codegen<'a> for MatchCase<'a> {
2699    fn codegen(&self, state: &mut CodegenState<'a>) {
2700        for l in &self.leading_lines {
2701            l.codegen(state);
2702        }
2703        state.add_indent();
2704        state.add_token("case");
2705        self.whitespace_after_case.codegen(state);
2706        self.pattern.codegen(state);
2707        if let Some(guard) = &self.guard {
2708            self.whitespace_before_if.codegen(state);
2709            state.add_token("if");
2710            self.whitespace_after_if.codegen(state);
2711            guard.codegen(state);
2712        }
2713        self.whitespace_before_colon.codegen(state);
2714        state.add_token(":");
2715        self.body.codegen(state);
2716    }
2717}
2718
2719impl<'r, 'a> Inflate<'a> for DeflatedMatchCase<'r, 'a> {
2720    type Inflated = MatchCase<'a>;
2721    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
2722        let leading_lines = parse_empty_lines(
2723            config,
2724            &mut self.case_tok.whitespace_before.borrow_mut(),
2725            None,
2726        )?;
2727        let whitespace_after_case =
2728            parse_simple_whitespace(config, &mut self.case_tok.whitespace_after.borrow_mut())?;
2729        let pattern = self.pattern.inflate(config)?;
2730        let (whitespace_before_if, whitespace_after_if, guard) =
2731            if let Some(if_tok) = self.if_tok.as_mut() {
2732                (
2733                    parse_simple_whitespace(config, &mut if_tok.whitespace_before.borrow_mut())?,
2734                    parse_simple_whitespace(config, &mut if_tok.whitespace_after.borrow_mut())?,
2735                    self.guard.inflate(config)?,
2736                )
2737            } else {
2738                Default::default()
2739            };
2740        let whitespace_before_colon =
2741            parse_simple_whitespace(config, &mut self.colon_tok.whitespace_before.borrow_mut())?;
2742        let body = self.body.inflate(config)?;
2743        Ok(Self::Inflated {
2744            pattern,
2745            guard,
2746            body,
2747            leading_lines,
2748            whitespace_after_case,
2749            whitespace_before_if,
2750            whitespace_after_if,
2751            whitespace_before_colon,
2752        })
2753    }
2754}
2755
2756#[allow(clippy::large_enum_variant)]
2757#[cst_node(Codegen, Inflate, ParenthesizedNode)]
2758pub enum MatchPattern<'a> {
2759    Value(MatchValue<'a>),
2760    Singleton(MatchSingleton<'a>),
2761    Sequence(MatchSequence<'a>),
2762    Mapping(MatchMapping<'a>),
2763    Class(MatchClass<'a>),
2764    As(Box<MatchAs<'a>>),
2765    Or(Box<MatchOr<'a>>),
2766}
2767
2768#[cst_node]
2769pub struct MatchValue<'a> {
2770    pub value: Expression<'a>,
2771}
2772
2773impl<'a> ParenthesizedNode<'a> for MatchValue<'a> {
2774    fn lpar(&self) -> &Vec<LeftParen<'a>> {
2775        self.value.lpar()
2776    }
2777    fn rpar(&self) -> &Vec<RightParen<'a>> {
2778        self.value.rpar()
2779    }
2780    fn parenthesize<F>(&self, state: &mut CodegenState<'a>, f: F)
2781    where
2782        F: FnOnce(&mut CodegenState<'a>),
2783    {
2784        self.value.parenthesize(state, f)
2785    }
2786    fn with_parens(self, left: LeftParen<'a>, right: RightParen<'a>) -> Self {
2787        Self {
2788            value: self.value.with_parens(left, right),
2789        }
2790    }
2791}
2792
2793impl<'a> Codegen<'a> for MatchValue<'a> {
2794    fn codegen(&self, state: &mut CodegenState<'a>) {
2795        self.value.codegen(state)
2796    }
2797}
2798
2799impl<'r, 'a> Inflate<'a> for DeflatedMatchValue<'r, 'a> {
2800    type Inflated = MatchValue<'a>;
2801    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2802        let value = self.value.inflate(config)?;
2803        Ok(Self::Inflated { value })
2804    }
2805}
2806
2807impl<'r, 'a> ParenthesizedDeflatedNode<'r, 'a> for DeflatedMatchValue<'r, 'a> {
2808    fn lpar(&self) -> &Vec<DeflatedLeftParen<'r, 'a>> {
2809        self.value.lpar()
2810    }
2811    fn rpar(&self) -> &Vec<DeflatedRightParen<'r, 'a>> {
2812        self.value.rpar()
2813    }
2814    fn with_parens(
2815        self,
2816        left: DeflatedLeftParen<'r, 'a>,
2817        right: DeflatedRightParen<'r, 'a>,
2818    ) -> Self {
2819        Self {
2820            value: self.value.with_parens(left, right),
2821        }
2822    }
2823}
2824
2825#[cst_node]
2826pub struct MatchSingleton<'a> {
2827    pub value: Name<'a>,
2828}
2829
2830impl<'a> ParenthesizedNode<'a> for MatchSingleton<'a> {
2831    fn lpar(&self) -> &Vec<LeftParen<'a>> {
2832        self.value.lpar()
2833    }
2834    fn rpar(&self) -> &Vec<RightParen<'a>> {
2835        self.value.rpar()
2836    }
2837    fn parenthesize<F>(&self, state: &mut CodegenState<'a>, f: F)
2838    where
2839        F: FnOnce(&mut CodegenState<'a>),
2840    {
2841        self.value.parenthesize(state, f)
2842    }
2843    fn with_parens(self, left: LeftParen<'a>, right: RightParen<'a>) -> Self {
2844        Self {
2845            value: self.value.with_parens(left, right),
2846        }
2847    }
2848}
2849
2850impl<'a> Codegen<'a> for MatchSingleton<'a> {
2851    fn codegen(&self, state: &mut CodegenState<'a>) {
2852        self.value.codegen(state)
2853    }
2854}
2855
2856impl<'r, 'a> Inflate<'a> for DeflatedMatchSingleton<'r, 'a> {
2857    type Inflated = MatchSingleton<'a>;
2858    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2859        let value = self.value.inflate(config)?;
2860        Ok(Self::Inflated { value })
2861    }
2862}
2863
2864impl<'r, 'a> ParenthesizedDeflatedNode<'r, 'a> for DeflatedMatchSingleton<'r, 'a> {
2865    fn lpar(&self) -> &Vec<DeflatedLeftParen<'r, 'a>> {
2866        self.value.lpar()
2867    }
2868    fn rpar(&self) -> &Vec<DeflatedRightParen<'r, 'a>> {
2869        self.value.rpar()
2870    }
2871    fn with_parens(
2872        self,
2873        left: DeflatedLeftParen<'r, 'a>,
2874        right: DeflatedRightParen<'r, 'a>,
2875    ) -> Self {
2876        Self {
2877            value: self.value.with_parens(left, right),
2878        }
2879    }
2880}
2881
2882#[allow(clippy::large_enum_variant)]
2883#[cst_node(Codegen, Inflate, ParenthesizedNode)]
2884pub enum MatchSequence<'a> {
2885    MatchList(MatchList<'a>),
2886    MatchTuple(MatchTuple<'a>),
2887}
2888
2889#[cst_node(ParenthesizedNode)]
2890pub struct MatchList<'a> {
2891    pub patterns: Vec<StarrableMatchSequenceElement<'a>>,
2892    pub lbracket: Option<LeftSquareBracket<'a>>,
2893    pub rbracket: Option<RightSquareBracket<'a>>,
2894    pub lpar: Vec<LeftParen<'a>>,
2895    pub rpar: Vec<RightParen<'a>>,
2896}
2897
2898impl<'a> Codegen<'a> for MatchList<'a> {
2899    fn codegen(&self, state: &mut CodegenState<'a>) {
2900        self.parenthesize(state, |state| {
2901            self.lbracket.codegen(state);
2902            let len = self.patterns.len();
2903            if len == 1 {
2904                self.patterns.first().unwrap().codegen(state, false, false);
2905            } else {
2906                for (idx, pat) in self.patterns.iter().enumerate() {
2907                    pat.codegen(state, idx < len - 1, true);
2908                }
2909            }
2910            self.rbracket.codegen(state);
2911        })
2912    }
2913}
2914
2915impl<'r, 'a> Inflate<'a> for DeflatedMatchList<'r, 'a> {
2916    type Inflated = MatchList<'a>;
2917    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2918        let lpar = self.lpar.inflate(config)?;
2919        let lbracket = self.lbracket.inflate(config)?;
2920
2921        let len = self.patterns.len();
2922        let patterns = self
2923            .patterns
2924            .into_iter()
2925            .enumerate()
2926            .map(|(idx, el)| el.inflate_element(config, idx + 1 == len))
2927            .collect::<Result<Vec<_>>>()?;
2928
2929        let rbracket = self.rbracket.inflate(config)?;
2930        let rpar = self.rpar.inflate(config)?;
2931        Ok(Self::Inflated {
2932            patterns,
2933            lbracket,
2934            rbracket,
2935            lpar,
2936            rpar,
2937        })
2938    }
2939}
2940
2941#[cst_node(ParenthesizedNode)]
2942pub struct MatchTuple<'a> {
2943    pub patterns: Vec<StarrableMatchSequenceElement<'a>>,
2944    pub lpar: Vec<LeftParen<'a>>,
2945    pub rpar: Vec<RightParen<'a>>,
2946}
2947
2948impl<'a> Codegen<'a> for MatchTuple<'a> {
2949    fn codegen(&self, state: &mut CodegenState<'a>) {
2950        self.parenthesize(state, |state| {
2951            let len = self.patterns.len();
2952            if len == 1 {
2953                self.patterns.first().unwrap().codegen(state, true, false);
2954            } else {
2955                for (idx, pat) in self.patterns.iter().enumerate() {
2956                    pat.codegen(state, idx < len - 1, true);
2957                }
2958            }
2959        })
2960    }
2961}
2962
2963impl<'r, 'a> Inflate<'a> for DeflatedMatchTuple<'r, 'a> {
2964    type Inflated = MatchTuple<'a>;
2965    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
2966        let lpar = self.lpar.inflate(config)?;
2967        let len = self.patterns.len();
2968        let patterns = self
2969            .patterns
2970            .into_iter()
2971            .enumerate()
2972            .map(|(idx, el)| el.inflate_element(config, idx + 1 == len))
2973            .collect::<Result<Vec<_>>>()?;
2974        let rpar = self.rpar.inflate(config)?;
2975        Ok(Self::Inflated {
2976            patterns,
2977            lpar,
2978            rpar,
2979        })
2980    }
2981}
2982
2983#[allow(clippy::large_enum_variant)]
2984#[cst_node]
2985pub enum StarrableMatchSequenceElement<'a> {
2986    Simple(MatchSequenceElement<'a>),
2987    Starred(MatchStar<'a>),
2988}
2989
2990impl<'a> StarrableMatchSequenceElement<'a> {
2991    fn codegen(
2992        &self,
2993        state: &mut CodegenState<'a>,
2994        default_comma: bool,
2995        default_comma_whitespace: bool,
2996    ) {
2997        match &self {
2998            Self::Simple(s) => s.codegen(state, default_comma, default_comma_whitespace),
2999            Self::Starred(s) => s.codegen(state, default_comma, default_comma_whitespace),
3000        }
3001    }
3002}
3003impl<'r, 'a> DeflatedStarrableMatchSequenceElement<'r, 'a> {
3004    fn inflate_element(
3005        self,
3006        config: &Config<'a>,
3007        last_element: bool,
3008    ) -> Result<StarrableMatchSequenceElement<'a>> {
3009        Ok(match self {
3010            Self::Simple(s) => {
3011                StarrableMatchSequenceElement::Simple(s.inflate_element(config, last_element)?)
3012            }
3013            Self::Starred(s) => {
3014                StarrableMatchSequenceElement::Starred(s.inflate_element(config, last_element)?)
3015            }
3016        })
3017    }
3018}
3019
3020impl<'r, 'a> WithComma<'r, 'a> for DeflatedStarrableMatchSequenceElement<'r, 'a> {
3021    fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
3022        match self {
3023            Self::Simple(s) => Self::Simple(s.with_comma(comma)),
3024            Self::Starred(s) => Self::Starred(s.with_comma(comma)),
3025        }
3026    }
3027}
3028
3029#[cst_node]
3030pub struct MatchSequenceElement<'a> {
3031    pub value: MatchPattern<'a>,
3032    pub comma: Option<Comma<'a>>,
3033}
3034
3035impl<'a> MatchSequenceElement<'a> {
3036    fn codegen(
3037        &self,
3038        state: &mut CodegenState<'a>,
3039        default_comma: bool,
3040        default_comma_whitespace: bool,
3041    ) {
3042        self.value.codegen(state);
3043        self.comma.codegen(state);
3044        if self.comma.is_none() && default_comma {
3045            state.add_token(if default_comma_whitespace { ", " } else { "," });
3046        }
3047    }
3048}
3049impl<'r, 'a> DeflatedMatchSequenceElement<'r, 'a> {
3050    fn inflate_element(
3051        self,
3052        config: &Config<'a>,
3053        last_element: bool,
3054    ) -> Result<MatchSequenceElement<'a>> {
3055        let value = self.value.inflate(config)?;
3056        let comma = if last_element {
3057            self.comma.map(|c| c.inflate_before(config)).transpose()
3058        } else {
3059            self.comma.inflate(config)
3060        }?;
3061        Ok(MatchSequenceElement { value, comma })
3062    }
3063}
3064
3065impl<'r, 'a> WithComma<'r, 'a> for DeflatedMatchSequenceElement<'r, 'a> {
3066    fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
3067        Self {
3068            comma: Some(comma),
3069            ..self
3070        }
3071    }
3072}
3073
3074#[cst_node]
3075pub struct MatchStar<'a> {
3076    pub name: Option<Name<'a>>,
3077    pub comma: Option<Comma<'a>>,
3078    pub whitespace_before_name: ParenthesizableWhitespace<'a>,
3079
3080    pub(crate) star_tok: TokenRef<'a>,
3081}
3082
3083impl<'a> MatchStar<'a> {
3084    fn codegen(
3085        &self,
3086        state: &mut CodegenState<'a>,
3087        default_comma: bool,
3088        default_comma_whitespace: bool,
3089    ) {
3090        state.add_token("*");
3091        self.whitespace_before_name.codegen(state);
3092        if let Some(name) = &self.name {
3093            name.codegen(state);
3094        } else {
3095            state.add_token("_");
3096        }
3097        self.comma.codegen(state);
3098        if self.comma.is_none() && default_comma {
3099            state.add_token(if default_comma_whitespace { ", " } else { "," });
3100        }
3101    }
3102}
3103impl<'r, 'a> DeflatedMatchStar<'r, 'a> {
3104    fn inflate_element(self, config: &Config<'a>, last_element: bool) -> Result<MatchStar<'a>> {
3105        let whitespace_before_name = parse_parenthesizable_whitespace(
3106            config,
3107            &mut self.star_tok.whitespace_after.borrow_mut(),
3108        )?;
3109        let name = self.name.inflate(config)?;
3110        let comma = if last_element {
3111            self.comma.map(|c| c.inflate_before(config)).transpose()
3112        } else {
3113            self.comma.inflate(config)
3114        }?;
3115        Ok(MatchStar {
3116            name,
3117            comma,
3118            whitespace_before_name,
3119        })
3120    }
3121}
3122
3123impl<'r, 'a> WithComma<'r, 'a> for DeflatedMatchStar<'r, 'a> {
3124    fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
3125        Self {
3126            comma: Some(comma),
3127            ..self
3128        }
3129    }
3130}
3131
3132#[cst_node(ParenthesizedNode)]
3133pub struct MatchMapping<'a> {
3134    pub elements: Vec<MatchMappingElement<'a>>,
3135    pub rest: Option<Name<'a>>,
3136    pub trailing_comma: Option<Comma<'a>>,
3137    pub lbrace: LeftCurlyBrace<'a>,
3138    pub rbrace: RightCurlyBrace<'a>,
3139    pub lpar: Vec<LeftParen<'a>>,
3140    pub rpar: Vec<RightParen<'a>>,
3141
3142    pub whitespace_before_rest: SimpleWhitespace<'a>,
3143
3144    pub(crate) star_tok: Option<TokenRef<'a>>,
3145}
3146
3147impl<'a> Codegen<'a> for MatchMapping<'a> {
3148    fn codegen(&self, state: &mut CodegenState<'a>) {
3149        self.parenthesize(state, |state| {
3150            self.lbrace.codegen(state);
3151            let len = self.elements.len();
3152            for (idx, el) in self.elements.iter().enumerate() {
3153                el.codegen(state, self.rest.is_some() || idx < len - 1);
3154            }
3155            if let Some(rest) = &self.rest {
3156                state.add_token("**");
3157                self.whitespace_before_rest.codegen(state);
3158                rest.codegen(state);
3159                self.trailing_comma.codegen(state);
3160            }
3161            self.rbrace.codegen(state);
3162        })
3163    }
3164}
3165
3166impl<'r, 'a> Inflate<'a> for DeflatedMatchMapping<'r, 'a> {
3167    type Inflated = MatchMapping<'a>;
3168    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
3169        let lpar = self.lpar.inflate(config)?;
3170        let lbrace = self.lbrace.inflate(config)?;
3171
3172        let len = self.elements.len();
3173        let no_star = self.star_tok.is_none();
3174        let elements = self
3175            .elements
3176            .into_iter()
3177            .enumerate()
3178            .map(|(idx, el)| el.inflate_element(config, no_star && idx + 1 == len))
3179            .collect::<Result<Vec<_>>>()?;
3180
3181        let (whitespace_before_rest, rest, trailing_comma) =
3182            if let Some(star_tok) = self.star_tok.as_mut() {
3183                (
3184                    parse_simple_whitespace(config, &mut star_tok.whitespace_after.borrow_mut())?,
3185                    self.rest.inflate(config)?,
3186                    self.trailing_comma
3187                        .map(|c| c.inflate_before(config))
3188                        .transpose()?,
3189                )
3190            } else {
3191                Default::default()
3192            };
3193
3194        let rbrace = self.rbrace.inflate(config)?;
3195        let rpar = self.rpar.inflate(config)?;
3196        Ok(Self::Inflated {
3197            elements,
3198            rest,
3199            trailing_comma,
3200            lbrace,
3201            rbrace,
3202            lpar,
3203            rpar,
3204            whitespace_before_rest,
3205        })
3206    }
3207}
3208
3209#[cst_node]
3210pub struct MatchMappingElement<'a> {
3211    pub key: Expression<'a>,
3212    pub pattern: MatchPattern<'a>,
3213    pub comma: Option<Comma<'a>>,
3214
3215    pub whitespace_before_colon: ParenthesizableWhitespace<'a>,
3216    pub whitespace_after_colon: ParenthesizableWhitespace<'a>,
3217
3218    pub(crate) colon_tok: TokenRef<'a>,
3219}
3220
3221impl<'a> MatchMappingElement<'a> {
3222    fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) {
3223        self.key.codegen(state);
3224        self.whitespace_before_colon.codegen(state);
3225        state.add_token(":");
3226        self.whitespace_after_colon.codegen(state);
3227        self.pattern.codegen(state);
3228        self.comma.codegen(state);
3229        if self.comma.is_none() && default_comma {
3230            state.add_token(", ");
3231        }
3232    }
3233}
3234impl<'r, 'a> DeflatedMatchMappingElement<'r, 'a> {
3235    fn inflate_element(
3236        self,
3237        config: &Config<'a>,
3238        last_element: bool,
3239    ) -> Result<MatchMappingElement<'a>> {
3240        let key = self.key.inflate(config)?;
3241        let whitespace_before_colon = parse_parenthesizable_whitespace(
3242            config,
3243            &mut self.colon_tok.whitespace_before.borrow_mut(),
3244        )?;
3245        let whitespace_after_colon = parse_parenthesizable_whitespace(
3246            config,
3247            &mut self.colon_tok.whitespace_after.borrow_mut(),
3248        )?;
3249        let pattern = self.pattern.inflate(config)?;
3250        let comma = if last_element {
3251            self.comma.map(|c| c.inflate_before(config)).transpose()
3252        } else {
3253            self.comma.inflate(config)
3254        }?;
3255        Ok(MatchMappingElement {
3256            key,
3257            pattern,
3258            comma,
3259            whitespace_before_colon,
3260            whitespace_after_colon,
3261        })
3262    }
3263}
3264
3265impl<'r, 'a> WithComma<'r, 'a> for DeflatedMatchMappingElement<'r, 'a> {
3266    fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
3267        Self {
3268            comma: Some(comma),
3269            ..self
3270        }
3271    }
3272}
3273
3274#[cst_node(ParenthesizedNode)]
3275pub struct MatchClass<'a> {
3276    pub cls: NameOrAttribute<'a>,
3277    pub patterns: Vec<MatchSequenceElement<'a>>,
3278    pub kwds: Vec<MatchKeywordElement<'a>>,
3279    pub lpar: Vec<LeftParen<'a>>,
3280    pub rpar: Vec<RightParen<'a>>,
3281
3282    pub whitespace_after_cls: ParenthesizableWhitespace<'a>,
3283    pub whitespace_before_patterns: ParenthesizableWhitespace<'a>,
3284    pub whitespace_after_kwds: ParenthesizableWhitespace<'a>,
3285
3286    pub(crate) lpar_tok: TokenRef<'a>,
3287    pub(crate) rpar_tok: TokenRef<'a>,
3288}
3289
3290impl<'a> Codegen<'a> for MatchClass<'a> {
3291    fn codegen(&self, state: &mut CodegenState<'a>) {
3292        self.parenthesize(state, |state| {
3293            self.cls.codegen(state);
3294            self.whitespace_after_cls.codegen(state);
3295            state.add_token("(");
3296            self.whitespace_before_patterns.codegen(state);
3297            let patlen = self.patterns.len();
3298            let kwdlen = self.kwds.len();
3299            for (idx, pat) in self.patterns.iter().enumerate() {
3300                pat.codegen(state, idx < patlen - 1 + kwdlen, patlen == 1 && kwdlen == 0);
3301            }
3302            for (idx, kwd) in self.kwds.iter().enumerate() {
3303                kwd.codegen(state, idx < kwdlen - 1);
3304            }
3305            self.whitespace_after_kwds.codegen(state);
3306            state.add_token(")");
3307        })
3308    }
3309}
3310
3311impl<'r, 'a> Inflate<'a> for DeflatedMatchClass<'r, 'a> {
3312    type Inflated = MatchClass<'a>;
3313    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
3314        let lpar = self.lpar.inflate(config)?;
3315
3316        let cls = self.cls.inflate(config)?;
3317        let whitespace_after_cls = parse_parenthesizable_whitespace(
3318            config,
3319            &mut self.lpar_tok.whitespace_before.borrow_mut(),
3320        )?;
3321        let whitespace_before_patterns = parse_parenthesizable_whitespace(
3322            config,
3323            &mut self.lpar_tok.whitespace_after.borrow_mut(),
3324        )?;
3325
3326        let patlen = self.patterns.len();
3327        let kwdlen = self.kwds.len();
3328        let patterns = self
3329            .patterns
3330            .into_iter()
3331            .enumerate()
3332            .map(|(idx, pat)| pat.inflate_element(config, idx + 1 == patlen + kwdlen))
3333            .collect::<Result<_>>()?;
3334        let kwds = self
3335            .kwds
3336            .into_iter()
3337            .enumerate()
3338            .map(|(idx, kwd)| kwd.inflate_element(config, idx + 1 == kwdlen))
3339            .collect::<Result<_>>()?;
3340
3341        let whitespace_after_kwds = parse_parenthesizable_whitespace(
3342            config,
3343            &mut self.rpar_tok.whitespace_before.borrow_mut(),
3344        )?;
3345
3346        let rpar = self.rpar.inflate(config)?;
3347        Ok(Self::Inflated {
3348            cls,
3349            patterns,
3350            kwds,
3351            lpar,
3352            rpar,
3353            whitespace_after_cls,
3354            whitespace_before_patterns,
3355            whitespace_after_kwds,
3356        })
3357    }
3358}
3359
3360#[cst_node]
3361pub struct MatchKeywordElement<'a> {
3362    pub key: Name<'a>,
3363    pub pattern: MatchPattern<'a>,
3364    pub comma: Option<Comma<'a>>,
3365
3366    pub whitespace_before_equal: ParenthesizableWhitespace<'a>,
3367    pub whitespace_after_equal: ParenthesizableWhitespace<'a>,
3368
3369    pub(crate) equal_tok: TokenRef<'a>,
3370}
3371
3372impl<'a> MatchKeywordElement<'a> {
3373    fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) {
3374        self.key.codegen(state);
3375        self.whitespace_before_equal.codegen(state);
3376        state.add_token("=");
3377        self.whitespace_after_equal.codegen(state);
3378        self.pattern.codegen(state);
3379        self.comma.codegen(state);
3380        if self.comma.is_none() && default_comma {
3381            state.add_token(", ");
3382        }
3383    }
3384}
3385impl<'r, 'a> DeflatedMatchKeywordElement<'r, 'a> {
3386    fn inflate_element(
3387        self,
3388        config: &Config<'a>,
3389        last_element: bool,
3390    ) -> Result<MatchKeywordElement<'a>> {
3391        let key = self.key.inflate(config)?;
3392        let whitespace_before_equal = parse_parenthesizable_whitespace(
3393            config,
3394            &mut self.equal_tok.whitespace_before.borrow_mut(),
3395        )?;
3396        let whitespace_after_equal = parse_parenthesizable_whitespace(
3397            config,
3398            &mut self.equal_tok.whitespace_after.borrow_mut(),
3399        )?;
3400        let pattern = self.pattern.inflate(config)?;
3401        let comma = if last_element {
3402            self.comma.map(|c| c.inflate_before(config)).transpose()
3403        } else {
3404            self.comma.inflate(config)
3405        }?;
3406        Ok(MatchKeywordElement {
3407            key,
3408            pattern,
3409            comma,
3410            whitespace_before_equal,
3411            whitespace_after_equal,
3412        })
3413    }
3414}
3415
3416impl<'r, 'a> WithComma<'r, 'a> for DeflatedMatchKeywordElement<'r, 'a> {
3417    fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
3418        Self {
3419            comma: Some(comma),
3420            ..self
3421        }
3422    }
3423}
3424
3425#[cst_node(ParenthesizedNode)]
3426pub struct MatchAs<'a> {
3427    pub pattern: Option<MatchPattern<'a>>,
3428    pub name: Option<Name<'a>>,
3429    pub lpar: Vec<LeftParen<'a>>,
3430    pub rpar: Vec<RightParen<'a>>,
3431
3432    pub whitespace_before_as: Option<ParenthesizableWhitespace<'a>>,
3433    pub whitespace_after_as: Option<ParenthesizableWhitespace<'a>>,
3434
3435    pub(crate) as_tok: Option<TokenRef<'a>>,
3436}
3437
3438impl<'a> Codegen<'a> for MatchAs<'a> {
3439    fn codegen(&self, state: &mut CodegenState<'a>) {
3440        self.parenthesize(state, |state| {
3441            if let Some(pat) = &self.pattern {
3442                pat.codegen(state);
3443                self.whitespace_before_as.codegen(state);
3444                state.add_token("as");
3445                self.whitespace_after_as.codegen(state);
3446            }
3447            if let Some(name) = &self.name {
3448                name.codegen(state);
3449            } else {
3450                state.add_token("_");
3451            }
3452        })
3453    }
3454}
3455
3456impl<'r, 'a> Inflate<'a> for DeflatedMatchAs<'r, 'a> {
3457    type Inflated = MatchAs<'a>;
3458    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
3459        let lpar = self.lpar.inflate(config)?;
3460        let pattern = self.pattern.inflate(config)?;
3461        let (whitespace_before_as, whitespace_after_as) = if let Some(as_tok) = self.as_tok.as_mut()
3462        {
3463            (
3464                Some(parse_parenthesizable_whitespace(
3465                    config,
3466                    &mut as_tok.whitespace_before.borrow_mut(),
3467                )?),
3468                Some(parse_parenthesizable_whitespace(
3469                    config,
3470                    &mut as_tok.whitespace_after.borrow_mut(),
3471                )?),
3472            )
3473        } else {
3474            Default::default()
3475        };
3476        let name = self.name.inflate(config)?;
3477        let rpar = self.rpar.inflate(config)?;
3478        Ok(Self::Inflated {
3479            pattern,
3480            name,
3481            lpar,
3482            rpar,
3483            whitespace_before_as,
3484            whitespace_after_as,
3485        })
3486    }
3487}
3488
3489#[cst_node]
3490pub struct MatchOrElement<'a> {
3491    pub pattern: MatchPattern<'a>,
3492    pub separator: Option<BitOr<'a>>,
3493}
3494
3495impl<'a> MatchOrElement<'a> {
3496    fn codegen(&self, state: &mut CodegenState<'a>, default_separator: bool) {
3497        self.pattern.codegen(state);
3498        self.separator.codegen(state);
3499        if self.separator.is_none() && default_separator {
3500            state.add_token(" | ");
3501        }
3502    }
3503}
3504
3505impl<'r, 'a> Inflate<'a> for DeflatedMatchOrElement<'r, 'a> {
3506    type Inflated = MatchOrElement<'a>;
3507    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
3508        let pattern = self.pattern.inflate(config)?;
3509        let separator = self.separator.inflate(config)?;
3510        Ok(Self::Inflated { pattern, separator })
3511    }
3512}
3513
3514#[cst_node(ParenthesizedNode)]
3515pub struct MatchOr<'a> {
3516    pub patterns: Vec<MatchOrElement<'a>>,
3517    pub lpar: Vec<LeftParen<'a>>,
3518    pub rpar: Vec<RightParen<'a>>,
3519}
3520
3521impl<'a> Codegen<'a> for MatchOr<'a> {
3522    fn codegen(&self, state: &mut CodegenState<'a>) {
3523        self.parenthesize(state, |state| {
3524            let len = self.patterns.len();
3525            for (idx, pat) in self.patterns.iter().enumerate() {
3526                pat.codegen(state, idx + 1 < len)
3527            }
3528        })
3529    }
3530}
3531
3532impl<'r, 'a> Inflate<'a> for DeflatedMatchOr<'r, 'a> {
3533    type Inflated = MatchOr<'a>;
3534    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
3535        let lpar = self.lpar.inflate(config)?;
3536        let patterns = self.patterns.inflate(config)?;
3537        let rpar = self.rpar.inflate(config)?;
3538        Ok(Self::Inflated {
3539            patterns,
3540            lpar,
3541            rpar,
3542        })
3543    }
3544}
3545
3546#[cst_node]
3547pub struct TypeVar<'a> {
3548    pub name: Name<'a>,
3549    pub bound: Option<Box<Expression<'a>>>,
3550    pub colon: Option<Colon<'a>>,
3551}
3552
3553impl<'a> Codegen<'a> for TypeVar<'a> {
3554    fn codegen(&self, state: &mut CodegenState<'a>) {
3555        self.name.codegen(state);
3556        self.colon.codegen(state);
3557        if let Some(bound) = &self.bound {
3558            bound.codegen(state);
3559        }
3560    }
3561}
3562
3563impl<'r, 'a> Inflate<'a> for DeflatedTypeVar<'r, 'a> {
3564    type Inflated = TypeVar<'a>;
3565    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
3566        let name = self.name.inflate(config)?;
3567        let colon = self.colon.inflate(config)?;
3568        let bound = self.bound.inflate(config)?;
3569        Ok(Self::Inflated { name, bound, colon })
3570    }
3571}
3572
3573#[cst_node]
3574pub struct TypeVarTuple<'a> {
3575    pub name: Name<'a>,
3576
3577    pub whitespace_after_star: SimpleWhitespace<'a>,
3578
3579    pub(crate) star_tok: TokenRef<'a>,
3580}
3581
3582impl<'a> Codegen<'a> for TypeVarTuple<'a> {
3583    fn codegen(&self, state: &mut CodegenState<'a>) {
3584        state.add_token("*");
3585        self.whitespace_after_star.codegen(state);
3586        self.name.codegen(state);
3587    }
3588}
3589
3590impl<'r, 'a> Inflate<'a> for DeflatedTypeVarTuple<'r, 'a> {
3591    type Inflated = TypeVarTuple<'a>;
3592    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
3593        let whitespace_after_star =
3594            parse_simple_whitespace(config, &mut self.star_tok.whitespace_after.borrow_mut())?;
3595        let name = self.name.inflate(config)?;
3596        Ok(Self::Inflated {
3597            name,
3598            whitespace_after_star,
3599        })
3600    }
3601}
3602
3603#[cst_node]
3604pub struct ParamSpec<'a> {
3605    pub name: Name<'a>,
3606
3607    pub whitespace_after_star: SimpleWhitespace<'a>,
3608
3609    pub(crate) star_tok: TokenRef<'a>,
3610}
3611
3612impl<'a> Codegen<'a> for ParamSpec<'a> {
3613    fn codegen(&self, state: &mut CodegenState<'a>) {
3614        state.add_token("**");
3615        self.whitespace_after_star.codegen(state);
3616        self.name.codegen(state);
3617    }
3618}
3619
3620impl<'r, 'a> Inflate<'a> for DeflatedParamSpec<'r, 'a> {
3621    type Inflated = ParamSpec<'a>;
3622    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
3623        let whitespace_after_star =
3624            parse_simple_whitespace(config, &mut self.star_tok.whitespace_after.borrow_mut())?;
3625        let name = self.name.inflate(config)?;
3626        Ok(Self::Inflated {
3627            name,
3628            whitespace_after_star,
3629        })
3630    }
3631}
3632
3633#[cst_node(Inflate, Codegen)]
3634pub enum TypeVarLike<'a> {
3635    TypeVar(TypeVar<'a>),
3636    TypeVarTuple(TypeVarTuple<'a>),
3637    ParamSpec(ParamSpec<'a>),
3638}
3639
3640#[cst_node]
3641pub struct TypeParam<'a> {
3642    pub param: TypeVarLike<'a>,
3643    pub comma: Option<Comma<'a>>,
3644    pub equal: Option<AssignEqual<'a>>,
3645    pub star: &'a str,
3646    pub whitespace_after_star: SimpleWhitespace<'a>,
3647    pub default: Option<Expression<'a>>,
3648    pub star_tok: Option<TokenRef<'a>>,
3649}
3650
3651impl<'a> Codegen<'a> for TypeParam<'a> {
3652    fn codegen(&self, state: &mut CodegenState<'a>) {
3653        self.param.codegen(state);
3654        self.equal.codegen(state);
3655        state.add_token(self.star);
3656        self.whitespace_after_star.codegen(state);
3657        self.default.codegen(state);
3658        self.comma.codegen(state);
3659    }
3660}
3661
3662impl<'r, 'a> Inflate<'a> for DeflatedTypeParam<'r, 'a> {
3663    type Inflated = TypeParam<'a>;
3664    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
3665        let whitespace_after_star = if let Some(star_tok) = self.star_tok.as_mut() {
3666            parse_simple_whitespace(config, &mut star_tok.whitespace_after.borrow_mut())?
3667        } else {
3668            Default::default()
3669        };
3670        let param = self.param.inflate(config)?;
3671        let equal = self.equal.inflate(config)?;
3672        let default = self.default.inflate(config)?;
3673        let comma = self.comma.inflate(config)?;
3674        Ok(Self::Inflated {
3675            param,
3676            comma,
3677            equal,
3678            star: self.star,
3679            whitespace_after_star,
3680            default,
3681        })
3682    }
3683}
3684
3685impl<'r, 'a> WithComma<'r, 'a> for DeflatedTypeParam<'r, 'a> {
3686    fn with_comma(self, comma: DeflatedComma<'r, 'a>) -> Self {
3687        Self {
3688            comma: Some(comma),
3689            ..self
3690        }
3691    }
3692}
3693
3694#[cst_node]
3695pub struct TypeParameters<'a> {
3696    pub params: Vec<TypeParam<'a>>,
3697
3698    pub lbracket: LeftSquareBracket<'a>,
3699    pub rbracket: RightSquareBracket<'a>,
3700}
3701
3702impl<'a> Codegen<'a> for TypeParameters<'a> {
3703    fn codegen(&self, state: &mut CodegenState<'a>) {
3704        self.lbracket.codegen(state);
3705        let params_len = self.params.len();
3706        for (idx, param) in self.params.iter().enumerate() {
3707            param.codegen(state);
3708            if idx + 1 < params_len && param.comma.is_none() {
3709                state.add_token(", ");
3710            }
3711        }
3712        self.rbracket.codegen(state);
3713    }
3714}
3715
3716impl<'r, 'a> Inflate<'a> for DeflatedTypeParameters<'r, 'a> {
3717    type Inflated = TypeParameters<'a>;
3718    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
3719        let lbracket = self.lbracket.inflate(config)?;
3720        let params = self.params.inflate(config)?;
3721        let rbracket = self.rbracket.inflate(config)?;
3722        Ok(Self::Inflated {
3723            params,
3724            lbracket,
3725            rbracket,
3726        })
3727    }
3728}
3729
3730#[cst_node]
3731pub struct TypeAlias<'a> {
3732    pub name: Name<'a>,
3733    pub value: Box<Expression<'a>>,
3734    pub type_parameters: Option<TypeParameters<'a>>,
3735
3736    pub whitespace_after_type: SimpleWhitespace<'a>,
3737    pub whitespace_after_name: Option<SimpleWhitespace<'a>>,
3738    pub whitespace_after_type_parameters: Option<SimpleWhitespace<'a>>,
3739    pub whitespace_after_equals: SimpleWhitespace<'a>,
3740    pub semicolon: Option<Semicolon<'a>>,
3741
3742    pub(crate) type_tok: TokenRef<'a>,
3743    pub(crate) lbracket_tok: Option<TokenRef<'a>>,
3744    pub(crate) equals_tok: TokenRef<'a>,
3745}
3746
3747impl<'a> Codegen<'a> for TypeAlias<'a> {
3748    fn codegen(&self, state: &mut CodegenState<'a>) {
3749        state.add_token("type");
3750        self.whitespace_after_type.codegen(state);
3751        self.name.codegen(state);
3752        if self.whitespace_after_name.is_none() && self.type_parameters.is_none() {
3753            state.add_token(" ");
3754        } else {
3755            self.whitespace_after_name.codegen(state);
3756        }
3757        if self.type_parameters.is_some() {
3758            self.type_parameters.codegen(state);
3759            self.whitespace_after_type_parameters.codegen(state);
3760        }
3761        state.add_token("=");
3762        self.whitespace_after_equals.codegen(state);
3763        self.value.codegen(state);
3764        self.semicolon.codegen(state);
3765    }
3766}
3767
3768impl<'r, 'a> Inflate<'a> for DeflatedTypeAlias<'r, 'a> {
3769    type Inflated = TypeAlias<'a>;
3770    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
3771        let whitespace_after_type =
3772            parse_simple_whitespace(config, &mut self.type_tok.whitespace_after.borrow_mut())?;
3773        let name = self.name.inflate(config)?;
3774        let whitespace_after_name = Some(if let Some(tok) = self.lbracket_tok {
3775            parse_simple_whitespace(config, &mut tok.whitespace_before.borrow_mut())
3776        } else {
3777            parse_simple_whitespace(config, &mut self.equals_tok.whitespace_before.borrow_mut())
3778        }?);
3779        let type_parameters = self.type_parameters.inflate(config)?;
3780        let whitespace_after_type_parameters = if type_parameters.is_some() {
3781            Some(parse_simple_whitespace(
3782                config,
3783                &mut self.equals_tok.whitespace_before.borrow_mut(),
3784            )?)
3785        } else {
3786            None
3787        };
3788        let whitespace_after_equals =
3789            parse_simple_whitespace(config, &mut self.equals_tok.whitespace_after.borrow_mut())?;
3790        let value = self.value.inflate(config)?;
3791        let semicolon = self.semicolon.inflate(config)?;
3792        Ok(Self::Inflated {
3793            name,
3794            value,
3795            type_parameters,
3796            whitespace_after_type,
3797            whitespace_after_name,
3798            whitespace_after_type_parameters,
3799            whitespace_after_equals,
3800            semicolon,
3801        })
3802    }
3803}
3804
3805impl<'r, 'a> DeflatedTypeAlias<'r, 'a> {
3806    pub fn with_semicolon(self, semicolon: Option<DeflatedSemicolon<'r, 'a>>) -> Self {
3807        Self { semicolon, ..self }
3808    }
3809}