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