pub type Span = (u32, u32);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
Mod,
Pow, Lt,
Le,
Gt,
Ge,
EqEqEq, NeEqEq, EqEq, NeEq, BitAnd,
BitOr,
BitXor,
Shl, Shr, UShr, In,
InstanceOf,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LogicalOp {
And, Or, Nullish, }
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AssignOp {
Binary(BinOp),
Logical(LogicalOp),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnOp {
Neg, Pos, Not, BitNot, TypeOf, Void, Delete, }
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DeclKind {
Var,
Let,
Const,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UpdateOp {
Inc, Dec, }
#[derive(Debug, Clone, PartialEq)]
pub enum Prop {
KeyValue {
key: Expr,
value: Expr,
computed: bool,
},
Spread(Expr),
Accessor {
key: Expr,
computed: bool,
is_getter: bool,
func: Expr,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
Null,
Undefined,
True,
False,
Number(f64),
BigInt(String),
Regex(String, String),
Str(String),
Template {
quasis: Vec<String>,
exprs: Vec<Expr>,
},
TaggedTemplate {
tag: Box<Expr>,
quasis: Vec<String>,
raws: Vec<String>,
exprs: Vec<Expr>,
},
Ident(String),
This,
Super,
NewTarget,
Yield {
arg: Option<Box<Expr>>,
delegate: bool,
},
Await(Box<Expr>),
Class(Box<ClassNode>),
Array(Vec<Expr>),
Hole,
Object(Vec<Prop>),
Spread(Box<Expr>),
Logical(LogicalOp, Box<Expr>, Box<Expr>),
Unary(UnOp, Box<Expr>),
Binary(BinOp, Box<Expr>, Box<Expr>),
Conditional {
test: Box<Expr>,
cons: Box<Expr>,
alt: Box<Expr>,
},
Assign {
target: Box<Expr>,
op: Option<AssignOp>,
value: Box<Expr>,
},
Update {
op: UpdateOp,
prefix: bool,
target: Box<Expr>,
},
Call {
func: Box<Expr>,
args: Vec<Expr>,
optional: bool,
},
New {
callee: Box<Expr>,
args: Vec<Expr>,
},
Member {
object: Box<Expr>,
property: String,
optional: bool,
},
Index {
object: Box<Expr>,
index: Box<Expr>,
optional: bool,
},
Function {
params: Vec<Param>,
body: FnBody,
is_arrow: bool,
name: Option<String>,
is_generator: bool,
is_async: bool,
is_method: bool,
span: Span,
},
Sequence(Vec<Expr>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct ClassNode {
pub name: Option<String>,
pub parent: Option<Box<Expr>>,
pub members: Vec<ClassMember>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ClassMember {
pub key: Expr,
pub computed: bool,
pub kind: MemberKind,
pub is_static: bool,
pub is_generator: bool,
pub is_async: bool,
pub params: Vec<Param>,
pub body: Vec<Stmt>,
pub field_init: Option<Expr>,
pub span: Span,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MemberKind {
Constructor,
Method,
Get,
Set,
Field,
StaticBlock,
}
#[derive(Debug, Clone, PartialEq)]
pub enum FnBody {
Block(Vec<Stmt>),
Expr(Box<Expr>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Param {
pub pattern: Expr,
pub default: Option<Expr>,
pub rest: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct SwitchCase {
pub test: Option<Expr>,
pub body: Vec<Stmt>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Declarator {
pub target: Expr,
pub init: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum StmtKind {
Expr(Expr),
Decl {
kind: DeclKind,
decls: Vec<Declarator>,
},
Block(Vec<Stmt>),
FuncDecl {
name: String,
params: Vec<Param>,
body: Vec<Stmt>,
is_generator: bool,
is_async: bool,
span: Span,
},
ClassDecl(ClassNode),
If {
test: Expr,
cons: Box<Stmt>,
alt: Option<Box<Stmt>>,
},
While {
test: Expr,
body: Box<Stmt>,
},
DoWhile {
body: Box<Stmt>,
test: Expr,
},
For {
init: Option<Box<Stmt>>,
test: Option<Expr>,
update: Option<Expr>,
body: Box<Stmt>,
},
ForOf {
decl_kind: Option<DeclKind>,
target: Expr,
iter: Expr,
body: Box<Stmt>,
is_await: bool,
},
ForIn {
decl_kind: Option<DeclKind>,
target: Expr,
object: Expr,
body: Box<Stmt>,
},
Switch {
disc: Expr,
cases: Vec<SwitchCase>,
},
Labeled {
label: String,
body: Box<Stmt>,
},
Return(Option<Expr>),
Break(Option<String>),
Continue(Option<String>),
Throw(Expr),
Try {
block: Vec<Stmt>,
handler: Option<(Option<Expr>, Vec<Stmt>)>, finalizer: Option<Vec<Stmt>>,
},
Empty,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Stmt {
pub kind: StmtKind,
pub line: u32,
}
impl Stmt {
pub fn new(kind: StmtKind, line: u32) -> Stmt {
Stmt { kind, line }
}
}
impl From<StmtKind> for Stmt {
fn from(kind: StmtKind) -> Stmt {
Stmt { kind, line: 0 }
}
}