boa/syntax/ast/node/array/
mod.rs1use super::{join_nodes, Node};
4use crate::{
5 builtins::{iterable, Array},
6 exec::Executable,
7 gc::{Finalize, Trace},
8 BoaProfiler, Context, JsResult, JsValue,
9};
10use std::fmt;
11
12#[cfg(feature = "deser")]
13use serde::{Deserialize, Serialize};
14
15#[cfg(test)]
16mod tests;
17
18#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
35#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
36pub struct ArrayDecl {
37 #[cfg_attr(feature = "deser", serde(flatten))]
38 arr: Box<[Node]>,
39}
40
41impl Executable for ArrayDecl {
42 fn run(&self, context: &mut Context) -> JsResult<JsValue> {
43 let _timer = BoaProfiler::global().start_event("ArrayDecl", "exec");
44 let array = Array::new_array(context);
45 let mut elements = Vec::new();
46 for elem in self.as_ref() {
47 if let Node::Spread(ref x) = elem {
48 let val = x.run(context)?;
49 let iterator_record = iterable::get_iterator(&val, context)?;
50 loop {
54 let next = iterator_record.next(context)?;
55 if next.done {
56 break;
57 }
58 let next_value = next.value;
59 elements.push(next_value);
61 }
62 } else {
63 elements.push(elem.run(context)?);
64 }
65 }
66
67 Array::add_to_array_object(&array, &elements, context)?;
68 Ok(array)
69 }
70}
71
72impl AsRef<[Node]> for ArrayDecl {
73 fn as_ref(&self) -> &[Node] {
74 &self.arr
75 }
76}
77
78impl<T> From<T> for ArrayDecl
79where
80 T: Into<Box<[Node]>>,
81{
82 fn from(decl: T) -> Self {
83 Self { arr: decl.into() }
84 }
85}
86
87impl fmt::Display for ArrayDecl {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 f.write_str("[")?;
90 join_nodes(f, &self.arr)?;
91 f.write_str("]")
92 }
93}
94
95impl From<ArrayDecl> for Node {
96 fn from(arr: ArrayDecl) -> Self {
97 Self::ArrayDecl(arr)
98 }
99}