boa_ast/statement/
block.rs1use crate::{
4 Statement, StatementList,
5 operations::{ContainsSymbol, contains},
6 scope::Scope,
7 visitor::{VisitWith, Visitor, VisitorMut},
8};
9use boa_interner::{Interner, ToIndentedString};
10use core::ops::ControlFlow;
11
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
29#[derive(Clone, Debug, PartialEq, Default)]
30pub struct Block {
31 #[cfg_attr(feature = "serde", serde(flatten))]
32 pub(crate) statements: StatementList,
33 pub(crate) contains_direct_eval: bool,
34
35 #[cfg_attr(feature = "serde", serde(skip))]
36 pub(crate) scope: Option<Scope>,
37}
38
39impl Block {
40 #[inline]
42 #[must_use]
43 pub const fn statement_list(&self) -> &StatementList {
44 &self.statements
45 }
46
47 #[inline]
49 #[must_use]
50 pub const fn scope(&self) -> Option<&Scope> {
51 self.scope.as_ref()
52 }
53}
54
55impl<T> From<T> for Block
56where
57 T: Into<StatementList>,
58{
59 fn from(list: T) -> Self {
60 let statements = list.into();
61 let contains_direct_eval = contains(&statements, ContainsSymbol::DirectEval);
62 Self {
63 statements,
64 scope: None,
65 contains_direct_eval,
66 }
67 }
68}
69
70impl ToIndentedString for Block {
71 fn to_indented_string(&self, interner: &Interner, indentation: usize) -> String {
72 format!(
73 "{{\n{}{}}}",
74 self.statements
75 .to_indented_string(interner, indentation + 1),
76 " ".repeat(indentation)
77 )
78 }
79}
80
81impl From<Block> for Statement {
82 #[inline]
83 fn from(block: Block) -> Self {
84 Self::Block(block)
85 }
86}
87
88impl VisitWith for Block {
89 fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
90 where
91 V: Visitor<'a>,
92 {
93 visitor.visit_statement_list(&self.statements)
94 }
95
96 fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
97 where
98 V: VisitorMut<'a>,
99 {
100 visitor.visit_statement_list_mut(&mut self.statements)
101 }
102}