libcst_native/nodes/
op.rs

1// Copyright (c) Meta Platforms, Inc. and affiliates.
2//
3// This source code is licensed under the MIT license found in the
4// LICENSE file in the root directory of this source tree.
5
6use super::{whitespace::ParenthesizableWhitespace, Codegen, CodegenState};
7use crate::{
8    nodes::traits::{Inflate, Result},
9    tokenizer::{
10        whitespace_parser::{parse_parenthesizable_whitespace, parse_simple_whitespace, Config},
11        Token,
12    },
13};
14use libcst_derive::cst_node;
15#[cfg(feature = "py")]
16use libcst_derive::TryIntoPy;
17
18type TokenRef<'r, 'a> = &'r Token<'a>;
19
20#[cst_node]
21pub struct Semicolon<'a> {
22    /// Any space that appears directly before this semicolon.
23    pub whitespace_before: ParenthesizableWhitespace<'a>,
24    /// Any space that appears directly after this semicolon.
25    pub whitespace_after: ParenthesizableWhitespace<'a>,
26
27    #[cfg_attr(feature = "py", skip_py)]
28    pub(crate) tok: TokenRef<'a>,
29}
30
31impl<'a> Codegen<'a> for Semicolon<'a> {
32    fn codegen(&self, state: &mut CodegenState<'a>) {
33        self.whitespace_before.codegen(state);
34        state.add_token(";");
35        self.whitespace_after.codegen(state);
36    }
37}
38
39impl<'r, 'a> Inflate<'a> for DeflatedSemicolon<'r, 'a> {
40    type Inflated = Semicolon<'a>;
41    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
42        let whitespace_before = ParenthesizableWhitespace::SimpleWhitespace(
43            parse_simple_whitespace(config, &mut (*self.tok).whitespace_before.borrow_mut())?,
44        );
45        let whitespace_after = ParenthesizableWhitespace::SimpleWhitespace(
46            parse_simple_whitespace(config, &mut (*self.tok).whitespace_after.borrow_mut())?,
47        );
48        Ok(Self::Inflated {
49            whitespace_before,
50            whitespace_after,
51        })
52    }
53}
54
55#[cst_node]
56pub struct Comma<'a> {
57    /// Any space that appears directly before this comma.
58    pub whitespace_before: ParenthesizableWhitespace<'a>,
59    /// Any space that appears directly after this comma.
60    pub whitespace_after: ParenthesizableWhitespace<'a>,
61
62    #[cfg_attr(feature = "py", skip_py)]
63    pub(crate) tok: TokenRef<'a>,
64}
65
66impl<'a> Codegen<'a> for Comma<'a> {
67    fn codegen(&self, state: &mut CodegenState<'a>) {
68        self.whitespace_before.codegen(state);
69        state.add_token(",");
70        self.whitespace_after.codegen(state);
71    }
72}
73
74impl<'r, 'a> Inflate<'a> for DeflatedComma<'r, 'a> {
75    type Inflated = Comma<'a>;
76    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
77        let whitespace_before = parse_parenthesizable_whitespace(
78            config,
79            &mut (*self.tok).whitespace_before.borrow_mut(),
80        )?;
81        let whitespace_after = parse_parenthesizable_whitespace(
82            config,
83            &mut (*self.tok).whitespace_after.borrow_mut(),
84        )?;
85        Ok(Self::Inflated {
86            whitespace_before,
87            whitespace_after,
88        })
89    }
90}
91
92impl<'r, 'a> DeflatedComma<'r, 'a> {
93    pub fn inflate_before(self, config: &Config<'a>) -> Result<Comma<'a>> {
94        let whitespace_before = parse_parenthesizable_whitespace(
95            config,
96            &mut (*self.tok).whitespace_before.borrow_mut(),
97        )?;
98        let whitespace_after = Default::default();
99        Ok(Comma {
100            whitespace_before,
101            whitespace_after,
102        })
103    }
104}
105
106#[cst_node]
107pub struct AssignEqual<'a> {
108    /// Any space that appears directly before this equal sign.
109    pub whitespace_before: ParenthesizableWhitespace<'a>,
110    /// Any space that appears directly after this equal sign.
111    pub whitespace_after: ParenthesizableWhitespace<'a>,
112
113    #[cfg_attr(feature = "py", skip_py)]
114    pub(crate) tok: TokenRef<'a>,
115}
116
117impl<'a> Codegen<'a> for AssignEqual<'a> {
118    fn codegen(&self, state: &mut CodegenState<'a>) {
119        self.whitespace_before.codegen(state);
120        state.add_token("=");
121        self.whitespace_after.codegen(state);
122    }
123}
124
125impl<'r, 'a> Inflate<'a> for DeflatedAssignEqual<'r, 'a> {
126    type Inflated = AssignEqual<'a>;
127    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
128        let whitespace_before = parse_parenthesizable_whitespace(
129            config,
130            &mut (*self.tok).whitespace_before.borrow_mut(),
131        )?;
132        let whitespace_after = parse_parenthesizable_whitespace(
133            config,
134            &mut (*self.tok).whitespace_after.borrow_mut(),
135        )?;
136        Ok(Self::Inflated {
137            whitespace_before,
138            whitespace_after,
139        })
140    }
141}
142
143#[cst_node]
144pub struct Dot<'a> {
145    /// Any space that appears directly before this dot.
146    pub whitespace_before: ParenthesizableWhitespace<'a>,
147    /// Any space that appears directly after this dot.
148    pub whitespace_after: ParenthesizableWhitespace<'a>,
149
150    #[cfg_attr(feature = "py", skip_py)]
151    pub(crate) tok: TokenRef<'a>,
152}
153
154impl<'a> Codegen<'a> for Dot<'a> {
155    fn codegen(&self, state: &mut CodegenState<'a>) {
156        self.whitespace_before.codegen(state);
157        state.add_token(".");
158        self.whitespace_after.codegen(state);
159    }
160}
161
162impl<'r, 'a> Inflate<'a> for DeflatedDot<'r, 'a> {
163    type Inflated = Dot<'a>;
164    fn inflate(mut self, config: &Config<'a>) -> Result<Self::Inflated> {
165        let whitespace_before = self.inflate_before(config)?;
166        let whitespace_after = self.inflate_after(config)?;
167        Ok(Self::Inflated {
168            whitespace_before,
169            whitespace_after,
170        })
171    }
172}
173
174impl<'r, 'a> DeflatedDot<'r, 'a> {
175    fn inflate_before(&mut self, config: &Config<'a>) -> Result<ParenthesizableWhitespace<'a>> {
176        parse_parenthesizable_whitespace(config, &mut (*self.tok).whitespace_before.borrow_mut())
177    }
178
179    fn inflate_after(&mut self, config: &Config<'a>) -> Result<ParenthesizableWhitespace<'a>> {
180        parse_parenthesizable_whitespace(config, &mut (*self.tok).whitespace_after.borrow_mut())
181    }
182}
183
184#[cst_node]
185pub struct ImportStar {}
186
187pub(crate) fn make_importstar<'r, 'a>() -> DeflatedImportStar<'r, 'a> {
188    DeflatedImportStar {
189        _phantom: Default::default(),
190    }
191}
192
193impl<'a> Codegen<'a> for ImportStar {
194    fn codegen(&self, state: &mut CodegenState<'a>) {
195        state.add_token("*");
196    }
197}
198
199impl<'r, 'a> Inflate<'a> for DeflatedImportStar<'r, 'a> {
200    type Inflated = ImportStar;
201    fn inflate(self, _config: &Config<'a>) -> Result<Self::Inflated> {
202        Ok(ImportStar {})
203    }
204}
205
206#[cst_node]
207pub enum UnaryOp<'a> {
208    Plus {
209        whitespace_after: ParenthesizableWhitespace<'a>,
210        #[cfg_attr(feature = "py", skip_py)]
211        tok: TokenRef<'a>,
212    },
213    Minus {
214        whitespace_after: ParenthesizableWhitespace<'a>,
215        #[cfg_attr(feature = "py", skip_py)]
216        tok: TokenRef<'a>,
217    },
218    BitInvert {
219        whitespace_after: ParenthesizableWhitespace<'a>,
220        #[cfg_attr(feature = "py", skip_py)]
221        tok: TokenRef<'a>,
222    },
223    Not {
224        whitespace_after: ParenthesizableWhitespace<'a>,
225        #[cfg_attr(feature = "py", skip_py)]
226        tok: TokenRef<'a>,
227    },
228}
229
230impl<'a> Codegen<'a> for UnaryOp<'a> {
231    fn codegen(&self, state: &mut CodegenState<'a>) {
232        let (tok, whitespace_after) = match self {
233            Self::Plus {
234                whitespace_after, ..
235            } => ("+", whitespace_after),
236            Self::Minus {
237                whitespace_after, ..
238            } => ("-", whitespace_after),
239            Self::BitInvert {
240                whitespace_after, ..
241            } => ("~", whitespace_after),
242            Self::Not {
243                whitespace_after, ..
244            } => ("not", whitespace_after),
245        };
246        state.add_token(tok);
247        whitespace_after.codegen(state);
248    }
249}
250
251impl<'r, 'a> Inflate<'a> for DeflatedUnaryOp<'r, 'a> {
252    type Inflated = UnaryOp<'a>;
253    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
254        Ok(match self {
255            Self::Plus { tok, .. } => {
256                let whitespace_after = parse_parenthesizable_whitespace(
257                    config,
258                    &mut (*tok).whitespace_after.borrow_mut(),
259                )?;
260                Self::Inflated::Plus { whitespace_after }
261            }
262            Self::Minus { tok, .. } => {
263                let whitespace_after = parse_parenthesizable_whitespace(
264                    config,
265                    &mut (*tok).whitespace_after.borrow_mut(),
266                )?;
267                Self::Inflated::Minus { whitespace_after }
268            }
269            Self::BitInvert { tok, .. } => {
270                let whitespace_after = parse_parenthesizable_whitespace(
271                    config,
272                    &mut (*tok).whitespace_after.borrow_mut(),
273                )?;
274                Self::Inflated::BitInvert { whitespace_after }
275            }
276            Self::Not { tok, .. } => {
277                let whitespace_after = parse_parenthesizable_whitespace(
278                    config,
279                    &mut (*tok).whitespace_after.borrow_mut(),
280                )?;
281                Self::Inflated::Not { whitespace_after }
282            }
283        })
284    }
285}
286
287#[cst_node]
288pub enum BooleanOp<'a> {
289    And {
290        whitespace_before: ParenthesizableWhitespace<'a>,
291        whitespace_after: ParenthesizableWhitespace<'a>,
292        #[cfg_attr(feature = "py", skip_py)]
293        tok: TokenRef<'a>,
294    },
295    Or {
296        whitespace_before: ParenthesizableWhitespace<'a>,
297        whitespace_after: ParenthesizableWhitespace<'a>,
298        #[cfg_attr(feature = "py", skip_py)]
299        tok: TokenRef<'a>,
300    },
301}
302
303impl<'a> Codegen<'a> for BooleanOp<'a> {
304    fn codegen(&self, state: &mut CodegenState<'a>) {
305        let (tok, ws_bef, ws_aft) = match self {
306            Self::And {
307                whitespace_after,
308                whitespace_before,
309                ..
310            } => ("and", whitespace_before, whitespace_after),
311            Self::Or {
312                whitespace_after,
313                whitespace_before,
314                ..
315            } => ("or", whitespace_before, whitespace_after),
316        };
317        ws_bef.codegen(state);
318        state.add_token(tok);
319        ws_aft.codegen(state);
320    }
321}
322
323impl<'r, 'a> Inflate<'a> for DeflatedBooleanOp<'r, 'a> {
324    type Inflated = BooleanOp<'a>;
325    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
326        Ok(match self {
327            Self::And { tok, .. } => {
328                let whitespace_before = parse_parenthesizable_whitespace(
329                    config,
330                    &mut (*tok).whitespace_before.borrow_mut(),
331                )?;
332                let whitespace_after = parse_parenthesizable_whitespace(
333                    config,
334                    &mut (*tok).whitespace_after.borrow_mut(),
335                )?;
336                Self::Inflated::And {
337                    whitespace_before,
338                    whitespace_after,
339                }
340            }
341            Self::Or { tok, .. } => {
342                let whitespace_before = parse_parenthesizable_whitespace(
343                    config,
344                    &mut (*tok).whitespace_before.borrow_mut(),
345                )?;
346                let whitespace_after = parse_parenthesizable_whitespace(
347                    config,
348                    &mut (*tok).whitespace_after.borrow_mut(),
349                )?;
350                Self::Inflated::Or {
351                    whitespace_before,
352                    whitespace_after,
353                }
354            }
355        })
356    }
357}
358
359#[cst_node]
360pub enum BinaryOp<'a> {
361    Add {
362        whitespace_before: ParenthesizableWhitespace<'a>,
363        whitespace_after: ParenthesizableWhitespace<'a>,
364        #[cfg_attr(feature = "py", skip_py)]
365        tok: TokenRef<'a>,
366    },
367    Subtract {
368        whitespace_before: ParenthesizableWhitespace<'a>,
369        whitespace_after: ParenthesizableWhitespace<'a>,
370        #[cfg_attr(feature = "py", skip_py)]
371        tok: TokenRef<'a>,
372    },
373    Multiply {
374        whitespace_before: ParenthesizableWhitespace<'a>,
375        whitespace_after: ParenthesizableWhitespace<'a>,
376        #[cfg_attr(feature = "py", skip_py)]
377        tok: TokenRef<'a>,
378    },
379    Divide {
380        whitespace_before: ParenthesizableWhitespace<'a>,
381        whitespace_after: ParenthesizableWhitespace<'a>,
382        #[cfg_attr(feature = "py", skip_py)]
383        tok: TokenRef<'a>,
384    },
385    FloorDivide {
386        whitespace_before: ParenthesizableWhitespace<'a>,
387        whitespace_after: ParenthesizableWhitespace<'a>,
388        #[cfg_attr(feature = "py", skip_py)]
389        tok: TokenRef<'a>,
390    },
391    Modulo {
392        whitespace_before: ParenthesizableWhitespace<'a>,
393        whitespace_after: ParenthesizableWhitespace<'a>,
394        #[cfg_attr(feature = "py", skip_py)]
395        tok: TokenRef<'a>,
396    },
397    Power {
398        whitespace_before: ParenthesizableWhitespace<'a>,
399        whitespace_after: ParenthesizableWhitespace<'a>,
400        #[cfg_attr(feature = "py", skip_py)]
401        tok: TokenRef<'a>,
402    },
403    LeftShift {
404        whitespace_before: ParenthesizableWhitespace<'a>,
405        whitespace_after: ParenthesizableWhitespace<'a>,
406        #[cfg_attr(feature = "py", skip_py)]
407        tok: TokenRef<'a>,
408    },
409    RightShift {
410        whitespace_before: ParenthesizableWhitespace<'a>,
411        whitespace_after: ParenthesizableWhitespace<'a>,
412        #[cfg_attr(feature = "py", skip_py)]
413        tok: TokenRef<'a>,
414    },
415    BitOr {
416        whitespace_before: ParenthesizableWhitespace<'a>,
417        whitespace_after: ParenthesizableWhitespace<'a>,
418        #[cfg_attr(feature = "py", skip_py)]
419        tok: TokenRef<'a>,
420    },
421    BitAnd {
422        whitespace_before: ParenthesizableWhitespace<'a>,
423        whitespace_after: ParenthesizableWhitespace<'a>,
424        #[cfg_attr(feature = "py", skip_py)]
425        tok: TokenRef<'a>,
426    },
427    BitXor {
428        whitespace_before: ParenthesizableWhitespace<'a>,
429        whitespace_after: ParenthesizableWhitespace<'a>,
430        #[cfg_attr(feature = "py", skip_py)]
431        tok: TokenRef<'a>,
432    },
433    MatrixMultiply {
434        whitespace_before: ParenthesizableWhitespace<'a>,
435        whitespace_after: ParenthesizableWhitespace<'a>,
436        #[cfg_attr(feature = "py", skip_py)]
437        tok: TokenRef<'a>,
438    },
439}
440
441impl<'a> Codegen<'a> for BinaryOp<'a> {
442    fn codegen(&self, state: &mut CodegenState<'a>) {
443        let (whitespace_before, whitespace_after) = match self {
444            Self::Add {
445                whitespace_before,
446                whitespace_after,
447            }
448            | Self::Subtract {
449                whitespace_before,
450                whitespace_after,
451            }
452            | Self::Multiply {
453                whitespace_before,
454                whitespace_after,
455            }
456            | Self::Divide {
457                whitespace_before,
458                whitespace_after,
459            }
460            | Self::FloorDivide {
461                whitespace_before,
462                whitespace_after,
463            }
464            | Self::Modulo {
465                whitespace_before,
466                whitespace_after,
467            }
468            | Self::Power {
469                whitespace_before,
470                whitespace_after,
471            }
472            | Self::LeftShift {
473                whitespace_before,
474                whitespace_after,
475            }
476            | Self::RightShift {
477                whitespace_before,
478                whitespace_after,
479            }
480            | Self::BitOr {
481                whitespace_before,
482                whitespace_after,
483            }
484            | Self::BitAnd {
485                whitespace_before,
486                whitespace_after,
487            }
488            | Self::BitXor {
489                whitespace_before,
490                whitespace_after,
491            }
492            | Self::MatrixMultiply {
493                whitespace_before,
494                whitespace_after,
495            } => (whitespace_before, whitespace_after),
496        };
497        let tok = match self {
498            BinaryOp::Add { .. } => "+",
499            BinaryOp::Subtract { .. } => "-",
500            BinaryOp::Multiply { .. } => "*",
501            BinaryOp::Divide { .. } => "/",
502            BinaryOp::FloorDivide { .. } => "//",
503            BinaryOp::Modulo { .. } => "%",
504            BinaryOp::Power { .. } => "**",
505            BinaryOp::LeftShift { .. } => "<<",
506            BinaryOp::RightShift { .. } => ">>",
507            BinaryOp::BitOr { .. } => "|",
508            BinaryOp::BitAnd { .. } => "&",
509            BinaryOp::BitXor { .. } => "^",
510            BinaryOp::MatrixMultiply { .. } => "@",
511        };
512        whitespace_before.codegen(state);
513        state.add_token(tok);
514        whitespace_after.codegen(state);
515    }
516}
517
518impl<'r, 'a> Inflate<'a> for DeflatedBinaryOp<'r, 'a> {
519    type Inflated = BinaryOp<'a>;
520    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
521        Ok(match self {
522            Self::Add { tok, .. } => {
523                let whitespace_before = parse_parenthesizable_whitespace(
524                    config,
525                    &mut (*tok).whitespace_before.borrow_mut(),
526                )?;
527                let whitespace_after = parse_parenthesizable_whitespace(
528                    config,
529                    &mut (*tok).whitespace_after.borrow_mut(),
530                )?;
531                Self::Inflated::Add {
532                    whitespace_before,
533                    whitespace_after,
534                }
535            }
536            Self::Subtract { tok, .. } => {
537                let whitespace_before = parse_parenthesizable_whitespace(
538                    config,
539                    &mut (*tok).whitespace_before.borrow_mut(),
540                )?;
541                let whitespace_after = parse_parenthesizable_whitespace(
542                    config,
543                    &mut (*tok).whitespace_after.borrow_mut(),
544                )?;
545                Self::Inflated::Subtract {
546                    whitespace_before,
547                    whitespace_after,
548                }
549            }
550            Self::Multiply { tok, .. } => {
551                let whitespace_before = parse_parenthesizable_whitespace(
552                    config,
553                    &mut (*tok).whitespace_before.borrow_mut(),
554                )?;
555                let whitespace_after = parse_parenthesizable_whitespace(
556                    config,
557                    &mut (*tok).whitespace_after.borrow_mut(),
558                )?;
559                Self::Inflated::Multiply {
560                    whitespace_before,
561                    whitespace_after,
562                }
563            }
564            Self::Divide { tok, .. } => {
565                let whitespace_before = parse_parenthesizable_whitespace(
566                    config,
567                    &mut (*tok).whitespace_before.borrow_mut(),
568                )?;
569                let whitespace_after = parse_parenthesizable_whitespace(
570                    config,
571                    &mut (*tok).whitespace_after.borrow_mut(),
572                )?;
573                Self::Inflated::Divide {
574                    whitespace_before,
575                    whitespace_after,
576                }
577            }
578            Self::FloorDivide { tok, .. } => {
579                let whitespace_before = parse_parenthesizable_whitespace(
580                    config,
581                    &mut (*tok).whitespace_before.borrow_mut(),
582                )?;
583                let whitespace_after = parse_parenthesizable_whitespace(
584                    config,
585                    &mut (*tok).whitespace_after.borrow_mut(),
586                )?;
587                Self::Inflated::FloorDivide {
588                    whitespace_before,
589                    whitespace_after,
590                }
591            }
592            Self::Modulo { tok, .. } => {
593                let whitespace_before = parse_parenthesizable_whitespace(
594                    config,
595                    &mut (*tok).whitespace_before.borrow_mut(),
596                )?;
597                let whitespace_after = parse_parenthesizable_whitespace(
598                    config,
599                    &mut (*tok).whitespace_after.borrow_mut(),
600                )?;
601                Self::Inflated::Modulo {
602                    whitespace_before,
603                    whitespace_after,
604                }
605            }
606            Self::Power { tok, .. } => {
607                let whitespace_before = parse_parenthesizable_whitespace(
608                    config,
609                    &mut (*tok).whitespace_before.borrow_mut(),
610                )?;
611                let whitespace_after = parse_parenthesizable_whitespace(
612                    config,
613                    &mut (*tok).whitespace_after.borrow_mut(),
614                )?;
615                Self::Inflated::Power {
616                    whitespace_before,
617                    whitespace_after,
618                }
619            }
620            Self::LeftShift { tok, .. } => {
621                let whitespace_before = parse_parenthesizable_whitespace(
622                    config,
623                    &mut (*tok).whitespace_before.borrow_mut(),
624                )?;
625                let whitespace_after = parse_parenthesizable_whitespace(
626                    config,
627                    &mut (*tok).whitespace_after.borrow_mut(),
628                )?;
629                Self::Inflated::LeftShift {
630                    whitespace_before,
631                    whitespace_after,
632                }
633            }
634            Self::RightShift { tok, .. } => {
635                let whitespace_before = parse_parenthesizable_whitespace(
636                    config,
637                    &mut (*tok).whitespace_before.borrow_mut(),
638                )?;
639                let whitespace_after = parse_parenthesizable_whitespace(
640                    config,
641                    &mut (*tok).whitespace_after.borrow_mut(),
642                )?;
643                Self::Inflated::RightShift {
644                    whitespace_before,
645                    whitespace_after,
646                }
647            }
648            Self::BitOr { tok, .. } => {
649                let whitespace_before = parse_parenthesizable_whitespace(
650                    config,
651                    &mut (*tok).whitespace_before.borrow_mut(),
652                )?;
653                let whitespace_after = parse_parenthesizable_whitespace(
654                    config,
655                    &mut (*tok).whitespace_after.borrow_mut(),
656                )?;
657                Self::Inflated::BitOr {
658                    whitespace_before,
659                    whitespace_after,
660                }
661            }
662            Self::BitAnd { tok, .. } => {
663                let whitespace_before = parse_parenthesizable_whitespace(
664                    config,
665                    &mut (*tok).whitespace_before.borrow_mut(),
666                )?;
667                let whitespace_after = parse_parenthesizable_whitespace(
668                    config,
669                    &mut (*tok).whitespace_after.borrow_mut(),
670                )?;
671                Self::Inflated::BitAnd {
672                    whitespace_before,
673                    whitespace_after,
674                }
675            }
676            Self::BitXor { tok, .. } => {
677                let whitespace_before = parse_parenthesizable_whitespace(
678                    config,
679                    &mut (*tok).whitespace_before.borrow_mut(),
680                )?;
681                let whitespace_after = parse_parenthesizable_whitespace(
682                    config,
683                    &mut (*tok).whitespace_after.borrow_mut(),
684                )?;
685                Self::Inflated::BitXor {
686                    whitespace_before,
687                    whitespace_after,
688                }
689            }
690            Self::MatrixMultiply { tok, .. } => {
691                let whitespace_before = parse_parenthesizable_whitespace(
692                    config,
693                    &mut (*tok).whitespace_before.borrow_mut(),
694                )?;
695                let whitespace_after = parse_parenthesizable_whitespace(
696                    config,
697                    &mut (*tok).whitespace_after.borrow_mut(),
698                )?;
699                Self::Inflated::MatrixMultiply {
700                    whitespace_before,
701                    whitespace_after,
702                }
703            }
704        })
705    }
706}
707
708#[cst_node]
709pub enum CompOp<'a> {
710    LessThan {
711        whitespace_before: ParenthesizableWhitespace<'a>,
712        whitespace_after: ParenthesizableWhitespace<'a>,
713        #[cfg_attr(feature = "py", skip_py)]
714        tok: TokenRef<'a>,
715    },
716    GreaterThan {
717        whitespace_before: ParenthesizableWhitespace<'a>,
718        whitespace_after: ParenthesizableWhitespace<'a>,
719        #[cfg_attr(feature = "py", skip_py)]
720        tok: TokenRef<'a>,
721    },
722    LessThanEqual {
723        whitespace_before: ParenthesizableWhitespace<'a>,
724        whitespace_after: ParenthesizableWhitespace<'a>,
725        #[cfg_attr(feature = "py", skip_py)]
726        tok: TokenRef<'a>,
727    },
728    GreaterThanEqual {
729        whitespace_before: ParenthesizableWhitespace<'a>,
730        whitespace_after: ParenthesizableWhitespace<'a>,
731        #[cfg_attr(feature = "py", skip_py)]
732        tok: TokenRef<'a>,
733    },
734    Equal {
735        whitespace_before: ParenthesizableWhitespace<'a>,
736        whitespace_after: ParenthesizableWhitespace<'a>,
737        #[cfg_attr(feature = "py", skip_py)]
738        tok: TokenRef<'a>,
739    },
740    NotEqual {
741        whitespace_before: ParenthesizableWhitespace<'a>,
742        whitespace_after: ParenthesizableWhitespace<'a>,
743        #[cfg_attr(feature = "py", skip_py)]
744        tok: TokenRef<'a>,
745    },
746    In {
747        whitespace_before: ParenthesizableWhitespace<'a>,
748        whitespace_after: ParenthesizableWhitespace<'a>,
749        #[cfg_attr(feature = "py", skip_py)]
750        tok: TokenRef<'a>,
751    },
752    NotIn {
753        whitespace_before: ParenthesizableWhitespace<'a>,
754        whitespace_between: ParenthesizableWhitespace<'a>,
755        whitespace_after: ParenthesizableWhitespace<'a>,
756        #[cfg_attr(feature = "py", skip_py)]
757        not_tok: TokenRef<'a>,
758        #[cfg_attr(feature = "py", skip_py)]
759        in_tok: TokenRef<'a>,
760    },
761    Is {
762        whitespace_before: ParenthesizableWhitespace<'a>,
763        whitespace_after: ParenthesizableWhitespace<'a>,
764        #[cfg_attr(feature = "py", skip_py)]
765        tok: TokenRef<'a>,
766    },
767    IsNot {
768        whitespace_before: ParenthesizableWhitespace<'a>,
769        whitespace_between: ParenthesizableWhitespace<'a>,
770        whitespace_after: ParenthesizableWhitespace<'a>,
771        #[cfg_attr(feature = "py", skip_py)]
772        is_tok: TokenRef<'a>,
773        #[cfg_attr(feature = "py", skip_py)]
774        not_tok: TokenRef<'a>,
775    },
776}
777
778impl<'a> Codegen<'a> for CompOp<'a> {
779    fn codegen(&self, state: &mut CodegenState<'a>) {
780        let (bef, aft, between) = match self {
781            Self::LessThan {
782                whitespace_before,
783                whitespace_after,
784            }
785            | Self::GreaterThan {
786                whitespace_before,
787                whitespace_after,
788            }
789            | Self::LessThanEqual {
790                whitespace_before,
791                whitespace_after,
792            }
793            | Self::GreaterThanEqual {
794                whitespace_before,
795                whitespace_after,
796            }
797            | Self::Equal {
798                whitespace_before,
799                whitespace_after,
800            }
801            | Self::NotEqual {
802                whitespace_before,
803                whitespace_after,
804            }
805            | Self::In {
806                whitespace_before,
807                whitespace_after,
808            }
809            | Self::Is {
810                whitespace_before,
811                whitespace_after,
812            } => (whitespace_before, whitespace_after, None),
813            Self::IsNot {
814                whitespace_before,
815                whitespace_between,
816                whitespace_after,
817            } => (
818                whitespace_before,
819                whitespace_after,
820                Some(whitespace_between),
821            ),
822            Self::NotIn {
823                whitespace_before,
824                whitespace_between,
825                whitespace_after,
826            } => (
827                whitespace_before,
828                whitespace_after,
829                Some(whitespace_between),
830            ),
831        };
832        let (first_tok, second_tok) = match self {
833            CompOp::LessThan { .. } => ("<", None),
834            CompOp::GreaterThan { .. } => (">", None),
835            CompOp::LessThanEqual { .. } => ("<=", None),
836            CompOp::GreaterThanEqual { .. } => (">=", None),
837            CompOp::Equal { .. } => ("==", None),
838            CompOp::NotEqual { .. } => ("!=", None),
839            CompOp::In { .. } => ("in", None),
840            CompOp::NotIn { .. } => ("not", Some("in")),
841            CompOp::Is { .. } => ("is", None),
842            CompOp::IsNot { .. } => ("is", Some("not")),
843        };
844        bef.codegen(state);
845        state.add_token(first_tok);
846        if let (Some(btw), Some(second_tok)) = (between, second_tok) {
847            btw.codegen(state);
848            state.add_token(second_tok);
849        }
850        aft.codegen(state);
851    }
852}
853
854impl<'r, 'a> Inflate<'a> for DeflatedCompOp<'r, 'a> {
855    type Inflated = CompOp<'a>;
856    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
857        Ok(match self {
858            Self::LessThan { tok, .. } => {
859                let whitespace_before = parse_parenthesizable_whitespace(
860                    config,
861                    &mut (*tok).whitespace_before.borrow_mut(),
862                )?;
863                let whitespace_after = parse_parenthesizable_whitespace(
864                    config,
865                    &mut (*tok).whitespace_after.borrow_mut(),
866                )?;
867                Self::Inflated::LessThan {
868                    whitespace_before,
869                    whitespace_after,
870                }
871            }
872            Self::GreaterThan { tok, .. } => {
873                let whitespace_before = parse_parenthesizable_whitespace(
874                    config,
875                    &mut (*tok).whitespace_before.borrow_mut(),
876                )?;
877                let whitespace_after = parse_parenthesizable_whitespace(
878                    config,
879                    &mut (*tok).whitespace_after.borrow_mut(),
880                )?;
881                Self::Inflated::GreaterThan {
882                    whitespace_before,
883                    whitespace_after,
884                }
885            }
886            Self::LessThanEqual { tok, .. } => {
887                let whitespace_before = parse_parenthesizable_whitespace(
888                    config,
889                    &mut (*tok).whitespace_before.borrow_mut(),
890                )?;
891                let whitespace_after = parse_parenthesizable_whitespace(
892                    config,
893                    &mut (*tok).whitespace_after.borrow_mut(),
894                )?;
895                Self::Inflated::LessThanEqual {
896                    whitespace_before,
897                    whitespace_after,
898                }
899            }
900            Self::GreaterThanEqual { tok, .. } => {
901                let whitespace_before = parse_parenthesizable_whitespace(
902                    config,
903                    &mut (*tok).whitespace_before.borrow_mut(),
904                )?;
905                let whitespace_after = parse_parenthesizable_whitespace(
906                    config,
907                    &mut (*tok).whitespace_after.borrow_mut(),
908                )?;
909                Self::Inflated::GreaterThanEqual {
910                    whitespace_before,
911                    whitespace_after,
912                }
913            }
914            Self::Equal { tok, .. } => {
915                let whitespace_before = parse_parenthesizable_whitespace(
916                    config,
917                    &mut (*tok).whitespace_before.borrow_mut(),
918                )?;
919                let whitespace_after = parse_parenthesizable_whitespace(
920                    config,
921                    &mut (*tok).whitespace_after.borrow_mut(),
922                )?;
923                Self::Inflated::Equal {
924                    whitespace_before,
925                    whitespace_after,
926                }
927            }
928            Self::NotEqual { tok, .. } => {
929                let whitespace_before = parse_parenthesizable_whitespace(
930                    config,
931                    &mut (*tok).whitespace_before.borrow_mut(),
932                )?;
933                let whitespace_after = parse_parenthesizable_whitespace(
934                    config,
935                    &mut (*tok).whitespace_after.borrow_mut(),
936                )?;
937                Self::Inflated::NotEqual {
938                    whitespace_before,
939                    whitespace_after,
940                }
941            }
942            Self::In { tok, .. } => {
943                let whitespace_before = parse_parenthesizable_whitespace(
944                    config,
945                    &mut (*tok).whitespace_before.borrow_mut(),
946                )?;
947                let whitespace_after = parse_parenthesizable_whitespace(
948                    config,
949                    &mut (*tok).whitespace_after.borrow_mut(),
950                )?;
951                Self::Inflated::In {
952                    whitespace_before,
953                    whitespace_after,
954                }
955            }
956            Self::Is { tok, .. } => {
957                let whitespace_before = parse_parenthesizable_whitespace(
958                    config,
959                    &mut (*tok).whitespace_before.borrow_mut(),
960                )?;
961                let whitespace_after = parse_parenthesizable_whitespace(
962                    config,
963                    &mut (*tok).whitespace_after.borrow_mut(),
964                )?;
965                Self::Inflated::Is {
966                    whitespace_before,
967                    whitespace_after,
968                }
969            }
970            Self::IsNot {
971                is_tok, not_tok, ..
972            } => {
973                let whitespace_before = parse_parenthesizable_whitespace(
974                    config,
975                    &mut (*is_tok).whitespace_before.borrow_mut(),
976                )?;
977                let whitespace_between = parse_parenthesizable_whitespace(
978                    config,
979                    &mut (*is_tok).whitespace_after.borrow_mut(),
980                )?;
981                let whitespace_after = parse_parenthesizable_whitespace(
982                    config,
983                    &mut (*not_tok).whitespace_after.borrow_mut(),
984                )?;
985                Self::Inflated::IsNot {
986                    whitespace_before,
987                    whitespace_between,
988                    whitespace_after,
989                }
990            }
991            Self::NotIn {
992                not_tok, in_tok, ..
993            } => {
994                let whitespace_before = parse_parenthesizable_whitespace(
995                    config,
996                    &mut (*not_tok).whitespace_before.borrow_mut(),
997                )?;
998                let whitespace_between = parse_parenthesizable_whitespace(
999                    config,
1000                    &mut (*not_tok).whitespace_after.borrow_mut(),
1001                )?;
1002                let whitespace_after = parse_parenthesizable_whitespace(
1003                    config,
1004                    &mut (*in_tok).whitespace_after.borrow_mut(),
1005                )?;
1006                Self::Inflated::NotIn {
1007                    whitespace_before,
1008                    whitespace_between,
1009                    whitespace_after,
1010                }
1011            }
1012        })
1013    }
1014}
1015
1016#[cst_node]
1017pub struct Colon<'a> {
1018    pub whitespace_before: ParenthesizableWhitespace<'a>,
1019    pub whitespace_after: ParenthesizableWhitespace<'a>,
1020
1021    #[cfg_attr(feature = "py", skip_py)]
1022    pub(crate) tok: TokenRef<'a>,
1023}
1024
1025impl<'r, 'a> Inflate<'a> for DeflatedColon<'r, 'a> {
1026    type Inflated = Colon<'a>;
1027    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1028        let whitespace_before = parse_parenthesizable_whitespace(
1029            config,
1030            &mut (*self.tok).whitespace_before.borrow_mut(),
1031        )?;
1032        let whitespace_after = parse_parenthesizable_whitespace(
1033            config,
1034            &mut (*self.tok).whitespace_after.borrow_mut(),
1035        )?;
1036        Ok(Self::Inflated {
1037            whitespace_before,
1038            whitespace_after,
1039        })
1040    }
1041}
1042
1043impl<'a> Codegen<'a> for Colon<'a> {
1044    fn codegen(&self, state: &mut CodegenState<'a>) {
1045        self.whitespace_before.codegen(state);
1046        state.add_token(":");
1047        self.whitespace_after.codegen(state);
1048    }
1049}
1050
1051#[cst_node]
1052pub enum AugOp<'a> {
1053    AddAssign {
1054        whitespace_before: ParenthesizableWhitespace<'a>,
1055        whitespace_after: ParenthesizableWhitespace<'a>,
1056        #[cfg_attr(feature = "py", skip_py)]
1057        tok: TokenRef<'a>,
1058    },
1059    SubtractAssign {
1060        whitespace_before: ParenthesizableWhitespace<'a>,
1061        whitespace_after: ParenthesizableWhitespace<'a>,
1062        #[cfg_attr(feature = "py", skip_py)]
1063        tok: TokenRef<'a>,
1064    },
1065    MultiplyAssign {
1066        whitespace_before: ParenthesizableWhitespace<'a>,
1067        whitespace_after: ParenthesizableWhitespace<'a>,
1068        #[cfg_attr(feature = "py", skip_py)]
1069        tok: TokenRef<'a>,
1070    },
1071    MatrixMultiplyAssign {
1072        whitespace_before: ParenthesizableWhitespace<'a>,
1073        whitespace_after: ParenthesizableWhitespace<'a>,
1074        #[cfg_attr(feature = "py", skip_py)]
1075        tok: TokenRef<'a>,
1076    },
1077    DivideAssign {
1078        whitespace_before: ParenthesizableWhitespace<'a>,
1079        whitespace_after: ParenthesizableWhitespace<'a>,
1080        #[cfg_attr(feature = "py", skip_py)]
1081        tok: TokenRef<'a>,
1082    },
1083    ModuloAssign {
1084        whitespace_before: ParenthesizableWhitespace<'a>,
1085        whitespace_after: ParenthesizableWhitespace<'a>,
1086        #[cfg_attr(feature = "py", skip_py)]
1087        tok: TokenRef<'a>,
1088    },
1089    BitAndAssign {
1090        whitespace_before: ParenthesizableWhitespace<'a>,
1091        whitespace_after: ParenthesizableWhitespace<'a>,
1092        #[cfg_attr(feature = "py", skip_py)]
1093        tok: TokenRef<'a>,
1094    },
1095    BitOrAssign {
1096        whitespace_before: ParenthesizableWhitespace<'a>,
1097        whitespace_after: ParenthesizableWhitespace<'a>,
1098        #[cfg_attr(feature = "py", skip_py)]
1099        tok: TokenRef<'a>,
1100    },
1101    BitXorAssign {
1102        whitespace_before: ParenthesizableWhitespace<'a>,
1103        whitespace_after: ParenthesizableWhitespace<'a>,
1104        #[cfg_attr(feature = "py", skip_py)]
1105        tok: TokenRef<'a>,
1106    },
1107    LeftShiftAssign {
1108        whitespace_before: ParenthesizableWhitespace<'a>,
1109        whitespace_after: ParenthesizableWhitespace<'a>,
1110        #[cfg_attr(feature = "py", skip_py)]
1111        tok: TokenRef<'a>,
1112    },
1113    RightShiftAssign {
1114        whitespace_before: ParenthesizableWhitespace<'a>,
1115        whitespace_after: ParenthesizableWhitespace<'a>,
1116        #[cfg_attr(feature = "py", skip_py)]
1117        tok: TokenRef<'a>,
1118    },
1119    PowerAssign {
1120        whitespace_before: ParenthesizableWhitespace<'a>,
1121        whitespace_after: ParenthesizableWhitespace<'a>,
1122        #[cfg_attr(feature = "py", skip_py)]
1123        tok: TokenRef<'a>,
1124    },
1125    FloorDivideAssign {
1126        whitespace_before: ParenthesizableWhitespace<'a>,
1127        whitespace_after: ParenthesizableWhitespace<'a>,
1128        #[cfg_attr(feature = "py", skip_py)]
1129        tok: TokenRef<'a>,
1130    },
1131}
1132
1133impl<'r, 'a> Inflate<'a> for DeflatedAugOp<'r, 'a> {
1134    type Inflated = AugOp<'a>;
1135    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1136        Ok(match self {
1137            Self::AddAssign { tok, .. } => {
1138                let whitespace_before = parse_parenthesizable_whitespace(
1139                    config,
1140                    &mut (*tok).whitespace_before.borrow_mut(),
1141                )?;
1142                let whitespace_after = parse_parenthesizable_whitespace(
1143                    config,
1144                    &mut (*tok).whitespace_after.borrow_mut(),
1145                )?;
1146                Self::Inflated::AddAssign {
1147                    whitespace_before,
1148                    whitespace_after,
1149                }
1150            }
1151            Self::SubtractAssign { tok, .. } => {
1152                let whitespace_before = parse_parenthesizable_whitespace(
1153                    config,
1154                    &mut (*tok).whitespace_before.borrow_mut(),
1155                )?;
1156                let whitespace_after = parse_parenthesizable_whitespace(
1157                    config,
1158                    &mut (*tok).whitespace_after.borrow_mut(),
1159                )?;
1160                Self::Inflated::SubtractAssign {
1161                    whitespace_before,
1162                    whitespace_after,
1163                }
1164            }
1165            Self::MultiplyAssign { tok, .. } => {
1166                let whitespace_before = parse_parenthesizable_whitespace(
1167                    config,
1168                    &mut (*tok).whitespace_before.borrow_mut(),
1169                )?;
1170                let whitespace_after = parse_parenthesizable_whitespace(
1171                    config,
1172                    &mut (*tok).whitespace_after.borrow_mut(),
1173                )?;
1174                Self::Inflated::MultiplyAssign {
1175                    whitespace_before,
1176                    whitespace_after,
1177                }
1178            }
1179            Self::MatrixMultiplyAssign { tok, .. } => {
1180                let whitespace_before = parse_parenthesizable_whitespace(
1181                    config,
1182                    &mut (*tok).whitespace_before.borrow_mut(),
1183                )?;
1184                let whitespace_after = parse_parenthesizable_whitespace(
1185                    config,
1186                    &mut (*tok).whitespace_after.borrow_mut(),
1187                )?;
1188                Self::Inflated::MatrixMultiplyAssign {
1189                    whitespace_before,
1190                    whitespace_after,
1191                }
1192            }
1193            Self::DivideAssign { tok, .. } => {
1194                let whitespace_before = parse_parenthesizable_whitespace(
1195                    config,
1196                    &mut (*tok).whitespace_before.borrow_mut(),
1197                )?;
1198                let whitespace_after = parse_parenthesizable_whitespace(
1199                    config,
1200                    &mut (*tok).whitespace_after.borrow_mut(),
1201                )?;
1202                Self::Inflated::DivideAssign {
1203                    whitespace_before,
1204                    whitespace_after,
1205                }
1206            }
1207            Self::ModuloAssign { tok, .. } => {
1208                let whitespace_before = parse_parenthesizable_whitespace(
1209                    config,
1210                    &mut (*tok).whitespace_before.borrow_mut(),
1211                )?;
1212                let whitespace_after = parse_parenthesizable_whitespace(
1213                    config,
1214                    &mut (*tok).whitespace_after.borrow_mut(),
1215                )?;
1216                Self::Inflated::ModuloAssign {
1217                    whitespace_before,
1218                    whitespace_after,
1219                }
1220            }
1221            Self::BitAndAssign { tok, .. } => {
1222                let whitespace_before = parse_parenthesizable_whitespace(
1223                    config,
1224                    &mut (*tok).whitespace_before.borrow_mut(),
1225                )?;
1226                let whitespace_after = parse_parenthesizable_whitespace(
1227                    config,
1228                    &mut (*tok).whitespace_after.borrow_mut(),
1229                )?;
1230                Self::Inflated::BitAndAssign {
1231                    whitespace_before,
1232                    whitespace_after,
1233                }
1234            }
1235            Self::BitOrAssign { tok, .. } => {
1236                let whitespace_before = parse_parenthesizable_whitespace(
1237                    config,
1238                    &mut (*tok).whitespace_before.borrow_mut(),
1239                )?;
1240                let whitespace_after = parse_parenthesizable_whitespace(
1241                    config,
1242                    &mut (*tok).whitespace_after.borrow_mut(),
1243                )?;
1244                Self::Inflated::BitOrAssign {
1245                    whitespace_before,
1246                    whitespace_after,
1247                }
1248            }
1249            Self::BitXorAssign { tok, .. } => {
1250                let whitespace_before = parse_parenthesizable_whitespace(
1251                    config,
1252                    &mut (*tok).whitespace_before.borrow_mut(),
1253                )?;
1254                let whitespace_after = parse_parenthesizable_whitespace(
1255                    config,
1256                    &mut (*tok).whitespace_after.borrow_mut(),
1257                )?;
1258                Self::Inflated::BitXorAssign {
1259                    whitespace_before,
1260                    whitespace_after,
1261                }
1262            }
1263            Self::LeftShiftAssign { tok, .. } => {
1264                let whitespace_before = parse_parenthesizable_whitespace(
1265                    config,
1266                    &mut (*tok).whitespace_before.borrow_mut(),
1267                )?;
1268                let whitespace_after = parse_parenthesizable_whitespace(
1269                    config,
1270                    &mut (*tok).whitespace_after.borrow_mut(),
1271                )?;
1272                Self::Inflated::LeftShiftAssign {
1273                    whitespace_before,
1274                    whitespace_after,
1275                }
1276            }
1277            Self::RightShiftAssign { tok, .. } => {
1278                let whitespace_before = parse_parenthesizable_whitespace(
1279                    config,
1280                    &mut (*tok).whitespace_before.borrow_mut(),
1281                )?;
1282                let whitespace_after = parse_parenthesizable_whitespace(
1283                    config,
1284                    &mut (*tok).whitespace_after.borrow_mut(),
1285                )?;
1286                Self::Inflated::RightShiftAssign {
1287                    whitespace_before,
1288                    whitespace_after,
1289                }
1290            }
1291            Self::PowerAssign { tok, .. } => {
1292                let whitespace_before = parse_parenthesizable_whitespace(
1293                    config,
1294                    &mut (*tok).whitespace_before.borrow_mut(),
1295                )?;
1296                let whitespace_after = parse_parenthesizable_whitespace(
1297                    config,
1298                    &mut (*tok).whitespace_after.borrow_mut(),
1299                )?;
1300                Self::Inflated::PowerAssign {
1301                    whitespace_before,
1302                    whitespace_after,
1303                }
1304            }
1305            Self::FloorDivideAssign { tok, .. } => {
1306                let whitespace_before = parse_parenthesizable_whitespace(
1307                    config,
1308                    &mut (*tok).whitespace_before.borrow_mut(),
1309                )?;
1310                let whitespace_after = parse_parenthesizable_whitespace(
1311                    config,
1312                    &mut (*tok).whitespace_after.borrow_mut(),
1313                )?;
1314                Self::Inflated::FloorDivideAssign {
1315                    whitespace_before,
1316                    whitespace_after,
1317                }
1318            }
1319        })
1320    }
1321}
1322
1323impl<'a> Codegen<'a> for AugOp<'a> {
1324    fn codegen(&self, state: &mut CodegenState<'a>) {
1325        let (tok, bef, aft) = match self {
1326            Self::AddAssign {
1327                whitespace_before,
1328                whitespace_after,
1329                ..
1330            } => ("+=", whitespace_before, whitespace_after),
1331            Self::SubtractAssign {
1332                whitespace_before,
1333                whitespace_after,
1334                ..
1335            } => ("-=", whitespace_before, whitespace_after),
1336            Self::MultiplyAssign {
1337                whitespace_before,
1338                whitespace_after,
1339                ..
1340            } => ("*=", whitespace_before, whitespace_after),
1341            Self::MatrixMultiplyAssign {
1342                whitespace_before,
1343                whitespace_after,
1344                ..
1345            } => ("@=", whitespace_before, whitespace_after),
1346            Self::DivideAssign {
1347                whitespace_before,
1348                whitespace_after,
1349                ..
1350            } => ("/=", whitespace_before, whitespace_after),
1351            Self::ModuloAssign {
1352                whitespace_before,
1353                whitespace_after,
1354                ..
1355            } => ("%=", whitespace_before, whitespace_after),
1356            Self::BitAndAssign {
1357                whitespace_before,
1358                whitespace_after,
1359                ..
1360            } => ("&=", whitespace_before, whitespace_after),
1361            Self::BitOrAssign {
1362                whitespace_before,
1363                whitespace_after,
1364                ..
1365            } => ("|=", whitespace_before, whitespace_after),
1366            Self::BitXorAssign {
1367                whitespace_before,
1368                whitespace_after,
1369                ..
1370            } => ("^=", whitespace_before, whitespace_after),
1371            Self::LeftShiftAssign {
1372                whitespace_before,
1373                whitespace_after,
1374                ..
1375            } => ("<<=", whitespace_before, whitespace_after),
1376            Self::RightShiftAssign {
1377                whitespace_before,
1378                whitespace_after,
1379                ..
1380            } => (">>=", whitespace_before, whitespace_after),
1381            Self::PowerAssign {
1382                whitespace_before,
1383                whitespace_after,
1384                ..
1385            } => ("**=", whitespace_before, whitespace_after),
1386            Self::FloorDivideAssign {
1387                whitespace_before,
1388                whitespace_after,
1389                ..
1390            } => ("//=", whitespace_before, whitespace_after),
1391        };
1392        bef.codegen(state);
1393        state.add_token(tok);
1394        aft.codegen(state);
1395    }
1396}
1397
1398#[cst_node]
1399pub struct BitOr<'a> {
1400    pub whitespace_before: ParenthesizableWhitespace<'a>,
1401    pub whitespace_after: ParenthesizableWhitespace<'a>,
1402
1403    pub(crate) tok: TokenRef<'a>,
1404}
1405
1406impl<'r, 'a> Inflate<'a> for DeflatedBitOr<'r, 'a> {
1407    type Inflated = BitOr<'a>;
1408    fn inflate(self, config: &Config<'a>) -> Result<Self::Inflated> {
1409        let whitespace_before = parse_parenthesizable_whitespace(
1410            config,
1411            &mut (*self.tok).whitespace_before.borrow_mut(),
1412        )?;
1413        let whitespace_after = parse_parenthesizable_whitespace(
1414            config,
1415            &mut (*self.tok).whitespace_after.borrow_mut(),
1416        )?;
1417        Ok(Self::Inflated {
1418            whitespace_before,
1419            whitespace_after,
1420        })
1421    }
1422}
1423
1424impl<'a> Codegen<'a> for BitOr<'a> {
1425    fn codegen(&self, state: &mut CodegenState<'a>) {
1426        self.whitespace_before.codegen(state);
1427        state.add_token("|");
1428        self.whitespace_after.codegen(state);
1429    }
1430}