use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct Span {
pub byte_start: usize,
pub byte_end: usize,
pub start: Point,
pub end: Point,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct Point {
pub row: usize,
pub column: usize,
}
impl From<tree_sitter::Range> for Span {
fn from(r: tree_sitter::Range) -> Self {
Span {
byte_start: r.start_byte,
byte_end: r.end_byte,
start: Point {
row: r.start_point.row,
column: r.start_point.column,
},
end: Point {
row: r.end_point.row,
column: r.end_point.column,
},
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Program {
pub span: Span,
pub statements: Vec<Statement>,
pub comments: Vec<Comment>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Statement {
Command(Command),
Pipeline(Pipeline),
List(List),
CompoundStatement(CompoundStatement),
Subshell(Subshell),
If(IfStatement),
While(WhileStatement),
For(ForStatement),
CStyleFor(CStyleForStatement),
Case(CaseStatement),
FunctionDefinition(FunctionDefinition),
Redirected(RedirectedStatement),
Declaration(DeclarationCommand),
Unset(UnsetCommand),
Test(TestCommand),
Negated(NegatedCommand),
VariableAssignment(VariableAssignment),
VariableAssignments(VariableAssignments),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Expression {
Primary(PrimaryExpression),
Binary(BinaryExpression),
Concatenation(Concatenation),
Parenthesized(ParenthesizedExpression),
Postfix(PostfixExpression),
Ternary(TernaryExpression),
Unary(UnaryExpression),
Word(Word),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum PrimaryExpression {
AnsiCString(AnsiCString),
ArithmeticExpansion(ArithmeticExpansion),
BraceExpression(BraceExpression),
CommandSubstitution(CommandSubstitution),
Expansion(Expansion),
Number(Number),
ProcessSubstitution(ProcessSubstitution),
RawString(RawString),
SimpleExpansion(SimpleExpansion),
StringNode(StringNode),
TranslatedString(TranslatedString),
Word(Word),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum TestOperand {
Expression(Box<Expression>),
CommandSubstitution(CommandSubstitution),
Expansion(Expansion),
Number(Number),
SimpleExpansion(SimpleExpansion),
StringNode(StringNode),
Subscript(Box<Subscript>),
VariableName(VariableName),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum BinaryRightOperand {
Expression(Box<Expression>),
CommandSubstitution(CommandSubstitution),
Expansion(Expansion),
ExtglobPattern(ExtglobPattern),
Number(Number),
Regex(Regex),
SimpleExpansion(SimpleExpansion),
StringNode(StringNode),
Subscript(Box<Subscript>),
VariableName(VariableName),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum CasePattern {
Primary(PrimaryExpression),
Concatenation(Concatenation),
ExtglobPattern(ExtglobPattern),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum CommandArgument {
Primary(PrimaryExpression),
Concatenation(Concatenation),
Regex(Regex),
Operator { span: Span, text: String },
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum FunctionBody {
Compound(CompoundStatement),
If(IfStatement),
Subshell(Subshell),
Test(TestCommand),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum LoopBody {
Compound(CompoundStatement),
DoGroup(DoGroup),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum AssignmentValue {
Primary(PrimaryExpression),
Array(Array),
Binary(BinaryExpression),
Concatenation(Concatenation),
Parenthesized(ParenthesizedExpression),
Postfix(PostfixExpression),
Unary(UnaryExpression),
Nested(Box<VariableAssignment>),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ExpansionElement {
Primary(PrimaryExpression),
Array(Array),
Binary(BinaryExpression),
Concatenation(Concatenation),
Parenthesized(ParenthesizedExpression),
Regex(Regex),
SpecialVariableName(SpecialVariableName),
Subscript(Subscript),
VariableName(VariableName),
}
pub type CommandSubBody = Vec<Statement>;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Redirect {
File(FileRedirect),
Heredoc(HeredocRedirect),
Herestring(HerestringRedirect),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum SimpleRedirect {
File(FileRedirect),
Herestring(HerestringRedirect),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum SubscriptIndex {
Primary(PrimaryExpression),
Binary(BinaryExpression),
Concatenation(Concatenation),
Parenthesized(ParenthesizedExpression),
Unary(UnaryExpression),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum AssignmentTarget {
VariableName(VariableName),
Subscript(Subscript),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ConditionPart {
Statement(Box<Statement>),
Terminator { span: Span, text: String },
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Command {
pub span: Span,
pub name: CommandName,
pub arguments: Vec<CommandArgument>,
pub redirects: Vec<SimpleRedirect>,
pub leading_assignments: Vec<VariableAssignment>,
pub subshells: Vec<Subshell>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Pipeline {
pub span: Span,
pub stages: Vec<Statement>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct List {
pub span: Span,
pub left: Box<Statement>,
pub operator: ListOperator,
pub right: Box<Statement>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ListOperator {
And,
Or,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CompoundStatement {
pub span: Span,
pub statements: Vec<Statement>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Subshell {
pub span: Span,
pub statements: Vec<Statement>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct IfStatement {
pub span: Span,
pub condition: Vec<ConditionPart>,
pub body: Vec<Statement>,
pub elif_clauses: Vec<ElifClause>,
pub else_clause: Option<ElseClause>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ElifClause {
pub span: Span,
pub condition: Vec<ConditionPart>,
pub body: Vec<Statement>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ElseClause {
pub span: Span,
pub body: Vec<Statement>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct WhileStatement {
pub span: Span,
pub condition: Vec<ConditionPart>,
pub body: LoopBody,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ForStatement {
pub span: Span,
pub variable: VariableName,
pub values: Vec<CasePattern>,
pub body: LoopBody,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CStyleForStatement {
pub span: Span,
pub initializer: Vec<CStyleForPart>,
pub condition: Vec<CStyleForPart>,
pub update: Vec<CStyleForPart>,
pub body: LoopBody,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum CStyleForPart {
Comma { span: Span },
Binary(BinaryExpression),
CommandSubstitution(CommandSubstitution),
Expansion(Expansion),
Number(Number),
Parenthesized(ParenthesizedExpression),
Postfix(PostfixExpression),
SimpleExpansion(SimpleExpansion),
StringNode(StringNode),
Unary(UnaryExpression),
VariableAssignment(VariableAssignment),
Word(Word),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CaseStatement {
pub span: Span,
pub value: CasePattern,
pub items: Vec<CaseItem>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CaseItem {
pub span: Span,
pub patterns: Vec<CasePattern>,
pub body: Vec<Statement>,
pub termination: Option<CaseTermination>,
pub fallthrough: Option<CaseFallthrough>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum CaseTermination {
DoubleSemi,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum CaseFallthrough {
Semiamp,
DoubleSemiAmp,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FunctionDefinition {
pub span: Span,
pub name: Word,
pub body: FunctionBody,
pub redirect: Option<SimpleRedirect>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RedirectedStatement {
pub span: Span,
pub body: Option<Box<Statement>>,
pub redirects: Vec<Redirect>,
pub bare_herestring: Option<HerestringRedirect>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DeclarationCommand {
pub span: Span,
pub parts: Vec<DeclarationPart>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum DeclarationPart {
Word(Word),
VariableName(VariableName),
VariableAssignment(VariableAssignment),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct UnsetCommand {
pub span: Span,
pub parts: Vec<UnsetPart>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum UnsetPart {
Word(Word),
VariableName(VariableName),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TestCommand {
pub span: Span,
pub expressions: Vec<Expression>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct NegatedCommand {
pub span: Span,
pub inner: Box<Statement>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct VariableAssignment {
pub span: Span,
pub name: AssignmentTarget,
pub value: AssignmentValue,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct VariableAssignments {
pub span: Span,
pub assignments: Vec<VariableAssignment>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BinaryExpression {
pub span: Span,
pub left: Option<TestOperand>,
pub operator: BinaryOperator,
pub right: Vec<BinaryRightOperand>,
pub extras: Vec<BinaryExtra>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum BinaryExtra {
Binary(Box<BinaryExpression>),
Expansion(Expansion),
Number(Number),
VariableName(VariableName),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct BinaryOperator {
pub span: Span,
pub kind: BinaryOperatorKind,
pub text: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum BinaryOperatorKind {
NotEq, Mod, ModAssign, BitAnd, AndAnd, BitAndAssign, Mul, Pow, PowAssign,
MulAssign, Plus, PlusAssign, Minus, MinusAssign, DashA, DashO, Div,
DivAssign, Lt, ShlOrHeredoc, ShlAssign, Le, Assign, EqEq, MatchRegex,
Gt, Ge, ShrOrHeredocAppend, ShrAssign, BitXor, BitXorAssign, TestOp,
BitOr, BitOrAssign, OrOr,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Concatenation {
pub span: Span,
pub parts: Vec<PrimaryExpression>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ParenthesizedExpression {
pub span: Span,
pub inner: Box<Expression>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PostfixExpression {
pub span: Span,
pub inner: TestOperand,
pub operator: PostfixOperator,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum PostfixOperator {
Inc,
Dec,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TernaryExpression {
pub span: Span,
pub condition: TestOperand,
pub consequence: TestOperand,
pub alternative: TestOperand,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct UnaryExpression {
pub span: Span,
pub operator: UnaryOperator,
pub inner: TestOperand,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct UnaryOperator {
pub span: Span,
pub kind: UnaryOperatorKind,
pub text: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum UnaryOperatorKind {
Not,
Plus,
Inc,
Minus,
Dec,
BitNot,
TestOp,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AnsiCString {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ArithmeticExpansion {
pub span: Span,
pub inner: Vec<Expression>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BraceExpression {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CommandSubstitution {
pub span: Span,
pub body: CommandSubBody,
pub redirect: Option<FileRedirect>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Expansion {
pub span: Span,
pub operators: Vec<ExpansionOperator>,
pub elements: Vec<ExpansionElement>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ExpansionOperator {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Number {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ProcessSubstitution {
pub span: Span,
pub body: Vec<Statement>,
pub direction: char,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct RawString {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SimpleExpansion {
pub span: Span,
pub element: SimpleExpansionElement,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum SimpleExpansionElement {
VariableName(VariableName),
SpecialVariableName(SpecialVariableName),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct StringNode {
pub span: Span,
pub parts: Vec<StringPart>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum StringPart {
Content(StringContent),
Expansion(Expansion),
SimpleExpansion(SimpleExpansion),
CommandSubstitution(CommandSubstitution),
ArithmeticExpansion(ArithmeticExpansion),
Raw { span: Span, text: String },
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TranslatedString {
pub span: Span,
pub parts: Vec<StringPart>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Word {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FileRedirect {
pub span: Span,
pub descriptor: Option<FileDescriptor>,
pub operator: String,
pub destinations: Vec<RedirectDestination>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum RedirectDestination {
Primary(PrimaryExpression),
Concatenation(Concatenation),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HeredocRedirect {
pub span: Span,
pub descriptor: Option<FileDescriptor>,
pub operator: Option<HeredocOperator>,
pub argument: Vec<RedirectDestination>,
pub redirects: Vec<SimpleRedirect>,
pub right: Option<Box<Statement>>,
pub start: Option<HeredocStart>,
pub body: Option<HeredocBody>,
pub end: Option<HeredocEnd>,
pub pipelines: Vec<Pipeline>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum HeredocOperator {
AndAnd,
OrOr,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HerestringRedirect {
pub span: Span,
pub descriptor: Option<FileDescriptor>,
pub value: HerestringValue,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum HerestringValue {
Primary(PrimaryExpression),
Concatenation(Concatenation),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Array {
pub span: Span,
pub elements: Vec<ArrayElement>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ArrayElement {
Primary(PrimaryExpression),
Concatenation(Concatenation),
VariableAssignment(VariableAssignment),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DoGroup {
pub span: Span,
pub statements: Vec<Statement>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Subscript {
pub span: Span,
pub name: VariableName,
pub index: SubscriptIndex,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Comment {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ExtglobPattern {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FileDescriptor {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HeredocBody {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HeredocContent {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HeredocEnd {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HeredocStart {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Regex {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SpecialVariableName {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct StringContent {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TestOperator {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct VariableName {
pub span: Span,
pub text: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CommandName {
pub span: Span,
pub inner: CommandNameInner,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum CommandNameInner {
Primary(PrimaryExpression),
Concatenation(Concatenation),
}