use super::{Arrow, AssignOp, BinaryOp, Class, Function, Ident, LogicalOp, UnaryOp, UpdateOp};
use crate::common::Span;
use alloc::boxed::Box;
use alloc::vec::Vec;
#[derive(Clone, Debug, PartialEq)]
#[allow(missing_docs)] pub enum Expr {
Null(Span),
Bool { value: bool, span: Span },
Number { value: f64, span: Span },
BigInt { digits: Box<str>, span: Span },
Str { value: Box<str>, span: Span },
Regex {
pattern: Box<str>,
flags: Box<str>,
span: Span,
},
Template(TemplateLiteral),
TaggedTemplate {
tag: Box<Expr>,
quasi: TemplateLiteral,
span: Span,
},
Ident(Ident),
PrivateName(Box<str>, Span),
This(Span),
Super(Span),
NewTarget(Span),
Array {
elements: Vec<ArrayElement>,
span: Span,
},
Object {
members: Vec<ObjectMember>,
span: Span,
},
Member {
object: Box<Expr>,
property: PropertyKey,
optional: bool,
span: Span,
},
Call {
callee: Box<Expr>,
arguments: Vec<Argument>,
optional: bool,
span: Span,
},
New {
callee: Box<Expr>,
arguments: Vec<Argument>,
span: Span,
},
OptChain {
expr: Box<Expr>,
span: Span,
},
Unary {
op: UnaryOp,
argument: Box<Expr>,
span: Span,
},
Update {
op: UpdateOp,
prefix: bool,
argument: Box<Expr>,
span: Span,
},
Binary {
op: BinaryOp,
left: Box<Expr>,
right: Box<Expr>,
span: Span,
},
Logical {
op: LogicalOp,
left: Box<Expr>,
right: Box<Expr>,
span: Span,
},
Conditional {
test: Box<Expr>,
consequent: Box<Expr>,
alternate: Box<Expr>,
span: Span,
},
Assign {
op: AssignOp,
target: Box<Expr>,
value: Box<Expr>,
span: Span,
},
Sequence { expressions: Vec<Expr>, span: Span },
Function(Function),
Arrow(Arrow),
Class(Class),
Yield {
argument: Option<Box<Expr>>,
delegate: bool,
span: Span,
},
Await { argument: Box<Expr>, span: Span },
}
impl Expr {
#[must_use]
pub fn span(&self) -> Span {
match self {
Expr::Null(span)
| Expr::PrivateName(_, span)
| Expr::This(span)
| Expr::Super(span)
| Expr::NewTarget(span)
| Expr::Bool { span, .. }
| Expr::Number { span, .. }
| Expr::BigInt { span, .. }
| Expr::Str { span, .. }
| Expr::Regex { span, .. }
| Expr::TaggedTemplate { span, .. }
| Expr::Array { span, .. }
| Expr::Object { span, .. }
| Expr::Member { span, .. }
| Expr::Call { span, .. }
| Expr::New { span, .. }
| Expr::OptChain { span, .. }
| Expr::Unary { span, .. }
| Expr::Update { span, .. }
| Expr::Binary { span, .. }
| Expr::Logical { span, .. }
| Expr::Conditional { span, .. }
| Expr::Assign { span, .. }
| Expr::Sequence { span, .. }
| Expr::Yield { span, .. }
| Expr::Await { span, .. } => *span,
Expr::Template(t) => t.span,
Expr::Ident(id) => id.span,
Expr::Function(f) => f.span,
Expr::Arrow(a) => a.span,
Expr::Class(c) => c.span,
}
}
#[must_use]
pub fn is_assignment_target(&self) -> bool {
match self {
Expr::Ident(_) | Expr::Member { .. } => true,
Expr::Array { elements, .. } => elements.iter().all(|el| match el {
ArrayElement::Hole => true,
ArrayElement::Item(e) | ArrayElement::Spread(e) => e.is_assignment_target(),
}),
Expr::Object { members, .. } => members.iter().all(|m| match m {
ObjectMember::Property { value, .. } => value.is_assignment_target(),
ObjectMember::Spread { value, .. } => value.is_assignment_target(),
ObjectMember::Accessor { .. } => false,
}),
Expr::Assign {
op: crate::ast::AssignOp::Assign,
target,
..
} => target.is_assignment_target(),
_ => false,
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[allow(missing_docs)]
pub enum ArrayElement {
Hole,
Item(Expr),
Spread(Expr),
}
#[derive(Clone, Debug, PartialEq)]
#[allow(missing_docs)]
pub enum Argument {
Item(Expr),
Spread(Expr),
}
#[derive(Clone, Debug, PartialEq)]
#[allow(missing_docs)]
pub enum PropertyKey {
Ident(Box<str>),
Private(Box<str>),
Str(Box<str>),
Number(f64),
Computed(Box<Expr>),
}
#[derive(Clone, Debug, PartialEq)]
#[allow(missing_docs)]
pub enum ObjectMember {
Property {
key: PropertyKey,
value: Box<Expr>,
shorthand: bool,
span: Span,
},
Spread { value: Box<Expr>, span: Span },
Accessor {
is_getter: bool,
key: PropertyKey,
value: super::Function,
span: Span,
},
}
#[derive(Clone, Debug, PartialEq)]
pub struct TemplateLiteral {
pub quasis: Vec<TemplateElement>,
pub expressions: Vec<Expr>,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq)]
pub struct TemplateElement {
pub raw: Box<str>,
pub cooked: Option<Box<str>>,
pub span: Span,
}