use super::{BindingTarget, Class, ExportDecl, Expr, Function, Ident, ImportDecl};
use crate::common::Span;
use alloc::boxed::Box;
use alloc::vec::Vec;
#[derive(Clone, Debug, PartialEq)]
pub struct Program {
pub body: Vec<Stmt>,
pub source_type: SourceType,
pub span: Span,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SourceType {
Script,
Module,
}
#[derive(Clone, Debug, PartialEq)]
#[allow(missing_docs)] pub enum Stmt {
Expr { expression: Box<Expr>, span: Span },
Block { body: Vec<Stmt>, span: Span },
Empty { span: Span },
Var(VarDecl),
If {
test: Box<Expr>,
consequent: Box<Stmt>,
alternate: Option<Box<Stmt>>,
span: Span,
},
For {
init: Option<ForInit>,
test: Option<Box<Expr>>,
update: Option<Box<Expr>>,
body: Box<Stmt>,
span: Span,
},
ForIn {
left: ForLeft,
right: Box<Expr>,
body: Box<Stmt>,
span: Span,
},
ForOf {
left: ForLeft,
right: Box<Expr>,
body: Box<Stmt>,
is_await: bool,
span: Span,
},
While {
test: Box<Expr>,
body: Box<Stmt>,
span: Span,
},
DoWhile {
body: Box<Stmt>,
test: Box<Expr>,
span: Span,
},
Switch {
discriminant: Box<Expr>,
cases: Vec<SwitchCase>,
span: Span,
},
Try {
block: Vec<Stmt>,
handler: Option<CatchClause>,
finalizer: Option<Vec<Stmt>>,
span: Span,
},
Return {
argument: Option<Box<Expr>>,
span: Span,
},
Break { label: Option<Ident>, span: Span },
Continue { label: Option<Ident>, span: Span },
Throw { argument: Box<Expr>, span: Span },
Labeled {
label: Ident,
body: Box<Stmt>,
span: Span,
},
Debugger { span: Span },
With {
object: Box<Expr>,
body: Box<Stmt>,
span: Span,
},
Function(Function),
Class(Class),
Import(ImportDecl),
Export(ExportDecl),
}
impl Stmt {
#[must_use]
pub fn span(&self) -> Span {
match self {
Stmt::Expr { span, .. }
| Stmt::Block { span, .. }
| Stmt::Empty { span }
| Stmt::If { span, .. }
| Stmt::For { span, .. }
| Stmt::ForIn { span, .. }
| Stmt::ForOf { span, .. }
| Stmt::While { span, .. }
| Stmt::DoWhile { span, .. }
| Stmt::Switch { span, .. }
| Stmt::Try { span, .. }
| Stmt::Return { span, .. }
| Stmt::Break { span, .. }
| Stmt::Continue { span, .. }
| Stmt::Throw { span, .. }
| Stmt::Labeled { span, .. }
| Stmt::Debugger { span }
| Stmt::With { span, .. } => *span,
Stmt::Var(decl) => decl.span,
Stmt::Function(f) => f.span,
Stmt::Class(c) => c.span,
Stmt::Import(i) => i.span,
Stmt::Export(e) => e.span(),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct VarDecl {
pub kind: VarDeclKind,
pub declarations: Vec<VarDeclarator>,
pub span: Span,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[allow(missing_docs)]
pub enum VarDeclKind {
Var,
Let,
Const,
}
impl VarDeclKind {
#[must_use]
pub fn as_str(self) -> &'static str {
match self {
VarDeclKind::Var => "var",
VarDeclKind::Let => "let",
VarDeclKind::Const => "const",
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct VarDeclarator {
pub target: BindingTarget,
pub init: Option<Expr>,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq)]
#[allow(missing_docs)]
pub enum ForInit {
Var(VarDecl),
Expr(Box<Expr>),
}
#[derive(Clone, Debug, PartialEq)]
#[allow(missing_docs)]
pub enum ForLeft {
Decl {
kind: VarDeclKind,
target: BindingTarget,
span: Span,
},
Target(Box<Expr>),
}
#[derive(Clone, Debug, PartialEq)]
pub struct SwitchCase {
pub test: Option<Expr>,
pub body: Vec<Stmt>,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq)]
pub struct CatchClause {
pub param: Option<BindingTarget>,
pub body: Vec<Stmt>,
pub span: Span,
}