boa_ast/
statement_list.rs1use super::Declaration;
4use crate::{
5 LinearPosition,
6 statement::Statement,
7 visitor::{VisitWith, Visitor, VisitorMut},
8};
9use boa_interner::{Interner, ToIndentedString};
10use core::ops::ControlFlow;
11use std::ops::Deref;
12
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
21#[derive(Clone, Debug, PartialEq)]
22pub enum StatementListItem {
23 Statement(Box<Statement>),
25 Declaration(Box<Declaration>),
27}
28
29impl ToIndentedString for StatementListItem {
30 fn to_indented_string(&self, interner: &Interner, indentation: usize) -> String {
41 let mut buf = " ".repeat(indentation);
42
43 match self {
44 Self::Statement(stmt) => {
45 buf.push_str(&stmt.to_no_indent_string(interner, indentation));
46 }
47 Self::Declaration(decl) => {
48 buf.push_str(&decl.to_indented_string(interner, indentation));
49 }
50 }
51
52 buf
53 }
54}
55
56impl From<Statement> for StatementListItem {
57 #[inline]
58 fn from(stmt: Statement) -> Self {
59 Self::Statement(Box::new(stmt))
60 }
61}
62
63impl From<Declaration> for StatementListItem {
64 #[inline]
65 fn from(decl: Declaration) -> Self {
66 Self::Declaration(Box::new(decl))
67 }
68}
69
70impl VisitWith for StatementListItem {
71 fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
72 where
73 V: Visitor<'a>,
74 {
75 match self {
76 Self::Statement(statement) => visitor.visit_statement(statement),
77 Self::Declaration(declaration) => visitor.visit_declaration(declaration),
78 }
79 }
80
81 fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
82 where
83 V: VisitorMut<'a>,
84 {
85 match self {
86 Self::Statement(statement) => visitor.visit_statement_mut(statement),
87 Self::Declaration(declaration) => visitor.visit_declaration_mut(declaration),
88 }
89 }
90}
91
92#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
99#[derive(Clone, Debug, Default)]
100pub struct StatementList {
101 pub(crate) statements: Box<[StatementListItem]>,
102 linear_pos_end: LinearPosition,
103 strict: bool,
104}
105
106impl PartialEq for StatementList {
107 fn eq(&self, other: &Self) -> bool {
108 self.statements == other.statements && self.strict == other.strict
109 }
110}
111
112impl StatementList {
113 #[must_use]
115 pub fn new<S>(statements: S, linear_pos_end: LinearPosition, strict: bool) -> Self
116 where
117 S: Into<Box<[StatementListItem]>>,
118 {
119 Self {
120 statements: statements.into(),
121 linear_pos_end,
122 strict,
123 }
124 }
125
126 #[inline]
128 #[must_use]
129 pub const fn statements(&self) -> &[StatementListItem] {
130 &self.statements
131 }
132
133 #[inline]
135 #[must_use]
136 pub const fn strict(&self) -> bool {
137 self.strict
138 }
139
140 #[inline]
142 #[must_use]
143 pub const fn linear_pos_end(&self) -> LinearPosition {
144 self.linear_pos_end
145 }
146}
147
148impl From<(Box<[StatementListItem]>, LinearPosition)> for StatementList {
149 #[inline]
150 fn from(value: (Box<[StatementListItem]>, LinearPosition)) -> Self {
151 Self {
152 statements: value.0,
153 linear_pos_end: value.1,
154 strict: false,
155 }
156 }
157}
158
159impl From<(Vec<StatementListItem>, LinearPosition)> for StatementList {
160 #[inline]
161 fn from(value: (Vec<StatementListItem>, LinearPosition)) -> Self {
162 Self {
163 statements: value.0.into(),
164 linear_pos_end: value.1,
165 strict: false,
166 }
167 }
168}
169
170impl Deref for StatementList {
171 type Target = [StatementListItem];
172
173 fn deref(&self) -> &Self::Target {
174 &self.statements
175 }
176}
177
178impl ToIndentedString for StatementList {
179 fn to_indented_string(&self, interner: &Interner, indentation: usize) -> String {
180 let mut buf = String::new();
181 for item in &*self.statements {
183 buf.push_str(&item.to_indented_string(interner, indentation));
185
186 buf.push('\n');
187 }
188 buf
189 }
190}
191
192impl VisitWith for StatementList {
193 fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
194 where
195 V: Visitor<'a>,
196 {
197 for statement in &*self.statements {
198 visitor.visit_statement_list_item(statement)?;
199 }
200 ControlFlow::Continue(())
201 }
202
203 fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
204 where
205 V: VisitorMut<'a>,
206 {
207 for statement in &mut *self.statements {
208 visitor.visit_statement_list_item_mut(statement)?;
209 }
210 ControlFlow::Continue(())
211 }
212}
213
214#[cfg(feature = "arbitrary")]
215impl<'a> arbitrary::Arbitrary<'a> for StatementList {
216 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
217 Ok(Self {
218 statements: u.arbitrary()?,
219 linear_pos_end: LinearPosition::default(),
220 strict: false, })
222 }
223}