1use serde::{Deserialize, Serialize};
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
26pub struct Span {
27 pub byte_start: usize,
28 pub byte_end: usize,
29 pub start: Point,
30 pub end: Point,
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
34pub struct Point {
35 pub row: usize,
36 pub column: usize,
37}
38
39impl From<tree_sitter::Range> for Span {
40 fn from(r: tree_sitter::Range) -> Self {
41 Span {
42 byte_start: r.start_byte,
43 byte_end: r.end_byte,
44 start: Point {
45 row: r.start_point.row,
46 column: r.start_point.column,
47 },
48 end: Point {
49 row: r.end_point.row,
50 column: r.end_point.column,
51 },
52 }
53 }
54}
55
56#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
61pub struct Program {
62 pub span: Span,
63 pub statements: Vec<Statement>,
64 pub comments: Vec<Comment>,
65}
66
67#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
72pub enum Statement {
73 Command(Command),
74 Pipeline(Pipeline),
75 List(List),
76 CompoundStatement(CompoundStatement),
77 Subshell(Subshell),
78 If(IfStatement),
79 While(WhileStatement),
80 For(ForStatement),
81 CStyleFor(CStyleForStatement),
82 Case(CaseStatement),
83 FunctionDefinition(FunctionDefinition),
84 Redirected(RedirectedStatement),
85 Declaration(DeclarationCommand),
86 Unset(UnsetCommand),
87 Test(TestCommand),
88 Negated(NegatedCommand),
89 VariableAssignment(VariableAssignment),
90 VariableAssignments(VariableAssignments),
91}
92
93#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
98pub enum Expression {
99 Primary(PrimaryExpression),
100 Binary(BinaryExpression),
101 Concatenation(Concatenation),
102 Parenthesized(ParenthesizedExpression),
103 Postfix(PostfixExpression),
104 Ternary(TernaryExpression),
105 Unary(UnaryExpression),
106 Word(Word),
112}
113
114#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
115pub enum PrimaryExpression {
116 AnsiCString(AnsiCString),
117 ArithmeticExpansion(ArithmeticExpansion),
118 BraceExpression(BraceExpression),
119 CommandSubstitution(CommandSubstitution),
120 Expansion(Expansion),
121 Number(Number),
122 ProcessSubstitution(ProcessSubstitution),
123 RawString(RawString),
124 SimpleExpansion(SimpleExpansion),
125 StringNode(StringNode),
127 TranslatedString(TranslatedString),
128 Word(Word),
129}
130
131#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
138pub enum TestOperand {
139 Expression(Box<Expression>),
140 CommandSubstitution(CommandSubstitution),
141 Expansion(Expansion),
142 Number(Number),
143 SimpleExpansion(SimpleExpansion),
144 StringNode(StringNode),
145 Subscript(Box<Subscript>),
146 VariableName(VariableName),
147}
148
149#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
151pub enum BinaryRightOperand {
152 Expression(Box<Expression>),
153 CommandSubstitution(CommandSubstitution),
154 Expansion(Expansion),
155 ExtglobPattern(ExtglobPattern),
156 Number(Number),
157 Regex(Regex),
158 SimpleExpansion(SimpleExpansion),
159 StringNode(StringNode),
160 Subscript(Box<Subscript>),
161 VariableName(VariableName),
162}
163
164#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
166pub enum CasePattern {
167 Primary(PrimaryExpression),
168 Concatenation(Concatenation),
169 ExtglobPattern(ExtglobPattern),
170}
171
172#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
174pub enum CommandArgument {
175 Primary(PrimaryExpression),
176 Concatenation(Concatenation),
177 Regex(Regex),
178 Operator { span: Span, text: String },
180}
181
182#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
184pub enum FunctionBody {
185 Compound(CompoundStatement),
186 If(IfStatement),
187 Subshell(Subshell),
188 Test(TestCommand),
189}
190
191#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
193pub enum LoopBody {
194 Compound(CompoundStatement),
195 DoGroup(DoGroup),
196}
197
198#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
200pub enum AssignmentValue {
201 Primary(PrimaryExpression),
202 Array(Array),
203 Binary(BinaryExpression),
204 Concatenation(Concatenation),
205 Parenthesized(ParenthesizedExpression),
206 Postfix(PostfixExpression),
207 Unary(UnaryExpression),
208 Nested(Box<VariableAssignment>),
209}
210
211#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
213pub enum ExpansionElement {
214 Primary(PrimaryExpression),
215 Array(Array),
216 Binary(BinaryExpression),
217 Concatenation(Concatenation),
218 Parenthesized(ParenthesizedExpression),
219 Regex(Regex),
220 SpecialVariableName(SpecialVariableName),
221 Subscript(Subscript),
222 VariableName(VariableName),
223}
224
225pub type CommandSubBody = Vec<Statement>;
227
228#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
230pub enum Redirect {
231 File(FileRedirect),
232 Heredoc(HeredocRedirect),
233 Herestring(HerestringRedirect),
234}
235
236#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
238pub enum SimpleRedirect {
239 File(FileRedirect),
240 Herestring(HerestringRedirect),
241}
242
243#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
245pub enum SubscriptIndex {
246 Primary(PrimaryExpression),
247 Binary(BinaryExpression),
248 Concatenation(Concatenation),
249 Parenthesized(ParenthesizedExpression),
250 Unary(UnaryExpression),
251}
252
253#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
255pub enum AssignmentTarget {
256 VariableName(VariableName),
257 Subscript(Subscript),
258}
259
260#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
263pub enum ConditionPart {
264 Statement(Box<Statement>),
265 Terminator { span: Span, text: String },
267}
268
269#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
274pub struct Command {
275 pub span: Span,
276 pub name: CommandName,
277 pub arguments: Vec<CommandArgument>,
278 pub redirects: Vec<SimpleRedirect>,
279 pub leading_assignments: Vec<VariableAssignment>,
281 pub subshells: Vec<Subshell>,
283}
284
285#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
286pub struct Pipeline {
287 pub span: Span,
288 pub stages: Vec<Statement>,
289}
290
291#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
292pub struct List {
293 pub span: Span,
294 pub left: Box<Statement>,
295 pub operator: ListOperator,
296 pub right: Box<Statement>,
297}
298
299#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
300pub enum ListOperator {
301 And,
303 Or,
305}
306
307#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
308pub struct CompoundStatement {
309 pub span: Span,
310 pub statements: Vec<Statement>,
311}
312
313#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
314pub struct Subshell {
315 pub span: Span,
316 pub statements: Vec<Statement>,
317}
318
319#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
320pub struct IfStatement {
321 pub span: Span,
322 pub condition: Vec<ConditionPart>,
323 pub body: Vec<Statement>,
324 pub elif_clauses: Vec<ElifClause>,
325 pub else_clause: Option<ElseClause>,
326}
327
328#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
329pub struct ElifClause {
330 pub span: Span,
331 pub condition: Vec<ConditionPart>,
332 pub body: Vec<Statement>,
333}
334
335#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
336pub struct ElseClause {
337 pub span: Span,
338 pub body: Vec<Statement>,
339}
340
341#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
342pub struct WhileStatement {
343 pub span: Span,
344 pub condition: Vec<ConditionPart>,
345 pub body: LoopBody,
346}
347
348#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
349pub struct ForStatement {
350 pub span: Span,
351 pub variable: VariableName,
352 pub values: Vec<CasePattern>,
353 pub body: LoopBody,
354}
355
356#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
357pub struct CStyleForStatement {
358 pub span: Span,
359 pub initializer: Vec<CStyleForPart>,
360 pub condition: Vec<CStyleForPart>,
361 pub update: Vec<CStyleForPart>,
362 pub body: LoopBody,
363}
364
365#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
367pub enum CStyleForPart {
368 Comma { span: Span },
369 Binary(BinaryExpression),
370 CommandSubstitution(CommandSubstitution),
371 Expansion(Expansion),
372 Number(Number),
373 Parenthesized(ParenthesizedExpression),
374 Postfix(PostfixExpression),
375 SimpleExpansion(SimpleExpansion),
376 StringNode(StringNode),
377 Unary(UnaryExpression),
378 VariableAssignment(VariableAssignment),
379 Word(Word),
380}
381
382#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
383pub struct CaseStatement {
384 pub span: Span,
385 pub value: CasePattern,
386 pub items: Vec<CaseItem>,
387}
388
389#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
390pub struct CaseItem {
391 pub span: Span,
392 pub patterns: Vec<CasePattern>,
393 pub body: Vec<Statement>,
394 pub termination: Option<CaseTermination>,
395 pub fallthrough: Option<CaseFallthrough>,
396}
397
398#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
399pub enum CaseTermination {
400 DoubleSemi,
402}
403
404#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
405pub enum CaseFallthrough {
406 Semiamp,
408 DoubleSemiAmp,
410}
411
412#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
413pub struct FunctionDefinition {
414 pub span: Span,
415 pub name: Word,
416 pub body: FunctionBody,
417 pub redirect: Option<SimpleRedirect>,
418}
419
420#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
421pub struct RedirectedStatement {
422 pub span: Span,
423 pub body: Option<Box<Statement>>,
424 pub redirects: Vec<Redirect>,
425 pub bare_herestring: Option<HerestringRedirect>,
427}
428
429#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
430pub struct DeclarationCommand {
431 pub span: Span,
432 pub parts: Vec<DeclarationPart>,
436}
437
438#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
439pub enum DeclarationPart {
440 Word(Word),
441 VariableName(VariableName),
442 VariableAssignment(VariableAssignment),
443}
444
445#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
446pub struct UnsetCommand {
447 pub span: Span,
448 pub parts: Vec<UnsetPart>,
449}
450
451#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
452pub enum UnsetPart {
453 Word(Word),
454 VariableName(VariableName),
455}
456
457#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
458pub struct TestCommand {
459 pub span: Span,
460 pub expressions: Vec<Expression>,
462}
463
464#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
465pub struct NegatedCommand {
466 pub span: Span,
467 pub inner: Box<Statement>,
468}
469
470#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
471pub struct VariableAssignment {
472 pub span: Span,
473 pub name: AssignmentTarget,
474 pub value: AssignmentValue,
475}
476
477#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
479pub struct VariableAssignments {
480 pub span: Span,
481 pub assignments: Vec<VariableAssignment>,
482}
483
484#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
489pub struct BinaryExpression {
490 pub span: Span,
491 pub left: Option<TestOperand>,
492 pub operator: BinaryOperator,
493 pub right: Vec<BinaryRightOperand>,
494 pub extras: Vec<BinaryExtra>,
497}
498
499#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
500pub enum BinaryExtra {
501 Binary(Box<BinaryExpression>),
502 Expansion(Expansion),
503 Number(Number),
504 VariableName(VariableName),
505}
506
507#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
510pub struct BinaryOperator {
511 pub span: Span,
512 pub kind: BinaryOperatorKind,
513 pub text: String,
515}
516
517#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
518pub enum BinaryOperatorKind {
519 NotEq, Mod, ModAssign, BitAnd, AndAnd, BitAndAssign, Mul, Pow, PowAssign,
520 MulAssign, Plus, PlusAssign, Minus, MinusAssign, DashA, DashO, Div,
521 DivAssign, Lt, ShlOrHeredoc, ShlAssign, Le, Assign, EqEq, MatchRegex,
522 Gt, Ge, ShrOrHeredocAppend, ShrAssign, BitXor, BitXorAssign, TestOp,
523 BitOr, BitOrAssign, OrOr,
524}
525
526#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
527pub struct Concatenation {
528 pub span: Span,
529 pub parts: Vec<PrimaryExpression>,
530}
531
532#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
533pub struct ParenthesizedExpression {
534 pub span: Span,
535 pub inner: Box<Expression>,
536}
537
538#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
539pub struct PostfixExpression {
540 pub span: Span,
541 pub inner: TestOperand,
542 pub operator: PostfixOperator,
543}
544
545#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
546pub enum PostfixOperator {
547 Inc,
549 Dec,
551}
552
553#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
554pub struct TernaryExpression {
555 pub span: Span,
556 pub condition: TestOperand,
557 pub consequence: TestOperand,
558 pub alternative: TestOperand,
559}
560
561#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
562pub struct UnaryExpression {
563 pub span: Span,
564 pub operator: UnaryOperator,
565 pub inner: TestOperand,
566}
567
568#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
569pub struct UnaryOperator {
570 pub span: Span,
571 pub kind: UnaryOperatorKind,
572 pub text: String,
573}
574
575#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
576pub enum UnaryOperatorKind {
577 Not,
579 Plus,
581 Inc,
583 Minus,
585 Dec,
587 BitNot,
589 TestOp,
591}
592
593#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
598pub struct AnsiCString {
599 pub span: Span,
600 pub text: String,
601}
602
603#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
604pub struct ArithmeticExpansion {
605 pub span: Span,
606 pub inner: Vec<Expression>,
607}
608
609#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
610pub struct BraceExpression {
611 pub span: Span,
612 pub text: String,
613}
614
615#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
616pub struct CommandSubstitution {
617 pub span: Span,
618 pub body: CommandSubBody,
619 pub redirect: Option<FileRedirect>,
620}
621
622#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
623pub struct Expansion {
624 pub span: Span,
625 pub operators: Vec<ExpansionOperator>,
626 pub elements: Vec<ExpansionElement>,
627}
628
629#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
630pub struct ExpansionOperator {
631 pub span: Span,
632 pub text: String,
633}
634
635#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
636pub struct Number {
637 pub span: Span,
638 pub text: String,
639}
640
641#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
642pub struct ProcessSubstitution {
643 pub span: Span,
644 pub body: Vec<Statement>,
645 pub direction: char,
647}
648
649#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
650pub struct RawString {
651 pub span: Span,
652 pub text: String,
653}
654
655#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
656pub struct SimpleExpansion {
657 pub span: Span,
658 pub element: SimpleExpansionElement,
660}
661
662#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
663pub enum SimpleExpansionElement {
664 VariableName(VariableName),
665 SpecialVariableName(SpecialVariableName),
666}
667
668#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
669pub struct StringNode {
670 pub span: Span,
671 pub parts: Vec<StringPart>,
673}
674
675#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
676pub enum StringPart {
677 Content(StringContent),
678 Expansion(Expansion),
679 SimpleExpansion(SimpleExpansion),
680 CommandSubstitution(CommandSubstitution),
681 ArithmeticExpansion(ArithmeticExpansion),
682 Raw { span: Span, text: String },
684}
685
686#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
687pub struct TranslatedString {
688 pub span: Span,
689 pub parts: Vec<StringPart>,
691}
692
693#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
694pub struct Word {
695 pub span: Span,
696 pub text: String,
697}
698
699#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
704pub struct FileRedirect {
705 pub span: Span,
706 pub descriptor: Option<FileDescriptor>,
707 pub operator: String,
710 pub destinations: Vec<RedirectDestination>,
711}
712
713#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
714pub enum RedirectDestination {
715 Primary(PrimaryExpression),
716 Concatenation(Concatenation),
717}
718
719#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
720pub struct HeredocRedirect {
721 pub span: Span,
722 pub descriptor: Option<FileDescriptor>,
723 pub operator: Option<HeredocOperator>,
724 pub argument: Vec<RedirectDestination>,
725 pub redirects: Vec<SimpleRedirect>,
726 pub right: Option<Box<Statement>>,
727 pub start: Option<HeredocStart>,
728 pub body: Option<HeredocBody>,
729 pub end: Option<HeredocEnd>,
730 pub pipelines: Vec<Pipeline>,
731}
732
733#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
734pub enum HeredocOperator {
735 AndAnd,
737 OrOr,
739}
740
741#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
742pub struct HerestringRedirect {
743 pub span: Span,
744 pub descriptor: Option<FileDescriptor>,
745 pub value: HerestringValue,
746}
747
748#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
749pub enum HerestringValue {
750 Primary(PrimaryExpression),
751 Concatenation(Concatenation),
752}
753
754#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
759pub struct Array {
760 pub span: Span,
761 pub elements: Vec<ArrayElement>,
763}
764
765#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
766pub enum ArrayElement {
767 Primary(PrimaryExpression),
768 Concatenation(Concatenation),
769 VariableAssignment(VariableAssignment),
770}
771
772#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
773pub struct DoGroup {
774 pub span: Span,
775 pub statements: Vec<Statement>,
776}
777
778#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
779pub struct Subscript {
780 pub span: Span,
781 pub name: VariableName,
782 pub index: SubscriptIndex,
783}
784
785#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
786pub struct Comment {
787 pub span: Span,
788 pub text: String,
790}
791
792#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
793pub struct ExtglobPattern {
794 pub span: Span,
795 pub text: String,
796}
797
798#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
799pub struct FileDescriptor {
800 pub span: Span,
801 pub text: String,
802}
803
804#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
805pub struct HeredocBody {
806 pub span: Span,
807 pub text: String,
808}
809
810#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
811pub struct HeredocContent {
812 pub span: Span,
813 pub text: String,
814}
815
816#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
817pub struct HeredocEnd {
818 pub span: Span,
819 pub text: String,
820}
821
822#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
823pub struct HeredocStart {
824 pub span: Span,
825 pub text: String,
826}
827
828#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
829pub struct Regex {
830 pub span: Span,
831 pub text: String,
832}
833
834#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
835pub struct SpecialVariableName {
836 pub span: Span,
837 pub text: String,
839}
840
841#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
842pub struct StringContent {
843 pub span: Span,
844 pub text: String,
845}
846
847#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
848pub struct TestOperator {
849 pub span: Span,
850 pub text: String,
852}
853
854#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
855pub struct VariableName {
856 pub span: Span,
857 pub text: String,
858}
859
860#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
861pub struct CommandName {
862 pub span: Span,
863 pub inner: CommandNameInner,
865}
866
867#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
868pub enum CommandNameInner {
869 Primary(PrimaryExpression),
870 Concatenation(Concatenation),
871}