From ad14efefb4f1c423d92a26ddc628d47405d159b0 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 14:54:30 +0100 Subject: [PATCH 01/34] use chalk/swc patterns --- boa_engine/src/syntax/ast/declaration/mod.rs | 20 +++++ boa_engine/src/syntax/ast/mod.rs | 1 + boa_engine/src/syntax/ast/statement/mod.rs | 20 +++++ .../src/syntax/ast/statement_list/mod.rs | 48 +++++++++++ boa_engine/src/syntax/ast/visitor.rs | 86 +++++++++++++++++++ boa_engine/src/value/mod.rs | 4 +- boa_examples/src/bin/printer_visitor.rs | 64 ++++++++++++++ 7 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 boa_engine/src/syntax/ast/visitor.rs create mode 100644 boa_examples/src/bin/printer_visitor.rs diff --git a/boa_engine/src/syntax/ast/declaration/mod.rs b/boa_engine/src/syntax/ast/declaration/mod.rs index 1b9fb43b19a..ef45001da86 100644 --- a/boa_engine/src/syntax/ast/declaration/mod.rs +++ b/boa_engine/src/syntax/ast/declaration/mod.rs @@ -20,10 +20,12 @@ use super::{ ContainsSymbol, }; use boa_interner::{Interner, ToIndentedString, ToInternedString}; +use core::ops::ControlFlow; use tap::Tap; mod variable; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; pub use variable::*; /// The `Declaration` Parse Node. @@ -165,3 +167,21 @@ impl ToIndentedString for Declaration { } } } + +impl VisitWith for Declaration { + fn visit_with<'a>(&'a self, _visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + // TODO implement + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a>(&'a mut self, _visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + // TODO implement + ControlFlow::Continue(()) + } +} diff --git a/boa_engine/src/syntax/ast/mod.rs b/boa_engine/src/syntax/ast/mod.rs index 360f45a16d5..6f4d3e87f40 100644 --- a/boa_engine/src/syntax/ast/mod.rs +++ b/boa_engine/src/syntax/ast/mod.rs @@ -24,6 +24,7 @@ pub mod keyword; pub mod pattern; pub mod property; pub mod statement; +pub mod visitor; use boa_interner::{Interner, ToIndentedString, ToInternedString}; diff --git a/boa_engine/src/syntax/ast/statement/mod.rs b/boa_engine/src/syntax/ast/statement/mod.rs index c097e04627b..92f3f3b572e 100644 --- a/boa_engine/src/syntax/ast/statement/mod.rs +++ b/boa_engine/src/syntax/ast/statement/mod.rs @@ -28,7 +28,9 @@ pub use self::{ switch::{Case, Switch}, throw::Throw, }; +use core::ops::ControlFlow; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use boa_interner::{Interner, ToIndentedString, ToInternedString}; use rustc_hash::FxHashSet; use tap::Tap; @@ -313,3 +315,21 @@ impl ToIndentedString for Statement { buf } } + +impl VisitWith for Statement { + fn visit_with<'a>(&'a self, _visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + // TODO implement + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a>(&'a mut self, _visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + // TODO implement + ControlFlow::Continue(()) + } +} diff --git a/boa_engine/src/syntax/ast/statement_list/mod.rs b/boa_engine/src/syntax/ast/statement_list/mod.rs index f9f0f5297c7..d761d7dddd7 100644 --- a/boa_engine/src/syntax/ast/statement_list/mod.rs +++ b/boa_engine/src/syntax/ast/statement_list/mod.rs @@ -1,8 +1,10 @@ //! Statement list node. use super::{declaration::Binding, Declaration}; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Identifier, statement::Statement, ContainsSymbol}; use boa_interner::{Interner, ToIndentedString}; +use core::ops::ControlFlow; use rustc_hash::FxHashSet; use std::cmp::Ordering; @@ -117,6 +119,30 @@ impl From for StatementListItem { } } +impl VisitWith for StatementListItem { + fn visit_with<'a>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + StatementListItem::Statement(statement) => visitor.visit_statement(statement), + StatementListItem::Declaration(declaration) => visitor.visit_declaration(declaration), + } + } + + fn visit_with_mut<'a>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + StatementListItem::Statement(statement) => visitor.visit_statement_mut(statement), + StatementListItem::Declaration(declaration) => { + visitor.visit_declaration_mut(declaration) + } + } + } +} + /// List of statements. /// /// More information: @@ -278,3 +304,25 @@ impl ToIndentedString for StatementList { buf } } + +impl VisitWith for StatementList { + fn visit_with<'a>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + for statement in self.statements.iter() { + visitor.visit_statement_list_item(statement); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + for statement in self.statements.iter_mut() { + visitor.visit_statement_list_item_mut(statement); + } + ControlFlow::Continue(()) + } +} diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs new file mode 100644 index 00000000000..b5f1d6a7b2a --- /dev/null +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -0,0 +1,86 @@ +//! Javascript Abstract Syntax Tree visitors. +//! +//! This module contains visitors which can be used to inspect or modify AST nodes. This allows for +//! fine-grained manipulation of ASTs for analysis, rewriting, or instrumentation. + +#[cfg(doc)] +use super::statement_list::StatementListVisitor; + +/// `Try`-like conditional unwrapping of `ControlFlow`. +#[macro_export] +macro_rules! try_break { + ($expr:expr) => { + match $expr { + core::ops::ControlFlow::Continue(c) => c, + core::ops::ControlFlow::Break(b) => return core::ops::ControlFlow::Break(b), + } + }; +} + +use crate::syntax::ast::{Declaration, Statement, StatementList, StatementListItem}; + +macro_rules! define_visit { + ($fn_name:ident, $type_name:ident) => { + fn $fn_name(&mut self, node: &'ast $type_name) -> core::ops::ControlFlow { + node.visit_with(self) + } + }; +} + +macro_rules! define_visit_mut { + ($fn_name:ident, $type_name:ident) => { + fn $fn_name( + &mut self, + node: &'ast mut $type_name, + ) -> core::ops::ControlFlow { + node.visit_with_mut(self) + } + }; +} + +/// Represents an AST visitor. +/// +/// This implementation is based largely on [chalk](https://github.com/rust-lang/chalk/blob/23d39c90ceb9242fbd4c43e9368e813e7c2179f7/chalk-ir/src/visit.rs)'s +/// visitor pattern. +#[allow(unused_variables)] +#[allow(missing_docs)] +pub trait Visitor<'ast>: Sized { + /// Type which will be propagated from the visitor if completing early. + type BreakTy; + + define_visit!(visit_statement_list, StatementList); + define_visit!(visit_statement_list_item, StatementListItem); + define_visit!(visit_statement, Statement); + define_visit!(visit_declaration, Declaration); +} + +/// Represents an AST visitor which can modify AST content. +/// +/// This implementation is based largely on [chalk](https://github.com/rust-lang/chalk/blob/23d39c90ceb9242fbd4c43e9368e813e7c2179f7/chalk-ir/src/visit.rs)'s +/// visitor pattern. +#[allow(unused_variables)] +#[allow(missing_docs)] +pub trait VisitorMut<'ast>: Sized { + /// Type which will be propagated from the visitor if completing early. + type BreakTy; + + define_visit_mut!(visit_statement_list_mut, StatementList); + define_visit_mut!(visit_statement_list_item_mut, StatementListItem); + define_visit_mut!(visit_statement_mut, Statement); + define_visit_mut!(visit_declaration_mut, Declaration); +} + +/// Denotes that a type may be visited, providing a method which allows a visitor to traverse its +/// private fields. +pub trait VisitWith { + /// Visit this node with the provided visitor. + fn visit_with<'a>(&'a self, visitor: &mut V) -> core::ops::ControlFlow + where + V: Visitor<'a>; + + /// Visit this node with the provided visitor mutably, allowing the visitor to modify private + /// fields. + fn visit_with_mut<'a>(&'a mut self, visitor: &mut V) -> core::ops::ControlFlow + where + V: VisitorMut<'a>; +} diff --git a/boa_engine/src/value/mod.rs b/boa_engine/src/value/mod.rs index 3b9ac4fcd3b..680e6b2f309 100644 --- a/boa_engine/src/value/mod.rs +++ b/boa_engine/src/value/mod.rs @@ -40,8 +40,8 @@ mod r#type; pub use conversions::*; pub use display::ValueDisplay; -pub use equality::*; -pub use hash::*; +// pub use equality::*; +// pub use hash::*; pub use integer::IntegerOrInfinity; pub use operations::*; pub use r#type::Type; diff --git a/boa_examples/src/bin/printer_visitor.rs b/boa_examples/src/bin/printer_visitor.rs new file mode 100644 index 00000000000..33137cf7b23 --- /dev/null +++ b/boa_examples/src/bin/printer_visitor.rs @@ -0,0 +1,64 @@ +use boa_engine::syntax::ast::visitor::{VisitWith, Visitor}; +use boa_engine::syntax::ast::{Declaration, Statement, StatementList, StatementListItem}; +use boa_engine::syntax::Parser; +use boa_engine::Context; +use std::convert::Infallible; +use std::fs::File; +use std::io::BufReader; +use core::ops::ControlFlow; + +#[derive(Debug, Clone, Default)] +struct PrinterVisitor { + indent: String, +} + +impl<'ast> Visitor<'ast> for PrinterVisitor { + type BreakTy = Infallible; + + fn visit_statement_list(&mut self, node: &'ast StatementList) -> ControlFlow { + println!( + "{}StatementList (strict: {}) {{", + self.indent, + node.strict() + ); + self.indent.push(' '); + let res = node.visit_with(self); + self.indent.pop(); + println!("{}}}", self.indent); + res + } + + fn visit_statement_list_item( + &mut self, + node: &'ast StatementListItem, + ) -> ControlFlow { + print!("{}StatementListItem: ", self.indent); + self.indent.push(' '); + let res = node.visit_with(self); + self.indent.pop(); + res + } + + fn visit_statement(&mut self, node: &'ast Statement) -> ControlFlow { + println!("Statement: {:?}", node); + ControlFlow::Continue(()) + } + + fn visit_declaration(&mut self, node: &'ast Declaration) -> ControlFlow { + println!("Declaration: {:?}", node); + ControlFlow::Continue(()) + } +} + +fn main() { + let mut parser = Parser::new(BufReader::new( + File::open("boa_examples/scripts/calctest.js").unwrap(), + )); + let mut ctx = Context::default(); + + let statements = parser.parse_all(&mut ctx).unwrap(); + + let mut visitor = PrinterVisitor::default(); + + visitor.visit_statement_list(&statements); +} From 9b8089ac41bad19e723ca22b1551772abcf392bc Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 14:56:10 +0100 Subject: [PATCH 02/34] make fmt happy --- boa_examples/src/bin/printer_visitor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa_examples/src/bin/printer_visitor.rs b/boa_examples/src/bin/printer_visitor.rs index 33137cf7b23..4d6113e05d5 100644 --- a/boa_examples/src/bin/printer_visitor.rs +++ b/boa_examples/src/bin/printer_visitor.rs @@ -2,10 +2,10 @@ use boa_engine::syntax::ast::visitor::{VisitWith, Visitor}; use boa_engine::syntax::ast::{Declaration, Statement, StatementList, StatementListItem}; use boa_engine::syntax::Parser; use boa_engine::Context; +use core::ops::ControlFlow; use std::convert::Infallible; use std::fs::File; use std::io::BufReader; -use core::ops::ControlFlow; #[derive(Debug, Clone, Default)] struct PrinterVisitor { From 548a44b61d54b47ec9c6813a73fa225697cfd29b Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 15:00:04 +0100 Subject: [PATCH 03/34] whoops, missed a spot --- boa_engine/src/syntax/ast/visitor.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index b5f1d6a7b2a..2e6c70f247c 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -3,9 +3,6 @@ //! This module contains visitors which can be used to inspect or modify AST nodes. This allows for //! fine-grained manipulation of ASTs for analysis, rewriting, or instrumentation. -#[cfg(doc)] -use super::statement_list::StatementListVisitor; - /// `Try`-like conditional unwrapping of `ControlFlow`. #[macro_export] macro_rules! try_break { From 3905165349c61cd7e9c901e4899a7778ad92f002 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 15:26:44 +0100 Subject: [PATCH 04/34] more precise missing_docs --- boa_engine/src/syntax/ast/visitor.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 2e6c70f247c..fc0f8ca58f7 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -18,6 +18,7 @@ use crate::syntax::ast::{Declaration, Statement, StatementList, StatementListIte macro_rules! define_visit { ($fn_name:ident, $type_name:ident) => { + #[allow(missing_docs)] fn $fn_name(&mut self, node: &'ast $type_name) -> core::ops::ControlFlow { node.visit_with(self) } @@ -26,6 +27,7 @@ macro_rules! define_visit { macro_rules! define_visit_mut { ($fn_name:ident, $type_name:ident) => { + #[allow(missing_docs)] fn $fn_name( &mut self, node: &'ast mut $type_name, @@ -40,7 +42,6 @@ macro_rules! define_visit_mut { /// This implementation is based largely on [chalk](https://github.com/rust-lang/chalk/blob/23d39c90ceb9242fbd4c43e9368e813e7c2179f7/chalk-ir/src/visit.rs)'s /// visitor pattern. #[allow(unused_variables)] -#[allow(missing_docs)] pub trait Visitor<'ast>: Sized { /// Type which will be propagated from the visitor if completing early. type BreakTy; From 481c433af55494a51d08b252b1f200bf5e69607c Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 15:27:37 +0100 Subject: [PATCH 05/34] again --- boa_engine/src/syntax/ast/visitor.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index fc0f8ca58f7..790dba75c89 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -57,7 +57,6 @@ pub trait Visitor<'ast>: Sized { /// This implementation is based largely on [chalk](https://github.com/rust-lang/chalk/blob/23d39c90ceb9242fbd4c43e9368e813e7c2179f7/chalk-ir/src/visit.rs)'s /// visitor pattern. #[allow(unused_variables)] -#[allow(missing_docs)] pub trait VisitorMut<'ast>: Sized { /// Type which will be propagated from the visitor if completing early. type BreakTy; From 5250407b376117e852e74c5110ceab27b0d3517b Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 16:42:03 +0100 Subject: [PATCH 06/34] Create documentation for Visitor{,Mut} dynamically --- boa_engine/src/syntax/ast/visitor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 790dba75c89..df6d5636233 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -18,7 +18,7 @@ use crate::syntax::ast::{Declaration, Statement, StatementList, StatementListIte macro_rules! define_visit { ($fn_name:ident, $type_name:ident) => { - #[allow(missing_docs)] + #[doc = concat!("Visits a `", stringify!($type_name), "` with this visitor")] fn $fn_name(&mut self, node: &'ast $type_name) -> core::ops::ControlFlow { node.visit_with(self) } @@ -27,7 +27,7 @@ macro_rules! define_visit { macro_rules! define_visit_mut { ($fn_name:ident, $type_name:ident) => { - #[allow(missing_docs)] + #[doc = concat!("Visits a `", stringify!($type_name), "` with this visitor, mutably")] fn $fn_name( &mut self, node: &'ast mut $type_name, From 0bbe562d872fa5fb2a1ffe156167f12f8fc504ed Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 17:08:26 +0100 Subject: [PATCH 07/34] expand for declaration, statement; move V parameter to function --- boa_engine/src/syntax/ast/declaration/mod.rs | 26 ++++++--- boa_engine/src/syntax/ast/statement/mod.rs | 54 +++++++++++++++--- .../src/syntax/ast/statement_list/mod.rs | 12 ++-- boa_engine/src/syntax/ast/visitor.rs | 57 +++++++++++++++++-- 4 files changed, 125 insertions(+), 24 deletions(-) diff --git a/boa_engine/src/syntax/ast/declaration/mod.rs b/boa_engine/src/syntax/ast/declaration/mod.rs index ef45001da86..eca685b8159 100644 --- a/boa_engine/src/syntax/ast/declaration/mod.rs +++ b/boa_engine/src/syntax/ast/declaration/mod.rs @@ -168,20 +168,32 @@ impl ToIndentedString for Declaration { } } -impl VisitWith for Declaration { - fn visit_with<'a>(&'a self, _visitor: &mut V) -> ControlFlow +impl VisitWith for Declaration { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow where V: Visitor<'a>, { - // TODO implement - ControlFlow::Continue(()) + match self { + Declaration::Function(f) => visitor.visit_function(f), + Declaration::Generator(g) => visitor.visit_generator(g), + Declaration::AsyncFunction(af) => visitor.visit_async_function(af), + Declaration::AsyncGenerator(ag) => visitor.visit_async_generator(ag), + Declaration::Class(c) => visitor.visit_class(c), + Declaration::Lexical(ld) => visitor.visit_lexical_declaration(ld), + } } - fn visit_with_mut<'a>(&'a mut self, _visitor: &mut V) -> ControlFlow + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow where V: VisitorMut<'a>, { - // TODO implement - ControlFlow::Continue(()) + match self { + Declaration::Function(f) => visitor.visit_function_mut(f), + Declaration::Generator(g) => visitor.visit_generator_mut(g), + Declaration::AsyncFunction(af) => visitor.visit_async_function_mut(af), + Declaration::AsyncGenerator(ag) => visitor.visit_async_generator_mut(ag), + Declaration::Class(c) => visitor.visit_class_mut(c), + Declaration::Lexical(ld) => visitor.visit_lexical_declaration_mut(ld), + } } } diff --git a/boa_engine/src/syntax/ast/statement/mod.rs b/boa_engine/src/syntax/ast/statement/mod.rs index 92f3f3b572e..831d3956514 100644 --- a/boa_engine/src/syntax/ast/statement/mod.rs +++ b/boa_engine/src/syntax/ast/statement/mod.rs @@ -316,20 +316,60 @@ impl ToIndentedString for Statement { } } -impl VisitWith for Statement { - fn visit_with<'a>(&'a self, _visitor: &mut V) -> ControlFlow +impl VisitWith for Statement { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow where V: Visitor<'a>, { - // TODO implement - ControlFlow::Continue(()) + match self { + Statement::Block(b) => visitor.visit_block(b), + Statement::Var(v) => visitor.visit_var_declaration(v), + Statement::Empty => { + // do nothing; there is nothing to visit here + ControlFlow::Continue(()) + } + Statement::Expression(e) => visitor.visit_expression(e), + Statement::If(i) => visitor.visit_if(i), + Statement::DoWhileLoop(dw) => visitor.visit_do_while_loop(dw), + Statement::WhileLoop(w) => visitor.visit_while_loop(w), + Statement::ForLoop(f) => visitor.visit_for_loop(f), + Statement::ForInLoop(fi) => visitor.visit_for_in_loop(fi), + Statement::ForOfLoop(fo) => visitor.visit_for_of_loop(fo), + Statement::Switch(s) => visitor.visit_switch(s), + Statement::Continue(c) => visitor.visit_continue(c), + Statement::Break(b) => visitor.visit_break(b), + Statement::Return(r) => visitor.visit_return(r), + Statement::Labelled(l) => visitor.visit_labelled(l), + Statement::Throw(th) => visitor.visit_throw(th), + Statement::Try(tr) => visitor.visit_try(tr), + } } - fn visit_with_mut<'a>(&'a mut self, _visitor: &mut V) -> ControlFlow + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow where V: VisitorMut<'a>, { - // TODO implement - ControlFlow::Continue(()) + match self { + Statement::Block(b) => visitor.visit_block_mut(b), + Statement::Var(v) => visitor.visit_var_declaration_mut(v), + Statement::Empty => { + // do nothing; there is nothing to visit here + ControlFlow::Continue(()) + } + Statement::Expression(e) => visitor.visit_expression_mut(e), + Statement::If(i) => visitor.visit_if_mut(i), + Statement::DoWhileLoop(dw) => visitor.visit_do_while_loop_mut(dw), + Statement::WhileLoop(w) => visitor.visit_while_loop_mut(w), + Statement::ForLoop(f) => visitor.visit_for_loop_mut(f), + Statement::ForInLoop(fi) => visitor.visit_for_in_loop_mut(fi), + Statement::ForOfLoop(fo) => visitor.visit_for_of_loop_mut(fo), + Statement::Switch(s) => visitor.visit_switch_mut(s), + Statement::Continue(c) => visitor.visit_continue_mut(c), + Statement::Break(b) => visitor.visit_break_mut(b), + Statement::Return(r) => visitor.visit_return_mut(r), + Statement::Labelled(l) => visitor.visit_labelled_mut(l), + Statement::Throw(th) => visitor.visit_throw_mut(th), + Statement::Try(tr) => visitor.visit_try_mut(tr), + } } } diff --git a/boa_engine/src/syntax/ast/statement_list/mod.rs b/boa_engine/src/syntax/ast/statement_list/mod.rs index d761d7dddd7..2e30e5fbb34 100644 --- a/boa_engine/src/syntax/ast/statement_list/mod.rs +++ b/boa_engine/src/syntax/ast/statement_list/mod.rs @@ -119,8 +119,8 @@ impl From for StatementListItem { } } -impl VisitWith for StatementListItem { - fn visit_with<'a>(&'a self, visitor: &mut V) -> ControlFlow +impl VisitWith for StatementListItem { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow where V: Visitor<'a>, { @@ -130,7 +130,7 @@ impl VisitWith for StatementListItem { } } - fn visit_with_mut<'a>(&'a mut self, visitor: &mut V) -> ControlFlow + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow where V: VisitorMut<'a>, { @@ -305,8 +305,8 @@ impl ToIndentedString for StatementList { } } -impl VisitWith for StatementList { - fn visit_with<'a>(&'a self, visitor: &mut V) -> ControlFlow +impl VisitWith for StatementList { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow where V: Visitor<'a>, { @@ -316,7 +316,7 @@ impl VisitWith for StatementList { ControlFlow::Continue(()) } - fn visit_with_mut<'a>(&'a mut self, visitor: &mut V) -> ControlFlow + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow where V: VisitorMut<'a>, { diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index df6d5636233..c0aa240ec61 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -14,8 +14,12 @@ macro_rules! try_break { }; } -use crate::syntax::ast::{Declaration, Statement, StatementList, StatementListItem}; +use crate::syntax::ast::declaration::*; +use crate::syntax::ast::function::*; +use crate::syntax::ast::statement::*; +use crate::syntax::ast::*; +/// Creates the default visit function implementation for a particular type macro_rules! define_visit { ($fn_name:ident, $type_name:ident) => { #[doc = concat!("Visits a `", stringify!($type_name), "` with this visitor")] @@ -25,6 +29,7 @@ macro_rules! define_visit { }; } +/// Creates the default mutable visit function implementation for a particular type macro_rules! define_visit_mut { ($fn_name:ident, $type_name:ident) => { #[doc = concat!("Visits a `", stringify!($type_name), "` with this visitor, mutably")] @@ -50,6 +55,28 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_statement_list_item, StatementListItem); define_visit!(visit_statement, Statement); define_visit!(visit_declaration, Declaration); + define_visit!(visit_function, Function); + define_visit!(visit_generator, Generator); + define_visit!(visit_async_function, AsyncFunction); + define_visit!(visit_async_generator, AsyncGenerator); + define_visit!(visit_class, Class); + define_visit!(visit_lexical_declaration, LexicalDeclaration); + define_visit!(visit_block, Block); + define_visit!(visit_var_declaration, VarDeclaration); + define_visit!(visit_expression, Expression); + define_visit!(visit_if, If); + define_visit!(visit_do_while_loop, DoWhileLoop); + define_visit!(visit_while_loop, WhileLoop); + define_visit!(visit_for_loop, ForLoop); + define_visit!(visit_for_in_loop, ForInLoop); + define_visit!(visit_for_of_loop, ForOfLoop); + define_visit!(visit_switch, Switch); + define_visit!(visit_continue, Continue); + define_visit!(visit_break, Break); + define_visit!(visit_return, Return); + define_visit!(visit_labelled, Labelled); + define_visit!(visit_throw, Throw); + define_visit!(visit_try, Try); } /// Represents an AST visitor which can modify AST content. @@ -65,19 +92,41 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_statement_list_item_mut, StatementListItem); define_visit_mut!(visit_statement_mut, Statement); define_visit_mut!(visit_declaration_mut, Declaration); + define_visit_mut!(visit_function_mut, Function); + define_visit_mut!(visit_generator_mut, Generator); + define_visit_mut!(visit_async_function_mut, AsyncFunction); + define_visit_mut!(visit_async_generator_mut, AsyncGenerator); + define_visit_mut!(visit_class_mut, Class); + define_visit_mut!(visit_lexical_declaration_mut, LexicalDeclaration); + define_visit_mut!(visit_block_mut, Block); + define_visit_mut!(visit_var_declaration_mut, VarDeclaration); + define_visit_mut!(visit_expression_mut, Expression); + define_visit_mut!(visit_if_mut, If); + define_visit_mut!(visit_do_while_loop_mut, DoWhileLoop); + define_visit_mut!(visit_while_loop_mut, WhileLoop); + define_visit_mut!(visit_for_loop_mut, ForLoop); + define_visit_mut!(visit_for_in_loop_mut, ForInLoop); + define_visit_mut!(visit_for_of_loop_mut, ForOfLoop); + define_visit_mut!(visit_switch_mut, Switch); + define_visit_mut!(visit_continue_mut, Continue); + define_visit_mut!(visit_break_mut, Break); + define_visit_mut!(visit_return_mut, Return); + define_visit_mut!(visit_labelled_mut, Labelled); + define_visit_mut!(visit_throw_mut, Throw); + define_visit_mut!(visit_try_mut, Try); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its /// private fields. -pub trait VisitWith { +pub trait VisitWith { /// Visit this node with the provided visitor. - fn visit_with<'a>(&'a self, visitor: &mut V) -> core::ops::ControlFlow + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> core::ops::ControlFlow where V: Visitor<'a>; /// Visit this node with the provided visitor mutably, allowing the visitor to modify private /// fields. - fn visit_with_mut<'a>(&'a mut self, visitor: &mut V) -> core::ops::ControlFlow + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> core::ops::ControlFlow where V: VisitorMut<'a>; } From 803ed95a71a4b4009cd5c76b45e3b0c39bd50341 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 17:14:21 +0100 Subject: [PATCH 08/34] expand for Function --- boa_engine/src/syntax/ast/function/mod.rs | 27 +++++++++++++++++++++++ boa_engine/src/syntax/ast/visitor.rs | 5 +++++ 2 files changed, 32 insertions(+) diff --git a/boa_engine/src/syntax/ast/function/mod.rs b/boa_engine/src/syntax/ast/function/mod.rs index 9eb6328a637..2e298b62788 100644 --- a/boa_engine/src/syntax/ast/function/mod.rs +++ b/boa_engine/src/syntax/ast/function/mod.rs @@ -33,10 +33,13 @@ pub use async_generator::AsyncGenerator; pub use class::{Class, ClassElement}; pub use generator::Generator; pub use parameters::{FormalParameter, FormalParameterList}; +use std::ops::ControlFlow; pub(crate) use parameters::FormalParameterListFlags; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{block_to_string, join_nodes, StatementList}; +use crate::try_break; use boa_interner::{Interner, ToIndentedString}; use super::expression::{Expression, Identifier}; @@ -165,6 +168,30 @@ pub(crate) fn has_direct_super(body: &StatementList, parameters: &FormalParamete false } +impl VisitWith for Function { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(ident) = &self.name { + try_break!(visitor.visit_identifier(ident)); + } + try_break!(visitor.visit_formal_parameter_list(&self.parameters)); + visitor.visit_statement_list(&self.body) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(ident) = &mut self.name { + try_break!(visitor.visit_identifier_mut(ident)); + } + try_break!(visitor.visit_formal_parameter_list_mut(&mut self.parameters)); + visitor.visit_statement_list_mut(&mut self.body) + } +} + #[cfg(test)] mod tests { diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index c0aa240ec61..d8cda200c32 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -15,6 +15,7 @@ macro_rules! try_break { } use crate::syntax::ast::declaration::*; +use crate::syntax::ast::expression::*; use crate::syntax::ast::function::*; use crate::syntax::ast::statement::*; use crate::syntax::ast::*; @@ -77,6 +78,8 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_labelled, Labelled); define_visit!(visit_throw, Throw); define_visit!(visit_try, Try); + define_visit!(visit_identifier, Identifier); + define_visit!(visit_formal_parameter_list, FormalParameterList); } /// Represents an AST visitor which can modify AST content. @@ -114,6 +117,8 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_labelled_mut, Labelled); define_visit_mut!(visit_throw_mut, Throw); define_visit_mut!(visit_try_mut, Try); + define_visit_mut!(visit_identifier_mut, Identifier); + define_visit_mut!(visit_formal_parameter_list_mut, FormalParameterList); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its From 350656d6418eed560b891b54a83283ac257a9967 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 17:16:00 +0100 Subject: [PATCH 09/34] expand other function types --- .../src/syntax/ast/function/async_function.rs | 27 +++++++++++++++++++ .../syntax/ast/function/async_generator.rs | 27 +++++++++++++++++++ .../src/syntax/ast/function/generator.rs | 27 +++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/boa_engine/src/syntax/ast/function/async_function.rs b/boa_engine/src/syntax/ast/function/async_function.rs index c399f9c1d44..24a75bceba3 100644 --- a/boa_engine/src/syntax/ast/function/async_function.rs +++ b/boa_engine/src/syntax/ast/function/async_function.rs @@ -1,10 +1,13 @@ //! Async Function Expression. +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{ expression::{Expression, Identifier}, join_nodes, Declaration, StatementList, }; +use crate::try_break; use boa_interner::{Interner, ToIndentedString}; +use std::ops::ControlFlow; use super::FormalParameterList; @@ -95,6 +98,30 @@ impl From for Declaration { } } +impl VisitWith for AsyncFunction { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(ident) = &self.name { + try_break!(visitor.visit_identifier(ident)); + } + try_break!(visitor.visit_formal_parameter_list(&self.parameters)); + visitor.visit_statement_list(&self.body) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(ident) = &mut self.name { + try_break!(visitor.visit_identifier_mut(ident)); + } + try_break!(visitor.visit_formal_parameter_list_mut(&mut self.parameters)); + visitor.visit_statement_list_mut(&mut self.body) + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/function/async_generator.rs b/boa_engine/src/syntax/ast/function/async_generator.rs index 8c246f03ee7..a24ab0e7c8b 100644 --- a/boa_engine/src/syntax/ast/function/async_generator.rs +++ b/boa_engine/src/syntax/ast/function/async_generator.rs @@ -1,10 +1,13 @@ //! Async Generator Expression +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{ block_to_string, expression::{Expression, Identifier}, join_nodes, Declaration, StatementList, }; +use crate::try_break; use boa_interner::{Interner, ToIndentedString}; +use std::ops::ControlFlow; use super::FormalParameterList; @@ -86,3 +89,27 @@ impl From for Declaration { Self::AsyncGenerator(f) } } + +impl VisitWith for AsyncGenerator { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(ident) = &self.name { + try_break!(visitor.visit_identifier(ident)); + } + try_break!(visitor.visit_formal_parameter_list(&self.parameters)); + visitor.visit_statement_list(&self.body) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(ident) = &mut self.name { + try_break!(visitor.visit_identifier_mut(ident)); + } + try_break!(visitor.visit_formal_parameter_list_mut(&mut self.parameters)); + visitor.visit_statement_list_mut(&mut self.body) + } +} diff --git a/boa_engine/src/syntax/ast/function/generator.rs b/boa_engine/src/syntax/ast/function/generator.rs index 3219d262fbc..1461c598dac 100644 --- a/boa_engine/src/syntax/ast/function/generator.rs +++ b/boa_engine/src/syntax/ast/function/generator.rs @@ -3,7 +3,10 @@ use crate::syntax::ast::{ expression::{Expression, Identifier}, join_nodes, Declaration, StatementList, }; +use std::ops::ControlFlow; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; +use crate::try_break; use boa_interner::{Interner, ToIndentedString}; use super::FormalParameterList; @@ -88,3 +91,27 @@ impl From for Declaration { Self::Generator(f) } } + +impl VisitWith for Generator { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(ident) = &self.name { + try_break!(visitor.visit_identifier(ident)); + } + try_break!(visitor.visit_formal_parameter_list(&self.parameters)); + visitor.visit_statement_list(&self.body) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(ident) = &mut self.name { + try_break!(visitor.visit_identifier_mut(ident)); + } + try_break!(visitor.visit_formal_parameter_list_mut(&mut self.parameters)); + visitor.visit_statement_list_mut(&mut self.body) + } +} From b0b7433ca469448bebd344c0ecad083c91ebfe87 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 17:22:16 +0100 Subject: [PATCH 10/34] expand class --- boa_engine/src/syntax/ast/function/class.rs | 43 +++++++++++++++++++++ boa_engine/src/syntax/ast/visitor.rs | 4 ++ 2 files changed, 47 insertions(+) diff --git a/boa_engine/src/syntax/ast/function/class.rs b/boa_engine/src/syntax/ast/function/class.rs index a9052778e33..9cfc0b7b688 100644 --- a/boa_engine/src/syntax/ast/function/class.rs +++ b/boa_engine/src/syntax/ast/function/class.rs @@ -1,5 +1,7 @@ use std::borrow::Cow; +use std::ops::ControlFlow; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::{ string::ToStringEscaped, syntax::ast::{ @@ -9,6 +11,7 @@ use crate::{ property::{MethodDefinition, PropertyName}, ContainsSymbol, Declaration, StatementList, StatementListItem, }, + try_break, }; use boa_interner::{Interner, Sym, ToIndentedString, ToInternedString}; @@ -446,6 +449,46 @@ impl ClassElement { } } +impl VisitWith for Class { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(ident) = &self.name { + try_break!(visitor.visit_identifier(ident)); + } + if let Some(expr) = &self.super_ref { + try_break!(visitor.visit_expression(expr)); + } + if let Some(func) = &self.constructor { + try_break!(visitor.visit_function(func)); + } + for elem in self.elements.iter() { + try_break!(visitor.visit_class_element(elem)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(ident) = &mut self.name { + try_break!(visitor.visit_identifier_mut(ident)); + } + if let Some(expr) = &mut self.super_ref { + try_break!(visitor.visit_expression_mut(expr)); + } + if let Some(func) = &mut self.constructor { + try_break!(visitor.visit_function_mut(func)); + } + for elem in self.elements.iter_mut() { + try_break!(visitor.visit_class_element_mut(elem)); + } + ControlFlow::Continue(()) + } +} + #[cfg(test)] mod tests { use crate::syntax::ast::test_formatting; diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index d8cda200c32..29937dec2e6 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -24,6 +24,7 @@ use crate::syntax::ast::*; macro_rules! define_visit { ($fn_name:ident, $type_name:ident) => { #[doc = concat!("Visits a `", stringify!($type_name), "` with this visitor")] + #[must_use] fn $fn_name(&mut self, node: &'ast $type_name) -> core::ops::ControlFlow { node.visit_with(self) } @@ -34,6 +35,7 @@ macro_rules! define_visit { macro_rules! define_visit_mut { ($fn_name:ident, $type_name:ident) => { #[doc = concat!("Visits a `", stringify!($type_name), "` with this visitor, mutably")] + #[must_use] fn $fn_name( &mut self, node: &'ast mut $type_name, @@ -80,6 +82,7 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_try, Try); define_visit!(visit_identifier, Identifier); define_visit!(visit_formal_parameter_list, FormalParameterList); + define_visit!(visit_class_element, ClassElement); } /// Represents an AST visitor which can modify AST content. @@ -119,6 +122,7 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_try_mut, Try); define_visit_mut!(visit_identifier_mut, Identifier); define_visit_mut!(visit_formal_parameter_list_mut, FormalParameterList); + define_visit_mut!(visit_class_element_mut, ClassElement); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its From fe4bbd519b5953f44b7bcf71bb2584424a19f644 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 17:52:56 +0100 Subject: [PATCH 11/34] expand variable --- .../src/syntax/ast/declaration/variable.rs | 95 +++++++++++++++++++ boa_engine/src/syntax/ast/visitor.rs | 9 ++ 2 files changed, 104 insertions(+) diff --git a/boa_engine/src/syntax/ast/declaration/variable.rs b/boa_engine/src/syntax/ast/declaration/variable.rs index 10fe4d4ad53..b888e70b92d 100644 --- a/boa_engine/src/syntax/ast/declaration/variable.rs +++ b/boa_engine/src/syntax/ast/declaration/variable.rs @@ -1,13 +1,16 @@ //! Variable related declarations. use std::convert::TryFrom; +use std::ops::ControlFlow; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{ expression::{Expression, Identifier}, join_nodes, pattern::Pattern, ContainsSymbol, Statement, }; +use crate::try_break; use boa_interner::{Interner, ToInternedString}; use super::Declaration; @@ -141,6 +144,30 @@ impl ToInternedString for LexicalDeclaration { } } +impl VisitWith for LexicalDeclaration { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + LexicalDeclaration::Const(vars) | LexicalDeclaration::Let(vars) => { + visitor.visit_variable_list(vars) + } + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + LexicalDeclaration::Const(vars) | LexicalDeclaration::Let(vars) => { + visitor.visit_variable_list_mut(vars) + } + } + } +} + /// List of variables in a variable declaration. #[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq)] @@ -171,6 +198,28 @@ impl ToInternedString for VariableList { } } +impl VisitWith for VariableList { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + for variable in self.list.iter() { + try_break!(visitor.visit_variable(variable)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + for variable in self.list.iter_mut() { + try_break!(visitor.visit_variable_mut(variable)); + } + ControlFlow::Continue(()) + } +} + /// The error returned by the [`VariableList::try_from`] function. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct TryFromVariableListError(()); @@ -288,6 +337,30 @@ impl Variable { } } +impl VisitWith for Variable { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_binding(&self.binding)); + if let Some(init) = &self.init { + try_break!(visitor.visit_expression(init)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_binding_mut(&mut self.binding)); + if let Some(init) = &mut self.init { + try_break!(visitor.visit_expression_mut(init)); + } + ControlFlow::Continue(()) + } +} + /// Binding represents either an individual binding or a binding pattern. /// /// More information: @@ -348,6 +421,28 @@ impl ToInternedString for Binding { } } +impl VisitWith for Binding { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + Binding::Identifier(id) => visitor.visit_identifier(id), + Binding::Pattern(pattern) => visitor.visit_pattern(pattern), + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + Binding::Identifier(id) => visitor.visit_identifier_mut(id), + Binding::Pattern(pattern) => visitor.visit_pattern_mut(pattern), + } + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 29937dec2e6..eabbbd54408 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -17,6 +17,7 @@ macro_rules! try_break { use crate::syntax::ast::declaration::*; use crate::syntax::ast::expression::*; use crate::syntax::ast::function::*; +use crate::syntax::ast::pattern::*; use crate::syntax::ast::statement::*; use crate::syntax::ast::*; @@ -83,6 +84,10 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_identifier, Identifier); define_visit!(visit_formal_parameter_list, FormalParameterList); define_visit!(visit_class_element, ClassElement); + define_visit!(visit_variable_list, VariableList); + define_visit!(visit_variable, Variable); + define_visit!(visit_binding, Binding); + define_visit!(visit_pattern, Pattern); } /// Represents an AST visitor which can modify AST content. @@ -123,6 +128,10 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_identifier_mut, Identifier); define_visit_mut!(visit_formal_parameter_list_mut, FormalParameterList); define_visit_mut!(visit_class_element_mut, ClassElement); + define_visit_mut!(visit_variable_list_mut, VariableList); + define_visit_mut!(visit_variable_mut, Variable); + define_visit_mut!(visit_binding_mut, Binding); + define_visit_mut!(visit_pattern_mut, Pattern); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its From 0b57f6b50514f924958213ab317a136361b87124 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 17:54:18 +0100 Subject: [PATCH 12/34] expand block --- boa_engine/src/syntax/ast/statement/block.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/boa_engine/src/syntax/ast/statement/block.rs b/boa_engine/src/syntax/ast/statement/block.rs index 5922326905a..f43b5908178 100644 --- a/boa_engine/src/syntax/ast/statement/block.rs +++ b/boa_engine/src/syntax/ast/statement/block.rs @@ -1,8 +1,10 @@ //! Block AST node. use super::Statement; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Identifier, ContainsSymbol, StatementList}; use boa_interner::{Interner, ToIndentedString}; +use std::ops::ControlFlow; /// A `block` statement (or compound statement in other languages) is used to group zero or /// more statements. @@ -80,6 +82,22 @@ impl From for Statement { } } +impl VisitWith for Block { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_statement_list(&self.statements) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_statement_list_mut(&mut self.statements) + } +} + #[cfg(test)] mod tests { #[test] From b2e730ea37b08801eb28c38288cda48079cb5dc3 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 17:55:49 +0100 Subject: [PATCH 13/34] expand vardeclaration --- .../src/syntax/ast/declaration/variable.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/boa_engine/src/syntax/ast/declaration/variable.rs b/boa_engine/src/syntax/ast/declaration/variable.rs index b888e70b92d..f31a60e7302 100644 --- a/boa_engine/src/syntax/ast/declaration/variable.rs +++ b/boa_engine/src/syntax/ast/declaration/variable.rs @@ -71,6 +71,22 @@ impl ToInternedString for VarDeclaration { } } +impl VisitWith for VarDeclaration { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_variable_list(&self.0) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_variable_list_mut(&mut self.0) + } +} + /// A **[lexical declaration]** defines variables that are scoped to the lexical environment of /// the variable declaration. /// From 4743d4562cc1eb1ffdf21873cfe2a3e5791359a1 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 18:09:38 +0100 Subject: [PATCH 14/34] expand expression --- boa_engine/src/syntax/ast/expression/mod.rs | 78 +++++++++++++++++++++ boa_engine/src/syntax/ast/visitor.rs | 39 +++++++++++ 2 files changed, 117 insertions(+) diff --git a/boa_engine/src/syntax/ast/expression/mod.rs b/boa_engine/src/syntax/ast/expression/mod.rs index 5e833abfd3b..8178c5fc3e4 100644 --- a/boa_engine/src/syntax/ast/expression/mod.rs +++ b/boa_engine/src/syntax/ast/expression/mod.rs @@ -10,6 +10,7 @@ //! [lhs]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#left-hand-side_expressions use boa_interner::{Interner, Sym, ToIndentedString, ToInternedString}; +use std::ops::ControlFlow; use self::{ access::PropertyAccess, @@ -32,6 +33,7 @@ mod spread; mod tagged_template; mod r#yield; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; pub use call::{Call, SuperCall}; pub use identifier::Identifier; pub use new::New; @@ -286,3 +288,79 @@ impl ToIndentedString for Expression { self.to_no_indent_string(interner, indentation) } } + +impl VisitWith for Expression { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + Expression::Identifier(id) => visitor.visit_identifier(id), + Expression::Literal(lit) => visitor.visit_literal(lit), + Expression::ArrayLiteral(arlit) => visitor.visit_array_literal(arlit), + Expression::ObjectLiteral(olit) => visitor.visit_object_literal(olit), + Expression::Spread(sp) => visitor.visit_spread(sp), + Expression::Function(f) => visitor.visit_function(f), + Expression::ArrowFunction(af) => visitor.visit_arrow_function(af), + Expression::Generator(g) => visitor.visit_generator(g), + Expression::AsyncFunction(af) => visitor.visit_async_function(af), + Expression::AsyncGenerator(ag) => visitor.visit_async_generator(ag), + Expression::Class(c) => visitor.visit_class(&**c), + Expression::TemplateLiteral(tlit) => visitor.visit_template_literal(tlit), + Expression::PropertyAccess(pa) => visitor.visit_property_access(pa), + Expression::New(n) => visitor.visit_new(n), + Expression::Call(c) => visitor.visit_call(c), + Expression::SuperCall(sc) => visitor.visit_super_call(sc), + Expression::Optional(opt) => visitor.visit_optional(opt), + Expression::TaggedTemplate(tt) => visitor.visit_tagged_template(tt), + Expression::Assign(a) => visitor.visit_assign(a), + Expression::Unary(u) => visitor.visit_unary(u), + Expression::Binary(b) => visitor.visit_binary(b), + Expression::Conditional(c) => visitor.visit_conditional(c), + Expression::Await(a) => visitor.visit_await(a), + Expression::Yield(y) => visitor.visit_yield(y), + Expression::FormalParameterList(fpl) => visitor.visit_formal_parameter_list(fpl), + Expression::This | Expression::NewTarget => { + // do nothing; can be handled as special case by visitor + ControlFlow::Continue(()) + } + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + Expression::Identifier(id) => visitor.visit_identifier_mut(id), + Expression::Literal(lit) => visitor.visit_literal_mut(lit), + Expression::ArrayLiteral(arlit) => visitor.visit_array_literal_mut(arlit), + Expression::ObjectLiteral(olit) => visitor.visit_object_literal_mut(olit), + Expression::Spread(sp) => visitor.visit_spread_mut(sp), + Expression::Function(f) => visitor.visit_function_mut(f), + Expression::ArrowFunction(af) => visitor.visit_arrow_function_mut(af), + Expression::Generator(g) => visitor.visit_generator_mut(g), + Expression::AsyncFunction(af) => visitor.visit_async_function_mut(af), + Expression::AsyncGenerator(ag) => visitor.visit_async_generator_mut(ag), + Expression::Class(c) => visitor.visit_class_mut(&mut **c), + Expression::TemplateLiteral(tlit) => visitor.visit_template_literal_mut(tlit), + Expression::PropertyAccess(pa) => visitor.visit_property_access_mut(pa), + Expression::New(n) => visitor.visit_new_mut(n), + Expression::Call(c) => visitor.visit_call_mut(c), + Expression::SuperCall(sc) => visitor.visit_super_call_mut(sc), + Expression::Optional(opt) => visitor.visit_optional_mut(opt), + Expression::TaggedTemplate(tt) => visitor.visit_tagged_template_mut(tt), + Expression::Assign(a) => visitor.visit_assign_mut(a), + Expression::Unary(u) => visitor.visit_unary_mut(u), + Expression::Binary(b) => visitor.visit_binary_mut(b), + Expression::Conditional(c) => visitor.visit_conditional_mut(c), + Expression::Await(a) => visitor.visit_await_mut(a), + Expression::Yield(y) => visitor.visit_yield_mut(y), + Expression::FormalParameterList(fpl) => visitor.visit_formal_parameter_list_mut(fpl), + Expression::This | Expression::NewTarget => { + // do nothing; can be handled as special case by visitor + ControlFlow::Continue(()) + } + } + } +} diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index eabbbd54408..3ee653e86f1 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -15,6 +15,9 @@ macro_rules! try_break { } use crate::syntax::ast::declaration::*; +use crate::syntax::ast::expression::access::*; +use crate::syntax::ast::expression::literal::*; +use crate::syntax::ast::expression::operator::*; use crate::syntax::ast::expression::*; use crate::syntax::ast::function::*; use crate::syntax::ast::pattern::*; @@ -88,6 +91,24 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_variable, Variable); define_visit!(visit_binding, Binding); define_visit!(visit_pattern, Pattern); + define_visit!(visit_literal, Literal); + define_visit!(visit_array_literal, ArrayLiteral); + define_visit!(visit_object_literal, ObjectLiteral); + define_visit!(visit_spread, Spread); + define_visit!(visit_arrow_function, ArrowFunction); + define_visit!(visit_template_literal, TemplateLiteral); + define_visit!(visit_property_access, PropertyAccess); + define_visit!(visit_new, New); + define_visit!(visit_call, Call); + define_visit!(visit_super_call, SuperCall); + define_visit!(visit_optional, Optional); + define_visit!(visit_tagged_template, TaggedTemplate); + define_visit!(visit_assign, Assign); + define_visit!(visit_unary, Unary); + define_visit!(visit_binary, Binary); + define_visit!(visit_conditional, Conditional); + define_visit!(visit_await, Await); + define_visit!(visit_yield, Yield); } /// Represents an AST visitor which can modify AST content. @@ -132,6 +153,24 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_variable_mut, Variable); define_visit_mut!(visit_binding_mut, Binding); define_visit_mut!(visit_pattern_mut, Pattern); + define_visit_mut!(visit_literal_mut, Literal); + define_visit_mut!(visit_array_literal_mut, ArrayLiteral); + define_visit_mut!(visit_object_literal_mut, ObjectLiteral); + define_visit_mut!(visit_spread_mut, Spread); + define_visit_mut!(visit_arrow_function_mut, ArrowFunction); + define_visit_mut!(visit_template_literal_mut, TemplateLiteral); + define_visit_mut!(visit_property_access_mut, PropertyAccess); + define_visit_mut!(visit_new_mut, New); + define_visit_mut!(visit_call_mut, Call); + define_visit_mut!(visit_super_call_mut, SuperCall); + define_visit_mut!(visit_optional_mut, Optional); + define_visit_mut!(visit_tagged_template_mut, TaggedTemplate); + define_visit_mut!(visit_assign_mut, Assign); + define_visit_mut!(visit_unary_mut, Unary); + define_visit_mut!(visit_binary_mut, Binary); + define_visit_mut!(visit_conditional_mut, Conditional); + define_visit_mut!(visit_await_mut, Await); + define_visit_mut!(visit_yield_mut, Yield); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its From 49e9d15b811a0fd4b00306adecca196e7eb11c62 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 18:30:54 +0100 Subject: [PATCH 15/34] loops --- boa_engine/src/syntax/ast/statement/if.rs | 29 +++++++++++++++ .../ast/statement/iteration/do_while_loop.rs | 21 +++++++++++ .../ast/statement/iteration/for_in_loop.rs | 23 ++++++++++++ .../ast/statement/iteration/for_loop.rs | 37 +++++++++++++++++++ .../ast/statement/iteration/for_of_loop.rs | 23 ++++++++++++ .../ast/statement/iteration/while_loop.rs | 21 +++++++++++ boa_engine/src/syntax/ast/visitor.rs | 5 +++ 7 files changed, 159 insertions(+) diff --git a/boa_engine/src/syntax/ast/statement/if.rs b/boa_engine/src/syntax/ast/statement/if.rs index a81dc8f53e4..01cf960c21b 100644 --- a/boa_engine/src/syntax/ast/statement/if.rs +++ b/boa_engine/src/syntax/ast/statement/if.rs @@ -1,7 +1,10 @@ //! If statement +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, statement::Statement, ContainsSymbol}; +use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; +use std::ops::ControlFlow; /// The `if` statement executes a statement if a specified condition is [`truthy`][truthy]. If /// the condition is [`falsy`][falsy], another statement can be executed. @@ -95,6 +98,32 @@ impl From for Statement { } } +impl VisitWith for If { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_expression(&self.condition)); + try_break!(visitor.visit_statement(&*self.body)); + if let Some(stmt) = &self.else_node { + try_break!(visitor.visit_statement(&**stmt)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_expression_mut(&mut self.condition)); + try_break!(visitor.visit_statement_mut(&mut *self.body)); + if let Some(stmt) = &mut self.else_node { + try_break!(visitor.visit_statement_mut(&mut **stmt)); + } + ControlFlow::Continue(()) + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs index 35ceca07a68..ca658fcac57 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs @@ -1,5 +1,8 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, statement::Statement, ContainsSymbol}; +use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; +use std::ops::ControlFlow; /// The `do...while` statement creates a loop that executes a specified statement until the /// test condition evaluates to false. @@ -67,3 +70,21 @@ impl From for Statement { Self::DoWhileLoop(do_while) } } + +impl VisitWith for DoWhileLoop { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_statement(&*self.body)); + visitor.visit_expression(&self.condition) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_statement_mut(&mut *self.body)); + visitor.visit_expression_mut(&mut self.condition) + } +} diff --git a/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs index f19fd95e956..b732f7d57e6 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs @@ -1,9 +1,12 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{ expression::Expression, statement::{iteration::IterableLoopInitializer, Statement}, ContainsSymbol, }; +use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; +use std::ops::ControlFlow; /// A `for...in` loop statement, as defined by the [spec]. /// @@ -83,3 +86,23 @@ impl From for Statement { Self::ForInLoop(for_in) } } + +impl VisitWith for ForInLoop { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_iterable_loop_initializer(&self.initializer)); + try_break!(visitor.visit_expression(&self.target)); + visitor.visit_statement(&*self.body) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_iterable_loop_initializer_mut(&mut self.initializer)); + try_break!(visitor.visit_expression_mut(&mut self.target)); + visitor.visit_statement_mut(&mut *self.body) + } +} diff --git a/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs index 8d7d242fc37..34c7b46f631 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs @@ -1,10 +1,13 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{ declaration::{LexicalDeclaration, VarDeclaration, Variable}, expression::Identifier, statement::Statement, ContainsSymbol, Expression, }; +use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; +use std::ops::ControlFlow; /// The `for` statement creates a loop that consists of three optional expressions. /// @@ -110,6 +113,40 @@ impl From for Statement { } } +impl VisitWith for ForLoop { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(fli) = &self.inner.init { + try_break!(visitor.visit_for_loop_initializer(fli)); + } + if let Some(expr) = &self.inner.condition { + try_break!(visitor.visit_expression(expr)); + } + if let Some(expr) = &self.inner.final_expr { + try_break!(visitor.visit_expression(expr)); + } + visitor.visit_statement(&self.inner.body) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(fli) = &mut self.inner.init { + try_break!(visitor.visit_for_loop_initializer_mut(fli)); + } + if let Some(expr) = &mut self.inner.condition { + try_break!(visitor.visit_expression_mut(expr)); + } + if let Some(expr) = &mut self.inner.final_expr { + try_break!(visitor.visit_expression_mut(expr)); + } + visitor.visit_statement_mut(&mut self.inner.body) + } +} + /// Inner structure to avoid multiple indirections in the heap. #[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq)] diff --git a/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs index 45d4a1c729d..77967d0d125 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs @@ -1,9 +1,12 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{ expression::Expression, statement::{iteration::IterableLoopInitializer, Statement}, ContainsSymbol, }; +use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; +use std::ops::ControlFlow; /// A `for...of` loop statement, as defined by the [spec]. /// @@ -97,3 +100,23 @@ impl From for Statement { Self::ForOfLoop(for_of) } } + +impl VisitWith for ForOfLoop { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_iterable_loop_initializer(&self.init)); + try_break!(visitor.visit_expression(&self.iterable)); + visitor.visit_statement(&*self.body) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_iterable_loop_initializer_mut(&mut self.init)); + try_break!(visitor.visit_expression_mut(&mut self.iterable)); + visitor.visit_statement_mut(&mut *self.body) + } +} diff --git a/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs index a59dd56c9b4..9e9a5e1c4bf 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs @@ -1,5 +1,8 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, statement::Statement, ContainsSymbol}; +use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; +use std::ops::ControlFlow; /// The `while` statement creates a loop that executes a specified statement as long as the /// test condition evaluates to `true`. @@ -68,3 +71,21 @@ impl From for Statement { Self::WhileLoop(while_loop) } } + +impl VisitWith for WhileLoop { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_expression(&self.condition)); + visitor.visit_statement(&*self.body) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_expression_mut(&mut self.condition)); + visitor.visit_statement_mut(&mut *self.body) + } +} diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 3ee653e86f1..030ff25885f 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -21,6 +21,7 @@ use crate::syntax::ast::expression::operator::*; use crate::syntax::ast::expression::*; use crate::syntax::ast::function::*; use crate::syntax::ast::pattern::*; +use crate::syntax::ast::statement::iteration::*; use crate::syntax::ast::statement::*; use crate::syntax::ast::*; @@ -109,6 +110,8 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_conditional, Conditional); define_visit!(visit_await, Await); define_visit!(visit_yield, Yield); + define_visit!(visit_for_loop_initializer, ForLoopInitializer); + define_visit!(visit_iterable_loop_initializer, IterableLoopInitializer); } /// Represents an AST visitor which can modify AST content. @@ -171,6 +174,8 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_conditional_mut, Conditional); define_visit_mut!(visit_await_mut, Await); define_visit_mut!(visit_yield_mut, Yield); + define_visit_mut!(visit_for_loop_initializer_mut, ForLoopInitializer); + define_visit_mut!(visit_iterable_loop_initializer_mut, IterableLoopInitializer); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its From 08899813c810831f62dfd4be132fca2db8a75d30 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 18:36:25 +0100 Subject: [PATCH 16/34] switch --- .../src/syntax/ast/statement/switch/mod.rs | 33 +++++++++++++++++++ boa_engine/src/syntax/ast/visitor.rs | 2 ++ 2 files changed, 35 insertions(+) diff --git a/boa_engine/src/syntax/ast/statement/switch/mod.rs b/boa_engine/src/syntax/ast/statement/switch/mod.rs index 4bda0249d5c..1695ae870f0 100644 --- a/boa_engine/src/syntax/ast/statement/switch/mod.rs +++ b/boa_engine/src/syntax/ast/statement/switch/mod.rs @@ -1,7 +1,10 @@ //! Switch node. //! +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, statement::Statement, StatementList}; +use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; +use std::ops::ControlFlow; use super::ContainsSymbol; @@ -155,3 +158,33 @@ impl From for Statement { Self::Switch(switch) } } + +impl VisitWith for Switch { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_expression(&self.val)); + for case in self.cases.iter() { + try_break!(visitor.visit_case(case)); + } + if let Some(sl) = &self.default { + try_break!(visitor.visit_statement_list(sl)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_expression_mut(&mut self.val)); + for case in self.cases.iter_mut() { + try_break!(visitor.visit_case_mut(case)); + } + if let Some(sl) = &mut self.default { + try_break!(visitor.visit_statement_list_mut(sl)); + } + ControlFlow::Continue(()) + } +} diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 030ff25885f..9b08b4d368c 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -112,6 +112,7 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_yield, Yield); define_visit!(visit_for_loop_initializer, ForLoopInitializer); define_visit!(visit_iterable_loop_initializer, IterableLoopInitializer); + define_visit!(visit_case, Case); } /// Represents an AST visitor which can modify AST content. @@ -176,6 +177,7 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_yield_mut, Yield); define_visit_mut!(visit_for_loop_initializer_mut, ForLoopInitializer); define_visit_mut!(visit_iterable_loop_initializer_mut, IterableLoopInitializer); + define_visit_mut!(visit_case_mut, Case); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its From 5c1b507559caa83e38fe994dd5eb101e5924b0f0 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 19:02:49 +0100 Subject: [PATCH 17/34] several additional expansions --- .../src/syntax/ast/expression/identifier.rs | 18 ++++++++++ .../syntax/ast/statement/iteration/break.rs | 27 +++++++++++++++ .../ast/statement/iteration/continue.rs | 27 +++++++++++++++ .../src/syntax/ast/statement/labelled.rs | 21 ++++++++++++ boa_engine/src/syntax/ast/statement/return.rs | 26 +++++++++++++++ boa_engine/src/syntax/ast/statement/throw.rs | 18 ++++++++++ .../src/syntax/ast/statement/try/mod.rs | 33 +++++++++++++++++++ boa_engine/src/syntax/ast/visitor.rs | 9 +++++ 8 files changed, 179 insertions(+) diff --git a/boa_engine/src/syntax/ast/expression/identifier.rs b/boa_engine/src/syntax/ast/expression/identifier.rs index 716af6a9628..d301b044e28 100644 --- a/boa_engine/src/syntax/ast/expression/identifier.rs +++ b/boa_engine/src/syntax/ast/expression/identifier.rs @@ -1,10 +1,12 @@ //! Local identifier Expression. +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::{ string::ToStringEscaped, syntax::{ast::Position, parser::ParseError}, }; use boa_interner::{Interner, Sym, ToInternedString}; +use std::ops::ControlFlow; use super::Expression; @@ -105,3 +107,19 @@ impl From for Expression { Self::Identifier(local) } } + +impl VisitWith for Identifier { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_sym(&self.ident) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_sym_mut(&mut self.ident) + } +} diff --git a/boa_engine/src/syntax/ast/statement/iteration/break.rs b/boa_engine/src/syntax/ast/statement/iteration/break.rs index 57dba8e8dee..6ffd75e9a6a 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/break.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/break.rs @@ -1,6 +1,9 @@ use boa_interner::{Interner, Sym, ToInternedString}; +use std::ops::ControlFlow; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::Statement; + /// The `break` statement terminates the current loop, switch, or label statement and transfers /// program control to the statement following the terminated statement. /// @@ -54,6 +57,30 @@ impl From for Statement { } } +impl VisitWith for Break { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(sym) = &self.label { + visitor.visit_sym(sym) + } else { + ControlFlow::Continue(()) + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(sym) = &mut self.label { + visitor.visit_sym_mut(sym) + } else { + ControlFlow::Continue(()) + } + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/statement/iteration/continue.rs b/boa_engine/src/syntax/ast/statement/iteration/continue.rs index 61dffe70027..1a0cf2c6d30 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/continue.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/continue.rs @@ -1,5 +1,8 @@ use crate::syntax::ast::statement::Statement; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use boa_interner::{Interner, Sym, ToInternedString}; +use std::ops::ControlFlow; + /// The `continue` statement terminates execution of the statements in the current iteration of /// the current or labeled loop, and continues execution of the loop with the next iteration. /// @@ -51,3 +54,27 @@ impl From for Statement { Self::Continue(cont) } } + +impl VisitWith for Continue { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(sym) = &self.label { + visitor.visit_sym(sym) + } else { + ControlFlow::Continue(()) + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(sym) = &mut self.label { + visitor.visit_sym_mut(sym) + } else { + ControlFlow::Continue(()) + } + } +} diff --git a/boa_engine/src/syntax/ast/statement/labelled.rs b/boa_engine/src/syntax/ast/statement/labelled.rs index d385e678728..13bb11c6898 100644 --- a/boa_engine/src/syntax/ast/statement/labelled.rs +++ b/boa_engine/src/syntax/ast/statement/labelled.rs @@ -1,6 +1,9 @@ use super::Statement; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{function::Function, ContainsSymbol}; +use crate::try_break; use boa_interner::{Interner, Sym, ToIndentedString, ToInternedString}; +use std::ops::ControlFlow; /// The set of Parse Nodes that can be preceded by a label, as defined by the [spec]. /// @@ -125,3 +128,21 @@ impl From for Statement { Self::Labelled(labelled) } } + +impl VisitWith for Labelled { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_labelled_item(&*self.item)); + visitor.visit_sym(&self.label) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_labelled_item_mut(&mut *self.item)); + visitor.visit_sym_mut(&mut self.label) + } +} diff --git a/boa_engine/src/syntax/ast/statement/return.rs b/boa_engine/src/syntax/ast/statement/return.rs index a8fbd04578f..fac1bd4a511 100644 --- a/boa_engine/src/syntax/ast/statement/return.rs +++ b/boa_engine/src/syntax/ast/statement/return.rs @@ -1,5 +1,7 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, statement::Statement, ContainsSymbol}; use boa_interner::{Interner, ToInternedString}; +use std::ops::ControlFlow; /// The `return` statement ends function execution and specifies a value to be returned to the /// function caller. @@ -60,6 +62,30 @@ impl ToInternedString for Return { } } +impl VisitWith for Return { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(expr) = &self.target { + visitor.visit_expression(expr) + } else { + ControlFlow::Continue(()) + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(expr) = &mut self.target { + visitor.visit_expression_mut(expr) + } else { + ControlFlow::Continue(()) + } + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/statement/throw.rs b/boa_engine/src/syntax/ast/statement/throw.rs index 552b0b4bd8e..607a49a8af6 100644 --- a/boa_engine/src/syntax/ast/statement/throw.rs +++ b/boa_engine/src/syntax/ast/statement/throw.rs @@ -1,5 +1,7 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{statement::Statement, ContainsSymbol, Expression}; use boa_interner::{Interner, ToInternedString}; +use std::ops::ControlFlow; /// The `throw` statement throws a user-defined exception. /// @@ -55,6 +57,22 @@ impl From for Statement { } } +impl VisitWith for Throw { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_expression(&self.target) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_expression_mut(&mut self.target) + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/statement/try/mod.rs b/boa_engine/src/syntax/ast/statement/try/mod.rs index 503f9c71df8..49c4b348a7d 100644 --- a/boa_engine/src/syntax/ast/statement/try/mod.rs +++ b/boa_engine/src/syntax/ast/statement/try/mod.rs @@ -1,11 +1,14 @@ //! Error handling statements +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{ declaration::Binding, statement::{Block, Statement}, StatementListItem, }; +use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; +use std::ops::ControlFlow; use super::ContainsSymbol; @@ -112,6 +115,36 @@ impl From for Statement { } } +impl VisitWith for Try { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_block(&self.block)); + if let Some(catch) = &self.catch { + try_break!(visitor.visit_catch(catch)); + } + if let Some(finally) = &self.finally { + try_break!(visitor.visit_finally(finally)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_block_mut(&mut self.block)); + if let Some(catch) = &mut self.catch { + try_break!(visitor.visit_catch_mut(catch)); + } + if let Some(finally) = &mut self.finally { + try_break!(visitor.visit_finally_mut(finally)); + } + ControlFlow::Continue(()) + } +} + /// Catch block. #[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq)] diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 9b08b4d368c..425ea1d7c2a 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -24,6 +24,7 @@ use crate::syntax::ast::pattern::*; use crate::syntax::ast::statement::iteration::*; use crate::syntax::ast::statement::*; use crate::syntax::ast::*; +use boa_interner::Sym; /// Creates the default visit function implementation for a particular type macro_rules! define_visit { @@ -113,6 +114,10 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_for_loop_initializer, ForLoopInitializer); define_visit!(visit_iterable_loop_initializer, IterableLoopInitializer); define_visit!(visit_case, Case); + define_visit!(visit_sym, Sym); + define_visit!(visit_labelled_item, LabelledItem); + define_visit!(visit_catch, Catch); + define_visit!(visit_finally, Finally); } /// Represents an AST visitor which can modify AST content. @@ -178,6 +183,10 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_for_loop_initializer_mut, ForLoopInitializer); define_visit_mut!(visit_iterable_loop_initializer_mut, IterableLoopInitializer); define_visit_mut!(visit_case_mut, Case); + define_visit_mut!(visit_sym_mut, Sym); + define_visit_mut!(visit_labelled_item_mut, LabelledItem); + define_visit_mut!(visit_catch_mut, Catch); + define_visit_mut!(visit_finally_mut, Finally); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its From de634a96594a6ee00f7ff73b324df7fa118779cb Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 19:06:49 +0100 Subject: [PATCH 18/34] formal parameter list --- .../src/syntax/ast/function/parameters.rs | 25 +++++++++++++++++++ boa_engine/src/syntax/ast/visitor.rs | 2 ++ 2 files changed, 27 insertions(+) diff --git a/boa_engine/src/syntax/ast/function/parameters.rs b/boa_engine/src/syntax/ast/function/parameters.rs index a2d6785c063..b18c0d7aa37 100644 --- a/boa_engine/src/syntax/ast/function/parameters.rs +++ b/boa_engine/src/syntax/ast/function/parameters.rs @@ -1,3 +1,4 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::{ ast::{ declaration::{Binding, Variable}, @@ -7,9 +8,11 @@ use crate::syntax::{ }, parser::ParseError, }; +use crate::try_break; use bitflags::bitflags; use boa_interner::{Interner, Sym, ToInternedString}; use rustc_hash::FxHashSet; +use std::ops::ControlFlow; /// A list of `FormalParameter`s that describes the parameters of a function, as defined by the [spec]. /// @@ -211,6 +214,28 @@ impl From for FormalParameterList { } } +impl VisitWith for FormalParameterList { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + for parameter in self.parameters.iter() { + try_break!(visitor.visit_formal_parameter(parameter)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + for parameter in self.parameters.iter_mut() { + try_break!(visitor.visit_formal_parameter_mut(parameter)); + } + ControlFlow::Continue(()) + } +} + bitflags! { /// Flags for a [`FormalParameterList`]. #[allow(clippy::unsafe_derive_deserialize)] diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 425ea1d7c2a..5bd6fdb9734 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -118,6 +118,7 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_labelled_item, LabelledItem); define_visit!(visit_catch, Catch); define_visit!(visit_finally, Finally); + define_visit!(visit_formal_parameter, FormalParameter); } /// Represents an AST visitor which can modify AST content. @@ -187,6 +188,7 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_labelled_item_mut, LabelledItem); define_visit_mut!(visit_catch_mut, Catch); define_visit_mut!(visit_finally_mut, Finally); + define_visit_mut!(visit_formal_parameter_mut, FormalParameter); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its From accf45356af122c368e64c0db35d06fcfa570d01 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 19:17:45 +0100 Subject: [PATCH 19/34] class element --- boa_engine/src/syntax/ast/function/class.rs | 126 ++++++++++++++++---- boa_engine/src/syntax/ast/visitor.rs | 5 + 2 files changed, 106 insertions(+), 25 deletions(-) diff --git a/boa_engine/src/syntax/ast/function/class.rs b/boa_engine/src/syntax/ast/function/class.rs index 9cfc0b7b688..4247f336b9c 100644 --- a/boa_engine/src/syntax/ast/function/class.rs +++ b/boa_engine/src/syntax/ast/function/class.rs @@ -380,6 +380,46 @@ impl From for Declaration { } } +impl VisitWith for Class { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(ident) = &self.name { + try_break!(visitor.visit_identifier(ident)); + } + if let Some(expr) = &self.super_ref { + try_break!(visitor.visit_expression(expr)); + } + if let Some(func) = &self.constructor { + try_break!(visitor.visit_function(func)); + } + for elem in self.elements.iter() { + try_break!(visitor.visit_class_element(elem)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(ident) = &mut self.name { + try_break!(visitor.visit_identifier_mut(ident)); + } + if let Some(expr) = &mut self.super_ref { + try_break!(visitor.visit_expression_mut(expr)); + } + if let Some(func) = &mut self.constructor { + try_break!(visitor.visit_function_mut(func)); + } + for elem in self.elements.iter_mut() { + try_break!(visitor.visit_class_element_mut(elem)); + } + ControlFlow::Continue(()) + } +} + /// An element that can be within a [`Class`], as defined by the [spec]. /// /// [spec]: https://tc39.es/ecma262/#prod-ClassElement @@ -449,43 +489,79 @@ impl ClassElement { } } -impl VisitWith for Class { +impl VisitWith for ClassElement { fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow where V: Visitor<'a>, { - if let Some(ident) = &self.name { - try_break!(visitor.visit_identifier(ident)); - } - if let Some(expr) = &self.super_ref { - try_break!(visitor.visit_expression(expr)); - } - if let Some(func) = &self.constructor { - try_break!(visitor.visit_function(func)); - } - for elem in self.elements.iter() { - try_break!(visitor.visit_class_element(elem)); + match self { + ClassElement::MethodDefinition(pn, md) + | ClassElement::StaticMethodDefinition(pn, md) => { + try_break!(visitor.visit_property_name(pn)); + visitor.visit_method_definition(md) + } + ClassElement::FieldDefinition(pn, maybe_expr) + | ClassElement::StaticFieldDefinition(pn, maybe_expr) => { + try_break!(visitor.visit_property_name(pn)); + if let Some(expr) = maybe_expr { + visitor.visit_expression(expr) + } else { + ControlFlow::Continue(()) + } + } + ClassElement::PrivateMethodDefinition(sym, md) + | ClassElement::PrivateStaticMethodDefinition(sym, md) => { + try_break!(visitor.visit_sym(sym)); + visitor.visit_method_definition(md) + } + ClassElement::PrivateFieldDefinition(sym, maybe_expr) + | ClassElement::PrivateStaticFieldDefinition(sym, maybe_expr) => { + try_break!(visitor.visit_sym(sym)); + if let Some(expr) = maybe_expr { + visitor.visit_expression(expr) + } else { + ControlFlow::Continue(()) + } + } + ClassElement::StaticBlock(sl) => visitor.visit_statement_list(sl), } - ControlFlow::Continue(()) } fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow where V: VisitorMut<'a>, { - if let Some(ident) = &mut self.name { - try_break!(visitor.visit_identifier_mut(ident)); - } - if let Some(expr) = &mut self.super_ref { - try_break!(visitor.visit_expression_mut(expr)); - } - if let Some(func) = &mut self.constructor { - try_break!(visitor.visit_function_mut(func)); - } - for elem in self.elements.iter_mut() { - try_break!(visitor.visit_class_element_mut(elem)); + match self { + ClassElement::MethodDefinition(pn, md) + | ClassElement::StaticMethodDefinition(pn, md) => { + try_break!(visitor.visit_property_name_mut(pn)); + visitor.visit_method_definition_mut(md) + } + ClassElement::FieldDefinition(pn, maybe_expr) + | ClassElement::StaticFieldDefinition(pn, maybe_expr) => { + try_break!(visitor.visit_property_name_mut(pn)); + if let Some(expr) = maybe_expr { + visitor.visit_expression_mut(expr) + } else { + ControlFlow::Continue(()) + } + } + ClassElement::PrivateMethodDefinition(sym, md) + | ClassElement::PrivateStaticMethodDefinition(sym, md) => { + try_break!(visitor.visit_sym_mut(sym)); + visitor.visit_method_definition_mut(md) + } + ClassElement::PrivateFieldDefinition(sym, maybe_expr) + | ClassElement::PrivateStaticFieldDefinition(sym, maybe_expr) => { + try_break!(visitor.visit_sym_mut(sym)); + if let Some(expr) = maybe_expr { + visitor.visit_expression_mut(expr) + } else { + ControlFlow::Continue(()) + } + } + ClassElement::StaticBlock(sl) => visitor.visit_statement_list_mut(sl), } - ControlFlow::Continue(()) } } diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 5bd6fdb9734..c29a7f1fc00 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -21,6 +21,7 @@ use crate::syntax::ast::expression::operator::*; use crate::syntax::ast::expression::*; use crate::syntax::ast::function::*; use crate::syntax::ast::pattern::*; +use crate::syntax::ast::property::*; use crate::syntax::ast::statement::iteration::*; use crate::syntax::ast::statement::*; use crate::syntax::ast::*; @@ -119,6 +120,8 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_catch, Catch); define_visit!(visit_finally, Finally); define_visit!(visit_formal_parameter, FormalParameter); + define_visit!(visit_property_name, PropertyName); + define_visit!(visit_method_definition, MethodDefinition); } /// Represents an AST visitor which can modify AST content. @@ -189,6 +192,8 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_catch_mut, Catch); define_visit_mut!(visit_finally_mut, Finally); define_visit_mut!(visit_formal_parameter_mut, FormalParameter); + define_visit_mut!(visit_property_name_mut, PropertyName); + define_visit_mut!(visit_method_definition_mut, MethodDefinition); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its From 5cccd2e24da071eb4a1cd62e5c21c869f7171cb2 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 19:52:09 +0100 Subject: [PATCH 20/34] lots of expansions, forgot to commit individually --- .../src/syntax/ast/expression/access.rs | 26 ++++++++++ boa_engine/src/syntax/ast/expression/call.rs | 49 +++++++++++++++++++ .../syntax/ast/expression/literal/array.rs | 25 ++++++++++ .../src/syntax/ast/expression/literal/mod.rs | 26 ++++++++++ .../ast/expression/literal/object/mod.rs | 25 ++++++++++ .../syntax/ast/expression/literal/template.rs | 25 ++++++++++ boa_engine/src/syntax/ast/expression/new.rs | 18 +++++++ .../ast/expression/operator/assign/mod.rs | 46 +++++++++++++++++ .../ast/expression/operator/binary/mod.rs | 22 +++++++++ .../ast/expression/operator/unary/mod.rs | 18 +++++++ .../src/syntax/ast/expression/optional.rs | 27 ++++++++++ .../src/syntax/ast/expression/spread.rs | 18 +++++++ .../syntax/ast/expression/tagged_template.rs | 39 +++++++++++++++ .../src/syntax/ast/function/arrow_function.rs | 27 ++++++++++ boa_engine/src/syntax/ast/pattern.rs | 24 +++++++++ boa_engine/src/syntax/ast/visitor.rs | 19 +++++++ 16 files changed, 434 insertions(+) diff --git a/boa_engine/src/syntax/ast/expression/access.rs b/boa_engine/src/syntax/ast/expression/access.rs index 75599775353..b88f03dc2ae 100644 --- a/boa_engine/src/syntax/ast/expression/access.rs +++ b/boa_engine/src/syntax/ast/expression/access.rs @@ -14,8 +14,10 @@ //! [spec]: https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-property-accessors //! [access]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, ContainsSymbol}; use boa_interner::{Interner, Sym, ToInternedString}; +use std::ops::ControlFlow; /// A property access field. /// @@ -111,6 +113,30 @@ impl From for Expression { } } +impl VisitWith for PropertyAccess { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + PropertyAccess::Simple(spa) => visitor.visit_simple_property_access(spa), + PropertyAccess::Private(ppa) => visitor.visit_private_property_access(ppa), + PropertyAccess::Super(supa) => visitor.visit_super_property_access(supa), + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + PropertyAccess::Simple(spa) => visitor.visit_simple_property_access_mut(spa), + PropertyAccess::Private(ppa) => visitor.visit_private_property_access_mut(ppa), + PropertyAccess::Super(supa) => visitor.visit_super_property_access_mut(supa), + } + } +} + /// A simple property access, where the target object is an [`Expression`]. #[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq)] diff --git a/boa_engine/src/syntax/ast/expression/call.rs b/boa_engine/src/syntax/ast/expression/call.rs index e003c475416..303ccfddb66 100644 --- a/boa_engine/src/syntax/ast/expression/call.rs +++ b/boa_engine/src/syntax/ast/expression/call.rs @@ -1,5 +1,8 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{join_nodes, ContainsSymbol}; +use crate::try_break; use boa_interner::{Interner, ToInternedString}; +use std::ops::ControlFlow; use super::Expression; @@ -75,6 +78,30 @@ impl From for Expression { } } +impl VisitWith for Call { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_expression(&self.function)); + for expr in self.args.iter() { + try_break!(visitor.visit_expression(expr)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_expression_mut(&mut self.function)); + for expr in self.args.iter_mut() { + try_break!(visitor.visit_expression_mut(expr)); + } + ControlFlow::Continue(()) + } +} + /// The `super` keyword is used to access and call functions on an object's parent. /// /// More information: @@ -128,6 +155,28 @@ impl From for Expression { } } +impl VisitWith for SuperCall { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + for expr in self.args.iter() { + try_break!(visitor.visit_expression(expr)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + for expr in self.args.iter_mut() { + try_break!(visitor.visit_expression_mut(expr)); + } + ControlFlow::Continue(()) + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/expression/literal/array.rs b/boa_engine/src/syntax/ast/expression/literal/array.rs index 76c3977f3db..3bf93fc9f02 100644 --- a/boa_engine/src/syntax/ast/expression/literal/array.rs +++ b/boa_engine/src/syntax/ast/expression/literal/array.rs @@ -1,7 +1,10 @@ //! Array declaration Expression. +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, ContainsSymbol}; +use crate::try_break; use boa_interner::{Interner, ToInternedString}; +use std::ops::ControlFlow; /// An array is an ordered collection of data (either primitive or object depending upon the /// language). @@ -105,6 +108,28 @@ impl From for Expression { } } +impl VisitWith for ArrayLiteral { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + for expr in self.arr.iter().flatten() { + try_break!(visitor.visit_expression(expr)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + for expr in self.arr.iter_mut().flatten() { + try_break!(visitor.visit_expression_mut(expr)); + } + ControlFlow::Continue(()) + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/expression/literal/mod.rs b/boa_engine/src/syntax/ast/expression/literal/mod.rs index a809b369e82..c20ef23a743 100644 --- a/boa_engine/src/syntax/ast/expression/literal/mod.rs +++ b/boa_engine/src/syntax/ast/expression/literal/mod.rs @@ -13,8 +13,10 @@ mod template; pub use array::ArrayLiteral; pub use object::ObjectLiteral; +use std::ops::ControlFlow; pub use template::{TemplateElement, TemplateLiteral}; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use boa_interner::{Interner, Sym, ToInternedString}; use num_bigint::BigInt; @@ -184,3 +186,27 @@ impl ToInternedString for Literal { } } } + +impl VisitWith for Literal { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Literal::String(sym) = self { + visitor.visit_sym(sym) + } else { + ControlFlow::Continue(()) + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Literal::String(sym) = self { + visitor.visit_sym_mut(sym) + } else { + ControlFlow::Continue(()) + } + } +} diff --git a/boa_engine/src/syntax/ast/expression/literal/object/mod.rs b/boa_engine/src/syntax/ast/expression/literal/object/mod.rs index a736129edb0..aef45a0e974 100644 --- a/boa_engine/src/syntax/ast/expression/literal/object/mod.rs +++ b/boa_engine/src/syntax/ast/expression/literal/object/mod.rs @@ -3,6 +3,7 @@ #[cfg(test)] mod tests; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{ block_to_string, expression::Expression, @@ -10,7 +11,9 @@ use crate::syntax::ast::{ property::{MethodDefinition, PropertyDefinition}, ContainsSymbol, }; +use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; +use std::ops::ControlFlow; /// Objects in JavaScript may be defined as an unordered collection of related data, of /// primitive or reference types, in the form of “key: value” pairs. @@ -153,3 +156,25 @@ impl From for Expression { Self::ObjectLiteral(obj) } } + +impl VisitWith for ObjectLiteral { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + for pd in self.properties.iter() { + try_break!(visitor.visit_property_definition(pd)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + for pd in self.properties.iter_mut() { + try_break!(visitor.visit_property_definition_mut(pd)); + } + ControlFlow::Continue(()) + } +} diff --git a/boa_engine/src/syntax/ast/expression/literal/template.rs b/boa_engine/src/syntax/ast/expression/literal/template.rs index 1f9dfac6489..258a6df17a9 100644 --- a/boa_engine/src/syntax/ast/expression/literal/template.rs +++ b/boa_engine/src/syntax/ast/expression/literal/template.rs @@ -1,12 +1,15 @@ //! Template literal Expression. use std::borrow::Cow; +use std::ops::ControlFlow; use boa_interner::{Interner, Sym, ToInternedString}; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::{ string::ToStringEscaped, syntax::ast::{expression::Expression, ContainsSymbol}, + try_break, }; /// Template literals are string literals allowing embedded expressions. @@ -96,6 +99,28 @@ impl ToInternedString for TemplateLiteral { } } +impl VisitWith for TemplateLiteral { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + for element in self.elements.iter() { + try_break!(visitor.visit_template_element(element)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + for element in self.elements.iter_mut() { + try_break!(visitor.visit_template_element_mut(element)); + } + ControlFlow::Continue(()) + } +} + #[cfg(test)] mod tests { use crate::exec; diff --git a/boa_engine/src/syntax/ast/expression/new.rs b/boa_engine/src/syntax/ast/expression/new.rs index 5dc2731c2ea..eb844e480e6 100644 --- a/boa_engine/src/syntax/ast/expression/new.rs +++ b/boa_engine/src/syntax/ast/expression/new.rs @@ -1,5 +1,7 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Call, ContainsSymbol}; use boa_interner::{Interner, ToInternedString}; +use std::ops::ControlFlow; use super::Expression; @@ -74,6 +76,22 @@ impl From for Expression { } } +impl VisitWith for New { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_call(&self.call) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_call_mut(&mut self.call) + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs b/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs index f3ed6b31cf7..93719a2056c 100644 --- a/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs +++ b/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs @@ -13,9 +13,11 @@ mod op; pub use op::*; +use std::ops::ControlFlow; use boa_interner::{Interner, Sym, ToInternedString}; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::{ ast::{ expression::{ @@ -32,6 +34,8 @@ use crate::syntax::{ }, parser::RESERVED_IDENTIFIERS_STRICT, }; +use crate::try_break; + /// An assignment operator expression. /// /// See the [module level documentation][self] for more information. @@ -109,6 +113,24 @@ impl From for Expression { } } +impl VisitWith for Assign { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_assign_target(&*self.lhs)); + visitor.visit_expression(&*self.rhs) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_assign_target_mut(&mut *self.lhs)); + visitor.visit_expression_mut(&mut *self.rhs) + } +} + /// The valid left-hand-side expressions of an assignment operator. Also called /// [`LeftHandSideExpression`][spec] in the spec. /// @@ -427,3 +449,27 @@ pub(crate) fn array_decl_to_declaration_pattern( } Some(ArrayPattern::new(bindings.into())) } + +impl VisitWith for AssignTarget { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + AssignTarget::Identifier(id) => visitor.visit_identifier(id), + AssignTarget::Access(pa) => visitor.visit_property_access(pa), + AssignTarget::Pattern(pat) => visitor.visit_pattern(pat), + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + AssignTarget::Identifier(id) => visitor.visit_identifier_mut(id), + AssignTarget::Access(pa) => visitor.visit_property_access_mut(pa), + AssignTarget::Pattern(pat) => visitor.visit_pattern_mut(pat), + } + } +} diff --git a/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs b/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs index 6b3ecca78a0..5e120cc1c75 100644 --- a/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs +++ b/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs @@ -15,11 +15,15 @@ //! [comma]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator mod op; + pub use op::*; +use std::ops::ControlFlow; use boa_interner::{Interner, ToInternedString}; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, ContainsSymbol}; +use crate::try_break; /// Binary operations require two operands, one before the operator and one after the operator. /// @@ -89,3 +93,21 @@ impl From for Expression { Self::Binary(op) } } + +impl VisitWith for Binary { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_expression(&*self.lhs)); + visitor.visit_expression(&*self.rhs) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_expression_mut(&mut *self.lhs)); + visitor.visit_expression_mut(&mut *self.rhs) + } +} diff --git a/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs b/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs index e5caf9869ee..ae6d6d927e7 100644 --- a/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs +++ b/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs @@ -14,9 +14,11 @@ mod op; pub use op::*; +use std::ops::ControlFlow; use boa_interner::{Interner, ToInternedString}; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, ContainsSymbol}; /// A unary expression is an operation with only one operand. @@ -87,3 +89,19 @@ impl From for Expression { Self::Unary(op) } } + +impl VisitWith for Unary { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_expression(&*self.target) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_expression_mut(&mut *self.target) + } +} diff --git a/boa_engine/src/syntax/ast/expression/optional.rs b/boa_engine/src/syntax/ast/expression/optional.rs index 11a56b1e8f6..e87c1ca6daa 100644 --- a/boa_engine/src/syntax/ast/expression/optional.rs +++ b/boa_engine/src/syntax/ast/expression/optional.rs @@ -1,6 +1,9 @@ use boa_interner::{Interner, Sym, ToInternedString}; +use std::ops::ControlFlow; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{join_nodes, ContainsSymbol}; +use crate::try_break; use super::{access::PropertyAccessField, Expression}; @@ -150,6 +153,30 @@ pub struct Optional { chain: Box<[OptionalOperation]>, } +impl VisitWith for Optional { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_expression(&self.target)); + for op in self.chain.iter() { + try_break!(visitor.visit_optional_operation(op)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_expression_mut(&mut self.target)); + for op in self.chain.iter_mut() { + try_break!(visitor.visit_optional_operation_mut(op)); + } + ControlFlow::Continue(()) + } +} + impl Optional { /// Creates a new `Optional` expression. #[inline] diff --git a/boa_engine/src/syntax/ast/expression/spread.rs b/boa_engine/src/syntax/ast/expression/spread.rs index cf6ece318cd..289dd5f70de 100644 --- a/boa_engine/src/syntax/ast/expression/spread.rs +++ b/boa_engine/src/syntax/ast/expression/spread.rs @@ -1,5 +1,7 @@ use boa_interner::{Interner, ToInternedString}; +use std::ops::ControlFlow; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::ContainsSymbol; use super::Expression; @@ -67,6 +69,22 @@ impl From for Expression { } } +impl VisitWith for Spread { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_expression(&*self.target) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_expression_mut(&mut *self.target) + } +} + #[cfg(test)] mod tests { use crate::exec; diff --git a/boa_engine/src/syntax/ast/expression/tagged_template.rs b/boa_engine/src/syntax/ast/expression/tagged_template.rs index d1400a6028a..6d182dcb4a8 100644 --- a/boa_engine/src/syntax/ast/expression/tagged_template.rs +++ b/boa_engine/src/syntax/ast/expression/tagged_template.rs @@ -1,6 +1,9 @@ use boa_interner::{Interner, Sym, ToInternedString}; +use std::ops::ControlFlow; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::ContainsSymbol; +use crate::try_break; use super::Expression; @@ -93,6 +96,42 @@ impl From for Expression { } } +impl VisitWith for TaggedTemplate { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_expression(&*self.tag)); + for raw in self.raws.iter() { + try_break!(visitor.visit_sym(raw)); + } + for cooked in self.cookeds.iter().flatten() { + try_break!(visitor.visit_sym(cooked)); + } + for expr in self.exprs.iter() { + try_break!(visitor.visit_expression(expr)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_expression_mut(&mut *self.tag)); + for raw in self.raws.iter_mut() { + try_break!(visitor.visit_sym_mut(raw)); + } + for cooked in self.cookeds.iter_mut().flatten() { + try_break!(visitor.visit_sym_mut(cooked)); + } + for expr in self.exprs.iter_mut() { + try_break!(visitor.visit_expression_mut(expr)); + } + ControlFlow::Continue(()) + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/function/arrow_function.rs b/boa_engine/src/syntax/ast/function/arrow_function.rs index 930262b2f9a..71ab69b238d 100644 --- a/boa_engine/src/syntax/ast/function/arrow_function.rs +++ b/boa_engine/src/syntax/ast/function/arrow_function.rs @@ -1,8 +1,11 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{ expression::{Expression, Identifier}, join_nodes, ContainsSymbol, StatementList, }; +use crate::try_break; use boa_interner::{Interner, ToIndentedString}; +use std::ops::ControlFlow; use super::FormalParameterList; @@ -105,6 +108,30 @@ impl From for Expression { } } +impl VisitWith for ArrowFunction { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(ident) = &self.name { + try_break!(visitor.visit_identifier(ident)); + } + try_break!(visitor.visit_formal_parameter_list(&self.parameters)); + visitor.visit_statement_list(&self.body) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(ident) = &mut self.name { + try_break!(visitor.visit_identifier_mut(ident)); + } + try_break!(visitor.visit_formal_parameter_list_mut(&mut self.parameters)); + visitor.visit_statement_list_mut(&mut self.body) + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/pattern.rs b/boa_engine/src/syntax/ast/pattern.rs index d70a513ffa6..e378a7a8cd8 100644 --- a/boa_engine/src/syntax/ast/pattern.rs +++ b/boa_engine/src/syntax/ast/pattern.rs @@ -22,7 +22,9 @@ //! [spec2]: https://tc39.es/ecma262/#prod-AssignmentPattern //! [destr]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use boa_interner::{Interner, Sym, ToInternedString}; +use std::ops::ControlFlow; use super::{ expression::{access::PropertyAccess, Identifier}, @@ -115,6 +117,28 @@ impl Pattern { } } +impl VisitWith for Pattern { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + Pattern::Object(op) => visitor.visit_object_pattern(op), + Pattern::Array(ap) => visitor.visit_array_pattern(ap), + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + Pattern::Object(op) => visitor.visit_object_pattern_mut(op), + Pattern::Array(ap) => visitor.visit_array_pattern_mut(ap), + } + } +} + /// An object binding or assignment pattern. /// /// Corresponds to the [`ObjectBindingPattern`][spec1] and the [`ObjectAssignmentPattern`][spec2] diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index c29a7f1fc00..385a9d2d2a6 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -17,6 +17,7 @@ macro_rules! try_break { use crate::syntax::ast::declaration::*; use crate::syntax::ast::expression::access::*; use crate::syntax::ast::expression::literal::*; +use crate::syntax::ast::expression::operator::assign::*; use crate::syntax::ast::expression::operator::*; use crate::syntax::ast::expression::*; use crate::syntax::ast::function::*; @@ -122,6 +123,15 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_formal_parameter, FormalParameter); define_visit!(visit_property_name, PropertyName); define_visit!(visit_method_definition, MethodDefinition); + define_visit!(visit_object_pattern, ObjectPattern); + define_visit!(visit_array_pattern, ArrayPattern); + define_visit!(visit_property_definition, PropertyDefinition); + define_visit!(visit_template_element, TemplateElement); + define_visit!(visit_simple_property_access, SimplePropertyAccess); + define_visit!(visit_private_property_access, PrivatePropertyAccess); + define_visit!(visit_super_property_access, SuperPropertyAccess); + define_visit!(visit_optional_operation, OptionalOperation); + define_visit!(visit_assign_target, AssignTarget); } /// Represents an AST visitor which can modify AST content. @@ -194,6 +204,15 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_formal_parameter_mut, FormalParameter); define_visit_mut!(visit_property_name_mut, PropertyName); define_visit_mut!(visit_method_definition_mut, MethodDefinition); + define_visit_mut!(visit_object_pattern_mut, ObjectPattern); + define_visit_mut!(visit_array_pattern_mut, ArrayPattern); + define_visit_mut!(visit_property_definition_mut, PropertyDefinition); + define_visit_mut!(visit_template_element_mut, TemplateElement); + define_visit_mut!(visit_simple_property_access_mut, SimplePropertyAccess); + define_visit_mut!(visit_private_property_access_mut, PrivatePropertyAccess); + define_visit_mut!(visit_super_property_access_mut, SuperPropertyAccess); + define_visit_mut!(visit_optional_operation_mut, OptionalOperation); + define_visit_mut!(visit_assign_target_mut, AssignTarget); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its From b47bb9486ba72b12748e03dc952a2c32b6d0aaa6 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 20:00:37 +0100 Subject: [PATCH 21/34] await, yield, loops --- boa_engine/src/syntax/ast/expression/await.rs | 18 +++++++++++ .../ast/expression/operator/conditional.rs | 23 +++++++++++++ boa_engine/src/syntax/ast/expression/yield.rs | 26 +++++++++++++++ .../ast/statement/iteration/for_loop.rs | 24 ++++++++++++++ .../src/syntax/ast/statement/iteration/mod.rs | 32 +++++++++++++++++++ 5 files changed, 123 insertions(+) diff --git a/boa_engine/src/syntax/ast/expression/await.rs b/boa_engine/src/syntax/ast/expression/await.rs index 035b84533fe..9aba70f5387 100644 --- a/boa_engine/src/syntax/ast/expression/await.rs +++ b/boa_engine/src/syntax/ast/expression/await.rs @@ -1,8 +1,10 @@ //! Await expression Expression. use crate::syntax::ast::ContainsSymbol; +use std::ops::ControlFlow; use super::Expression; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use boa_interner::{Interner, ToIndentedString, ToInternedString}; /// An await expression is used within an async function to pause execution and wait for a @@ -62,6 +64,22 @@ impl From for Expression { } } +impl VisitWith for Await { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_expression(&*self.target) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_expression_mut(&mut *self.target) + } +} + #[cfg(test)] mod tests { #[test] diff --git a/boa_engine/src/syntax/ast/expression/operator/conditional.rs b/boa_engine/src/syntax/ast/expression/operator/conditional.rs index 6233bd4f745..0795cf32482 100644 --- a/boa_engine/src/syntax/ast/expression/operator/conditional.rs +++ b/boa_engine/src/syntax/ast/expression/operator/conditional.rs @@ -1,5 +1,8 @@ +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, ContainsSymbol}; +use crate::try_break; use boa_interner::{Interner, ToInternedString}; +use std::ops::ControlFlow; /// The `conditional` (ternary) operation is the only JavaScript operation that takes three /// operands. @@ -85,3 +88,23 @@ impl From for Expression { Self::Conditional(cond_op) } } + +impl VisitWith for Conditional { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_expression(&*self.condition)); + try_break!(visitor.visit_expression(&*self.if_true)); + visitor.visit_expression(&*self.if_false) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_expression_mut(&mut *self.condition)); + try_break!(visitor.visit_expression_mut(&mut *self.if_true)); + visitor.visit_expression_mut(&mut *self.if_false) + } +} diff --git a/boa_engine/src/syntax/ast/expression/yield.rs b/boa_engine/src/syntax/ast/expression/yield.rs index 213ab133d12..b3ee6c31fb2 100644 --- a/boa_engine/src/syntax/ast/expression/yield.rs +++ b/boa_engine/src/syntax/ast/expression/yield.rs @@ -1,5 +1,7 @@ use boa_interner::{Interner, ToInternedString}; +use std::ops::ControlFlow; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::ContainsSymbol; use super::Expression; @@ -70,3 +72,27 @@ impl ToInternedString for Yield { } } } + +impl VisitWith for Yield { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(expr) = &self.target { + visitor.visit_expression(&**expr) + } else { + ControlFlow::Continue(()) + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(expr) = &mut self.target { + visitor.visit_expression_mut(&mut **expr) + } else { + ControlFlow::Continue(()) + } + } +} diff --git a/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs index 34c7b46f631..05d0b640e22 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs @@ -285,3 +285,27 @@ impl From for ForLoopInitializer { ForLoopInitializer::Var(list) } } + +impl VisitWith for ForLoopInitializer { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + ForLoopInitializer::Expression(expr) => visitor.visit_expression(expr), + ForLoopInitializer::Var(vd) => visitor.visit_var_declaration(vd), + ForLoopInitializer::Lexical(ld) => visitor.visit_lexical_declaration(ld), + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + ForLoopInitializer::Expression(expr) => visitor.visit_expression_mut(expr), + ForLoopInitializer::Var(vd) => visitor.visit_var_declaration_mut(vd), + ForLoopInitializer::Lexical(ld) => visitor.visit_lexical_declaration_mut(ld), + } + } +} diff --git a/boa_engine/src/syntax/ast/statement/iteration/mod.rs b/boa_engine/src/syntax/ast/statement/iteration/mod.rs index 54c4239ead5..a3cf4b2f6de 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/mod.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/mod.rs @@ -13,6 +13,7 @@ use crate::syntax::ast::{ expression::{access::PropertyAccess, Identifier}, pattern::Pattern, }; +use std::ops::ControlFlow; pub use self::{ do_while_loop::DoWhileLoop, @@ -23,6 +24,7 @@ pub use self::{ r#continue::Continue, while_loop::WhileLoop, }; +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use boa_interner::{Interner, Sym, ToInternedString}; use super::ContainsSymbol; @@ -107,3 +109,33 @@ impl ToInternedString for IterableLoopInitializer { format!("{pre} {}", binding.to_interned_string(interner)) } } + +impl VisitWith for IterableLoopInitializer { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + IterableLoopInitializer::Identifier(id) => visitor.visit_identifier(id), + IterableLoopInitializer::Access(pa) => visitor.visit_property_access(pa), + IterableLoopInitializer::Var(b) + | IterableLoopInitializer::Let(b) + | IterableLoopInitializer::Const(b) => visitor.visit_binding(b), + IterableLoopInitializer::Pattern(p) => visitor.visit_pattern(p), + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + IterableLoopInitializer::Identifier(id) => visitor.visit_identifier_mut(id), + IterableLoopInitializer::Access(pa) => visitor.visit_property_access_mut(pa), + IterableLoopInitializer::Var(b) + | IterableLoopInitializer::Let(b) + | IterableLoopInitializer::Const(b) => visitor.visit_binding_mut(b), + IterableLoopInitializer::Pattern(p) => visitor.visit_pattern_mut(p), + } + } +} From 942c38df2ef5ffdeb1b296f59740c82c15870762 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 20:10:28 +0100 Subject: [PATCH 22/34] several more expansions --- .../src/syntax/ast/function/parameters.rs | 16 ++++++++ boa_engine/src/syntax/ast/property.rs | 24 ++++++++++++ .../src/syntax/ast/statement/labelled.rs | 22 +++++++++++ .../src/syntax/ast/statement/switch/mod.rs | 18 +++++++++ .../src/syntax/ast/statement/try/mod.rs | 38 +++++++++++++++++++ boa_engine/src/syntax/ast/visitor.rs | 17 +++++++++ 6 files changed, 135 insertions(+) diff --git a/boa_engine/src/syntax/ast/function/parameters.rs b/boa_engine/src/syntax/ast/function/parameters.rs index b18c0d7aa37..b6424359bd7 100644 --- a/boa_engine/src/syntax/ast/function/parameters.rs +++ b/boa_engine/src/syntax/ast/function/parameters.rs @@ -342,3 +342,19 @@ impl ToInternedString for FormalParameter { buf } } + +impl VisitWith for FormalParameter { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_variable(&self.variable) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_variable_mut(&mut self.variable) + } +} diff --git a/boa_engine/src/syntax/ast/property.rs b/boa_engine/src/syntax/ast/property.rs index 69421877435..767e49e603e 100644 --- a/boa_engine/src/syntax/ast/property.rs +++ b/boa_engine/src/syntax/ast/property.rs @@ -1,6 +1,8 @@ //! Property definition related types, used in object literals and class definitions. +use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use boa_interner::{Interner, Sym, ToInternedString}; +use std::ops::ControlFlow; use super::{ expression::{literal::Literal, Identifier}, @@ -317,6 +319,28 @@ impl From for PropertyName { } } +impl VisitWith for PropertyName { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + PropertyName::Literal(sym) => visitor.visit_sym(sym), + PropertyName::Computed(expr) => visitor.visit_expression(expr), + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + PropertyName::Literal(sym) => visitor.visit_sym_mut(sym), + PropertyName::Computed(expr) => visitor.visit_expression_mut(expr), + } + } +} + /// `ClassElementName` can be either a property name or a private identifier. /// /// More information: diff --git a/boa_engine/src/syntax/ast/statement/labelled.rs b/boa_engine/src/syntax/ast/statement/labelled.rs index 13bb11c6898..bed1ae0328f 100644 --- a/boa_engine/src/syntax/ast/statement/labelled.rs +++ b/boa_engine/src/syntax/ast/statement/labelled.rs @@ -66,6 +66,28 @@ impl From for LabelledItem { } } +impl VisitWith for LabelledItem { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + LabelledItem::Function(f) => visitor.visit_function(f), + LabelledItem::Statement(s) => visitor.visit_statement(s), + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + LabelledItem::Function(f) => visitor.visit_function_mut(f), + LabelledItem::Statement(s) => visitor.visit_statement_mut(s), + } + } +} + /// Labelled statement nodes, as defined by the [spec]. /// /// The method [`Labelled::item`] doesn't return a [`Statement`] for compatibility reasons. diff --git a/boa_engine/src/syntax/ast/statement/switch/mod.rs b/boa_engine/src/syntax/ast/statement/switch/mod.rs index 1695ae870f0..92b82e50f32 100644 --- a/boa_engine/src/syntax/ast/statement/switch/mod.rs +++ b/boa_engine/src/syntax/ast/statement/switch/mod.rs @@ -61,6 +61,24 @@ impl Case { } } +impl VisitWith for Case { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_expression(&self.condition)); + visitor.visit_statement_list(&self.body) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_expression_mut(&mut self.condition)); + visitor.visit_statement_list_mut(&mut self.body) + } +} + /// The `switch` statement evaluates an expression, matching the expression's value to a case /// clause, and executes statements associated with that case, as well as statements in cases /// that follow the matching case. diff --git a/boa_engine/src/syntax/ast/statement/try/mod.rs b/boa_engine/src/syntax/ast/statement/try/mod.rs index 49c4b348a7d..1308ac6fa46 100644 --- a/boa_engine/src/syntax/ast/statement/try/mod.rs +++ b/boa_engine/src/syntax/ast/statement/try/mod.rs @@ -206,6 +206,28 @@ impl ToIndentedString for Catch { } } +impl VisitWith for Catch { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + if let Some(binding) = &self.parameter { + try_break!(visitor.visit_binding(binding)); + } + visitor.visit_block(&self.block) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + if let Some(binding) = &mut self.parameter { + try_break!(visitor.visit_binding_mut(binding)); + } + visitor.visit_block_mut(&mut self.block) + } +} + /// Finally block. #[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq)] @@ -254,3 +276,19 @@ impl From for Finally { Self { block } } } + +impl VisitWith for Finally { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_block(&self.block) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_block_mut(&mut self.block) + } +} diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 385a9d2d2a6..fbc8608993b 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -229,3 +229,20 @@ pub trait VisitWith { where V: VisitorMut<'a>; } + +// implementation for Sym as it is out-of-crate +impl VisitWith for Sym { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> core::ops::ControlFlow + where + V: Visitor<'a>, + { + core::ops::ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> core::ops::ControlFlow + where + V: VisitorMut<'a>, + { + core::ops::ControlFlow::Continue(()) + } +} From f3a40ef2fde5937c9d9ff96620eee7c42788d37f Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 20:11:13 +0100 Subject: [PATCH 23/34] add todo for formal parameter flag recompute --- boa_engine/src/syntax/ast/function/parameters.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/boa_engine/src/syntax/ast/function/parameters.rs b/boa_engine/src/syntax/ast/function/parameters.rs index b6424359bd7..6d3cc38c6de 100644 --- a/boa_engine/src/syntax/ast/function/parameters.rs +++ b/boa_engine/src/syntax/ast/function/parameters.rs @@ -232,6 +232,7 @@ impl VisitWith for FormalParameterList { for parameter in self.parameters.iter_mut() { try_break!(visitor.visit_formal_parameter_mut(parameter)); } + // TODO recompute flags ControlFlow::Continue(()) } } From 89b3d661507dbc893b3b64d2aaa9f1f77a04d48d Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 20:31:21 +0100 Subject: [PATCH 24/34] implement remaining, prep next pass --- .../src/syntax/ast/expression/access.rs | 53 +++++++++++++ .../syntax/ast/expression/literal/template.rs | 22 ++++++ .../src/syntax/ast/expression/optional.rs | 16 ++++ boa_engine/src/syntax/ast/pattern.rs | 45 +++++++++++ boa_engine/src/syntax/ast/property.rs | 77 +++++++++++++++++++ boa_engine/src/syntax/ast/visitor.rs | 8 ++ 6 files changed, 221 insertions(+) diff --git a/boa_engine/src/syntax/ast/expression/access.rs b/boa_engine/src/syntax/ast/expression/access.rs index b88f03dc2ae..a773e33f8e3 100644 --- a/boa_engine/src/syntax/ast/expression/access.rs +++ b/boa_engine/src/syntax/ast/expression/access.rs @@ -16,6 +16,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, ContainsSymbol}; +use crate::try_break; use boa_interner::{Interner, Sym, ToInternedString}; use std::ops::ControlFlow; @@ -201,6 +202,24 @@ impl From for PropertyAccess { } } +impl VisitWith for SimplePropertyAccess { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_expression(&*self.target)); + visitor.visit_property_access_field(&self.field) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_expression_mut(&mut *self.target)); + visitor.visit_property_access_field_mut(&mut self.field) + } +} + /// An access expression to a class object's [private fields][mdn]. /// /// Private property accesses differ slightly from plain property accesses, since the accessed @@ -269,6 +288,24 @@ impl From for PropertyAccess { } } +impl VisitWith for PrivatePropertyAccess { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + try_break!(visitor.visit_expression(&*self.target)); + visitor.visit_sym(&self.field) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + try_break!(visitor.visit_expression_mut(&mut *self.target)); + visitor.visit_sym_mut(&mut self.field) + } +} + /// A property access of an object's parent, as defined by the [spec]. /// /// A `SuperPropertyAccess` is much like a regular [`PropertyAccess`], but where its `target` object @@ -324,3 +361,19 @@ impl From for PropertyAccess { Self::Super(access) } } + +impl VisitWith for SuperPropertyAccess { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_property_access_field(&self.field) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_property_access_field_mut(&mut self.field) + } +} diff --git a/boa_engine/src/syntax/ast/expression/literal/template.rs b/boa_engine/src/syntax/ast/expression/literal/template.rs index 258a6df17a9..c69f39f67d0 100644 --- a/boa_engine/src/syntax/ast/expression/literal/template.rs +++ b/boa_engine/src/syntax/ast/expression/literal/template.rs @@ -121,6 +121,28 @@ impl VisitWith for TemplateLiteral { } } +impl VisitWith for TemplateElement { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + TemplateElement::String(sym) => visitor.visit_sym(sym), + TemplateElement::Expr(expr) => visitor.visit_expression(expr), + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + TemplateElement::String(sym) => visitor.visit_sym_mut(sym), + TemplateElement::Expr(expr) => visitor.visit_expression_mut(expr), + } + } +} + #[cfg(test)] mod tests { use crate::exec; diff --git a/boa_engine/src/syntax/ast/expression/optional.rs b/boa_engine/src/syntax/ast/expression/optional.rs index e87c1ca6daa..1a9056912ae 100644 --- a/boa_engine/src/syntax/ast/expression/optional.rs +++ b/boa_engine/src/syntax/ast/expression/optional.rs @@ -124,6 +124,22 @@ impl ToInternedString for OptionalOperation { } } +impl VisitWith for OptionalOperation { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + visitor.visit_optional_operation_kind(&self.kind) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + visitor.visit_optional_operation_kind_mut(&mut self.kind) + } +} + /// An optional chain expression, as defined by the [spec]. /// /// [Optional chaining][mdn] allows for short-circuiting property accesses and function calls, which diff --git a/boa_engine/src/syntax/ast/pattern.rs b/boa_engine/src/syntax/ast/pattern.rs index e378a7a8cd8..48efd41a071 100644 --- a/boa_engine/src/syntax/ast/pattern.rs +++ b/boa_engine/src/syntax/ast/pattern.rs @@ -23,6 +23,7 @@ //! [destr]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; +use crate::try_break; use boa_interner::{Interner, Sym, ToInternedString}; use std::ops::ControlFlow; @@ -221,6 +222,28 @@ impl ObjectPattern { } } +impl VisitWith for ObjectPattern { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + for elem in self.0.iter() { + try_break!(visitor.visit_object_pattern_element(elem)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + for elem in self.0.iter_mut() { + try_break!(visitor.visit_object_pattern_element_mut(elem)); + } + ControlFlow::Continue(()) + } +} + /// An array binding or assignment pattern. /// /// Corresponds to the [`ArrayBindingPattern`][spec1] and the [`ArrayAssignmentPattern`][spec2] @@ -292,6 +315,28 @@ impl ArrayPattern { } } +impl VisitWith for ArrayPattern { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + for elem in self.0.iter() { + try_break!(visitor.visit_array_pattern_element(elem)); + } + ControlFlow::Continue(()) + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + for elem in self.0.iter_mut() { + try_break!(visitor.visit_array_pattern_element_mut(elem)); + } + ControlFlow::Continue(()) + } +} + /// The different types of bindings that an [`ObjectPattern`] may contain. /// /// Corresponds to the [`BindingProperty`][spec1] and the [`AssignmentProperty`][spec2] nodes. diff --git a/boa_engine/src/syntax/ast/property.rs b/boa_engine/src/syntax/ast/property.rs index 767e49e603e..17d2467de8d 100644 --- a/boa_engine/src/syntax/ast/property.rs +++ b/boa_engine/src/syntax/ast/property.rs @@ -1,6 +1,7 @@ //! Property definition related types, used in object literals and class definitions. use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; +use crate::try_break; use boa_interner::{Interner, Sym, ToInternedString}; use std::ops::ControlFlow; @@ -115,6 +116,52 @@ impl PropertyDefinition { } } +impl VisitWith for PropertyDefinition { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + PropertyDefinition::IdentifierReference(id) => visitor.visit_identifier(id), + PropertyDefinition::Property(pn, expr) => { + try_break!(visitor.visit_property_name(pn)); + visitor.visit_expression(expr) + } + PropertyDefinition::MethodDefinition(pn, md) => { + try_break!(visitor.visit_property_name(pn)); + visitor.visit_method_definition(md) + } + PropertyDefinition::SpreadObject(expr) => visitor.visit_expression(expr), + PropertyDefinition::CoverInitializedName(id, expr) => { + try_break!(visitor.visit_identifier(id)); + visitor.visit_expression(expr) + } + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + PropertyDefinition::IdentifierReference(id) => visitor.visit_identifier_mut(id), + PropertyDefinition::Property(pn, expr) => { + try_break!(visitor.visit_property_name_mut(pn)); + visitor.visit_expression_mut(expr) + } + PropertyDefinition::MethodDefinition(pn, md) => { + try_break!(visitor.visit_property_name_mut(pn)); + visitor.visit_method_definition_mut(md) + } + PropertyDefinition::SpreadObject(expr) => visitor.visit_expression_mut(expr), + PropertyDefinition::CoverInitializedName(id, expr) => { + try_break!(visitor.visit_identifier_mut(id)); + visitor.visit_expression_mut(expr) + } + } + } +} + /// Method definition. /// /// Starting with ECMAScript 2015, a shorter syntax for method definitions on objects initializers is introduced. @@ -227,6 +274,36 @@ impl MethodDefinition { } } +impl VisitWith for MethodDefinition { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + MethodDefinition::Get(f) | MethodDefinition::Set(f) | MethodDefinition::Ordinary(f) => { + visitor.visit_function(f) + } + MethodDefinition::Generator(g) => visitor.visit_generator(g), + MethodDefinition::AsyncGenerator(ag) => visitor.visit_async_generator(ag), + MethodDefinition::Async(af) => visitor.visit_async_function(af), + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + MethodDefinition::Get(f) | MethodDefinition::Set(f) | MethodDefinition::Ordinary(f) => { + visitor.visit_function_mut(f) + } + MethodDefinition::Generator(g) => visitor.visit_generator_mut(g), + MethodDefinition::AsyncGenerator(ag) => visitor.visit_async_generator_mut(ag), + MethodDefinition::Async(af) => visitor.visit_async_function_mut(af), + } + } +} + /// `PropertyName` can be either a literal or computed. /// /// More information: diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index fbc8608993b..8cedbf6b479 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -132,6 +132,10 @@ pub trait Visitor<'ast>: Sized { define_visit!(visit_super_property_access, SuperPropertyAccess); define_visit!(visit_optional_operation, OptionalOperation); define_visit!(visit_assign_target, AssignTarget); + define_visit!(visit_object_pattern_element, ObjectPatternElement); + define_visit!(visit_array_pattern_element, ArrayPatternElement); + define_visit!(visit_property_access_field, PropertyAccessField); + define_visit!(visit_optional_operation_kind, OptionalOperationKind); } /// Represents an AST visitor which can modify AST content. @@ -213,6 +217,10 @@ pub trait VisitorMut<'ast>: Sized { define_visit_mut!(visit_super_property_access_mut, SuperPropertyAccess); define_visit_mut!(visit_optional_operation_mut, OptionalOperation); define_visit_mut!(visit_assign_target_mut, AssignTarget); + define_visit_mut!(visit_object_pattern_element_mut, ObjectPatternElement); + define_visit_mut!(visit_array_pattern_element_mut, ArrayPatternElement); + define_visit_mut!(visit_property_access_field_mut, PropertyAccessField); + define_visit_mut!(visit_optional_operation_kind_mut, OptionalOperationKind); } /// Denotes that a type may be visited, providing a method which allows a visitor to traverse its From 0e06f053529de86af9a19f923b3da5bc87303fd5 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 20:43:52 +0100 Subject: [PATCH 25/34] finish visitors --- .../src/syntax/ast/expression/access.rs | 22 ++ .../src/syntax/ast/expression/optional.rs | 38 +++ boa_engine/src/syntax/ast/pattern.rs | 218 ++++++++++++++++++ .../src/syntax/ast/statement_list/mod.rs | 5 +- boa_engine/src/syntax/ast/visitor.rs | 4 +- 5 files changed, 283 insertions(+), 4 deletions(-) diff --git a/boa_engine/src/syntax/ast/expression/access.rs b/boa_engine/src/syntax/ast/expression/access.rs index a773e33f8e3..6e799d79f71 100644 --- a/boa_engine/src/syntax/ast/expression/access.rs +++ b/boa_engine/src/syntax/ast/expression/access.rs @@ -62,6 +62,28 @@ impl From for PropertyAccessField { } } +impl VisitWith for PropertyAccessField { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + PropertyAccessField::Const(sym) => visitor.visit_sym(sym), + PropertyAccessField::Expr(expr) => visitor.visit_expression(&*expr), + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + PropertyAccessField::Const(sym) => visitor.visit_sym_mut(sym), + PropertyAccessField::Expr(expr) => visitor.visit_expression_mut(&mut *expr), + } + } +} + /// A property access expression. /// /// See the [module level documentation][self] for more information. diff --git a/boa_engine/src/syntax/ast/expression/optional.rs b/boa_engine/src/syntax/ast/expression/optional.rs index 1a9056912ae..b3d76f1a456 100644 --- a/boa_engine/src/syntax/ast/expression/optional.rs +++ b/boa_engine/src/syntax/ast/expression/optional.rs @@ -47,6 +47,44 @@ impl OptionalOperationKind { } } +impl VisitWith for OptionalOperationKind { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + OptionalOperationKind::SimplePropertyAccess { field } => { + visitor.visit_property_access_field(field) + } + OptionalOperationKind::PrivatePropertyAccess { field } => visitor.visit_sym(field), + OptionalOperationKind::Call { args } => { + for arg in args.iter() { + try_break!(visitor.visit_expression(arg)); + } + ControlFlow::Continue(()) + } + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + OptionalOperationKind::SimplePropertyAccess { field } => { + visitor.visit_property_access_field_mut(field) + } + OptionalOperationKind::PrivatePropertyAccess { field } => visitor.visit_sym_mut(field), + OptionalOperationKind::Call { args } => { + for arg in args.iter_mut() { + try_break!(visitor.visit_expression_mut(arg)); + } + ControlFlow::Continue(()) + } + } + } +} + /// Operation within an [`Optional`] chain. /// /// An operation within an `Optional` chain can be either shorted or non-shorted. A shorted operation diff --git a/boa_engine/src/syntax/ast/pattern.rs b/boa_engine/src/syntax/ast/pattern.rs index 48efd41a071..2a5a4885da3 100644 --- a/boa_engine/src/syntax/ast/pattern.rs +++ b/boa_engine/src/syntax/ast/pattern.rs @@ -610,6 +610,142 @@ impl ToInternedString for ObjectPatternElement { } } +impl VisitWith for ObjectPatternElement { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + ObjectPatternElement::SingleName { + name, + ident, + default_init, + } => { + try_break!(visitor.visit_property_name(name)); + try_break!(visitor.visit_identifier(ident)); + if let Some(expr) = default_init { + visitor.visit_expression(expr) + } else { + ControlFlow::Continue(()) + } + } + ObjectPatternElement::RestProperty { + ident, + excluded_keys, + } => { + try_break!(visitor.visit_identifier(ident)); + for key in excluded_keys { + try_break!(visitor.visit_identifier(key)); + } + ControlFlow::Continue(()) + } + ObjectPatternElement::AssignmentPropertyAccess { + name, + access, + default_init, + } => { + try_break!(visitor.visit_property_name(name)); + try_break!(visitor.visit_property_access(access)); + if let Some(expr) = default_init { + visitor.visit_expression(expr) + } else { + ControlFlow::Continue(()) + } + } + ObjectPatternElement::AssignmentRestPropertyAccess { + access, + excluded_keys, + } => { + try_break!(visitor.visit_property_access(access)); + for key in excluded_keys { + try_break!(visitor.visit_identifier(key)); + } + ControlFlow::Continue(()) + } + ObjectPatternElement::Pattern { + name, + pattern, + default_init, + } => { + try_break!(visitor.visit_property_name(name)); + try_break!(visitor.visit_pattern(pattern)); + if let Some(expr) = default_init { + visitor.visit_expression(expr) + } else { + ControlFlow::Continue(()) + } + } + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + ObjectPatternElement::SingleName { + name, + ident, + default_init, + } => { + try_break!(visitor.visit_property_name_mut(name)); + try_break!(visitor.visit_identifier_mut(ident)); + if let Some(expr) = default_init { + visitor.visit_expression_mut(expr) + } else { + ControlFlow::Continue(()) + } + } + ObjectPatternElement::RestProperty { + ident, + excluded_keys, + } => { + try_break!(visitor.visit_identifier_mut(ident)); + for key in excluded_keys { + try_break!(visitor.visit_identifier_mut(key)); + } + ControlFlow::Continue(()) + } + ObjectPatternElement::AssignmentPropertyAccess { + name, + access, + default_init, + } => { + try_break!(visitor.visit_property_name_mut(name)); + try_break!(visitor.visit_property_access_mut(access)); + if let Some(expr) = default_init { + visitor.visit_expression_mut(expr) + } else { + ControlFlow::Continue(()) + } + } + ObjectPatternElement::AssignmentRestPropertyAccess { + access, + excluded_keys, + } => { + try_break!(visitor.visit_property_access_mut(access)); + for key in excluded_keys { + try_break!(visitor.visit_identifier_mut(key)); + } + ControlFlow::Continue(()) + } + ObjectPatternElement::Pattern { + name, + pattern, + default_init, + } => { + try_break!(visitor.visit_property_name_mut(name)); + try_break!(visitor.visit_pattern_mut(pattern)); + if let Some(expr) = default_init { + visitor.visit_expression_mut(expr) + } else { + ControlFlow::Continue(()) + } + } + } + } +} + /// The different types of bindings that an array binding pattern may contain. /// /// Corresponds to the [`BindingElement`][spec1] and the [`AssignmentElement`][spec2] nodes. @@ -821,3 +957,85 @@ impl ToInternedString for ArrayPatternElement { } } } + +impl VisitWith for ArrayPatternElement { + fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow + where + V: Visitor<'a>, + { + match self { + ArrayPatternElement::SingleName { + ident, + default_init, + } => { + try_break!(visitor.visit_identifier(ident)); + if let Some(expr) = default_init { + visitor.visit_expression(expr) + } else { + ControlFlow::Continue(()) + } + } + ArrayPatternElement::PropertyAccess { access } + | ArrayPatternElement::PropertyAccessRest { access } => { + visitor.visit_property_access(access) + } + ArrayPatternElement::Pattern { + pattern, + default_init, + } => { + try_break!(visitor.visit_pattern(pattern)); + if let Some(expr) = default_init { + visitor.visit_expression(expr) + } else { + ControlFlow::Continue(()) + } + } + ArrayPatternElement::SingleNameRest { ident } => visitor.visit_identifier(ident), + ArrayPatternElement::PatternRest { pattern } => visitor.visit_pattern(pattern), + ArrayPatternElement::Elision => { + // special case to be handled by user + ControlFlow::Continue(()) + } + } + } + + fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow + where + V: VisitorMut<'a>, + { + match self { + ArrayPatternElement::SingleName { + ident, + default_init, + } => { + try_break!(visitor.visit_identifier_mut(ident)); + if let Some(expr) = default_init { + visitor.visit_expression_mut(expr) + } else { + ControlFlow::Continue(()) + } + } + ArrayPatternElement::PropertyAccess { access } + | ArrayPatternElement::PropertyAccessRest { access } => { + visitor.visit_property_access_mut(access) + } + ArrayPatternElement::Pattern { + pattern, + default_init, + } => { + try_break!(visitor.visit_pattern_mut(pattern)); + if let Some(expr) = default_init { + visitor.visit_expression_mut(expr) + } else { + ControlFlow::Continue(()) + } + } + ArrayPatternElement::SingleNameRest { ident } => visitor.visit_identifier_mut(ident), + ArrayPatternElement::PatternRest { pattern } => visitor.visit_pattern_mut(pattern), + ArrayPatternElement::Elision => { + // special case to be handled by user + ControlFlow::Continue(()) + } + } + } +} diff --git a/boa_engine/src/syntax/ast/statement_list/mod.rs b/boa_engine/src/syntax/ast/statement_list/mod.rs index 2e30e5fbb34..c43bc3bd8c9 100644 --- a/boa_engine/src/syntax/ast/statement_list/mod.rs +++ b/boa_engine/src/syntax/ast/statement_list/mod.rs @@ -3,6 +3,7 @@ use super::{declaration::Binding, Declaration}; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Identifier, statement::Statement, ContainsSymbol}; +use crate::try_break; use boa_interner::{Interner, ToIndentedString}; use core::ops::ControlFlow; use rustc_hash::FxHashSet; @@ -311,7 +312,7 @@ impl VisitWith for StatementList { V: Visitor<'a>, { for statement in self.statements.iter() { - visitor.visit_statement_list_item(statement); + try_break!(visitor.visit_statement_list_item(statement)); } ControlFlow::Continue(()) } @@ -321,7 +322,7 @@ impl VisitWith for StatementList { V: VisitorMut<'a>, { for statement in self.statements.iter_mut() { - visitor.visit_statement_list_item_mut(statement); + try_break!(visitor.visit_statement_list_item_mut(statement)); } ControlFlow::Continue(()) } diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 8cedbf6b479..4c2d0ef110d 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -240,14 +240,14 @@ pub trait VisitWith { // implementation for Sym as it is out-of-crate impl VisitWith for Sym { - fn visit_with<'a, V>(&'a self, visitor: &mut V) -> core::ops::ControlFlow + fn visit_with<'a, V>(&'a self, _visitor: &mut V) -> core::ops::ControlFlow where V: Visitor<'a>, { core::ops::ControlFlow::Continue(()) } - fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> core::ops::ControlFlow + fn visit_with_mut<'a, V>(&'a mut self, _visitor: &mut V) -> core::ops::ControlFlow where V: VisitorMut<'a>, { From 61ca13db02e98fb7ecf90a9efc3cc8b8d6307dd5 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 20:54:15 +0100 Subject: [PATCH 26/34] simplify visitor example --- Cargo.lock | 1 + boa_examples/Cargo.toml | 1 + boa_examples/src/bin/printer_visitor.rs | 64 ------------------------- boa_examples/src/bin/symbol_visitor.rs | 47 ++++++++++++++++++ 4 files changed, 49 insertions(+), 64 deletions(-) delete mode 100644 boa_examples/src/bin/printer_visitor.rs create mode 100644 boa_examples/src/bin/symbol_visitor.rs diff --git a/Cargo.lock b/Cargo.lock index 7514563f101..00c71dbf3c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,6 +119,7 @@ version = "0.16.0" dependencies = [ "boa_engine", "boa_gc", + "boa_interner", "gc", ] diff --git a/boa_examples/Cargo.toml b/boa_examples/Cargo.toml index cfdf7dcdbac..04dc03809df 100644 --- a/boa_examples/Cargo.toml +++ b/boa_examples/Cargo.toml @@ -13,5 +13,6 @@ rust-version.workspace = true [dependencies] boa_engine = { workspace = true, features = ["console"] } +boa_interner = { workspace = true } boa_gc.workspace = true gc = "0.4.1" diff --git a/boa_examples/src/bin/printer_visitor.rs b/boa_examples/src/bin/printer_visitor.rs deleted file mode 100644 index 4d6113e05d5..00000000000 --- a/boa_examples/src/bin/printer_visitor.rs +++ /dev/null @@ -1,64 +0,0 @@ -use boa_engine::syntax::ast::visitor::{VisitWith, Visitor}; -use boa_engine::syntax::ast::{Declaration, Statement, StatementList, StatementListItem}; -use boa_engine::syntax::Parser; -use boa_engine::Context; -use core::ops::ControlFlow; -use std::convert::Infallible; -use std::fs::File; -use std::io::BufReader; - -#[derive(Debug, Clone, Default)] -struct PrinterVisitor { - indent: String, -} - -impl<'ast> Visitor<'ast> for PrinterVisitor { - type BreakTy = Infallible; - - fn visit_statement_list(&mut self, node: &'ast StatementList) -> ControlFlow { - println!( - "{}StatementList (strict: {}) {{", - self.indent, - node.strict() - ); - self.indent.push(' '); - let res = node.visit_with(self); - self.indent.pop(); - println!("{}}}", self.indent); - res - } - - fn visit_statement_list_item( - &mut self, - node: &'ast StatementListItem, - ) -> ControlFlow { - print!("{}StatementListItem: ", self.indent); - self.indent.push(' '); - let res = node.visit_with(self); - self.indent.pop(); - res - } - - fn visit_statement(&mut self, node: &'ast Statement) -> ControlFlow { - println!("Statement: {:?}", node); - ControlFlow::Continue(()) - } - - fn visit_declaration(&mut self, node: &'ast Declaration) -> ControlFlow { - println!("Declaration: {:?}", node); - ControlFlow::Continue(()) - } -} - -fn main() { - let mut parser = Parser::new(BufReader::new( - File::open("boa_examples/scripts/calctest.js").unwrap(), - )); - let mut ctx = Context::default(); - - let statements = parser.parse_all(&mut ctx).unwrap(); - - let mut visitor = PrinterVisitor::default(); - - visitor.visit_statement_list(&statements); -} diff --git a/boa_examples/src/bin/symbol_visitor.rs b/boa_examples/src/bin/symbol_visitor.rs new file mode 100644 index 00000000000..033f1008784 --- /dev/null +++ b/boa_examples/src/bin/symbol_visitor.rs @@ -0,0 +1,47 @@ +use boa_engine::syntax::ast::visitor::Visitor; +use boa_engine::syntax::Parser; +use boa_engine::Context; +use boa_interner::Sym; +use core::ops::ControlFlow; +use std::collections::HashSet; +use std::convert::Infallible; +use std::fs::File; +use std::io::BufReader; + +#[derive(Debug, Clone, Default)] +struct SymbolVisitor { + observed: HashSet, +} + +impl<'ast> Visitor<'ast> for SymbolVisitor { + type BreakTy = Infallible; + + fn visit_sym(&mut self, node: &'ast Sym) -> ControlFlow { + self.observed.insert(*node); + ControlFlow::Continue(()) + } +} + +fn main() { + let mut parser = Parser::new(BufReader::new( + File::open("boa_examples/scripts/calc.js").unwrap(), + )); + let mut ctx = Context::default(); + + let statements = parser.parse_all(&mut ctx).unwrap(); + + let mut visitor = SymbolVisitor::default(); + + assert!(matches!( + visitor.visit_statement_list(&statements), + ControlFlow::Continue(_) + )); + + println!( + "Observed {} unique strings/symbols:", + visitor.observed.len() + ); + for sym in visitor.observed { + println!(" - {}", ctx.interner().resolve(sym).unwrap()); + } +} From dc9aa74e2c87ec2e49265830ccb2e243b12de37a Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 21:20:54 +0100 Subject: [PATCH 27/34] Add VisitorMut example --- boa_examples/src/bin/commuter_visitor.rs | 83 ++++++++++++++++++++++++ boa_examples/src/bin/symbol_visitor.rs | 4 ++ 2 files changed, 87 insertions(+) create mode 100644 boa_examples/src/bin/commuter_visitor.rs diff --git a/boa_examples/src/bin/commuter_visitor.rs b/boa_examples/src/bin/commuter_visitor.rs new file mode 100644 index 00000000000..814b4282a34 --- /dev/null +++ b/boa_examples/src/bin/commuter_visitor.rs @@ -0,0 +1,83 @@ +// This example demonstrates how to use visitors to modify an AST. Namely, the visitors shown here +// are used to swap the operands of commutable arithmetic operations. For an example which simply +// inspects the AST without modifying it, see symbol_visitor.rs. + +use boa_engine::syntax::ast::expression::operator::binary::{ArithmeticOp, BinaryOp}; +use boa_engine::syntax::ast::expression::operator::Binary; +use boa_engine::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; +use boa_engine::syntax::ast::Expression; +use boa_engine::syntax::Parser; +use boa_engine::Context; +use boa_interner::ToInternedString; +use std::convert::Infallible; +use std::fs::File; +use std::io::BufReader; +use std::marker::PhantomData; +use std::ops::ControlFlow; +use std::os::linux::raw::stat; + +/// Visitor which, when applied to a binary expression, will swap the operands. Use in other +/// circumstances is undefined. +#[derive(Default)] +struct OpExchanger<'ast> { + lhs: Option<&'ast mut Expression>, +} + +impl<'ast> VisitorMut<'ast> for OpExchanger<'ast> { + type BreakTy = (); + + fn visit_expression_mut(&mut self, node: &'ast mut Expression) -> ControlFlow { + if let Some(lhs) = self.lhs.take() { + core::mem::swap(lhs, node); + ControlFlow::Break(()) + } else { + self.lhs = Some(node); + // we do not traverse into the expression; we are only to be used with a binary op + ControlFlow::Continue(()) + } + } +} + +/// Visitor which walks the AST and swaps the operands of commutable arithmetic binary expressions. +#[derive(Default)] +struct CommutorVisitor {} + +impl<'ast> VisitorMut<'ast> for CommutorVisitor { + type BreakTy = Infallible; + + fn visit_binary_mut(&mut self, node: &'ast mut Binary) -> ControlFlow { + match node.op() { + BinaryOp::Arithmetic(op) => { + match op { + ArithmeticOp::Add | ArithmeticOp::Mul => { + // set up the exchanger and swap lhs and rhs + let mut exchanger = OpExchanger::default(); + exchanger.visit_binary_mut(node); + } + _ => {} + } + } + _ => {} + } + // traverse further in; there may nested binary operations + node.visit_with_mut(self) + } +} + +fn main() { + let mut parser = Parser::new(BufReader::new( + File::open("boa_examples/scripts/calc.js").unwrap(), + )); + let mut ctx = Context::default(); + + let mut statements = parser.parse_all(&mut ctx).unwrap(); + + let mut visitor = CommutorVisitor::default(); + + assert!(matches!( + visitor.visit_statement_list_mut(&mut statements), + ControlFlow::Continue(_) + )); + + println!("{}", statements.to_interned_string(ctx.interner())); +} diff --git a/boa_examples/src/bin/symbol_visitor.rs b/boa_examples/src/bin/symbol_visitor.rs index 033f1008784..d1cd169846d 100644 --- a/boa_examples/src/bin/symbol_visitor.rs +++ b/boa_examples/src/bin/symbol_visitor.rs @@ -1,3 +1,7 @@ +// This example demonstrates how to use a visitor to perform simple operations over the Javascript +// AST, namely: finding all the `Sym`s present in a script. See commuter_visitor.rs for an example +// which mutates the AST. + use boa_engine::syntax::ast::visitor::Visitor; use boa_engine::syntax::Parser; use boa_engine::Context; From 1dc765778397c60af11e385ceab2b03b03dbcbb5 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 21:21:49 +0100 Subject: [PATCH 28/34] simplify Cargo.toml --- boa_examples/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa_examples/Cargo.toml b/boa_examples/Cargo.toml index 04dc03809df..daf754f80bb 100644 --- a/boa_examples/Cargo.toml +++ b/boa_examples/Cargo.toml @@ -13,6 +13,6 @@ rust-version.workspace = true [dependencies] boa_engine = { workspace = true, features = ["console"] } -boa_interner = { workspace = true } +boa_interner.workspace = true boa_gc.workspace = true gc = "0.4.1" From 0953cfc60ca46beb08a15d54a65b42d2356c894e Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 21:25:59 +0100 Subject: [PATCH 29/34] cleanup examples --- boa_examples/src/bin/commuter_visitor.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/boa_examples/src/bin/commuter_visitor.rs b/boa_examples/src/bin/commuter_visitor.rs index 814b4282a34..65de6848ffe 100644 --- a/boa_examples/src/bin/commuter_visitor.rs +++ b/boa_examples/src/bin/commuter_visitor.rs @@ -4,7 +4,7 @@ use boa_engine::syntax::ast::expression::operator::binary::{ArithmeticOp, BinaryOp}; use boa_engine::syntax::ast::expression::operator::Binary; -use boa_engine::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; +use boa_engine::syntax::ast::visitor::{VisitWith, VisitorMut}; use boa_engine::syntax::ast::Expression; use boa_engine::syntax::Parser; use boa_engine::Context; @@ -12,9 +12,7 @@ use boa_interner::ToInternedString; use std::convert::Infallible; use std::fs::File; use std::io::BufReader; -use std::marker::PhantomData; use std::ops::ControlFlow; -use std::os::linux::raw::stat; /// Visitor which, when applied to a binary expression, will swap the operands. Use in other /// circumstances is undefined. @@ -52,7 +50,10 @@ impl<'ast> VisitorMut<'ast> for CommutorVisitor { ArithmeticOp::Add | ArithmeticOp::Mul => { // set up the exchanger and swap lhs and rhs let mut exchanger = OpExchanger::default(); - exchanger.visit_binary_mut(node); + assert!(matches!( + exchanger.visit_binary_mut(node), + ControlFlow::Break(_) + )); } _ => {} } From c1ce837d8abcd167f1aeeafd8bae9f5e2809781e Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 22:10:34 +0100 Subject: [PATCH 30/34] apply clippy fixes --- .../src/syntax/ast/expression/access.rs | 10 ++++---- boa_engine/src/syntax/ast/expression/await.rs | 4 ++-- boa_engine/src/syntax/ast/expression/mod.rs | 4 ++-- .../ast/expression/operator/assign/mod.rs | 8 +++---- .../ast/expression/operator/binary/mod.rs | 8 +++---- .../ast/expression/operator/conditional.rs | 12 +++++----- .../ast/expression/operator/unary/mod.rs | 4 ++-- .../src/syntax/ast/expression/spread.rs | 4 ++-- .../syntax/ast/expression/tagged_template.rs | 4 ++-- boa_engine/src/syntax/ast/expression/yield.rs | 4 ++-- boa_engine/src/syntax/ast/function/class.rs | 4 ++-- boa_engine/src/syntax/ast/statement/if.rs | 8 +++---- .../ast/statement/iteration/do_while_loop.rs | 4 ++-- .../ast/statement/iteration/for_in_loop.rs | 4 ++-- .../ast/statement/iteration/for_of_loop.rs | 4 ++-- .../ast/statement/iteration/while_loop.rs | 4 ++-- .../src/syntax/ast/statement/labelled.rs | 4 ++-- boa_engine/src/syntax/ast/visitor.rs | 24 +++++++++---------- 18 files changed, 59 insertions(+), 59 deletions(-) diff --git a/boa_engine/src/syntax/ast/expression/access.rs b/boa_engine/src/syntax/ast/expression/access.rs index 6e799d79f71..5c9b972906b 100644 --- a/boa_engine/src/syntax/ast/expression/access.rs +++ b/boa_engine/src/syntax/ast/expression/access.rs @@ -69,7 +69,7 @@ impl VisitWith for PropertyAccessField { { match self { PropertyAccessField::Const(sym) => visitor.visit_sym(sym), - PropertyAccessField::Expr(expr) => visitor.visit_expression(&*expr), + PropertyAccessField::Expr(expr) => visitor.visit_expression(expr), } } @@ -229,7 +229,7 @@ impl VisitWith for SimplePropertyAccess { where V: Visitor<'a>, { - try_break!(visitor.visit_expression(&*self.target)); + try_break!(visitor.visit_expression(&self.target)); visitor.visit_property_access_field(&self.field) } @@ -237,7 +237,7 @@ impl VisitWith for SimplePropertyAccess { where V: VisitorMut<'a>, { - try_break!(visitor.visit_expression_mut(&mut *self.target)); + try_break!(visitor.visit_expression_mut(&mut self.target)); visitor.visit_property_access_field_mut(&mut self.field) } } @@ -315,7 +315,7 @@ impl VisitWith for PrivatePropertyAccess { where V: Visitor<'a>, { - try_break!(visitor.visit_expression(&*self.target)); + try_break!(visitor.visit_expression(&self.target)); visitor.visit_sym(&self.field) } @@ -323,7 +323,7 @@ impl VisitWith for PrivatePropertyAccess { where V: VisitorMut<'a>, { - try_break!(visitor.visit_expression_mut(&mut *self.target)); + try_break!(visitor.visit_expression_mut(&mut self.target)); visitor.visit_sym_mut(&mut self.field) } } diff --git a/boa_engine/src/syntax/ast/expression/await.rs b/boa_engine/src/syntax/ast/expression/await.rs index 9aba70f5387..de58935a99b 100644 --- a/boa_engine/src/syntax/ast/expression/await.rs +++ b/boa_engine/src/syntax/ast/expression/await.rs @@ -69,14 +69,14 @@ impl VisitWith for Await { where V: Visitor<'a>, { - visitor.visit_expression(&*self.target) + visitor.visit_expression(&self.target) } fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow where V: VisitorMut<'a>, { - visitor.visit_expression_mut(&mut *self.target) + visitor.visit_expression_mut(&mut self.target) } } diff --git a/boa_engine/src/syntax/ast/expression/mod.rs b/boa_engine/src/syntax/ast/expression/mod.rs index 8178c5fc3e4..c573af8a33e 100644 --- a/boa_engine/src/syntax/ast/expression/mod.rs +++ b/boa_engine/src/syntax/ast/expression/mod.rs @@ -305,7 +305,7 @@ impl VisitWith for Expression { Expression::Generator(g) => visitor.visit_generator(g), Expression::AsyncFunction(af) => visitor.visit_async_function(af), Expression::AsyncGenerator(ag) => visitor.visit_async_generator(ag), - Expression::Class(c) => visitor.visit_class(&**c), + Expression::Class(c) => visitor.visit_class(c), Expression::TemplateLiteral(tlit) => visitor.visit_template_literal(tlit), Expression::PropertyAccess(pa) => visitor.visit_property_access(pa), Expression::New(n) => visitor.visit_new(n), @@ -342,7 +342,7 @@ impl VisitWith for Expression { Expression::Generator(g) => visitor.visit_generator_mut(g), Expression::AsyncFunction(af) => visitor.visit_async_function_mut(af), Expression::AsyncGenerator(ag) => visitor.visit_async_generator_mut(ag), - Expression::Class(c) => visitor.visit_class_mut(&mut **c), + Expression::Class(c) => visitor.visit_class_mut(c), Expression::TemplateLiteral(tlit) => visitor.visit_template_literal_mut(tlit), Expression::PropertyAccess(pa) => visitor.visit_property_access_mut(pa), Expression::New(n) => visitor.visit_new_mut(n), diff --git a/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs b/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs index 93719a2056c..3e47ec2bf9b 100644 --- a/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs +++ b/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs @@ -118,16 +118,16 @@ impl VisitWith for Assign { where V: Visitor<'a>, { - try_break!(visitor.visit_assign_target(&*self.lhs)); - visitor.visit_expression(&*self.rhs) + try_break!(visitor.visit_assign_target(&self.lhs)); + visitor.visit_expression(&self.rhs) } fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow where V: VisitorMut<'a>, { - try_break!(visitor.visit_assign_target_mut(&mut *self.lhs)); - visitor.visit_expression_mut(&mut *self.rhs) + try_break!(visitor.visit_assign_target_mut(&mut self.lhs)); + visitor.visit_expression_mut(&mut self.rhs) } } diff --git a/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs b/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs index 5e120cc1c75..6cc5c15b9a4 100644 --- a/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs +++ b/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs @@ -99,15 +99,15 @@ impl VisitWith for Binary { where V: Visitor<'a>, { - try_break!(visitor.visit_expression(&*self.lhs)); - visitor.visit_expression(&*self.rhs) + try_break!(visitor.visit_expression(&self.lhs)); + visitor.visit_expression(&self.rhs) } fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow where V: VisitorMut<'a>, { - try_break!(visitor.visit_expression_mut(&mut *self.lhs)); - visitor.visit_expression_mut(&mut *self.rhs) + try_break!(visitor.visit_expression_mut(&mut self.lhs)); + visitor.visit_expression_mut(&mut self.rhs) } } diff --git a/boa_engine/src/syntax/ast/expression/operator/conditional.rs b/boa_engine/src/syntax/ast/expression/operator/conditional.rs index 0795cf32482..7e57647b817 100644 --- a/boa_engine/src/syntax/ast/expression/operator/conditional.rs +++ b/boa_engine/src/syntax/ast/expression/operator/conditional.rs @@ -94,17 +94,17 @@ impl VisitWith for Conditional { where V: Visitor<'a>, { - try_break!(visitor.visit_expression(&*self.condition)); - try_break!(visitor.visit_expression(&*self.if_true)); - visitor.visit_expression(&*self.if_false) + try_break!(visitor.visit_expression(&self.condition)); + try_break!(visitor.visit_expression(&self.if_true)); + visitor.visit_expression(&self.if_false) } fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow where V: VisitorMut<'a>, { - try_break!(visitor.visit_expression_mut(&mut *self.condition)); - try_break!(visitor.visit_expression_mut(&mut *self.if_true)); - visitor.visit_expression_mut(&mut *self.if_false) + try_break!(visitor.visit_expression_mut(&mut self.condition)); + try_break!(visitor.visit_expression_mut(&mut self.if_true)); + visitor.visit_expression_mut(&mut self.if_false) } } diff --git a/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs b/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs index ae6d6d927e7..5b3c1a8eb57 100644 --- a/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs +++ b/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs @@ -95,13 +95,13 @@ impl VisitWith for Unary { where V: Visitor<'a>, { - visitor.visit_expression(&*self.target) + visitor.visit_expression(&self.target) } fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow where V: VisitorMut<'a>, { - visitor.visit_expression_mut(&mut *self.target) + visitor.visit_expression_mut(&mut self.target) } } diff --git a/boa_engine/src/syntax/ast/expression/spread.rs b/boa_engine/src/syntax/ast/expression/spread.rs index 289dd5f70de..b4e31bcc244 100644 --- a/boa_engine/src/syntax/ast/expression/spread.rs +++ b/boa_engine/src/syntax/ast/expression/spread.rs @@ -74,14 +74,14 @@ impl VisitWith for Spread { where V: Visitor<'a>, { - visitor.visit_expression(&*self.target) + visitor.visit_expression(&self.target) } fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow where V: VisitorMut<'a>, { - visitor.visit_expression_mut(&mut *self.target) + visitor.visit_expression_mut(&mut self.target) } } diff --git a/boa_engine/src/syntax/ast/expression/tagged_template.rs b/boa_engine/src/syntax/ast/expression/tagged_template.rs index 6d182dcb4a8..da308bcb4b2 100644 --- a/boa_engine/src/syntax/ast/expression/tagged_template.rs +++ b/boa_engine/src/syntax/ast/expression/tagged_template.rs @@ -101,7 +101,7 @@ impl VisitWith for TaggedTemplate { where V: Visitor<'a>, { - try_break!(visitor.visit_expression(&*self.tag)); + try_break!(visitor.visit_expression(&self.tag)); for raw in self.raws.iter() { try_break!(visitor.visit_sym(raw)); } @@ -118,7 +118,7 @@ impl VisitWith for TaggedTemplate { where V: VisitorMut<'a>, { - try_break!(visitor.visit_expression_mut(&mut *self.tag)); + try_break!(visitor.visit_expression_mut(&mut self.tag)); for raw in self.raws.iter_mut() { try_break!(visitor.visit_sym_mut(raw)); } diff --git a/boa_engine/src/syntax/ast/expression/yield.rs b/boa_engine/src/syntax/ast/expression/yield.rs index b3ee6c31fb2..7be4bec74ee 100644 --- a/boa_engine/src/syntax/ast/expression/yield.rs +++ b/boa_engine/src/syntax/ast/expression/yield.rs @@ -79,7 +79,7 @@ impl VisitWith for Yield { V: Visitor<'a>, { if let Some(expr) = &self.target { - visitor.visit_expression(&**expr) + visitor.visit_expression(expr) } else { ControlFlow::Continue(()) } @@ -90,7 +90,7 @@ impl VisitWith for Yield { V: VisitorMut<'a>, { if let Some(expr) = &mut self.target { - visitor.visit_expression_mut(&mut **expr) + visitor.visit_expression_mut(expr) } else { ControlFlow::Continue(()) } diff --git a/boa_engine/src/syntax/ast/function/class.rs b/boa_engine/src/syntax/ast/function/class.rs index 4247f336b9c..2ab4aa04ee4 100644 --- a/boa_engine/src/syntax/ast/function/class.rs +++ b/boa_engine/src/syntax/ast/function/class.rs @@ -110,7 +110,7 @@ impl ToIndentedString for Class { if let Some(sup) = &self.super_ref { format!(" extends {}", sup.to_interned_string(interner)) } else { - "".to_string() + String::new() } ); } @@ -120,7 +120,7 @@ impl ToIndentedString for Class { if let Some(sup) = &self.super_ref { format!("extends {}", sup.to_interned_string(interner)) } else { - "".to_string() + String::new() } ); if let Some(expr) = &self.constructor { diff --git a/boa_engine/src/syntax/ast/statement/if.rs b/boa_engine/src/syntax/ast/statement/if.rs index 01cf960c21b..57421ba08ff 100644 --- a/boa_engine/src/syntax/ast/statement/if.rs +++ b/boa_engine/src/syntax/ast/statement/if.rs @@ -104,9 +104,9 @@ impl VisitWith for If { V: Visitor<'a>, { try_break!(visitor.visit_expression(&self.condition)); - try_break!(visitor.visit_statement(&*self.body)); + try_break!(visitor.visit_statement(&self.body)); if let Some(stmt) = &self.else_node { - try_break!(visitor.visit_statement(&**stmt)); + try_break!(visitor.visit_statement(stmt)); } ControlFlow::Continue(()) } @@ -116,9 +116,9 @@ impl VisitWith for If { V: VisitorMut<'a>, { try_break!(visitor.visit_expression_mut(&mut self.condition)); - try_break!(visitor.visit_statement_mut(&mut *self.body)); + try_break!(visitor.visit_statement_mut(&mut self.body)); if let Some(stmt) = &mut self.else_node { - try_break!(visitor.visit_statement_mut(&mut **stmt)); + try_break!(visitor.visit_statement_mut(stmt)); } ControlFlow::Continue(()) } diff --git a/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs index ca658fcac57..971d89a105d 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs @@ -76,7 +76,7 @@ impl VisitWith for DoWhileLoop { where V: Visitor<'a>, { - try_break!(visitor.visit_statement(&*self.body)); + try_break!(visitor.visit_statement(&self.body)); visitor.visit_expression(&self.condition) } @@ -84,7 +84,7 @@ impl VisitWith for DoWhileLoop { where V: VisitorMut<'a>, { - try_break!(visitor.visit_statement_mut(&mut *self.body)); + try_break!(visitor.visit_statement_mut(&mut self.body)); visitor.visit_expression_mut(&mut self.condition) } } diff --git a/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs index b732f7d57e6..381c37ef721 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs @@ -94,7 +94,7 @@ impl VisitWith for ForInLoop { { try_break!(visitor.visit_iterable_loop_initializer(&self.initializer)); try_break!(visitor.visit_expression(&self.target)); - visitor.visit_statement(&*self.body) + visitor.visit_statement(&self.body) } fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow @@ -103,6 +103,6 @@ impl VisitWith for ForInLoop { { try_break!(visitor.visit_iterable_loop_initializer_mut(&mut self.initializer)); try_break!(visitor.visit_expression_mut(&mut self.target)); - visitor.visit_statement_mut(&mut *self.body) + visitor.visit_statement_mut(&mut self.body) } } diff --git a/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs index 77967d0d125..db905843f30 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs @@ -108,7 +108,7 @@ impl VisitWith for ForOfLoop { { try_break!(visitor.visit_iterable_loop_initializer(&self.init)); try_break!(visitor.visit_expression(&self.iterable)); - visitor.visit_statement(&*self.body) + visitor.visit_statement(&self.body) } fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow @@ -117,6 +117,6 @@ impl VisitWith for ForOfLoop { { try_break!(visitor.visit_iterable_loop_initializer_mut(&mut self.init)); try_break!(visitor.visit_expression_mut(&mut self.iterable)); - visitor.visit_statement_mut(&mut *self.body) + visitor.visit_statement_mut(&mut self.body) } } diff --git a/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs index 9e9a5e1c4bf..ee4f08c813d 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs @@ -78,7 +78,7 @@ impl VisitWith for WhileLoop { V: Visitor<'a>, { try_break!(visitor.visit_expression(&self.condition)); - visitor.visit_statement(&*self.body) + visitor.visit_statement(&self.body) } fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow @@ -86,6 +86,6 @@ impl VisitWith for WhileLoop { V: VisitorMut<'a>, { try_break!(visitor.visit_expression_mut(&mut self.condition)); - visitor.visit_statement_mut(&mut *self.body) + visitor.visit_statement_mut(&mut self.body) } } diff --git a/boa_engine/src/syntax/ast/statement/labelled.rs b/boa_engine/src/syntax/ast/statement/labelled.rs index bed1ae0328f..77a73c4e996 100644 --- a/boa_engine/src/syntax/ast/statement/labelled.rs +++ b/boa_engine/src/syntax/ast/statement/labelled.rs @@ -156,7 +156,7 @@ impl VisitWith for Labelled { where V: Visitor<'a>, { - try_break!(visitor.visit_labelled_item(&*self.item)); + try_break!(visitor.visit_labelled_item(&self.item)); visitor.visit_sym(&self.label) } @@ -164,7 +164,7 @@ impl VisitWith for Labelled { where V: VisitorMut<'a>, { - try_break!(visitor.visit_labelled_item_mut(&mut *self.item)); + try_break!(visitor.visit_labelled_item_mut(&mut self.item)); visitor.visit_sym_mut(&mut self.label) } } diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 4c2d0ef110d..24586f69fbc 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -14,18 +14,18 @@ macro_rules! try_break { }; } -use crate::syntax::ast::declaration::*; -use crate::syntax::ast::expression::access::*; -use crate::syntax::ast::expression::literal::*; -use crate::syntax::ast::expression::operator::assign::*; -use crate::syntax::ast::expression::operator::*; -use crate::syntax::ast::expression::*; -use crate::syntax::ast::function::*; -use crate::syntax::ast::pattern::*; -use crate::syntax::ast::property::*; -use crate::syntax::ast::statement::iteration::*; -use crate::syntax::ast::statement::*; -use crate::syntax::ast::*; +use crate::syntax::ast::declaration::{Binding, Declaration, LexicalDeclaration, VarDeclaration, Variable, VariableList}; +use crate::syntax::ast::expression::access::{PrivatePropertyAccess, PropertyAccess, PropertyAccessField, SimplePropertyAccess, SuperPropertyAccess}; +use crate::syntax::ast::expression::literal::{ArrayLiteral, Literal, ObjectLiteral, TemplateElement, TemplateLiteral}; +use crate::syntax::ast::expression::operator::assign::{Assign, AssignTarget}; +use crate::syntax::ast::expression::operator::{Binary, Conditional, Unary}; +use crate::syntax::ast::expression::{Await, Call, Expression, Identifier, New, Optional, OptionalOperation, OptionalOperationKind, Spread, SuperCall, TaggedTemplate, Yield}; +use crate::syntax::ast::function::{ArrowFunction, AsyncFunction, AsyncGenerator, Class, ClassElement, FormalParameter, FormalParameterList, Function, Generator}; +use crate::syntax::ast::pattern::{ArrayPattern, ArrayPatternElement, ObjectPattern, ObjectPatternElement, Pattern}; +use crate::syntax::ast::property::{MethodDefinition, PropertyDefinition, PropertyName}; +use crate::syntax::ast::statement::iteration::{Break, Continue, DoWhileLoop, ForInLoop, ForLoop, ForLoopInitializer, ForOfLoop, IterableLoopInitializer, WhileLoop}; +use crate::syntax::ast::statement::{Block, Case, Catch, Finally, If, Labelled, LabelledItem, Return, Statement, Switch, Throw, Try}; +use crate::syntax::ast::{StatementList, StatementListItem}; use boa_interner::Sym; /// Creates the default visit function implementation for a particular type From 88c6f01dc454917a63b83d9ff0cb2ca241b0eb72 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 22:14:09 +0100 Subject: [PATCH 31/34] fixup fmt --- boa_engine/src/syntax/ast/visitor.rs | 36 +++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/boa_engine/src/syntax/ast/visitor.rs b/boa_engine/src/syntax/ast/visitor.rs index 24586f69fbc..ea38a122ee7 100644 --- a/boa_engine/src/syntax/ast/visitor.rs +++ b/boa_engine/src/syntax/ast/visitor.rs @@ -14,17 +14,37 @@ macro_rules! try_break { }; } -use crate::syntax::ast::declaration::{Binding, Declaration, LexicalDeclaration, VarDeclaration, Variable, VariableList}; -use crate::syntax::ast::expression::access::{PrivatePropertyAccess, PropertyAccess, PropertyAccessField, SimplePropertyAccess, SuperPropertyAccess}; -use crate::syntax::ast::expression::literal::{ArrayLiteral, Literal, ObjectLiteral, TemplateElement, TemplateLiteral}; +use crate::syntax::ast::declaration::{ + Binding, Declaration, LexicalDeclaration, VarDeclaration, Variable, VariableList, +}; +use crate::syntax::ast::expression::access::{ + PrivatePropertyAccess, PropertyAccess, PropertyAccessField, SimplePropertyAccess, + SuperPropertyAccess, +}; +use crate::syntax::ast::expression::literal::{ + ArrayLiteral, Literal, ObjectLiteral, TemplateElement, TemplateLiteral, +}; use crate::syntax::ast::expression::operator::assign::{Assign, AssignTarget}; use crate::syntax::ast::expression::operator::{Binary, Conditional, Unary}; -use crate::syntax::ast::expression::{Await, Call, Expression, Identifier, New, Optional, OptionalOperation, OptionalOperationKind, Spread, SuperCall, TaggedTemplate, Yield}; -use crate::syntax::ast::function::{ArrowFunction, AsyncFunction, AsyncGenerator, Class, ClassElement, FormalParameter, FormalParameterList, Function, Generator}; -use crate::syntax::ast::pattern::{ArrayPattern, ArrayPatternElement, ObjectPattern, ObjectPatternElement, Pattern}; +use crate::syntax::ast::expression::{ + Await, Call, Expression, Identifier, New, Optional, OptionalOperation, OptionalOperationKind, + Spread, SuperCall, TaggedTemplate, Yield, +}; +use crate::syntax::ast::function::{ + ArrowFunction, AsyncFunction, AsyncGenerator, Class, ClassElement, FormalParameter, + FormalParameterList, Function, Generator, +}; +use crate::syntax::ast::pattern::{ + ArrayPattern, ArrayPatternElement, ObjectPattern, ObjectPatternElement, Pattern, +}; use crate::syntax::ast::property::{MethodDefinition, PropertyDefinition, PropertyName}; -use crate::syntax::ast::statement::iteration::{Break, Continue, DoWhileLoop, ForInLoop, ForLoop, ForLoopInitializer, ForOfLoop, IterableLoopInitializer, WhileLoop}; -use crate::syntax::ast::statement::{Block, Case, Catch, Finally, If, Labelled, LabelledItem, Return, Statement, Switch, Throw, Try}; +use crate::syntax::ast::statement::iteration::{ + Break, Continue, DoWhileLoop, ForInLoop, ForLoop, ForLoopInitializer, ForOfLoop, + IterableLoopInitializer, WhileLoop, +}; +use crate::syntax::ast::statement::{ + Block, Case, Catch, Finally, If, Labelled, LabelledItem, Return, Statement, Switch, Throw, Try, +}; use crate::syntax::ast::{StatementList, StatementListItem}; use boa_interner::Sym; From 468ecb9905171a5ce62d4ba840b6884754b4aba7 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 22:29:57 +0100 Subject: [PATCH 32/34] {std=>core}::ops::ControlFlow --- boa_engine/src/syntax/ast/declaration/variable.rs | 2 +- boa_engine/src/syntax/ast/expression/access.rs | 2 +- boa_engine/src/syntax/ast/expression/await.rs | 2 +- boa_engine/src/syntax/ast/expression/call.rs | 2 +- boa_engine/src/syntax/ast/expression/identifier.rs | 2 +- boa_engine/src/syntax/ast/expression/literal/array.rs | 2 +- boa_engine/src/syntax/ast/expression/literal/mod.rs | 2 +- boa_engine/src/syntax/ast/expression/literal/object/mod.rs | 2 +- boa_engine/src/syntax/ast/expression/literal/template.rs | 2 +- boa_engine/src/syntax/ast/expression/mod.rs | 2 +- boa_engine/src/syntax/ast/expression/new.rs | 2 +- boa_engine/src/syntax/ast/expression/operator/assign/mod.rs | 2 +- boa_engine/src/syntax/ast/expression/operator/binary/mod.rs | 2 +- boa_engine/src/syntax/ast/expression/operator/conditional.rs | 2 +- boa_engine/src/syntax/ast/expression/operator/unary/mod.rs | 2 +- boa_engine/src/syntax/ast/expression/optional.rs | 2 +- boa_engine/src/syntax/ast/expression/spread.rs | 2 +- boa_engine/src/syntax/ast/expression/tagged_template.rs | 2 +- boa_engine/src/syntax/ast/expression/yield.rs | 2 +- boa_engine/src/syntax/ast/function/arrow_function.rs | 2 +- boa_engine/src/syntax/ast/function/async_function.rs | 2 +- boa_engine/src/syntax/ast/function/async_generator.rs | 2 +- boa_engine/src/syntax/ast/function/class.rs | 2 +- boa_engine/src/syntax/ast/function/generator.rs | 2 +- boa_engine/src/syntax/ast/function/mod.rs | 2 +- boa_engine/src/syntax/ast/function/parameters.rs | 2 +- boa_engine/src/syntax/ast/pattern.rs | 2 +- boa_engine/src/syntax/ast/property.rs | 2 +- boa_engine/src/syntax/ast/statement/block.rs | 2 +- boa_engine/src/syntax/ast/statement/if.rs | 2 +- boa_engine/src/syntax/ast/statement/iteration/break.rs | 2 +- boa_engine/src/syntax/ast/statement/iteration/continue.rs | 2 +- boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs | 2 +- boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs | 2 +- boa_engine/src/syntax/ast/statement/iteration/for_loop.rs | 2 +- boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs | 2 +- boa_engine/src/syntax/ast/statement/iteration/mod.rs | 2 +- boa_engine/src/syntax/ast/statement/iteration/while_loop.rs | 2 +- boa_engine/src/syntax/ast/statement/labelled.rs | 2 +- boa_engine/src/syntax/ast/statement/return.rs | 2 +- boa_engine/src/syntax/ast/statement/switch/mod.rs | 2 +- boa_engine/src/syntax/ast/statement/throw.rs | 2 +- boa_engine/src/syntax/ast/statement/try/mod.rs | 2 +- boa_examples/src/bin/commuter_visitor.rs | 2 +- 44 files changed, 44 insertions(+), 44 deletions(-) diff --git a/boa_engine/src/syntax/ast/declaration/variable.rs b/boa_engine/src/syntax/ast/declaration/variable.rs index f31a60e7302..c2ea06b86e4 100644 --- a/boa_engine/src/syntax/ast/declaration/variable.rs +++ b/boa_engine/src/syntax/ast/declaration/variable.rs @@ -1,7 +1,7 @@ //! Variable related declarations. +use core::ops::ControlFlow; use std::convert::TryFrom; -use std::ops::ControlFlow; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{ diff --git a/boa_engine/src/syntax/ast/expression/access.rs b/boa_engine/src/syntax/ast/expression/access.rs index 5c9b972906b..2c4e2b3257f 100644 --- a/boa_engine/src/syntax/ast/expression/access.rs +++ b/boa_engine/src/syntax/ast/expression/access.rs @@ -18,7 +18,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, ContainsSymbol}; use crate::try_break; use boa_interner::{Interner, Sym, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// A property access field. /// diff --git a/boa_engine/src/syntax/ast/expression/await.rs b/boa_engine/src/syntax/ast/expression/await.rs index de58935a99b..00154c3b78c 100644 --- a/boa_engine/src/syntax/ast/expression/await.rs +++ b/boa_engine/src/syntax/ast/expression/await.rs @@ -1,7 +1,7 @@ //! Await expression Expression. use crate::syntax::ast::ContainsSymbol; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use super::Expression; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; diff --git a/boa_engine/src/syntax/ast/expression/call.rs b/boa_engine/src/syntax/ast/expression/call.rs index 303ccfddb66..f99bc9956bb 100644 --- a/boa_engine/src/syntax/ast/expression/call.rs +++ b/boa_engine/src/syntax/ast/expression/call.rs @@ -2,7 +2,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{join_nodes, ContainsSymbol}; use crate::try_break; use boa_interner::{Interner, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use super::Expression; diff --git a/boa_engine/src/syntax/ast/expression/identifier.rs b/boa_engine/src/syntax/ast/expression/identifier.rs index d301b044e28..c9b753bed3e 100644 --- a/boa_engine/src/syntax/ast/expression/identifier.rs +++ b/boa_engine/src/syntax/ast/expression/identifier.rs @@ -6,7 +6,7 @@ use crate::{ syntax::{ast::Position, parser::ParseError}, }; use boa_interner::{Interner, Sym, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use super::Expression; diff --git a/boa_engine/src/syntax/ast/expression/literal/array.rs b/boa_engine/src/syntax/ast/expression/literal/array.rs index 3bf93fc9f02..b072b72a40c 100644 --- a/boa_engine/src/syntax/ast/expression/literal/array.rs +++ b/boa_engine/src/syntax/ast/expression/literal/array.rs @@ -4,7 +4,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, ContainsSymbol}; use crate::try_break; use boa_interner::{Interner, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// An array is an ordered collection of data (either primitive or object depending upon the /// language). diff --git a/boa_engine/src/syntax/ast/expression/literal/mod.rs b/boa_engine/src/syntax/ast/expression/literal/mod.rs index c20ef23a743..dac95a4e7f1 100644 --- a/boa_engine/src/syntax/ast/expression/literal/mod.rs +++ b/boa_engine/src/syntax/ast/expression/literal/mod.rs @@ -12,8 +12,8 @@ mod object; mod template; pub use array::ArrayLiteral; +use core::ops::ControlFlow; pub use object::ObjectLiteral; -use std::ops::ControlFlow; pub use template::{TemplateElement, TemplateLiteral}; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; diff --git a/boa_engine/src/syntax/ast/expression/literal/object/mod.rs b/boa_engine/src/syntax/ast/expression/literal/object/mod.rs index aef45a0e974..e3e410feacf 100644 --- a/boa_engine/src/syntax/ast/expression/literal/object/mod.rs +++ b/boa_engine/src/syntax/ast/expression/literal/object/mod.rs @@ -13,7 +13,7 @@ use crate::syntax::ast::{ }; use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// Objects in JavaScript may be defined as an unordered collection of related data, of /// primitive or reference types, in the form of “key: value” pairs. diff --git a/boa_engine/src/syntax/ast/expression/literal/template.rs b/boa_engine/src/syntax/ast/expression/literal/template.rs index c69f39f67d0..cd1dc7c7ceb 100644 --- a/boa_engine/src/syntax/ast/expression/literal/template.rs +++ b/boa_engine/src/syntax/ast/expression/literal/template.rs @@ -1,7 +1,7 @@ //! Template literal Expression. +use core::ops::ControlFlow; use std::borrow::Cow; -use std::ops::ControlFlow; use boa_interner::{Interner, Sym, ToInternedString}; diff --git a/boa_engine/src/syntax/ast/expression/mod.rs b/boa_engine/src/syntax/ast/expression/mod.rs index c573af8a33e..75d74068a71 100644 --- a/boa_engine/src/syntax/ast/expression/mod.rs +++ b/boa_engine/src/syntax/ast/expression/mod.rs @@ -10,7 +10,7 @@ //! [lhs]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#left-hand-side_expressions use boa_interner::{Interner, Sym, ToIndentedString, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use self::{ access::PropertyAccess, diff --git a/boa_engine/src/syntax/ast/expression/new.rs b/boa_engine/src/syntax/ast/expression/new.rs index eb844e480e6..9b8c0a70880 100644 --- a/boa_engine/src/syntax/ast/expression/new.rs +++ b/boa_engine/src/syntax/ast/expression/new.rs @@ -1,7 +1,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Call, ContainsSymbol}; use boa_interner::{Interner, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use super::Expression; diff --git a/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs b/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs index 3e47ec2bf9b..bc6d339245a 100644 --- a/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs +++ b/boa_engine/src/syntax/ast/expression/operator/assign/mod.rs @@ -12,8 +12,8 @@ mod op; +use core::ops::ControlFlow; pub use op::*; -use std::ops::ControlFlow; use boa_interner::{Interner, Sym, ToInternedString}; diff --git a/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs b/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs index 6cc5c15b9a4..d46ea962d41 100644 --- a/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs +++ b/boa_engine/src/syntax/ast/expression/operator/binary/mod.rs @@ -16,8 +16,8 @@ mod op; +use core::ops::ControlFlow; pub use op::*; -use std::ops::ControlFlow; use boa_interner::{Interner, ToInternedString}; diff --git a/boa_engine/src/syntax/ast/expression/operator/conditional.rs b/boa_engine/src/syntax/ast/expression/operator/conditional.rs index 7e57647b817..fc0f19eddec 100644 --- a/boa_engine/src/syntax/ast/expression/operator/conditional.rs +++ b/boa_engine/src/syntax/ast/expression/operator/conditional.rs @@ -2,7 +2,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, ContainsSymbol}; use crate::try_break; use boa_interner::{Interner, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// The `conditional` (ternary) operation is the only JavaScript operation that takes three /// operands. diff --git a/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs b/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs index 5b3c1a8eb57..baa262f940f 100644 --- a/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs +++ b/boa_engine/src/syntax/ast/expression/operator/unary/mod.rs @@ -13,8 +13,8 @@ //! [not]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT mod op; +use core::ops::ControlFlow; pub use op::*; -use std::ops::ControlFlow; use boa_interner::{Interner, ToInternedString}; diff --git a/boa_engine/src/syntax/ast/expression/optional.rs b/boa_engine/src/syntax/ast/expression/optional.rs index b3d76f1a456..4919578ac76 100644 --- a/boa_engine/src/syntax/ast/expression/optional.rs +++ b/boa_engine/src/syntax/ast/expression/optional.rs @@ -1,5 +1,5 @@ use boa_interner::{Interner, Sym, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{join_nodes, ContainsSymbol}; diff --git a/boa_engine/src/syntax/ast/expression/spread.rs b/boa_engine/src/syntax/ast/expression/spread.rs index b4e31bcc244..5dc32d36ba3 100644 --- a/boa_engine/src/syntax/ast/expression/spread.rs +++ b/boa_engine/src/syntax/ast/expression/spread.rs @@ -1,5 +1,5 @@ use boa_interner::{Interner, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::ContainsSymbol; diff --git a/boa_engine/src/syntax/ast/expression/tagged_template.rs b/boa_engine/src/syntax/ast/expression/tagged_template.rs index da308bcb4b2..78b1f8f45cd 100644 --- a/boa_engine/src/syntax/ast/expression/tagged_template.rs +++ b/boa_engine/src/syntax/ast/expression/tagged_template.rs @@ -1,5 +1,5 @@ use boa_interner::{Interner, Sym, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::ContainsSymbol; diff --git a/boa_engine/src/syntax/ast/expression/yield.rs b/boa_engine/src/syntax/ast/expression/yield.rs index 7be4bec74ee..6284f316fc4 100644 --- a/boa_engine/src/syntax/ast/expression/yield.rs +++ b/boa_engine/src/syntax/ast/expression/yield.rs @@ -1,5 +1,5 @@ use boa_interner::{Interner, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::ContainsSymbol; diff --git a/boa_engine/src/syntax/ast/function/arrow_function.rs b/boa_engine/src/syntax/ast/function/arrow_function.rs index 71ab69b238d..ad2003d7eb3 100644 --- a/boa_engine/src/syntax/ast/function/arrow_function.rs +++ b/boa_engine/src/syntax/ast/function/arrow_function.rs @@ -5,7 +5,7 @@ use crate::syntax::ast::{ }; use crate::try_break; use boa_interner::{Interner, ToIndentedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use super::FormalParameterList; diff --git a/boa_engine/src/syntax/ast/function/async_function.rs b/boa_engine/src/syntax/ast/function/async_function.rs index 24a75bceba3..867c8fb8daa 100644 --- a/boa_engine/src/syntax/ast/function/async_function.rs +++ b/boa_engine/src/syntax/ast/function/async_function.rs @@ -7,7 +7,7 @@ use crate::syntax::ast::{ }; use crate::try_break; use boa_interner::{Interner, ToIndentedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use super::FormalParameterList; diff --git a/boa_engine/src/syntax/ast/function/async_generator.rs b/boa_engine/src/syntax/ast/function/async_generator.rs index a24ab0e7c8b..93db559e5bf 100644 --- a/boa_engine/src/syntax/ast/function/async_generator.rs +++ b/boa_engine/src/syntax/ast/function/async_generator.rs @@ -7,7 +7,7 @@ use crate::syntax::ast::{ }; use crate::try_break; use boa_interner::{Interner, ToIndentedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use super::FormalParameterList; diff --git a/boa_engine/src/syntax/ast/function/class.rs b/boa_engine/src/syntax/ast/function/class.rs index 2ab4aa04ee4..302313f8033 100644 --- a/boa_engine/src/syntax/ast/function/class.rs +++ b/boa_engine/src/syntax/ast/function/class.rs @@ -1,5 +1,5 @@ +use core::ops::ControlFlow; use std::borrow::Cow; -use std::ops::ControlFlow; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::{ diff --git a/boa_engine/src/syntax/ast/function/generator.rs b/boa_engine/src/syntax/ast/function/generator.rs index 1461c598dac..89f240d0092 100644 --- a/boa_engine/src/syntax/ast/function/generator.rs +++ b/boa_engine/src/syntax/ast/function/generator.rs @@ -3,7 +3,7 @@ use crate::syntax::ast::{ expression::{Expression, Identifier}, join_nodes, Declaration, StatementList, }; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::try_break; diff --git a/boa_engine/src/syntax/ast/function/mod.rs b/boa_engine/src/syntax/ast/function/mod.rs index 2e298b62788..f9e6c2f90c0 100644 --- a/boa_engine/src/syntax/ast/function/mod.rs +++ b/boa_engine/src/syntax/ast/function/mod.rs @@ -31,9 +31,9 @@ pub use arrow_function::ArrowFunction; pub use async_function::AsyncFunction; pub use async_generator::AsyncGenerator; pub use class::{Class, ClassElement}; +use core::ops::ControlFlow; pub use generator::Generator; pub use parameters::{FormalParameter, FormalParameterList}; -use std::ops::ControlFlow; pub(crate) use parameters::FormalParameterListFlags; diff --git a/boa_engine/src/syntax/ast/function/parameters.rs b/boa_engine/src/syntax/ast/function/parameters.rs index 6d3cc38c6de..9386ec5bec8 100644 --- a/boa_engine/src/syntax/ast/function/parameters.rs +++ b/boa_engine/src/syntax/ast/function/parameters.rs @@ -11,8 +11,8 @@ use crate::syntax::{ use crate::try_break; use bitflags::bitflags; use boa_interner::{Interner, Sym, ToInternedString}; +use core::ops::ControlFlow; use rustc_hash::FxHashSet; -use std::ops::ControlFlow; /// A list of `FormalParameter`s that describes the parameters of a function, as defined by the [spec]. /// diff --git a/boa_engine/src/syntax/ast/pattern.rs b/boa_engine/src/syntax/ast/pattern.rs index 2a5a4885da3..080c8697f3e 100644 --- a/boa_engine/src/syntax/ast/pattern.rs +++ b/boa_engine/src/syntax/ast/pattern.rs @@ -25,7 +25,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::try_break; use boa_interner::{Interner, Sym, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use super::{ expression::{access::PropertyAccess, Identifier}, diff --git a/boa_engine/src/syntax/ast/property.rs b/boa_engine/src/syntax/ast/property.rs index 17d2467de8d..6a465dbb638 100644 --- a/boa_engine/src/syntax/ast/property.rs +++ b/boa_engine/src/syntax/ast/property.rs @@ -3,7 +3,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::try_break; use boa_interner::{Interner, Sym, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use super::{ expression::{literal::Literal, Identifier}, diff --git a/boa_engine/src/syntax/ast/statement/block.rs b/boa_engine/src/syntax/ast/statement/block.rs index f43b5908178..c6a8d61ec4e 100644 --- a/boa_engine/src/syntax/ast/statement/block.rs +++ b/boa_engine/src/syntax/ast/statement/block.rs @@ -4,7 +4,7 @@ use super::Statement; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Identifier, ContainsSymbol, StatementList}; use boa_interner::{Interner, ToIndentedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// A `block` statement (or compound statement in other languages) is used to group zero or /// more statements. diff --git a/boa_engine/src/syntax/ast/statement/if.rs b/boa_engine/src/syntax/ast/statement/if.rs index 57421ba08ff..adca66a8552 100644 --- a/boa_engine/src/syntax/ast/statement/if.rs +++ b/boa_engine/src/syntax/ast/statement/if.rs @@ -4,7 +4,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, statement::Statement, ContainsSymbol}; use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// The `if` statement executes a statement if a specified condition is [`truthy`][truthy]. If /// the condition is [`falsy`][falsy], another statement can be executed. diff --git a/boa_engine/src/syntax/ast/statement/iteration/break.rs b/boa_engine/src/syntax/ast/statement/iteration/break.rs index 6ffd75e9a6a..b05c47aeb13 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/break.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/break.rs @@ -1,5 +1,5 @@ use boa_interner::{Interner, Sym, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::Statement; diff --git a/boa_engine/src/syntax/ast/statement/iteration/continue.rs b/boa_engine/src/syntax/ast/statement/iteration/continue.rs index 1a0cf2c6d30..7c7f1f1f177 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/continue.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/continue.rs @@ -1,7 +1,7 @@ use crate::syntax::ast::statement::Statement; use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use boa_interner::{Interner, Sym, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// The `continue` statement terminates execution of the statements in the current iteration of /// the current or labeled loop, and continues execution of the loop with the next iteration. diff --git a/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs index 971d89a105d..5ebd5de0b16 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs @@ -2,7 +2,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, statement::Statement, ContainsSymbol}; use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// The `do...while` statement creates a loop that executes a specified statement until the /// test condition evaluates to false. diff --git a/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs index 381c37ef721..0b04974dae1 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs @@ -6,7 +6,7 @@ use crate::syntax::ast::{ }; use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// A `for...in` loop statement, as defined by the [spec]. /// diff --git a/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs index 05d0b640e22..c697e2c7e39 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/for_loop.rs @@ -7,7 +7,7 @@ use crate::syntax::ast::{ }; use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// The `for` statement creates a loop that consists of three optional expressions. /// diff --git a/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs index db905843f30..cfcd1079c34 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs @@ -6,7 +6,7 @@ use crate::syntax::ast::{ }; use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// A `for...of` loop statement, as defined by the [spec]. /// diff --git a/boa_engine/src/syntax/ast/statement/iteration/mod.rs b/boa_engine/src/syntax/ast/statement/iteration/mod.rs index a3cf4b2f6de..ff1ecd30370 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/mod.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/mod.rs @@ -13,7 +13,7 @@ use crate::syntax::ast::{ expression::{access::PropertyAccess, Identifier}, pattern::Pattern, }; -use std::ops::ControlFlow; +use core::ops::ControlFlow; pub use self::{ do_while_loop::DoWhileLoop, diff --git a/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs b/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs index ee4f08c813d..6b2eeb396c8 100644 --- a/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs +++ b/boa_engine/src/syntax/ast/statement/iteration/while_loop.rs @@ -2,7 +2,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, statement::Statement, ContainsSymbol}; use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// The `while` statement creates a loop that executes a specified statement as long as the /// test condition evaluates to `true`. diff --git a/boa_engine/src/syntax/ast/statement/labelled.rs b/boa_engine/src/syntax/ast/statement/labelled.rs index 77a73c4e996..477fdd0af0a 100644 --- a/boa_engine/src/syntax/ast/statement/labelled.rs +++ b/boa_engine/src/syntax/ast/statement/labelled.rs @@ -3,7 +3,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{function::Function, ContainsSymbol}; use crate::try_break; use boa_interner::{Interner, Sym, ToIndentedString, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// The set of Parse Nodes that can be preceded by a label, as defined by the [spec]. /// diff --git a/boa_engine/src/syntax/ast/statement/return.rs b/boa_engine/src/syntax/ast/statement/return.rs index fac1bd4a511..4370f64aec7 100644 --- a/boa_engine/src/syntax/ast/statement/return.rs +++ b/boa_engine/src/syntax/ast/statement/return.rs @@ -1,7 +1,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, statement::Statement, ContainsSymbol}; use boa_interner::{Interner, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// The `return` statement ends function execution and specifies a value to be returned to the /// function caller. diff --git a/boa_engine/src/syntax/ast/statement/switch/mod.rs b/boa_engine/src/syntax/ast/statement/switch/mod.rs index 92b82e50f32..44d85c44d58 100644 --- a/boa_engine/src/syntax/ast/statement/switch/mod.rs +++ b/boa_engine/src/syntax/ast/statement/switch/mod.rs @@ -4,7 +4,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{expression::Expression, statement::Statement, StatementList}; use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use super::ContainsSymbol; diff --git a/boa_engine/src/syntax/ast/statement/throw.rs b/boa_engine/src/syntax/ast/statement/throw.rs index 607a49a8af6..c1747c6f510 100644 --- a/boa_engine/src/syntax/ast/statement/throw.rs +++ b/boa_engine/src/syntax/ast/statement/throw.rs @@ -1,7 +1,7 @@ use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut}; use crate::syntax::ast::{statement::Statement, ContainsSymbol, Expression}; use boa_interner::{Interner, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; /// The `throw` statement throws a user-defined exception. /// diff --git a/boa_engine/src/syntax/ast/statement/try/mod.rs b/boa_engine/src/syntax/ast/statement/try/mod.rs index 1308ac6fa46..0237162f858 100644 --- a/boa_engine/src/syntax/ast/statement/try/mod.rs +++ b/boa_engine/src/syntax/ast/statement/try/mod.rs @@ -8,7 +8,7 @@ use crate::syntax::ast::{ }; use crate::try_break; use boa_interner::{Interner, ToIndentedString, ToInternedString}; -use std::ops::ControlFlow; +use core::ops::ControlFlow; use super::ContainsSymbol; diff --git a/boa_examples/src/bin/commuter_visitor.rs b/boa_examples/src/bin/commuter_visitor.rs index 65de6848ffe..eee08b50e4c 100644 --- a/boa_examples/src/bin/commuter_visitor.rs +++ b/boa_examples/src/bin/commuter_visitor.rs @@ -9,10 +9,10 @@ use boa_engine::syntax::ast::Expression; use boa_engine::syntax::Parser; use boa_engine::Context; use boa_interner::ToInternedString; +use core::ops::ControlFlow; use std::convert::Infallible; use std::fs::File; use std::io::BufReader; -use std::ops::ControlFlow; /// Visitor which, when applied to a binary expression, will swap the operands. Use in other /// circumstances is undefined. From 04b24823db39049736adec5c2bdd31e37ff95a28 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 22:37:07 +0100 Subject: [PATCH 33/34] undo comment --- boa_engine/src/value/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boa_engine/src/value/mod.rs b/boa_engine/src/value/mod.rs index 680e6b2f309..3b9ac4fcd3b 100644 --- a/boa_engine/src/value/mod.rs +++ b/boa_engine/src/value/mod.rs @@ -40,8 +40,8 @@ mod r#type; pub use conversions::*; pub use display::ValueDisplay; -// pub use equality::*; -// pub use hash::*; +pub use equality::*; +pub use hash::*; pub use integer::IntegerOrInfinity; pub use operations::*; pub use r#type::Type; From 58aa3978161b73b5f4be088283a4e658f77a6e30 Mon Sep 17 00:00:00 2001 From: Addison Crump Date: Tue, 1 Nov 2022 22:46:51 +0100 Subject: [PATCH 34/34] poof --- boa_engine/src/value/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/boa_engine/src/value/mod.rs b/boa_engine/src/value/mod.rs index 3b9ac4fcd3b..9202fc5fb85 100644 --- a/boa_engine/src/value/mod.rs +++ b/boa_engine/src/value/mod.rs @@ -40,8 +40,6 @@ mod r#type; pub use conversions::*; pub use display::ValueDisplay; -pub use equality::*; -pub use hash::*; pub use integer::IntegerOrInfinity; pub use operations::*; pub use r#type::Type;