ara_parser/tree/expression/
operator.rs

1use bincode::Decode;
2use bincode::Encode;
3use schemars::JsonSchema;
4use serde::Deserialize;
5use serde::Serialize;
6
7use crate::tree::comment::CommentGroup;
8use crate::tree::definition::r#type::TypeDefinition;
9use crate::tree::expression::argument::ArgumentListExpression;
10use crate::tree::expression::argument::ArgumentPlaceholderExpression;
11use crate::tree::expression::class::AnonymousClassExpression;
12use crate::tree::expression::generic::GenericGroupExpression;
13use crate::tree::expression::Expression;
14use crate::tree::identifier::Identifier;
15use crate::tree::token::Keyword;
16use crate::tree::utils::CommaSeparated;
17use crate::tree::variable::Variable;
18use crate::tree::Node;
19
20#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
21#[serde(rename_all = "snake_case", tag = "type", content = "value")]
22pub enum FunctionalOperationExpression {
23    Pipe {
24        comments: CommentGroup,
25        left: Box<Expression>,
26        pipe: usize,
27        greater_than: usize,
28        right: Box<Expression>,
29    },
30    Expression {
31        comments: CommentGroup,
32        dollar: usize,
33        generics: Option<GenericGroupExpression>,
34        left_parenthesis: usize,
35        expression: Box<Expression>,
36        right_parenthesis: usize,
37    },
38}
39
40#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
41#[serde(rename_all = "snake_case", tag = "type", content = "value")]
42pub enum ArithmeticOperationExpression {
43    Addition {
44        comments: CommentGroup,
45        left: Box<Expression>,
46        plus: usize,
47        right: Box<Expression>,
48    },
49    Subtraction {
50        comments: CommentGroup,
51        left: Box<Expression>,
52        minus: usize,
53        right: Box<Expression>,
54    },
55    Multiplication {
56        comments: CommentGroup,
57        left: Box<Expression>,
58        asterisk: usize,
59        right: Box<Expression>,
60    },
61    Division {
62        comments: CommentGroup,
63        left: Box<Expression>,
64        slash: usize,
65        right: Box<Expression>,
66    },
67    Modulo {
68        comments: CommentGroup,
69        left: Box<Expression>,
70        percent: usize,
71        right: Box<Expression>,
72    },
73    Exponentiation {
74        comments: CommentGroup,
75        left: Box<Expression>,
76        pow: usize,
77        right: Box<Expression>,
78    },
79    Negative {
80        comments: CommentGroup,
81        minus: usize,
82        right: Box<Expression>,
83    },
84    Positive {
85        comments: CommentGroup,
86        plus: usize,
87        right: Box<Expression>,
88    },
89    PreIncrement {
90        comments: CommentGroup,
91        increment: usize,
92        right: Box<Expression>,
93    },
94    PostIncrement {
95        left: Box<Expression>,
96        increment: usize,
97    },
98    PreDecrement {
99        comments: CommentGroup,
100        decrement: usize,
101        right: Box<Expression>,
102    },
103    PostDecrement {
104        left: Box<Expression>,
105        decrement: usize,
106    },
107}
108
109#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
110#[serde(rename_all = "snake_case", tag = "type", content = "value")]
111pub enum AssignmentOperationExpression {
112    Assignment {
113        comments: CommentGroup,
114        left: Box<Expression>,
115        equals: usize,
116        right: Box<Expression>,
117    },
118    Addition {
119        comments: CommentGroup,
120        left: Box<Expression>,
121        plus_equals: usize,
122        right: Box<Expression>,
123    },
124    Subtraction {
125        comments: CommentGroup,
126        left: Box<Expression>,
127        minus_equals: usize,
128        right: Box<Expression>,
129    },
130    Multiplication {
131        comments: CommentGroup,
132        left: Box<Expression>,
133        asterisk_equals: usize,
134        right: Box<Expression>,
135    },
136    Division {
137        comments: CommentGroup,
138        left: Box<Expression>,
139        slash_equals: usize,
140        right: Box<Expression>,
141    },
142    Modulo {
143        comments: CommentGroup,
144        left: Box<Expression>,
145        percent_equals: usize,
146        right: Box<Expression>,
147    },
148    Exponentiation {
149        comments: CommentGroup,
150        left: Box<Expression>,
151        pow_equals: usize,
152        right: Box<Expression>,
153    },
154    Concat {
155        comments: CommentGroup,
156        left: Box<Expression>,
157        dot_equals: usize,
158        right: Box<Expression>,
159    },
160    BitwiseAnd {
161        comments: CommentGroup,
162        left: Box<Expression>,
163        ampersand_equals: usize,
164        right: Box<Expression>,
165    },
166    BitwiseOr {
167        comments: CommentGroup,
168        left: Box<Expression>,
169        pipe_equals: usize,
170        right: Box<Expression>,
171    },
172    BitwiseXor {
173        comments: CommentGroup,
174        left: Box<Expression>,
175        caret_equals: usize,
176        right: Box<Expression>,
177    },
178    LeftShift {
179        comments: CommentGroup,
180        left: Box<Expression>,
181        left_shift_equals: usize,
182        right: Box<Expression>,
183    },
184    RightShift {
185        comments: CommentGroup,
186        left: Box<Expression>,
187        right_shift_equals: usize,
188        right: Box<Expression>,
189    },
190    Coalesce {
191        comments: CommentGroup,
192        left: Box<Expression>,
193        coalesce_equals: usize,
194        right: Box<Expression>,
195    },
196}
197
198#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
199#[serde(rename_all = "snake_case", tag = "type", content = "value")]
200pub enum BitwiseOperationExpression {
201    And {
202        comments: CommentGroup,
203        left: Box<Expression>,
204        and: usize,
205        right: Box<Expression>,
206    },
207    Or {
208        comments: CommentGroup,
209        left: Box<Expression>,
210        or: usize,
211        right: Box<Expression>,
212    },
213    Xor {
214        comments: CommentGroup,
215        left: Box<Expression>,
216        xor: usize,
217        right: Box<Expression>,
218    },
219    LeftShift {
220        comments: CommentGroup,
221        left: Box<Expression>,
222        left_shift: usize,
223        right: Box<Expression>,
224    },
225    RightShift {
226        comments: CommentGroup,
227        left: Box<Expression>,
228        right_shift: usize,
229        right: Box<Expression>,
230    },
231    Not {
232        comments: CommentGroup,
233        not: usize,
234        right: Box<Expression>,
235    },
236}
237
238#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
239#[serde(rename_all = "snake_case", tag = "type", content = "value")]
240pub enum ComparisonOperationExpression {
241    Equal {
242        comments: CommentGroup,
243        left: Box<Expression>,
244        double_equals: usize,
245        right: Box<Expression>,
246    },
247    Identical {
248        comments: CommentGroup,
249        left: Box<Expression>,
250        triple_equals: usize,
251        right: Box<Expression>,
252    },
253    NotEqual {
254        comments: CommentGroup,
255        left: Box<Expression>,
256        bang_equals: usize,
257        right: Box<Expression>,
258    },
259    NotIdentical {
260        comments: CommentGroup,
261        left: Box<Expression>,
262        bang_double_equals: usize,
263        right: Box<Expression>,
264    },
265    LessThan {
266        comments: CommentGroup,
267        left: Box<Expression>,
268        less_than: usize,
269        right: Box<Expression>,
270    },
271    GreaterThan {
272        comments: CommentGroup,
273        left: Box<Expression>,
274        greater_than: usize,
275        right: Box<Expression>,
276    },
277    LessThanOrEqual {
278        comments: CommentGroup,
279        left: Box<Expression>,
280        less_than_equals: usize,
281        right: Box<Expression>,
282    },
283    GreaterThanOrEqual {
284        comments: CommentGroup,
285        left: Box<Expression>,
286        greater_than_equals: usize,
287        right: Box<Expression>,
288    },
289    Spaceship {
290        comments: CommentGroup,
291        left: Box<Expression>,
292        spaceship: usize,
293        right: Box<Expression>,
294    },
295}
296
297#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
298#[serde(rename_all = "snake_case", tag = "type", content = "value")]
299pub enum LogicalOperationExpression {
300    And {
301        comments: CommentGroup,
302        left: Box<Expression>,
303        double_ampersand: usize,
304        right: Box<Expression>,
305    },
306    Or {
307        comments: CommentGroup,
308        left: Box<Expression>,
309        double_pipe: usize,
310        right: Box<Expression>,
311    },
312    Not {
313        comments: CommentGroup,
314        bang: usize,
315        right: Box<Expression>,
316    },
317}
318
319#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
320#[serde(rename_all = "snake_case", tag = "type", content = "value")]
321pub enum StringOperationExpression {
322    Concat {
323        comments: CommentGroup,
324        left: Box<Expression>,
325        dot: usize,
326        right: Box<Expression>,
327    },
328}
329
330#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
331#[serde(rename_all = "snake_case", tag = "type", content = "value")]
332pub enum ArrayOperationExpression {
333    Access {
334        comments: CommentGroup,
335        array: Box<Expression>,
336        left_bracket: usize,
337        index: Box<Expression>,
338        right_bracket: usize,
339    },
340    Push {
341        comments: CommentGroup,
342        array: Box<Expression>,
343        left_bracket: usize,
344        right_bracket: usize,
345    },
346    Unset {
347        comments: CommentGroup,
348        unset: Keyword,
349        item: Box<Expression>,
350    },
351    Isset {
352        comments: CommentGroup,
353        isset: Keyword,
354        item: Box<Expression>,
355    },
356    In {
357        comments: CommentGroup,
358        item: Box<Expression>,
359        r#in: Keyword,
360        array: Box<Expression>,
361    },
362}
363
364#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
365#[serde(rename_all = "snake_case", tag = "type", content = "value")]
366pub enum CoalesceOperationExpression {
367    Coalesce {
368        comments: CommentGroup,
369        left: Box<Expression>,
370        double_question: usize,
371        right: Box<Expression>,
372    },
373}
374
375#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
376#[serde(rename_all = "snake_case", tag = "type", content = "value")]
377pub enum TernaryOperationExpression {
378    Ternary {
379        comments: CommentGroup,
380        condition: Box<Expression>,
381        question: usize,
382        if_true: Box<Expression>,
383        colon: usize,
384        if_false: Box<Expression>,
385    },
386    ImplicitShortTernary {
387        comments: CommentGroup,
388        condition: Box<Expression>,
389        question: usize,
390        colon: usize,
391        if_false: Box<Expression>,
392    },
393    ShortTernary {
394        comments: CommentGroup,
395        condition: Box<Expression>,
396        question_colon: usize,
397        if_false: Box<Expression>,
398    },
399}
400
401#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
402#[serde(rename_all = "snake_case", tag = "type", content = "value")]
403pub enum TypeOperationExpression {
404    Instanceof {
405        comments: CommentGroup,
406        left: Box<Expression>,
407        instanceof: Keyword,
408        right: Identifier,
409    },
410    Is {
411        comments: CommentGroup,
412        left: Box<Expression>,
413        is: Keyword,
414        right: TypeDefinition,
415    },
416    Into {
417        comments: CommentGroup,
418        left: Box<Expression>,
419        into: Keyword,
420        right: TypeDefinition,
421    },
422    As {
423        comments: CommentGroup,
424        left: Box<Expression>,
425        r#as: Keyword,
426        right: TypeDefinition,
427    },
428}
429
430#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
431#[serde(rename_all = "snake_case", tag = "type", content = "value")]
432pub enum GeneratorOperationExpression {
433    Yield {
434        comments: CommentGroup,
435        r#yield: Keyword,
436    },
437    YieldValue {
438        comments: CommentGroup,
439        r#yield: Keyword,
440        value: Box<Expression>,
441    },
442    YieldKeyValue {
443        comments: CommentGroup,
444        r#yield: Keyword,
445        key: Box<Expression>,
446        double_arrow: usize,
447        value: Box<Expression>,
448    },
449    YieldFrom {
450        comments: CommentGroup,
451        r#yield: Keyword,
452        from: Keyword,
453        value: Box<Expression>,
454    },
455}
456
457#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
458#[serde(rename_all = "snake_case", tag = "type", content = "value")]
459pub enum ExceptionOperationExpression {
460    Throw {
461        comments: CommentGroup,
462        r#throw: Keyword,
463        value: Box<Expression>,
464    },
465}
466
467#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
468#[serde(rename_all = "snake_case", tag = "type", content = "value")]
469pub enum ObjectOperationExpression {
470    Clone {
471        comments: CommentGroup,
472        clone: Keyword,
473        object: Box<Expression>,
474    },
475    MethodCall {
476        comments: CommentGroup,
477        object: Box<Expression>,
478        arrow: usize,
479        method: Identifier,
480        generics: Option<GenericGroupExpression>,
481        arguments: ArgumentListExpression,
482    },
483    NullsafeMethodCall {
484        comments: CommentGroup,
485        object: Box<Expression>,
486        question_arrow: usize,
487        method: Identifier,
488        generics: Option<GenericGroupExpression>,
489        arguments: ArgumentListExpression,
490    },
491    MethodClosureCreation {
492        comments: CommentGroup,
493        object: Box<Expression>,
494        arrow: usize,
495        method: Identifier,
496        generics: Option<GenericGroupExpression>,
497        placeholder: ArgumentPlaceholderExpression,
498    },
499    PropertyFetch {
500        comments: CommentGroup,
501        object: Box<Expression>,
502        arrow: usize,
503        property: Identifier,
504    },
505    NullsafePropertyFetch {
506        comments: CommentGroup,
507        object: Box<Expression>,
508        question_arrow: usize,
509        property: Identifier,
510    },
511}
512
513#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
514#[serde(rename_all = "snake_case", tag = "type", content = "value")]
515pub enum ClassOperationInitializationClassExpression {
516    Identifier(Identifier),
517    Variable(Variable),
518}
519
520#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
521#[serde(rename_all = "snake_case", tag = "type", content = "value")]
522pub enum ClassOperationExpression {
523    Initialization {
524        comments: CommentGroup,
525        new: Keyword,
526        class: ClassOperationInitializationClassExpression,
527        generics: Option<GenericGroupExpression>,
528        arguments: ArgumentListExpression,
529    },
530    AnonymousInitialization {
531        comments: CommentGroup,
532        new: Keyword,
533        class: AnonymousClassExpression,
534    },
535    StaticMethodCall {
536        comments: CommentGroup,
537        class: Box<Expression>,
538        double_colon: usize,
539        method: Identifier,
540        generics: Option<GenericGroupExpression>,
541        arguments: ArgumentListExpression,
542    },
543    StaticMethodClosureCreation {
544        comments: CommentGroup,
545        class: Box<Expression>,
546        double_colon: usize,
547        method: Identifier,
548        generics: Option<GenericGroupExpression>,
549        placeholder: ArgumentPlaceholderExpression,
550    },
551    StaticPropertyFetch {
552        comments: CommentGroup,
553        class: Box<Expression>,
554        double_colon: usize,
555        property: Variable,
556    },
557    ConstantFetch {
558        comments: CommentGroup,
559        class: Box<Expression>,
560        double_colon: usize,
561        constant: Identifier,
562    },
563}
564
565#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
566#[serde(rename_all = "snake_case", tag = "type", content = "value")]
567pub enum FunctionOperationExpression {
568    Call {
569        comments: CommentGroup,
570        function: Box<Expression>,
571        generics: Option<GenericGroupExpression>,
572        arguments: ArgumentListExpression,
573    },
574    ClosureCreation {
575        comments: CommentGroup,
576        function: Box<Expression>,
577        generics: Option<GenericGroupExpression>,
578        placeholder: ArgumentPlaceholderExpression,
579    },
580}
581
582#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
583#[serde(rename_all = "snake_case", tag = "type", content = "value")]
584pub enum AsyncOperationExpression {
585    Async {
586        comments: CommentGroup,
587        r#async: Keyword,
588        expression: Box<Expression>,
589    },
590    Await {
591        comments: CommentGroup,
592        r#await: Keyword,
593        expression: Box<Expression>,
594    },
595    Concurrently {
596        comments: CommentGroup,
597        concurrently: Keyword,
598        left_brace: usize,
599        expressions: CommaSeparated<Expression>,
600        right_brace: usize,
601    },
602}
603
604#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize, Encode, Decode, JsonSchema)]
605#[serde(rename_all = "snake_case", tag = "type", content = "value")]
606pub enum RangeOperationExpression {
607    Between {
608        comments: CommentGroup,
609        from: Box<Expression>,
610        double_dot: usize,
611        to: Box<Expression>,
612    },
613    BetweenInclusive {
614        comments: CommentGroup,
615        from: Box<Expression>,
616        double_dot: usize,
617        equals: usize,
618        to: Box<Expression>,
619    },
620    To {
621        comments: CommentGroup,
622        double_dot: usize,
623        to: Box<Expression>,
624    },
625    ToInclusive {
626        comments: CommentGroup,
627        double_dot: usize,
628        equals: usize,
629        to: Box<Expression>,
630    },
631    From {
632        comments: CommentGroup,
633        from: Box<Expression>,
634        double_dot: usize,
635    },
636    Full {
637        comments: CommentGroup,
638        double_dot: usize,
639    },
640}
641
642impl RangeOperationExpression {
643    pub fn has_start(&self) -> bool {
644        match &self {
645            Self::Between { .. } => true,
646            Self::BetweenInclusive { .. } => true,
647            Self::To { .. } => false,
648            Self::ToInclusive { .. } => false,
649            Self::From { .. } => true,
650            Self::Full { .. } => false,
651        }
652    }
653}
654
655impl Node for FunctionalOperationExpression {
656    fn comments(&self) -> Option<&CommentGroup> {
657        match self {
658            Self::Pipe { comments, .. } | Self::Expression { comments, .. } => Some(comments),
659        }
660    }
661
662    fn initial_position(&self) -> usize {
663        match &self {
664            Self::Pipe { left, .. } => left.initial_position(),
665            Self::Expression { dollar, .. } => *dollar,
666        }
667    }
668
669    fn final_position(&self) -> usize {
670        match &self {
671            Self::Pipe { right, .. } => right.final_position(),
672            Self::Expression {
673                right_parenthesis, ..
674            } => *right_parenthesis,
675        }
676    }
677
678    fn children(&self) -> Vec<&dyn Node> {
679        match &self {
680            Self::Pipe { left, right, .. } => vec![left.as_ref(), right.as_ref()],
681            Self::Expression {
682                generics,
683                expression,
684                ..
685            } => {
686                let mut children: Vec<&dyn Node> = vec![expression.as_ref()];
687                if let Some(generics) = generics {
688                    children.push(generics);
689                }
690                children
691            }
692        }
693    }
694
695    fn get_description(&self) -> String {
696        match &self {
697            Self::Pipe { .. } => "pipe functional operation expression".to_string(),
698            Self::Expression { .. } => "functional operation expression".to_string(),
699        }
700    }
701}
702
703impl Node for ArithmeticOperationExpression {
704    fn comments(&self) -> Option<&CommentGroup> {
705        match &self {
706            Self::Addition { comments, .. } => Some(comments),
707            Self::Subtraction { comments, .. } => Some(comments),
708            Self::Multiplication { comments, .. } => Some(comments),
709            Self::Division { comments, .. } => Some(comments),
710            Self::Modulo { comments, .. } => Some(comments),
711            Self::Exponentiation { comments, .. } => Some(comments),
712            Self::Negative { comments, .. } => Some(comments),
713            Self::Positive { comments, .. } => Some(comments),
714            Self::PreIncrement { comments, .. } => Some(comments),
715            Self::PreDecrement { comments, .. } => Some(comments),
716            Self::PostIncrement { .. } => None,
717            Self::PostDecrement { .. } => None,
718        }
719    }
720
721    fn initial_position(&self) -> usize {
722        match &self {
723            Self::Addition { left, .. } => left.initial_position(),
724            Self::Subtraction { left, .. } => left.initial_position(),
725            Self::Multiplication { left, .. } => left.initial_position(),
726            Self::Division { left, .. } => left.initial_position(),
727            Self::Modulo { left, .. } => left.initial_position(),
728            Self::Exponentiation { left, .. } => left.initial_position(),
729            Self::Negative { minus, .. } => *minus,
730            Self::Positive { plus, .. } => *plus,
731            Self::PreIncrement { increment, .. } => *increment,
732            Self::PreDecrement { decrement, .. } => *decrement,
733            Self::PostIncrement { left, .. } => left.initial_position(),
734            Self::PostDecrement { left, .. } => left.initial_position(),
735        }
736    }
737
738    fn final_position(&self) -> usize {
739        match &self {
740            Self::Addition { right, .. } => right.final_position(),
741            Self::Subtraction { right, .. } => right.final_position(),
742            Self::Multiplication { right, .. } => right.final_position(),
743            Self::Division { right, .. } => right.final_position(),
744            Self::Modulo { right, .. } => right.final_position(),
745            Self::Exponentiation { right, .. } => right.final_position(),
746            Self::Negative { right, .. } => right.final_position(),
747            Self::Positive { right, .. } => right.final_position(),
748            Self::PreIncrement { right, .. } => right.final_position(),
749            Self::PreDecrement { right, .. } => right.final_position(),
750            Self::PostIncrement { increment, .. } => *increment,
751            Self::PostDecrement { decrement, .. } => *decrement,
752        }
753    }
754
755    fn children(&self) -> Vec<&dyn Node> {
756        match &self {
757            Self::Addition { left, right, .. }
758            | Self::Subtraction { left, right, .. }
759            | Self::Multiplication { left, right, .. }
760            | Self::Division { left, right, .. }
761            | Self::Modulo { left, right, .. }
762            | Self::Exponentiation { left, right, .. } => {
763                vec![left.as_ref(), right.as_ref()]
764            }
765            Self::Negative { right, .. }
766            | Self::Positive { right, .. }
767            | Self::PreIncrement { right, .. }
768            | Self::PreDecrement { right, .. } => vec![right.as_ref()],
769            Self::PostIncrement { left, .. } | Self::PostDecrement { left, .. } => {
770                vec![left.as_ref()]
771            }
772        }
773    }
774
775    fn get_description(&self) -> String {
776        match &self {
777            Self::Addition { .. } => "addition arithmetic operation expression".to_string(),
778            Self::Subtraction { .. } => "subtraction arithmetic operation expression".to_string(),
779            Self::Multiplication { .. } => {
780                "multiplication arithmetic operation expression".to_string()
781            }
782            Self::Division { .. } => "division arithmetic operation expression".to_string(),
783            Self::Modulo { .. } => "modulo arithmetic operation expression".to_string(),
784            Self::Exponentiation { .. } => {
785                "exponentiation arithmetic operation expression".to_string()
786            }
787            Self::Negative { .. } => "negative arithmetic operation expression".to_string(),
788            Self::Positive { .. } => "positive arithmetic operation expression".to_string(),
789            Self::PreIncrement { .. } => {
790                "pre-increment arithmetic operation expression".to_string()
791            }
792            Self::PreDecrement { .. } => {
793                "pre-decrement arithmetic operation expression".to_string()
794            }
795            Self::PostIncrement { .. } => {
796                "post-increment arithmetic operation expression".to_string()
797            }
798            Self::PostDecrement { .. } => {
799                "post-decrement arithmetic operation expression".to_string()
800            }
801        }
802    }
803}
804
805impl Node for AssignmentOperationExpression {
806    fn comments(&self) -> Option<&CommentGroup> {
807        match &self {
808            Self::Assignment { comments, .. } => Some(comments),
809            Self::Addition { comments, .. } => Some(comments),
810            Self::Subtraction { comments, .. } => Some(comments),
811            Self::Multiplication { comments, .. } => Some(comments),
812            Self::Division { comments, .. } => Some(comments),
813            Self::Modulo { comments, .. } => Some(comments),
814            Self::Exponentiation { comments, .. } => Some(comments),
815            Self::BitwiseAnd { comments, .. } => Some(comments),
816            Self::BitwiseOr { comments, .. } => Some(comments),
817            Self::BitwiseXor { comments, .. } => Some(comments),
818            Self::LeftShift { comments, .. } => Some(comments),
819            Self::RightShift { comments, .. } => Some(comments),
820            Self::Coalesce { comments, .. } => Some(comments),
821            Self::Concat { comments, .. } => Some(comments),
822        }
823    }
824
825    fn initial_position(&self) -> usize {
826        match &self {
827            Self::Assignment { left, .. } => left.initial_position(),
828            Self::Addition { left, .. } => left.initial_position(),
829            Self::Subtraction { left, .. } => left.initial_position(),
830            Self::Multiplication { left, .. } => left.initial_position(),
831            Self::Division { left, .. } => left.initial_position(),
832            Self::Modulo { left, .. } => left.initial_position(),
833            Self::Exponentiation { left, .. } => left.initial_position(),
834            Self::BitwiseAnd { left, .. } => left.initial_position(),
835            Self::BitwiseOr { left, .. } => left.initial_position(),
836            Self::BitwiseXor { left, .. } => left.initial_position(),
837            Self::LeftShift { left, .. } => left.initial_position(),
838            Self::RightShift { left, .. } => left.initial_position(),
839            Self::Coalesce { left, .. } => left.initial_position(),
840            Self::Concat { left, .. } => left.initial_position(),
841        }
842    }
843
844    fn final_position(&self) -> usize {
845        match &self {
846            Self::Assignment { right, .. } => right.final_position(),
847            Self::Addition { right, .. } => right.final_position(),
848            Self::Subtraction { right, .. } => right.final_position(),
849            Self::Multiplication { right, .. } => right.final_position(),
850            Self::Division { right, .. } => right.final_position(),
851            Self::Modulo { right, .. } => right.final_position(),
852            Self::Exponentiation { right, .. } => right.final_position(),
853            Self::BitwiseAnd { right, .. } => right.final_position(),
854            Self::BitwiseOr { right, .. } => right.final_position(),
855            Self::BitwiseXor { right, .. } => right.final_position(),
856            Self::LeftShift { right, .. } => right.final_position(),
857            Self::RightShift { right, .. } => right.final_position(),
858            Self::Coalesce { right, .. } => right.final_position(),
859            Self::Concat { right, .. } => right.final_position(),
860        }
861    }
862
863    fn children(&self) -> Vec<&dyn Node> {
864        match &self {
865            Self::Assignment { left, right, .. }
866            | Self::Addition { left, right, .. }
867            | Self::Subtraction { left, right, .. }
868            | Self::Multiplication { left, right, .. }
869            | Self::Division { left, right, .. }
870            | Self::Modulo { left, right, .. }
871            | Self::Exponentiation { left, right, .. }
872            | Self::BitwiseAnd { left, right, .. }
873            | Self::BitwiseOr { left, right, .. }
874            | Self::BitwiseXor { left, right, .. }
875            | Self::LeftShift { left, right, .. }
876            | Self::RightShift { left, right, .. }
877            | Self::Coalesce { left, right, .. }
878            | Self::Concat { left, right, .. } => {
879                vec![left.as_ref(), right.as_ref()]
880            }
881        }
882    }
883
884    fn get_description(&self) -> String {
885        match &self {
886            Self::Assignment { .. } => "assignment operation expression".to_string(),
887            Self::Addition { .. } => "addition assignment operation expression".to_string(),
888            Self::Subtraction { .. } => "subtraction assignment operation expression".to_string(),
889            Self::Multiplication { .. } => {
890                "multiplication assignment operation expression".to_string()
891            }
892            Self::Division { .. } => "division assignment operation expression".to_string(),
893            Self::Modulo { .. } => "modulo assignment operation expression".to_string(),
894            Self::Exponentiation { .. } => {
895                "exponentiation assignment operation expression".to_string()
896            }
897            Self::BitwiseAnd { .. } => "bitwise AND assignment operation expression".to_string(),
898            Self::BitwiseOr { .. } => "bitwise OR assignment operation expression".to_string(),
899            Self::BitwiseXor { .. } => "bitwise XOR assignment operation expression".to_string(),
900            Self::LeftShift { .. } => "left shift assignment operation expression".to_string(),
901            Self::RightShift { .. } => "right shift assignment operation expression".to_string(),
902            Self::Coalesce { .. } => "coalesce assignment operation expression".to_string(),
903            Self::Concat { .. } => "concat assignment operation expression".to_string(),
904        }
905    }
906}
907
908impl Node for BitwiseOperationExpression {
909    fn comments(&self) -> Option<&CommentGroup> {
910        match &self {
911            Self::And { comments, .. } => Some(comments),
912            Self::Or { comments, .. } => Some(comments),
913            Self::Xor { comments, .. } => Some(comments),
914            Self::LeftShift { comments, .. } => Some(comments),
915            Self::RightShift { comments, .. } => Some(comments),
916            Self::Not { comments, .. } => Some(comments),
917        }
918    }
919
920    fn initial_position(&self) -> usize {
921        match &self {
922            Self::And { left, .. } => left.initial_position(),
923            Self::Or { left, .. } => left.initial_position(),
924            Self::Xor { left, .. } => left.initial_position(),
925            Self::LeftShift { left, .. } => left.initial_position(),
926            Self::RightShift { left, .. } => left.initial_position(),
927            Self::Not { not, .. } => *not,
928        }
929    }
930
931    fn final_position(&self) -> usize {
932        match &self {
933            Self::And { right, .. } => right.final_position(),
934            Self::Or { right, .. } => right.final_position(),
935            Self::Xor { right, .. } => right.final_position(),
936            Self::LeftShift { right, .. } => right.final_position(),
937            Self::RightShift { right, .. } => right.final_position(),
938            Self::Not { right, .. } => right.final_position(),
939        }
940    }
941
942    fn children(&self) -> Vec<&dyn Node> {
943        match &self {
944            Self::And { left, right, .. }
945            | Self::Or { left, right, .. }
946            | Self::Xor { left, right, .. }
947            | Self::LeftShift { left, right, .. }
948            | Self::RightShift { left, right, .. } => {
949                vec![left.as_ref(), right.as_ref()]
950            }
951            Self::Not { right, .. } => vec![right.as_ref()],
952        }
953    }
954
955    fn get_description(&self) -> String {
956        match &self {
957            Self::And { .. } => "bitwise AND operation expression".to_string(),
958            Self::Or { .. } => "bitwise OR operation expression".to_string(),
959            Self::Xor { .. } => "bitwise XOR operation expression".to_string(),
960            Self::LeftShift { .. } => "left shift operation expression".to_string(),
961            Self::RightShift { .. } => "right shift operation expression".to_string(),
962            Self::Not { .. } => "bitwise NOT operation expression".to_string(),
963        }
964    }
965}
966
967impl Node for ComparisonOperationExpression {
968    fn comments(&self) -> Option<&CommentGroup> {
969        match &self {
970            Self::Equal { comments, .. }
971            | Self::NotEqual { comments, .. }
972            | Self::Identical { comments, .. }
973            | Self::NotIdentical { comments, .. }
974            | Self::LessThan { comments, .. }
975            | Self::LessThanOrEqual { comments, .. }
976            | Self::GreaterThan { comments, .. }
977            | Self::GreaterThanOrEqual { comments, .. }
978            | Self::Spaceship { comments, .. } => Some(comments),
979        }
980    }
981
982    fn initial_position(&self) -> usize {
983        match &self {
984            Self::Equal { left, .. }
985            | Self::NotEqual { left, .. }
986            | Self::Identical { left, .. }
987            | Self::NotIdentical { left, .. }
988            | Self::LessThan { left, .. }
989            | Self::LessThanOrEqual { left, .. }
990            | Self::GreaterThan { left, .. }
991            | Self::GreaterThanOrEqual { left, .. }
992            | Self::Spaceship { left, .. } => left.initial_position(),
993        }
994    }
995
996    fn final_position(&self) -> usize {
997        match &self {
998            Self::Equal { right, .. }
999            | Self::NotEqual { right, .. }
1000            | Self::Identical { right, .. }
1001            | Self::NotIdentical { right, .. }
1002            | Self::LessThan { right, .. }
1003            | Self::LessThanOrEqual { right, .. }
1004            | Self::GreaterThan { right, .. }
1005            | Self::GreaterThanOrEqual { right, .. }
1006            | Self::Spaceship { right, .. } => right.final_position(),
1007        }
1008    }
1009
1010    fn children(&self) -> Vec<&dyn Node> {
1011        match &self {
1012            Self::Equal { left, right, .. }
1013            | Self::NotEqual { left, right, .. }
1014            | Self::Identical { left, right, .. }
1015            | Self::NotIdentical { left, right, .. }
1016            | Self::LessThan { left, right, .. }
1017            | Self::LessThanOrEqual { left, right, .. }
1018            | Self::GreaterThan { left, right, .. }
1019            | Self::GreaterThanOrEqual { left, right, .. }
1020            | Self::Spaceship { left, right, .. } => {
1021                vec![left.as_ref(), right.as_ref()]
1022            }
1023        }
1024    }
1025
1026    fn get_description(&self) -> String {
1027        match &self {
1028            Self::Equal { .. } => "equal comparison operation expression".to_string(),
1029            Self::NotEqual { .. } => "not equal comparison operation expression".to_string(),
1030            Self::Identical { .. } => "identical comparison operation expression".to_string(),
1031            Self::NotIdentical { .. } => {
1032                "not identical comparison operation expression".to_string()
1033            }
1034            Self::LessThan { .. } => "less than comparison operation expression".to_string(),
1035            Self::LessThanOrEqual { .. } => {
1036                "less than or equal comparison operation expression".to_string()
1037            }
1038            Self::GreaterThan { .. } => "greater than comparison operation expression".to_string(),
1039            Self::GreaterThanOrEqual { .. } => {
1040                "greater than or equal comparison operation expression".to_string()
1041            }
1042            Self::Spaceship { .. } => "spaceship comparison operation expression".to_string(),
1043        }
1044    }
1045}
1046
1047impl Node for LogicalOperationExpression {
1048    fn comments(&self) -> Option<&CommentGroup> {
1049        match &self {
1050            Self::And { comments, .. } => Some(comments),
1051            Self::Or { comments, .. } => Some(comments),
1052            Self::Not { comments, .. } => Some(comments),
1053        }
1054    }
1055
1056    fn initial_position(&self) -> usize {
1057        match &self {
1058            Self::And { left, .. } => left.initial_position(),
1059            Self::Or { left, .. } => left.initial_position(),
1060            Self::Not { bang, .. } => *bang,
1061        }
1062    }
1063
1064    fn final_position(&self) -> usize {
1065        match &self {
1066            Self::And { right, .. } => right.final_position(),
1067            Self::Or { right, .. } => right.final_position(),
1068            Self::Not { right, .. } => right.final_position(),
1069        }
1070    }
1071
1072    fn children(&self) -> Vec<&dyn Node> {
1073        match &self {
1074            Self::And { left, right, .. } | Self::Or { left, right, .. } => {
1075                vec![left.as_ref(), right.as_ref()]
1076            }
1077            Self::Not { right, .. } => vec![right.as_ref()],
1078        }
1079    }
1080
1081    fn get_description(&self) -> String {
1082        match &self {
1083            Self::And { .. } => "logical AND operation expression".to_string(),
1084            Self::Or { .. } => "logical OR operation expression".to_string(),
1085            Self::Not { .. } => "logical NOT operation expression".to_string(),
1086        }
1087    }
1088}
1089
1090impl Node for StringOperationExpression {
1091    fn comments(&self) -> Option<&CommentGroup> {
1092        match &self {
1093            Self::Concat { comments, .. } => Some(comments),
1094        }
1095    }
1096
1097    fn initial_position(&self) -> usize {
1098        match &self {
1099            Self::Concat { left, .. } => left.initial_position(),
1100        }
1101    }
1102
1103    fn final_position(&self) -> usize {
1104        match &self {
1105            Self::Concat { right, .. } => right.final_position(),
1106        }
1107    }
1108
1109    fn children(&self) -> Vec<&dyn Node> {
1110        match &self {
1111            Self::Concat { left, right, .. } => {
1112                vec![left.as_ref(), right.as_ref()]
1113            }
1114        }
1115    }
1116
1117    fn get_description(&self) -> String {
1118        match &self {
1119            Self::Concat { .. } => "string concatenation operation expression".to_string(),
1120        }
1121    }
1122}
1123
1124impl Node for ArrayOperationExpression {
1125    fn comments(&self) -> Option<&CommentGroup> {
1126        match &self {
1127            Self::Access { comments, .. }
1128            | Self::Push { comments, .. }
1129            | Self::Isset { comments, .. }
1130            | Self::Unset { comments, .. }
1131            | Self::In { comments, .. } => Some(comments),
1132        }
1133    }
1134
1135    fn initial_position(&self) -> usize {
1136        match &self {
1137            Self::Access { array, .. } | Self::Push { array, .. } => array.initial_position(),
1138            Self::Isset { isset, .. } => isset.initial_position(),
1139            Self::Unset { unset, .. } => unset.initial_position(),
1140            Self::In { item, .. } => item.initial_position(),
1141        }
1142    }
1143
1144    fn final_position(&self) -> usize {
1145        match &self {
1146            Self::Access { right_bracket, .. } | Self::Push { right_bracket, .. } => {
1147                right_bracket + 1
1148            }
1149            Self::Isset { item, .. } | Self::Unset { item, .. } => item.final_position(),
1150            Self::In { array, .. } => array.final_position(),
1151        }
1152    }
1153
1154    fn children(&self) -> Vec<&dyn Node> {
1155        match &self {
1156            Self::Access { array, index, .. } => {
1157                vec![array.as_ref(), index.as_ref()]
1158            }
1159            Self::Push { array, .. } => {
1160                vec![array.as_ref()]
1161            }
1162            Self::Isset {
1163                isset: keyword,
1164                item,
1165                ..
1166            }
1167            | Self::Unset {
1168                unset: keyword,
1169                item,
1170                ..
1171            } => {
1172                vec![keyword, item.as_ref()]
1173            }
1174            Self::In {
1175                item, r#in, array, ..
1176            } => {
1177                vec![item.as_ref(), r#in, array.as_ref()]
1178            }
1179        }
1180    }
1181
1182    fn get_description(&self) -> String {
1183        match &self {
1184            Self::Access { .. } => "array access operation expression".to_string(),
1185            Self::Push { .. } => "array push operation expression".to_string(),
1186            Self::Isset { .. } => "array isset operation expression".to_string(),
1187            Self::Unset { .. } => "array unset operation expression".to_string(),
1188            Self::In { .. } => "array in operation expression".to_string(),
1189        }
1190    }
1191}
1192
1193impl Node for CoalesceOperationExpression {
1194    fn comments(&self) -> Option<&CommentGroup> {
1195        match &self {
1196            Self::Coalesce { comments, .. } => Some(comments),
1197        }
1198    }
1199
1200    fn initial_position(&self) -> usize {
1201        match &self {
1202            Self::Coalesce { left, .. } => left.initial_position(),
1203        }
1204    }
1205
1206    fn final_position(&self) -> usize {
1207        match &self {
1208            Self::Coalesce { right, .. } => right.final_position(),
1209        }
1210    }
1211
1212    fn children(&self) -> Vec<&dyn Node> {
1213        match &self {
1214            Self::Coalesce { left, right, .. } => {
1215                vec![left.as_ref(), right.as_ref()]
1216            }
1217        }
1218    }
1219
1220    fn get_description(&self) -> String {
1221        match &self {
1222            Self::Coalesce { .. } => "coalesce operation expression".to_string(),
1223        }
1224    }
1225}
1226
1227impl Node for TernaryOperationExpression {
1228    fn comments(&self) -> Option<&CommentGroup> {
1229        match &self {
1230            Self::Ternary { comments, .. } => Some(comments),
1231            Self::ShortTernary { comments, .. } => Some(comments),
1232            Self::ImplicitShortTernary { comments, .. } => Some(comments),
1233        }
1234    }
1235
1236    fn initial_position(&self) -> usize {
1237        match &self {
1238            Self::Ternary { condition, .. } => condition.initial_position(),
1239            Self::ShortTernary { condition, .. } => condition.initial_position(),
1240            Self::ImplicitShortTernary { condition, .. } => condition.initial_position(),
1241        }
1242    }
1243
1244    fn final_position(&self) -> usize {
1245        match &self {
1246            Self::Ternary { if_false, .. } => if_false.final_position(),
1247            Self::ShortTernary { if_false, .. } => if_false.final_position(),
1248            Self::ImplicitShortTernary { if_false, .. } => if_false.final_position(),
1249        }
1250    }
1251
1252    fn children(&self) -> Vec<&dyn Node> {
1253        match &self {
1254            Self::Ternary {
1255                condition,
1256                if_true,
1257                if_false,
1258                ..
1259            } => vec![condition.as_ref(), if_true.as_ref(), if_false.as_ref()],
1260            Self::ShortTernary {
1261                condition,
1262                if_false,
1263                ..
1264            } => vec![condition.as_ref(), if_false.as_ref()],
1265            Self::ImplicitShortTernary {
1266                condition,
1267                if_false,
1268                ..
1269            } => vec![condition.as_ref(), if_false.as_ref()],
1270        }
1271    }
1272
1273    fn get_description(&self) -> String {
1274        match &self {
1275            Self::Ternary { .. } => "ternary operation expression".to_string(),
1276            Self::ShortTernary { .. } => "short ternary operation expression".to_string(),
1277            Self::ImplicitShortTernary { .. } => {
1278                "implicit short ternary operation expression".to_string()
1279            }
1280        }
1281    }
1282}
1283
1284impl Node for TypeOperationExpression {
1285    fn comments(&self) -> Option<&CommentGroup> {
1286        match &self {
1287            Self::Instanceof { comments, .. } => Some(comments),
1288            Self::Is { comments, .. } => Some(comments),
1289            Self::Into { comments, .. } => Some(comments),
1290            Self::As { comments, .. } => Some(comments),
1291        }
1292    }
1293
1294    fn initial_position(&self) -> usize {
1295        match &self {
1296            Self::Instanceof { left, .. } => left.initial_position(),
1297            Self::Is { left, .. } => left.initial_position(),
1298            Self::Into { left, .. } => left.initial_position(),
1299            Self::As { left, .. } => left.initial_position(),
1300        }
1301    }
1302
1303    fn final_position(&self) -> usize {
1304        match &self {
1305            Self::Instanceof { right, .. } => right.final_position(),
1306            Self::Is { right, .. } => right.final_position(),
1307            Self::Into { right, .. } => right.final_position(),
1308            Self::As { right, .. } => right.final_position(),
1309        }
1310    }
1311
1312    fn children(&self) -> Vec<&dyn Node> {
1313        match &self {
1314            Self::Instanceof {
1315                left,
1316                instanceof,
1317                right,
1318                ..
1319            } => vec![left.as_ref(), instanceof, right],
1320            Self::Is {
1321                left, is, right, ..
1322            } => vec![left.as_ref(), is, right],
1323            Self::Into {
1324                left, into, right, ..
1325            } => vec![left.as_ref(), into, right],
1326            Self::As {
1327                left, r#as, right, ..
1328            } => vec![left.as_ref(), r#as, right],
1329        }
1330    }
1331
1332    fn get_description(&self) -> String {
1333        match &self {
1334            Self::Instanceof { .. } => "instanceof type operation expression".to_string(),
1335            Self::Is { .. } => "is type operation expression".to_string(),
1336            Self::Into { .. } => "into type operation expression".to_string(),
1337            Self::As { .. } => "as type operation expression".to_string(),
1338        }
1339    }
1340}
1341
1342impl Node for GeneratorOperationExpression {
1343    fn comments(&self) -> Option<&CommentGroup> {
1344        match &self {
1345            Self::Yield { comments, .. } => Some(comments),
1346            Self::YieldValue { comments, .. } => Some(comments),
1347            Self::YieldKeyValue { comments, .. } => Some(comments),
1348            Self::YieldFrom { comments, .. } => Some(comments),
1349        }
1350    }
1351
1352    fn initial_position(&self) -> usize {
1353        match &self {
1354            Self::Yield { r#yield, .. }
1355            | Self::YieldValue { r#yield, .. }
1356            | Self::YieldKeyValue { r#yield, .. }
1357            | Self::YieldFrom { r#yield, .. } => r#yield.initial_position(),
1358        }
1359    }
1360
1361    fn final_position(&self) -> usize {
1362        match &self {
1363            Self::Yield { r#yield, .. } => r#yield.final_position(),
1364            Self::YieldValue { value, .. } => value.final_position(),
1365            Self::YieldKeyValue { value, .. } => value.final_position(),
1366            Self::YieldFrom { value, .. } => value.final_position(),
1367        }
1368    }
1369
1370    fn children(&self) -> Vec<&dyn Node> {
1371        match &self {
1372            Self::Yield { r#yield, .. } => vec![r#yield],
1373            Self::YieldValue { r#yield, value, .. } => {
1374                vec![r#yield, value.as_ref()]
1375            }
1376            Self::YieldKeyValue {
1377                r#yield,
1378                key,
1379                value,
1380                ..
1381            } => {
1382                vec![r#yield, key.as_ref(), value.as_ref()]
1383            }
1384            Self::YieldFrom {
1385                r#yield,
1386                from,
1387                value,
1388                ..
1389            } => vec![r#yield, from, value.as_ref()],
1390        }
1391    }
1392
1393    fn get_description(&self) -> String {
1394        match &self {
1395            Self::Yield { .. } => "yield generator operation expression".to_string(),
1396            Self::YieldValue { .. } => "yield value generator operation expression".to_string(),
1397            Self::YieldKeyValue { .. } => {
1398                "yield key value generator operation expression".to_string()
1399            }
1400            Self::YieldFrom { .. } => "yield from generator operation expression".to_string(),
1401        }
1402    }
1403}
1404
1405impl Node for ExceptionOperationExpression {
1406    fn comments(&self) -> Option<&CommentGroup> {
1407        match &self {
1408            Self::Throw { comments, .. } => Some(comments),
1409        }
1410    }
1411
1412    fn initial_position(&self) -> usize {
1413        match &self {
1414            Self::Throw { throw, .. } => throw.initial_position(),
1415        }
1416    }
1417
1418    fn final_position(&self) -> usize {
1419        match &self {
1420            Self::Throw { value, .. } => value.final_position(),
1421        }
1422    }
1423
1424    fn children(&self) -> Vec<&dyn Node> {
1425        match &self {
1426            Self::Throw { throw, value, .. } => vec![throw, value.as_ref()],
1427        }
1428    }
1429
1430    fn get_description(&self) -> String {
1431        match &self {
1432            Self::Throw { .. } => "throw exception operation expression".to_string(),
1433        }
1434    }
1435}
1436
1437impl Node for ObjectOperationExpression {
1438    fn comments(&self) -> Option<&CommentGroup> {
1439        match &self {
1440            Self::Clone { comments, .. } => Some(comments),
1441            Self::MethodCall { comments, .. } => Some(comments),
1442            Self::NullsafeMethodCall { comments, .. } => Some(comments),
1443            Self::MethodClosureCreation { comments, .. } => Some(comments),
1444            Self::PropertyFetch { comments, .. } => Some(comments),
1445            Self::NullsafePropertyFetch { comments, .. } => Some(comments),
1446        }
1447    }
1448
1449    fn initial_position(&self) -> usize {
1450        match &self {
1451            Self::Clone { clone, .. } => clone.initial_position(),
1452            Self::MethodCall { object, .. } => object.initial_position(),
1453            Self::NullsafeMethodCall { object, .. } => object.initial_position(),
1454            Self::MethodClosureCreation { object, .. } => object.initial_position(),
1455            Self::PropertyFetch { object, .. } => object.initial_position(),
1456            Self::NullsafePropertyFetch { object, .. } => object.initial_position(),
1457        }
1458    }
1459
1460    fn final_position(&self) -> usize {
1461        match &self {
1462            Self::Clone { object, .. } => object.final_position(),
1463            Self::MethodCall { arguments, .. } => arguments.final_position(),
1464            Self::NullsafeMethodCall { arguments, .. } => arguments.final_position(),
1465            Self::MethodClosureCreation { placeholder, .. } => placeholder.final_position(),
1466            Self::PropertyFetch { property, .. } => property.final_position(),
1467            Self::NullsafePropertyFetch { property, .. } => property.final_position(),
1468        }
1469    }
1470
1471    fn children(&self) -> Vec<&dyn Node> {
1472        match &self {
1473            Self::Clone { clone, object, .. } => vec![clone, object.as_ref()],
1474            Self::MethodCall {
1475                object,
1476                method,
1477                generics,
1478                arguments,
1479                ..
1480            }
1481            | Self::NullsafeMethodCall {
1482                object,
1483                method,
1484                generics,
1485                arguments,
1486                ..
1487            } => {
1488                let mut children: Vec<&dyn Node> = vec![object.as_ref(), method];
1489                if let Some(generics) = generics {
1490                    children.push(generics);
1491                }
1492
1493                children.push(arguments);
1494
1495                children
1496            }
1497            Self::MethodClosureCreation {
1498                object,
1499                method,
1500                generics,
1501                placeholder,
1502                ..
1503            } => {
1504                let mut children: Vec<&dyn Node> = vec![object.as_ref(), method];
1505                if let Some(generics) = generics {
1506                    children.push(generics);
1507                }
1508
1509                children.push(placeholder);
1510
1511                children
1512            }
1513            Self::PropertyFetch {
1514                object, property, ..
1515            }
1516            | Self::NullsafePropertyFetch {
1517                object, property, ..
1518            } => {
1519                vec![object.as_ref(), property]
1520            }
1521        }
1522    }
1523
1524    fn get_description(&self) -> String {
1525        match &self {
1526            Self::Clone { .. } => "object clone operation expression".to_string(),
1527            Self::MethodCall { .. } => "object method call operation expression".to_string(),
1528            Self::NullsafeMethodCall { .. } => {
1529                "object nullsafe method call operation expression".to_string()
1530            }
1531            Self::MethodClosureCreation { .. } => {
1532                "object method closure creation operation expression".to_string()
1533            }
1534            Self::PropertyFetch { .. } => "object property fetch operation expression".to_string(),
1535            Self::NullsafePropertyFetch { .. } => {
1536                "object nullsafe property fetch operation expression".to_string()
1537            }
1538        }
1539    }
1540}
1541
1542impl Node for ClassOperationInitializationClassExpression {
1543    fn comments(&self) -> Option<&CommentGroup> {
1544        match &self {
1545            Self::Identifier(_) => None,
1546            Self::Variable(_) => None,
1547        }
1548    }
1549
1550    fn initial_position(&self) -> usize {
1551        match &self {
1552            Self::Identifier(identifier) => identifier.initial_position(),
1553            Self::Variable(variable) => variable.initial_position(),
1554        }
1555    }
1556
1557    fn final_position(&self) -> usize {
1558        match &self {
1559            Self::Identifier(identifier) => identifier.final_position(),
1560            Self::Variable(variable) => variable.final_position(),
1561        }
1562    }
1563
1564    fn children(&self) -> Vec<&dyn Node> {
1565        match &self {
1566            Self::Identifier(identifier) => vec![identifier],
1567            Self::Variable(variable) => vec![variable],
1568        }
1569    }
1570
1571    fn get_description(&self) -> String {
1572        match &self {
1573            Self::Identifier(identifier) => identifier.get_description(),
1574            Self::Variable(variable) => variable.get_description(),
1575        }
1576    }
1577}
1578
1579impl Node for ClassOperationExpression {
1580    fn comments(&self) -> Option<&CommentGroup> {
1581        match &self {
1582            Self::Initialization { comments, .. } => Some(comments),
1583            Self::AnonymousInitialization { comments, .. } => Some(comments),
1584            Self::StaticMethodCall { comments, .. } => Some(comments),
1585            Self::StaticMethodClosureCreation { comments, .. } => Some(comments),
1586            Self::StaticPropertyFetch { comments, .. } => Some(comments),
1587            Self::ConstantFetch { comments, .. } => Some(comments),
1588        }
1589    }
1590
1591    fn initial_position(&self) -> usize {
1592        match &self {
1593            Self::Initialization { new, .. }
1594            | ClassOperationExpression::AnonymousInitialization { new, .. } => {
1595                new.initial_position()
1596            }
1597            Self::StaticMethodCall { class, .. } => class.initial_position(),
1598            Self::StaticMethodClosureCreation { class, .. } => class.initial_position(),
1599            Self::StaticPropertyFetch { class, .. } => class.initial_position(),
1600            Self::ConstantFetch { class, .. } => class.initial_position(),
1601        }
1602    }
1603
1604    fn final_position(&self) -> usize {
1605        match &self {
1606            Self::Initialization { arguments, .. } => arguments.final_position(),
1607            Self::AnonymousInitialization { class, .. } => class.final_position(),
1608            Self::StaticMethodCall { arguments, .. } => arguments.final_position(),
1609            Self::StaticMethodClosureCreation { placeholder, .. } => placeholder.final_position(),
1610            Self::StaticPropertyFetch { property, .. } => property.final_position(),
1611            Self::ConstantFetch { constant, .. } => constant.final_position(),
1612        }
1613    }
1614
1615    fn children(&self) -> Vec<&dyn Node> {
1616        match &self {
1617            Self::Initialization {
1618                new,
1619                class,
1620                generics,
1621                arguments,
1622                ..
1623            } => {
1624                let mut children: Vec<&dyn Node> = vec![new, class];
1625                if let Some(generics) = generics {
1626                    children.push(generics);
1627                }
1628
1629                children.push(arguments);
1630
1631                children
1632            }
1633            Self::AnonymousInitialization { new, class, .. } => {
1634                vec![new, class]
1635            }
1636            Self::StaticMethodCall {
1637                class,
1638                method,
1639                generics,
1640                arguments,
1641                ..
1642            } => {
1643                let mut children: Vec<&dyn Node> = vec![class.as_ref(), method];
1644                if let Some(generics) = generics {
1645                    children.push(generics);
1646                }
1647
1648                children.push(arguments);
1649
1650                children
1651            }
1652            Self::StaticMethodClosureCreation {
1653                class,
1654                generics,
1655                method,
1656                placeholder,
1657                ..
1658            } => {
1659                let mut children: Vec<&dyn Node> = vec![class.as_ref(), method];
1660                if let Some(generics) = generics {
1661                    children.push(generics);
1662                }
1663
1664                children.push(placeholder);
1665
1666                children
1667            }
1668            Self::StaticPropertyFetch {
1669                class, property, ..
1670            } => {
1671                vec![class.as_ref(), property]
1672            }
1673            Self::ConstantFetch {
1674                class, constant, ..
1675            } => {
1676                vec![class.as_ref(), constant]
1677            }
1678        }
1679    }
1680
1681    fn get_description(&self) -> String {
1682        match &self {
1683            Self::Initialization { .. } => "class initialization operation expression".to_string(),
1684            Self::AnonymousInitialization { .. } => {
1685                "class anonymous initialization operation expression".to_string()
1686            }
1687            Self::StaticMethodCall { .. } => {
1688                "class static method call operation expression".to_string()
1689            }
1690            Self::StaticMethodClosureCreation { .. } => {
1691                "class static method closure creation operation expression".to_string()
1692            }
1693            Self::StaticPropertyFetch { .. } => {
1694                "class static property fetch operation expression".to_string()
1695            }
1696            Self::ConstantFetch { .. } => "class constant fetch operation expression".to_string(),
1697        }
1698    }
1699}
1700
1701impl Node for FunctionOperationExpression {
1702    fn comments(&self) -> Option<&CommentGroup> {
1703        match &self {
1704            Self::Call { comments, .. } => Some(comments),
1705            Self::ClosureCreation { comments, .. } => Some(comments),
1706        }
1707    }
1708
1709    fn initial_position(&self) -> usize {
1710        match &self {
1711            Self::Call { function, .. } => function.initial_position(),
1712            Self::ClosureCreation { function, .. } => function.initial_position(),
1713        }
1714    }
1715
1716    fn final_position(&self) -> usize {
1717        match &self {
1718            Self::Call { arguments, .. } => arguments.final_position(),
1719            Self::ClosureCreation { placeholder, .. } => placeholder.final_position(),
1720        }
1721    }
1722
1723    fn children(&self) -> Vec<&dyn Node> {
1724        match &self {
1725            Self::Call {
1726                function,
1727                generics,
1728                arguments,
1729                ..
1730            } => {
1731                let mut children: Vec<&dyn Node> = vec![];
1732                children.push(function.as_ref());
1733                if let Some(generics) = generics {
1734                    children.push(generics);
1735                }
1736                children.push(arguments);
1737
1738                children
1739            }
1740            Self::ClosureCreation {
1741                function,
1742                generics,
1743                placeholder,
1744                ..
1745            } => {
1746                let mut children: Vec<&dyn Node> = vec![];
1747                children.push(function.as_ref());
1748                if let Some(generics) = generics {
1749                    children.push(generics);
1750                }
1751                children.push(placeholder);
1752
1753                children
1754            }
1755        }
1756    }
1757
1758    fn get_description(&self) -> String {
1759        match &self {
1760            Self::Call { .. } => "function call operation expression".to_string(),
1761            Self::ClosureCreation { .. } => {
1762                "function closure creation operation expression".to_string()
1763            }
1764        }
1765    }
1766}
1767
1768impl Node for AsyncOperationExpression {
1769    fn comments(&self) -> Option<&CommentGroup> {
1770        match &self {
1771            Self::Await { comments, .. } => Some(comments),
1772            Self::Async { comments, .. } => Some(comments),
1773            Self::Concurrently { comments, .. } => Some(comments),
1774        }
1775    }
1776
1777    fn initial_position(&self) -> usize {
1778        match &self {
1779            Self::Await { r#await, .. } => r#await.initial_position(),
1780            Self::Async { r#async, .. } => r#async.initial_position(),
1781            Self::Concurrently { concurrently, .. } => concurrently.initial_position(),
1782        }
1783    }
1784
1785    fn final_position(&self) -> usize {
1786        match &self {
1787            Self::Await { expression, .. } => expression.final_position(),
1788            Self::Async { expression, .. } => expression.final_position(),
1789            Self::Concurrently { right_brace, .. } => right_brace + 1,
1790        }
1791    }
1792
1793    fn children(&self) -> Vec<&dyn Node> {
1794        match &self {
1795            Self::Await {
1796                r#await,
1797                expression,
1798                ..
1799            } => vec![r#await, expression.as_ref()],
1800            Self::Async {
1801                r#async,
1802                expression,
1803                ..
1804            } => vec![r#async, expression.as_ref()],
1805            Self::Concurrently {
1806                concurrently,
1807                expressions,
1808                ..
1809            } => {
1810                let mut children: Vec<&dyn Node> = vec![concurrently];
1811                for expression in &expressions.inner {
1812                    children.push(expression);
1813                }
1814
1815                children
1816            }
1817        }
1818    }
1819
1820    fn get_description(&self) -> String {
1821        match &self {
1822            Self::Await { .. } => "async await operation expression".to_string(),
1823            Self::Async { .. } => "async operation expression".to_string(),
1824            Self::Concurrently { .. } => "async concurrently operation expression".to_string(),
1825        }
1826    }
1827}
1828
1829impl Node for RangeOperationExpression {
1830    fn comments(&self) -> Option<&CommentGroup> {
1831        match &self {
1832            Self::Between { comments, .. } => Some(comments),
1833            Self::BetweenInclusive { comments, .. } => Some(comments),
1834            Self::To { comments, .. } => Some(comments),
1835            Self::ToInclusive { comments, .. } => Some(comments),
1836            Self::From { comments, .. } => Some(comments),
1837            Self::Full { comments, .. } => Some(comments),
1838        }
1839    }
1840
1841    fn initial_position(&self) -> usize {
1842        match &self {
1843            Self::Between { from, .. } => from.initial_position(),
1844            Self::BetweenInclusive { from, .. } => from.initial_position(),
1845            Self::To { double_dot, .. } => *double_dot,
1846            Self::ToInclusive { double_dot, .. } => *double_dot,
1847            Self::From { from, .. } => from.initial_position(),
1848            Self::Full { double_dot, .. } => *double_dot,
1849        }
1850    }
1851
1852    fn final_position(&self) -> usize {
1853        match &self {
1854            Self::Between { to, .. } => to.final_position(),
1855            Self::BetweenInclusive { to, .. } => to.final_position(),
1856            Self::To { to, .. } => to.final_position(),
1857            Self::ToInclusive { to, .. } => to.final_position(),
1858            Self::From { double_dot, .. } => *double_dot,
1859            Self::Full { double_dot, .. } => *double_dot,
1860        }
1861    }
1862
1863    fn children(&self) -> Vec<&dyn Node> {
1864        match &self {
1865            Self::Between { from, to, .. } => {
1866                vec![from.as_ref(), to.as_ref()]
1867            }
1868            Self::BetweenInclusive { from, to, .. } => {
1869                vec![from.as_ref(), to.as_ref()]
1870            }
1871            Self::To { to, .. } => vec![to.as_ref()],
1872            Self::ToInclusive { to, .. } => vec![to.as_ref()],
1873            Self::From { from, .. } => vec![from.as_ref()],
1874            Self::Full { .. } => vec![],
1875        }
1876    }
1877
1878    fn get_description(&self) -> String {
1879        match &self {
1880            Self::Between { .. } => "range between operation expression".to_string(),
1881            Self::BetweenInclusive { .. } => {
1882                "range between inclusive operation expression".to_string()
1883            }
1884            Self::To { .. } => "range to operation expression".to_string(),
1885            Self::ToInclusive { .. } => "range to inclusive operation expression".to_string(),
1886            Self::From { .. } => "range from operation expression".to_string(),
1887            Self::Full { .. } => "range full operation expression".to_string(),
1888        }
1889    }
1890}