boa/syntax/ast/node/spread/
mod.rs

1use crate::{
2    exec::Executable,
3    gc::{Finalize, Trace},
4    syntax::ast::node::Node,
5    Context, JsResult, JsValue,
6};
7use std::fmt;
8
9#[cfg(feature = "deser")]
10use serde::{Deserialize, Serialize};
11
12#[cfg(test)]
13mod tests;
14
15/// The `spread` operator allows an iterable such as an array expression or string to be
16/// expanded.
17///
18/// Syntax: `...x`
19///
20/// It expands array expressions or strings in places where zero or more arguments (for
21/// function calls) or elements (for array literals)
22/// are expected, or an object expression to be expanded in places where zero or more key-value
23/// pairs (for object literals) are expected.
24///
25/// More information:
26///  - [ECMAScript reference][spec]
27///  - [MDN documentation][mdn]
28///
29/// [spec]: https://tc39.es/ecma262/#prod-SpreadElement
30/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
31#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
32#[cfg_attr(feature = "deser", serde(transparent))]
33#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
34pub struct Spread {
35    val: Box<Node>,
36}
37
38impl Spread {
39    pub fn val(&self) -> &Node {
40        &self.val
41    }
42
43    /// Creates a `Spread` AST node.
44    pub fn new<V>(val: V) -> Self
45    where
46        V: Into<Node>,
47    {
48        Self {
49            val: Box::new(val.into()),
50        }
51    }
52}
53
54impl Executable for Spread {
55    fn run(&self, context: &mut Context) -> JsResult<JsValue> {
56        // TODO: for now we can do nothing but return the value as-is
57        self.val().run(context)
58    }
59}
60
61impl fmt::Display for Spread {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        write!(f, "...{}", self.val())
64    }
65}
66
67impl From<Spread> for Node {
68    fn from(spread: Spread) -> Node {
69        Self::Spread(spread)
70    }
71}