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