use crate::visitor::{VisitWith, Visitor, VisitorMut};
use crate::{Span, Spanned, join_nodes};
use boa_interner::{Interner, ToInternedString};
use core::ops::ControlFlow;
use super::Expression;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Clone, Debug, PartialEq)]
pub struct Call {
function: Box<Expression>,
args: Box<[Expression]>,
span: Span,
}
impl Call {
#[inline]
#[must_use]
pub fn new(function: Expression, args: Box<[Expression]>, span: Span) -> Self {
Self {
function: Box::new(function),
args,
span,
}
}
#[inline]
#[must_use]
pub const fn function(&self) -> &Expression {
&self.function
}
#[inline]
#[must_use]
pub const fn args(&self) -> &[Expression] {
&self.args
}
}
impl Spanned for Call {
#[inline]
fn span(&self) -> Span {
self.span
}
}
impl ToInternedString for Call {
#[inline]
fn to_interned_string(&self, interner: &Interner) -> String {
format!(
"{}({})",
self.function.to_interned_string(interner),
join_nodes(interner, &self.args)
)
}
}
impl From<Call> for Expression {
#[inline]
fn from(call: Call) -> Self {
Self::Call(call)
}
}
impl VisitWith for Call {
fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: Visitor<'a>,
{
visitor.visit_expression(&self.function)?;
for expr in &*self.args {
visitor.visit_expression(expr)?;
}
ControlFlow::Continue(())
}
fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: VisitorMut<'a>,
{
visitor.visit_expression_mut(&mut self.function)?;
for expr in &mut *self.args {
visitor.visit_expression_mut(expr)?;
}
ControlFlow::Continue(())
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Clone, Debug, PartialEq)]
pub struct SuperCall {
args: Box<[Expression]>,
span: Span,
}
impl SuperCall {
pub fn new<A>(args: A, span: Span) -> Self
where
A: Into<Box<[Expression]>>,
{
Self {
args: args.into(),
span,
}
}
#[must_use]
pub const fn arguments(&self) -> &[Expression] {
&self.args
}
}
impl Spanned for SuperCall {
#[inline]
fn span(&self) -> Span {
self.span
}
}
impl ToInternedString for SuperCall {
#[inline]
fn to_interned_string(&self, interner: &Interner) -> String {
format!("super({})", join_nodes(interner, &self.args))
}
}
impl From<SuperCall> for Expression {
#[inline]
fn from(call: SuperCall) -> Self {
Self::SuperCall(call)
}
}
impl VisitWith for SuperCall {
fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: Visitor<'a>,
{
for expr in &*self.args {
visitor.visit_expression(expr)?;
}
ControlFlow::Continue(())
}
fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: VisitorMut<'a>,
{
for expr in &mut *self.args {
visitor.visit_expression_mut(expr)?;
}
ControlFlow::Continue(())
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[derive(Clone, Debug, PartialEq)]
pub struct ImportCall {
arg: Box<Expression>,
span: Span,
}
impl ImportCall {
pub fn new<A>(arg: A, span: Span) -> Self
where
A: Into<Expression>,
{
Self {
arg: Box::new(arg.into()),
span,
}
}
#[must_use]
pub const fn argument(&self) -> &Expression {
&self.arg
}
}
impl Spanned for ImportCall {
#[inline]
fn span(&self) -> Span {
self.span
}
}
impl ToInternedString for ImportCall {
#[inline]
fn to_interned_string(&self, interner: &Interner) -> String {
format!("import({})", self.arg.to_interned_string(interner))
}
}
impl From<ImportCall> for Expression {
#[inline]
fn from(call: ImportCall) -> Self {
Self::ImportCall(call)
}
}
impl VisitWith for ImportCall {
fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: Visitor<'a>,
{
visitor.visit_expression(&self.arg)
}
fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
where
V: VisitorMut<'a>,
{
visitor.visit_expression_mut(&mut self.arg)
}
}