From 25562ec1be582c9556cb27938a7d0a126388fd1f Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Tue, 8 Jun 2021 16:57:17 -0700 Subject: [PATCH 01/46] Fixed top level indents --- boa/src/syntax/ast/node/statement_list/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boa/src/syntax/ast/node/statement_list/mod.rs b/boa/src/syntax/ast/node/statement_list/mod.rs index 9f7b4eafbd7..e322f051081 100644 --- a/boa/src/syntax/ast/node/statement_list/mod.rs +++ b/boa/src/syntax/ast/node/statement_list/mod.rs @@ -45,7 +45,8 @@ impl StatementList { // Print statements for node in self.items.iter() { f.write_str(&indent)?; - node.display(f, indentation + 1)?; + // Never used except in the top-level list of nodes, so we don't add to indentation here. + node.display(f, indentation)?; match node { Node::Block(_) | Node::If(_) | Node::Switch(_) | Node::WhileLoop(_) => {} From cfda1687f8d6394de1613d547304e17008151757 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Tue, 8 Jun 2021 16:57:35 -0700 Subject: [PATCH 02/46] Fixed function definitions --- boa/src/syntax/ast/node/declaration/function_decl/mod.rs | 4 ++-- boa/src/syntax/ast/node/declaration/function_expr/mod.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boa/src/syntax/ast/node/declaration/function_decl/mod.rs b/boa/src/syntax/ast/node/declaration/function_decl/mod.rs index e3b68bc7670..cf38e1326be 100644 --- a/boa/src/syntax/ast/node/declaration/function_decl/mod.rs +++ b/boa/src/syntax/ast/node/declaration/function_decl/mod.rs @@ -75,11 +75,11 @@ impl FunctionDecl { ) -> fmt::Result { write!(f, "function {}(", self.name)?; join_nodes(f, &self.parameters)?; - f.write_str(") {{")?; + writeln!(f, ") {{")?; self.body.display(f, indentation + 1)?; - writeln!(f, "}}") + writeln!(f, "{}}}", " ".repeat(indentation)) } } diff --git a/boa/src/syntax/ast/node/declaration/function_expr/mod.rs b/boa/src/syntax/ast/node/declaration/function_expr/mod.rs index 6f56d54cf6c..de8d6c76ab6 100644 --- a/boa/src/syntax/ast/node/declaration/function_expr/mod.rs +++ b/boa/src/syntax/ast/node/declaration/function_expr/mod.rs @@ -76,11 +76,11 @@ impl FunctionExpr { } f.write_str("(")?; join_nodes(f, &self.parameters)?; - f.write_str(") {{")?; + writeln!(f, ") {{")?; self.body.display(f, indentation + 1)?; - writeln!(f, "}}") + write!(f, "}}") } } From 8cc481e7992e5ffd4c9d0e5c4f17bd8942f60464 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Tue, 8 Jun 2021 17:20:59 -0700 Subject: [PATCH 03/46] For loops display correctly now --- boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs | 5 ++--- boa/src/syntax/ast/node/iteration/for_loop/mod.rs | 11 ++++------- boa/src/syntax/ast/node/statement_list/mod.rs | 4 +--- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs b/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs index 628c60bd895..2d596c6cc26 100644 --- a/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs @@ -59,9 +59,8 @@ impl ForInLoop { } pub fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result { - write!(f, "for ({} in {}) {{", self.variable, self.expr,)?; - self.body().display(f, indentation + 1)?; - f.write_str("}") + write!(f, "for ({} in {}) ", self.variable, self.expr)?; + self.body().display(f, indentation) } } diff --git a/boa/src/syntax/ast/node/iteration/for_loop/mod.rs b/boa/src/syntax/ast/node/iteration/for_loop/mod.rs index f33c14e1370..f992edd924c 100644 --- a/boa/src/syntax/ast/node/iteration/for_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_loop/mod.rs @@ -73,19 +73,16 @@ impl ForLoop { if let Some(init) = self.init() { fmt::Display::fmt(init, f)?; } - f.write_str(";")?; + f.write_str("; ")?; if let Some(condition) = self.condition() { fmt::Display::fmt(condition, f)?; } - f.write_str(";")?; + f.write_str("; ")?; if let Some(final_expr) = self.final_expr() { fmt::Display::fmt(final_expr, f)?; } - writeln!(f, ") {{")?; - - self.inner.body().display(f, indentation + 1)?; - - write!(f, "}}") + write!(f, ") ")?; + self.inner.body().display(f, indentation) } pub fn label(&self) -> Option<&str> { diff --git a/boa/src/syntax/ast/node/statement_list/mod.rs b/boa/src/syntax/ast/node/statement_list/mod.rs index e322f051081..076998367b1 100644 --- a/boa/src/syntax/ast/node/statement_list/mod.rs +++ b/boa/src/syntax/ast/node/statement_list/mod.rs @@ -41,11 +41,9 @@ impl StatementList { f: &mut fmt::Formatter<'_>, indentation: usize, ) -> fmt::Result { - let indent = " ".repeat(indentation); // Print statements for node in self.items.iter() { - f.write_str(&indent)?; - // Never used except in the top-level list of nodes, so we don't add to indentation here. + // We rely on the node to add the correct indent. node.display(f, indentation)?; match node { From b09891b280e5669fa38fedc4ca3345317680c083 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Tue, 8 Jun 2021 17:22:40 -0700 Subject: [PATCH 04/46] Await expressions display correctly --- boa/src/syntax/ast/node/await_expr/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boa/src/syntax/ast/node/await_expr/mod.rs b/boa/src/syntax/ast/node/await_expr/mod.rs index f527dd0f067..5d7ae6917cd 100644 --- a/boa/src/syntax/ast/node/await_expr/mod.rs +++ b/boa/src/syntax/ast/node/await_expr/mod.rs @@ -34,8 +34,8 @@ impl Executable for AwaitExpr { impl AwaitExpr { /// Implements the display formatting with indentation. pub(super) fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result { - writeln!(f, "await ")?; - self.expr.display(f, indentation) + write!(f, "await ")?; + self.expr.display(f, 0) } } From 054c9c0b92e785f23e4fe0a3ef45a3eb3db03db7 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Tue, 8 Jun 2021 17:24:13 -0700 Subject: [PATCH 05/46] Await calls no longer have a custom display() function --- boa/src/syntax/ast/node/await_expr/mod.rs | 11 ++--------- boa/src/syntax/ast/node/mod.rs | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/boa/src/syntax/ast/node/await_expr/mod.rs b/boa/src/syntax/ast/node/await_expr/mod.rs index 5d7ae6917cd..8e6d3265e9f 100644 --- a/boa/src/syntax/ast/node/await_expr/mod.rs +++ b/boa/src/syntax/ast/node/await_expr/mod.rs @@ -31,14 +31,6 @@ impl Executable for AwaitExpr { } } -impl AwaitExpr { - /// Implements the display formatting with indentation. - pub(super) fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result { - write!(f, "await ")?; - self.expr.display(f, 0) - } -} - impl From for AwaitExpr where T: Into>, @@ -50,7 +42,8 @@ where impl fmt::Display for AwaitExpr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.display(f, 0) + write!(f, "await ")?; + self.expr.display(f, 0) } } diff --git a/boa/src/syntax/ast/node/mod.rs b/boa/src/syntax/ast/node/mod.rs index 6f38bb22ed0..7fb0e480cf5 100644 --- a/boa/src/syntax/ast/node/mod.rs +++ b/boa/src/syntax/ast/node/mod.rs @@ -285,7 +285,7 @@ impl Node { Self::ConstDeclList(ref decl) => Display::fmt(decl, f), Self::AsyncFunctionDecl(ref decl) => decl.display(f, indentation), Self::AsyncFunctionExpr(ref expr) => expr.display(f, indentation), - Self::AwaitExpr(ref expr) => expr.display(f, indentation), + Self::AwaitExpr(ref expr) => Display::fmt(expr, f), Self::Empty => write!(f, ";"), } } From a542c8e83f2a9d621f2e5059e6b132e146ede552 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Tue, 8 Jun 2021 17:30:08 -0700 Subject: [PATCH 06/46] Fixed async function declaration --- .../ast/node/declaration/async_function_decl/mod.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs b/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs index 5078b5b2940..8d2064c8caf 100644 --- a/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs +++ b/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs @@ -64,15 +64,11 @@ impl AsyncFunctionDecl { indentation: usize, ) -> fmt::Result { match &self.name { - Some(name) => { - write!(f, "async function {}(", name)?; - } - None => { - write!(f, "async function (")?; - } + Some(name) => write!(f, "async function {}(", name)?, + None => write!(f, "async function (")?, } join_nodes(f, &self.parameters)?; - f.write_str(") {{")?; + writeln!(f, ") {{")?; self.body.display(f, indentation + 1)?; From fd4804ea4d9d9e29a616aa065690abe491a4c2a3 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Tue, 8 Jun 2021 17:33:23 -0700 Subject: [PATCH 07/46] Added spacing to do-while loop --- boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs b/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs index a5d8fcd01eb..397dd2f214b 100644 --- a/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs @@ -64,9 +64,9 @@ impl DoWhileLoop { f: &mut fmt::Formatter<'_>, indentation: usize, ) -> fmt::Result { - write!(f, "do")?; + write!(f, "do ")?; self.body().display(f, indentation)?; - write!(f, "while ({})", self.cond()) + write!(f, " while ({})", self.cond()) } } From 947700126b31387aa5c8f021962e470df2bb6cff Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Tue, 8 Jun 2021 17:35:20 -0700 Subject: [PATCH 08/46] Fixed for of loop --- boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs b/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs index bbdc9547262..34949c1d9d7 100644 --- a/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs @@ -59,9 +59,8 @@ impl ForOfLoop { } pub fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result { - write!(f, "for ({} of {}) {{", self.variable, self.iterable)?; - self.body().display(f, indentation + 1)?; - f.write_str("}") + write!(f, "for ({} of {}) ", self.variable, self.iterable)?; + self.body().display(f, indentation) } } From ddfcfecaaee12d2b9f205631210c69d83f0f7af9 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Tue, 8 Jun 2021 17:39:21 -0700 Subject: [PATCH 09/46] Fixed object declaration formatter --- boa/src/syntax/ast/node/object/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/boa/src/syntax/ast/node/object/mod.rs b/boa/src/syntax/ast/node/object/mod.rs index 8a4fcc37242..a56ff811f92 100644 --- a/boa/src/syntax/ast/node/object/mod.rs +++ b/boa/src/syntax/ast/node/object/mod.rs @@ -53,16 +53,17 @@ impl Object { indent: usize, ) -> fmt::Result { f.write_str("{\n")?; + let indent = " ".repeat(indent + 1); for property in self.properties().iter() { match property { PropertyDefinition::IdentifierReference(key) => { - write!(f, "{} {},", indent, key)?; + writeln!(f, "{}{},", indent, key)?; } PropertyDefinition::Property(key, value) => { - write!(f, "{} {}: {},", indent, key, value)?; + writeln!(f, "{}{}: {},", indent, key, value)?; } PropertyDefinition::SpreadObject(key) => { - write!(f, "{} ...{},", indent, key)?; + writeln!(f, "{}...{},", indent, key)?; } PropertyDefinition::MethodDefinition(_kind, _key, _node) => { // TODO: Implement display for PropertyDefinition::MethodDefinition. From f05a7b49d509dc50af1a1301bc35da25752a6a93 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Tue, 8 Jun 2021 17:46:24 -0700 Subject: [PATCH 10/46] Fixed switch statements formatting --- boa/src/syntax/ast/node/switch/mod.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/boa/src/syntax/ast/node/switch/mod.rs b/boa/src/syntax/ast/node/switch/mod.rs index 41ba6a372fe..ba817b2b47f 100644 --- a/boa/src/syntax/ast/node/switch/mod.rs +++ b/boa/src/syntax/ast/node/switch/mod.rs @@ -105,19 +105,20 @@ impl Switch { pub(in crate::syntax::ast::node) fn display( &self, f: &mut fmt::Formatter<'_>, - indent: usize, + indentation: usize, ) -> fmt::Result { + let indent = " ".repeat(indentation); writeln!(f, "switch ({}) {{", self.val())?; for e in self.cases().iter() { - writeln!(f, "{}case {}:", indent, e.condition())?; - e.body().display(f, indent)?; + writeln!(f, "{} case {}:", indent, e.condition())?; + e.body().display(f, indentation + 2)?; } if let Some(ref default) = self.default { - writeln!(f, "{}default:", indent)?; - default.display(f, indent + 1)?; + writeln!(f, "{} default:", indent)?; + default.display(f, indentation + 2)?; } - writeln!(f, "{}}}", indent) + write!(f, "{}}}", indent) } } From c460f293f7a37c17d2f097f7ff3c44a07c18af57 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 14:19:16 -0700 Subject: [PATCH 11/46] Added operator fmt test --- boa/src/syntax/ast/node/operator/tests.rs | 30 ++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/boa/src/syntax/ast/node/operator/tests.rs b/boa/src/syntax/ast/node/operator/tests.rs index 3fbc80086ad..f25c0ffa495 100644 --- a/boa/src/syntax/ast/node/operator/tests.rs +++ b/boa/src/syntax/ast/node/operator/tests.rs @@ -1,4 +1,4 @@ -use crate::exec; +use crate::{exec, parse}; #[test] fn assignmentoperator_lhs_not_defined() { @@ -113,3 +113,31 @@ fn logical_assignment() { assert_eq!(&exec(scenario), "20"); } + +#[test] +fn fmt() { + let scenario = r#" + let a = 20; + a += 10; + a -= 10; + a *= 10; + a **= 10; + a /= 10; + a %= 10; + a &= 10; + a |= 10; + a ^= 10; + a <<= 10; + a >>= 10; + a >>>= 10; + a &&= 10; + a ||= 10; + a ??= 10; + a; + "#[1..] // Remove the preceding newline + .lines() + .map(|l| l.trim()) // Remove trailing whitespace from each line + .collect::>() + .join("\n"); + assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); +} From bad35743d4dc0116e15aeacab81d143a75c5aceb Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 14:24:39 -0700 Subject: [PATCH 12/46] Added array display test --- boa/src/syntax/ast/node/array/mod.rs | 3 +++ boa/src/syntax/ast/node/array/tests.rs | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 boa/src/syntax/ast/node/array/tests.rs diff --git a/boa/src/syntax/ast/node/array/mod.rs b/boa/src/syntax/ast/node/array/mod.rs index 8bb7f5ac32e..d9ce793584a 100644 --- a/boa/src/syntax/ast/node/array/mod.rs +++ b/boa/src/syntax/ast/node/array/mod.rs @@ -12,6 +12,9 @@ use std::fmt; #[cfg(feature = "deser")] use serde::{Deserialize, Serialize}; +#[cfg(test)] +mod tests; + /// An array is an ordered collection of data (either primitive or object depending upon the /// language). /// diff --git a/boa/src/syntax/ast/node/array/tests.rs b/boa/src/syntax/ast/node/array/tests.rs new file mode 100644 index 00000000000..c090b9da853 --- /dev/null +++ b/boa/src/syntax/ast/node/array/tests.rs @@ -0,0 +1,14 @@ +use crate::parse; + +#[test] +fn fmt() { + let scenario = r#" + let a = [1, 2, 3, "words", "more words"]; + let b = []; + "#[1..] // Remove the preceding newline + .lines() + .map(|l| l.trim()) // Remove trailing whitespace from each line + .collect::>() + .join("\n"); + assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); +} From f13f1da6d81a1cf09873f66c58810c42871209cb Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 14:31:30 -0700 Subject: [PATCH 13/46] Added tests for await expressions. Unclear if let a = await blah() has been implemented yet, but I got parse errors when testing that --- boa/src/syntax/ast/node/await_expr/mod.rs | 3 +++ boa/src/syntax/ast/node/await_expr/tests.rs | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 boa/src/syntax/ast/node/await_expr/tests.rs diff --git a/boa/src/syntax/ast/node/await_expr/mod.rs b/boa/src/syntax/ast/node/await_expr/mod.rs index 8e6d3265e9f..ab1291f18e9 100644 --- a/boa/src/syntax/ast/node/await_expr/mod.rs +++ b/boa/src/syntax/ast/node/await_expr/mod.rs @@ -8,6 +8,9 @@ use std::fmt; #[cfg(feature = "deser")] use serde::{Deserialize, Serialize}; +#[cfg(test)] +mod tests; + /// An await expression is used within an async function to pause execution and wait for a /// promise to resolve. /// diff --git a/boa/src/syntax/ast/node/await_expr/tests.rs b/boa/src/syntax/ast/node/await_expr/tests.rs new file mode 100644 index 00000000000..0881b510470 --- /dev/null +++ b/boa/src/syntax/ast/node/await_expr/tests.rs @@ -0,0 +1,14 @@ +use crate::parse; + +#[test] +fn fmt() { + // TODO: `let a = await fn()` is invalid syntax as of writing. It should be tested here once implemented. + let scenario = r#" + await function_call(); + "#[1..] // Remove the preceding newline + .lines() + .map(|l| l.trim()) // Remove trailing whitespace from each line + .collect::>() + .join("\n"); + assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); +} From 1cc35e52bd868902b1751585fbd47c5fbb06a9b5 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 14:33:59 -0700 Subject: [PATCH 14/46] Added block display test --- boa/src/syntax/ast/node/block/mod.rs | 3 +++ boa/src/syntax/ast/node/block/tests.rs | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 boa/src/syntax/ast/node/block/tests.rs diff --git a/boa/src/syntax/ast/node/block/mod.rs b/boa/src/syntax/ast/node/block/mod.rs index 25abdc3369a..0dcd654389e 100644 --- a/boa/src/syntax/ast/node/block/mod.rs +++ b/boa/src/syntax/ast/node/block/mod.rs @@ -13,6 +13,9 @@ use std::fmt; #[cfg(feature = "deser")] use serde::{Deserialize, Serialize}; +#[cfg(test)] +mod tests; + /// A `block` statement (or compound statement in other languages) is used to group zero or /// more statements. /// diff --git a/boa/src/syntax/ast/node/block/tests.rs b/boa/src/syntax/ast/node/block/tests.rs new file mode 100644 index 00000000000..5e25aac2447 --- /dev/null +++ b/boa/src/syntax/ast/node/block/tests.rs @@ -0,0 +1,17 @@ +use crate::parse; + +#[test] +fn fmt() { + let scenario = r#" + { + let a = function_call(); + console.log("hello"); + } + another_statement(); + "#[1..] // Remove the preceding newline + .lines() + .map(|l| &l[8..]) // Remove preceding whitespace from each line + .collect::>() + .join("\n"); + assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); +} From b27052f19d8d2606cd1ac750cdf5139b88f5b6e7 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 14:42:34 -0700 Subject: [PATCH 15/46] Added break formatting test --- boa/src/syntax/ast/node/break_node/tests.rs | 35 +++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/boa/src/syntax/ast/node/break_node/tests.rs b/boa/src/syntax/ast/node/break_node/tests.rs index 194c22c2b8a..593a392115c 100644 --- a/boa/src/syntax/ast/node/break_node/tests.rs +++ b/boa/src/syntax/ast/node/break_node/tests.rs @@ -1,5 +1,6 @@ use crate::{ exec::{Executable, InterpreterState}, + parse, syntax::ast::node::Break, Context, }; @@ -17,3 +18,37 @@ fn check_post_state() { &InterpreterState::Break(Some("label".into())) ); } + +#[test] +fn fmt() { + // Blocks do not store their label, so we cannot test with + // the outer block having a label. + // + // TODO: Once block labels are implemented, this test should + // include them: + // + // ``` + // outer: { + // while (true) { + // break outer; + // } + // skipped_call(); + // } + // ``` + let scenario = r#" + { + while (true) { + break outer; + } + skipped_call(); + } + while (true) { + break; + } + "#[1..] // Remove the preceding newline + .lines() + .map(|l| &l[8..]) // Remove preceding whitespace from each line + .collect::>() + .join("\n"); + assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); +} From 53e1927969a49ca750ad0ea410514fcac131fe73 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 14:43:37 -0700 Subject: [PATCH 16/46] Added a potential test for when block labels are added --- boa/src/syntax/ast/node/block/tests.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/boa/src/syntax/ast/node/block/tests.rs b/boa/src/syntax/ast/node/block/tests.rs index 5e25aac2447..b6056a67859 100644 --- a/boa/src/syntax/ast/node/block/tests.rs +++ b/boa/src/syntax/ast/node/block/tests.rs @@ -14,4 +14,17 @@ fn fmt() { .collect::>() .join("\n"); assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); + // TODO: Once block labels are implemtned, this should be tested: + // let scenario = r#" + // block_name: { + // let a = function_call(); + // console.log("hello"); + // } + // another_statement(); + // "#[1..] // Remove the preceding newline + // .lines() + // .map(|l| &l[8..]) // Remove preceding whitespace from each line + // .collect::>() + // .join("\n"); + // assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); } From b6ffd899191d3695562e9c16b44f0f59bdaf5548 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 14:45:37 -0700 Subject: [PATCH 17/46] Added call formatting tests --- boa/src/syntax/ast/node/call/mod.rs | 3 +++ boa/src/syntax/ast/node/call/tests.rs | 15 +++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 boa/src/syntax/ast/node/call/tests.rs diff --git a/boa/src/syntax/ast/node/call/mod.rs b/boa/src/syntax/ast/node/call/mod.rs index d6f1b6eba36..d065d76a84f 100644 --- a/boa/src/syntax/ast/node/call/mod.rs +++ b/boa/src/syntax/ast/node/call/mod.rs @@ -12,6 +12,9 @@ use std::fmt; #[cfg(feature = "deser")] use serde::{Deserialize, Serialize}; +#[cfg(test)] +mod tests; + /// Calling the function actually performs the specified actions with the indicated parameters. /// /// Defining a function does not execute it. Defining it simply names the function and diff --git a/boa/src/syntax/ast/node/call/tests.rs b/boa/src/syntax/ast/node/call/tests.rs new file mode 100644 index 00000000000..4e4c960573d --- /dev/null +++ b/boa/src/syntax/ast/node/call/tests.rs @@ -0,0 +1,15 @@ +use crate::parse; + +#[test] +fn fmt() { + let scenario = r#" + call_1(1, 2, 3); + call_2("argument here"); + call_3(); + "#[1..] // Remove the preceding newline + .lines() + .map(|l| &l[8..]) // Remove preceding whitespace from each line + .collect::>() + .join("\n"); + assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); +} From 047442b522ed7d044218138007452199400e34fb Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 14:52:42 -0700 Subject: [PATCH 18/46] Added a testing utility function for formatting tests --- boa/src/syntax/ast/node/mod.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/boa/src/syntax/ast/node/mod.rs b/boa/src/syntax/ast/node/mod.rs index 7fb0e480cf5..949695e7705 100644 --- a/boa/src/syntax/ast/node/mod.rs +++ b/boa/src/syntax/ast/node/mod.rs @@ -588,3 +588,33 @@ pub enum MethodDefinitionKind { unsafe impl Trace for MethodDefinitionKind { empty_trace!(); } + +/// This parses the given source code, and then makes sure that +/// the resulting StatementList is formatted in the same manner +/// as the source code. This is expected to have a preceding +/// newline. +/// +/// This is a utility function for tests. It was made in case people +/// are using different indents in their source files. This fixes +/// any strings which may have been changed in a different indent +/// level. +#[cfg(test)] +fn test_formatting(source: &'static str) { + // Remove preceding newline. + let source = &source[1..]; + + // Find out how much the code is indented + let first_line = &source[..source.find('\n').unwrap()]; + let trimmed_first_line = first_line.trim(); + let characters_to_remove = first_line.len() - trimmed_first_line.len(); + + let scenario = source + .lines() + .map(|l| &l[characters_to_remove..]) // Remove preceding whitespace from each line + .collect::>() + .join("\n"); + assert_eq!( + format!("{}", crate::parse(&scenario, false).unwrap()), + scenario + ); +} From e677dd07b404ad7a9e4680b11369ae5abb6cd400 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 14:55:29 -0700 Subject: [PATCH 19/46] Using custom testing function instead of a bunch of asserts in formatting tests --- boa/src/syntax/ast/node/array/tests.rs | 13 ++++------- boa/src/syntax/ast/node/await_expr/tests.rs | 13 ++++------- boa/src/syntax/ast/node/block/tests.rs | 24 +++++++-------------- boa/src/syntax/ast/node/break_node/tests.rs | 12 ++++------- boa/src/syntax/ast/node/call/tests.rs | 13 ++++------- 5 files changed, 24 insertions(+), 51 deletions(-) diff --git a/boa/src/syntax/ast/node/array/tests.rs b/boa/src/syntax/ast/node/array/tests.rs index c090b9da853..bc14e7b6f80 100644 --- a/boa/src/syntax/ast/node/array/tests.rs +++ b/boa/src/syntax/ast/node/array/tests.rs @@ -1,14 +1,9 @@ -use crate::parse; - #[test] fn fmt() { - let scenario = r#" + super::super::test_formatting( + r#" let a = [1, 2, 3, "words", "more words"]; let b = []; - "#[1..] // Remove the preceding newline - .lines() - .map(|l| l.trim()) // Remove trailing whitespace from each line - .collect::>() - .join("\n"); - assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); + "#, + ); } diff --git a/boa/src/syntax/ast/node/await_expr/tests.rs b/boa/src/syntax/ast/node/await_expr/tests.rs index 0881b510470..b1b30504ae6 100644 --- a/boa/src/syntax/ast/node/await_expr/tests.rs +++ b/boa/src/syntax/ast/node/await_expr/tests.rs @@ -1,14 +1,9 @@ -use crate::parse; - #[test] fn fmt() { // TODO: `let a = await fn()` is invalid syntax as of writing. It should be tested here once implemented. - let scenario = r#" + super::super::test_formatting( + r#" await function_call(); - "#[1..] // Remove the preceding newline - .lines() - .map(|l| l.trim()) // Remove trailing whitespace from each line - .collect::>() - .join("\n"); - assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); + "#, + ); } diff --git a/boa/src/syntax/ast/node/block/tests.rs b/boa/src/syntax/ast/node/block/tests.rs index b6056a67859..b81cba9b846 100644 --- a/boa/src/syntax/ast/node/block/tests.rs +++ b/boa/src/syntax/ast/node/block/tests.rs @@ -1,30 +1,22 @@ -use crate::parse; - #[test] fn fmt() { - let scenario = r#" + super::super::test_formatting( + r#" { let a = function_call(); console.log("hello"); } another_statement(); - "#[1..] // Remove the preceding newline - .lines() - .map(|l| &l[8..]) // Remove preceding whitespace from each line - .collect::>() - .join("\n"); - assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); + "#, + ); // TODO: Once block labels are implemtned, this should be tested: - // let scenario = r#" + // super::super::test_formatting( + // r#" // block_name: { // let a = function_call(); // console.log("hello"); // } // another_statement(); - // "#[1..] // Remove the preceding newline - // .lines() - // .map(|l| &l[8..]) // Remove preceding whitespace from each line - // .collect::>() - // .join("\n"); - // assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); + // "#, + // ); } diff --git a/boa/src/syntax/ast/node/break_node/tests.rs b/boa/src/syntax/ast/node/break_node/tests.rs index 593a392115c..20487ee3998 100644 --- a/boa/src/syntax/ast/node/break_node/tests.rs +++ b/boa/src/syntax/ast/node/break_node/tests.rs @@ -1,6 +1,5 @@ use crate::{ exec::{Executable, InterpreterState}, - parse, syntax::ast::node::Break, Context, }; @@ -35,7 +34,8 @@ fn fmt() { // skipped_call(); // } // ``` - let scenario = r#" + super::super::test_formatting( + r#" { while (true) { break outer; @@ -45,10 +45,6 @@ fn fmt() { while (true) { break; } - "#[1..] // Remove the preceding newline - .lines() - .map(|l| &l[8..]) // Remove preceding whitespace from each line - .collect::>() - .join("\n"); - assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); + "#, + ); } diff --git a/boa/src/syntax/ast/node/call/tests.rs b/boa/src/syntax/ast/node/call/tests.rs index 4e4c960573d..e3dd74d85aa 100644 --- a/boa/src/syntax/ast/node/call/tests.rs +++ b/boa/src/syntax/ast/node/call/tests.rs @@ -1,15 +1,10 @@ -use crate::parse; - #[test] fn fmt() { - let scenario = r#" + super::super::test_formatting( + r#" call_1(1, 2, 3); call_2("argument here"); call_3(); - "#[1..] // Remove the preceding newline - .lines() - .map(|l| &l[8..]) // Remove preceding whitespace from each line - .collect::>() - .join("\n"); - assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); + "#, + ); } From feaf76883cf674802c87f1b43b127696a40c900a Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 15:05:26 -0700 Subject: [PATCH 20/46] Improved formatting of failed parsing formatting tests --- boa/src/syntax/ast/node/mod.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/boa/src/syntax/ast/node/mod.rs b/boa/src/syntax/ast/node/mod.rs index 949695e7705..3c7745607cb 100644 --- a/boa/src/syntax/ast/node/mod.rs +++ b/boa/src/syntax/ast/node/mod.rs @@ -613,8 +613,13 @@ fn test_formatting(source: &'static str) { .map(|l| &l[characters_to_remove..]) // Remove preceding whitespace from each line .collect::>() .join("\n"); - assert_eq!( - format!("{}", crate::parse(&scenario, false).unwrap()), - scenario - ); + let result = format!("{}", crate::parse(&scenario, false).unwrap()); + if scenario != result { + print!("========= Expected:\n{}", scenario); + print!("========= Got:\n{}", result); + // Might be helpful to find differing whitespace + println!("========= Expected: {:?}", scenario); + println!("========= Got: {:?}", result); + panic!("parsing test did not give the correct result (see above)"); + } } From 325b26232848972e8542f5e77eec102ad4782f7a Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 15:05:47 -0700 Subject: [PATCH 21/46] Added conditional formatting tests --- boa/src/syntax/ast/node/conditional/mod.rs | 3 +++ boa/src/syntax/ast/node/conditional/tests.rs | 13 +++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 boa/src/syntax/ast/node/conditional/tests.rs diff --git a/boa/src/syntax/ast/node/conditional/mod.rs b/boa/src/syntax/ast/node/conditional/mod.rs index fdfe8ea81ff..68b1d424db1 100644 --- a/boa/src/syntax/ast/node/conditional/mod.rs +++ b/boa/src/syntax/ast/node/conditional/mod.rs @@ -4,3 +4,6 @@ pub mod conditional_op; pub mod if_node; pub use self::{conditional_op::ConditionalOp, if_node::If}; + +#[cfg(test)] +mod tests; diff --git a/boa/src/syntax/ast/node/conditional/tests.rs b/boa/src/syntax/ast/node/conditional/tests.rs new file mode 100644 index 00000000000..d1900164645 --- /dev/null +++ b/boa/src/syntax/ast/node/conditional/tests.rs @@ -0,0 +1,13 @@ +#[test] +fn fmt() { + super::super::test_formatting( + r#" + let a = true ? 5 : 6; + if (false) { + a = 10; + } else { + a = 20; + } + "#, + ); +} From f288f63487bf97428833e43117850c9075d57ae1 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 15:13:51 -0700 Subject: [PATCH 22/46] Wrote function tests, and found out that functions are still horribly broken --- boa/src/syntax/ast/node/declaration/tests.rs | 29 ++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/boa/src/syntax/ast/node/declaration/tests.rs b/boa/src/syntax/ast/node/declaration/tests.rs index a98ac86f523..dd5f4412440 100644 --- a/boa/src/syntax/ast/node/declaration/tests.rs +++ b/boa/src/syntax/ast/node/declaration/tests.rs @@ -10,3 +10,32 @@ fn duplicate_function_name() { assert_eq!(&exec(scenario), "12"); } + +#[test] +fn fmt() { + super::super::test_formatting( + r#" + let arrow_func = (a, b) => { + console.log("in multi statement arrow"); + console.log(b); + }; + async function async_func(a, b) { + console.log(a); + }; + pass_async_func(async function(a, b) { + console.log("in async callback", a); + }); + function func(a, b) { + console.log(a); + }; + pass_func(function(a, b) { + console.log("in callback", a); + }); + let arrow_func_2 = (a, b) => {}; + async function async_func_2(a, b) {}; + pass_async_func(async function(a, b) {}); + function func_2(a, b) {}; + pass_func(function(a, b) {}); + "#, + ); +} From f56dee8b635f23170892bb0834a113737e6d7516 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 15:16:59 -0700 Subject: [PATCH 23/46] Fixed arrow function declaration --- .../ast/node/declaration/arrow_function_decl/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/boa/src/syntax/ast/node/declaration/arrow_function_decl/mod.rs b/boa/src/syntax/ast/node/declaration/arrow_function_decl/mod.rs index 6646a9542dd..43c57b482a9 100644 --- a/boa/src/syntax/ast/node/declaration/arrow_function_decl/mod.rs +++ b/boa/src/syntax/ast/node/declaration/arrow_function_decl/mod.rs @@ -61,8 +61,13 @@ impl ArrowFunctionDecl { ) -> fmt::Result { write!(f, "(")?; join_nodes(f, &self.params)?; - f.write_str(") => ")?; - self.body.display(f, indentation) + if self.body().is_empty() { + f.write_str(") => {}") + } else { + f.write_str(") => {\n")?; + self.body.display(f, indentation + 1)?; + write!(f, "{}}}", " ".repeat(indentation)) + } } } From c7d66f487d87e50d04aa81dd26873a6d163a7781 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 15:20:40 -0700 Subject: [PATCH 24/46] Fixed the formatting for the rest of the functions. Async function expressions don't seem to be parsed correctly --- .../ast/node/declaration/async_function_decl/mod.rs | 12 +++++++----- .../ast/node/declaration/async_function_expr/mod.rs | 12 +++++++----- .../syntax/ast/node/declaration/function_decl/mod.rs | 12 +++++++----- .../syntax/ast/node/declaration/function_expr/mod.rs | 12 +++++++----- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs b/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs index 8d2064c8caf..8416843de5e 100644 --- a/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs +++ b/boa/src/syntax/ast/node/declaration/async_function_decl/mod.rs @@ -68,11 +68,13 @@ impl AsyncFunctionDecl { None => write!(f, "async function (")?, } join_nodes(f, &self.parameters)?; - writeln!(f, ") {{")?; - - self.body.display(f, indentation + 1)?; - - writeln!(f, "}}") + if self.body().is_empty() { + f.write_str(") {}") + } else { + f.write_str(") {\n")?; + self.body.display(f, indentation + 1)?; + write!(f, "{}}}", " ".repeat(indentation)) + } } } diff --git a/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs b/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs index 056976f9619..c67a8a5781a 100644 --- a/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs +++ b/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs @@ -70,11 +70,13 @@ impl AsyncFunctionExpr { } f.write_str("(")?; join_nodes(f, &self.parameters)?; - f.write_str(") {{")?; - - self.body.display(f, indentation + 1)?; - - writeln!(f, "}}") + if self.body().is_empty() { + f.write_str(") {}") + } else { + f.write_str(") {\n")?; + self.body.display(f, indentation + 1)?; + write!(f, "{}}}", " ".repeat(indentation)) + } } } diff --git a/boa/src/syntax/ast/node/declaration/function_decl/mod.rs b/boa/src/syntax/ast/node/declaration/function_decl/mod.rs index cf38e1326be..88eb70baaeb 100644 --- a/boa/src/syntax/ast/node/declaration/function_decl/mod.rs +++ b/boa/src/syntax/ast/node/declaration/function_decl/mod.rs @@ -75,11 +75,13 @@ impl FunctionDecl { ) -> fmt::Result { write!(f, "function {}(", self.name)?; join_nodes(f, &self.parameters)?; - writeln!(f, ") {{")?; - - self.body.display(f, indentation + 1)?; - - writeln!(f, "{}}}", " ".repeat(indentation)) + if self.body().is_empty() { + f.write_str(") {}") + } else { + f.write_str(") {\n")?; + self.body.display(f, indentation + 1)?; + write!(f, "{}}}", " ".repeat(indentation)) + } } } diff --git a/boa/src/syntax/ast/node/declaration/function_expr/mod.rs b/boa/src/syntax/ast/node/declaration/function_expr/mod.rs index de8d6c76ab6..6319feab5be 100644 --- a/boa/src/syntax/ast/node/declaration/function_expr/mod.rs +++ b/boa/src/syntax/ast/node/declaration/function_expr/mod.rs @@ -76,11 +76,13 @@ impl FunctionExpr { } f.write_str("(")?; join_nodes(f, &self.parameters)?; - writeln!(f, ") {{")?; - - self.body.display(f, indentation + 1)?; - - write!(f, "}}") + if self.body().is_empty() { + f.write_str(") {}") + } else { + f.write_str(") {\n")?; + self.body.display(f, indentation + 1)?; + write!(f, "{}}}", " ".repeat(indentation)) + } } } From 847eac2ded443d0293fa345cb94a820347f5bd6b Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 15:23:18 -0700 Subject: [PATCH 25/46] Re-ordered functions to match the output of StatementList --- boa/src/syntax/ast/node/declaration/tests.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/boa/src/syntax/ast/node/declaration/tests.rs b/boa/src/syntax/ast/node/declaration/tests.rs index dd5f4412440..a6ac25b9734 100644 --- a/boa/src/syntax/ast/node/declaration/tests.rs +++ b/boa/src/syntax/ast/node/declaration/tests.rs @@ -13,8 +13,14 @@ fn duplicate_function_name() { #[test] fn fmt() { + // TODO: Async function expr are considered valid syntax, but are converted + // into normal functions somewhere in the parser. super::super::test_formatting( r#" + function func(a, b) { + console.log(a); + }; + function func_2(a, b) {}; let arrow_func = (a, b) => { console.log("in multi statement arrow"); console.log(b); @@ -22,19 +28,15 @@ fn fmt() { async function async_func(a, b) { console.log(a); }; - pass_async_func(async function(a, b) { + pass_async_func(function(a, b) { console.log("in async callback", a); }); - function func(a, b) { - console.log(a); - }; pass_func(function(a, b) { console.log("in callback", a); }); let arrow_func_2 = (a, b) => {}; async function async_func_2(a, b) {}; - pass_async_func(async function(a, b) {}); - function func_2(a, b) {}; + pass_async_func(function(a, b) {}); pass_func(function(a, b) {}); "#, ); From 8ae1744eea7fe5980a58f5eca57c213fa63d8021 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Wed, 9 Jun 2021 15:24:37 -0700 Subject: [PATCH 26/46] Fixed async function expressions --- .../syntax/ast/node/declaration/async_function_expr/mod.rs | 2 +- boa/src/syntax/ast/node/declaration/tests.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs b/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs index c67a8a5781a..2bc9dd3ccc1 100644 --- a/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs +++ b/boa/src/syntax/ast/node/declaration/async_function_expr/mod.rs @@ -64,7 +64,7 @@ impl AsyncFunctionExpr { f: &mut fmt::Formatter<'_>, indentation: usize, ) -> fmt::Result { - f.write_str("function")?; + f.write_str("async function")?; if let Some(ref name) = self.name { write!(f, " {}", name)?; } diff --git a/boa/src/syntax/ast/node/declaration/tests.rs b/boa/src/syntax/ast/node/declaration/tests.rs index a6ac25b9734..7c6dec9a95e 100644 --- a/boa/src/syntax/ast/node/declaration/tests.rs +++ b/boa/src/syntax/ast/node/declaration/tests.rs @@ -13,8 +13,6 @@ fn duplicate_function_name() { #[test] fn fmt() { - // TODO: Async function expr are considered valid syntax, but are converted - // into normal functions somewhere in the parser. super::super::test_formatting( r#" function func(a, b) { @@ -28,7 +26,7 @@ fn fmt() { async function async_func(a, b) { console.log(a); }; - pass_async_func(function(a, b) { + pass_async_func(async function(a, b) { console.log("in async callback", a); }); pass_func(function(a, b) { @@ -36,7 +34,7 @@ fn fmt() { }); let arrow_func_2 = (a, b) => {}; async function async_func_2(a, b) {}; - pass_async_func(function(a, b) {}); + pass_async_func(async function(a, b) {}); pass_func(function(a, b) {}); "#, ); From 1173d8dfbb6179c47f7a650afbc863f0a3b53a00 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Thu, 10 Jun 2021 23:10:07 -0700 Subject: [PATCH 27/46] Added field formatting tests --- boa/src/syntax/ast/node/field/mod.rs | 3 +++ boa/src/syntax/ast/node/field/tests.rs | 10 ++++++++++ 2 files changed, 13 insertions(+) create mode 100644 boa/src/syntax/ast/node/field/tests.rs diff --git a/boa/src/syntax/ast/node/field/mod.rs b/boa/src/syntax/ast/node/field/mod.rs index 8c52719e8f5..54455ff5dfc 100644 --- a/boa/src/syntax/ast/node/field/mod.rs +++ b/boa/src/syntax/ast/node/field/mod.rs @@ -4,3 +4,6 @@ pub mod get_const_field; pub mod get_field; pub use self::{get_const_field::GetConstField, get_field::GetField}; + +#[cfg(test)] +mod tests; diff --git a/boa/src/syntax/ast/node/field/tests.rs b/boa/src/syntax/ast/node/field/tests.rs new file mode 100644 index 00000000000..3c4cb69ce91 --- /dev/null +++ b/boa/src/syntax/ast/node/field/tests.rs @@ -0,0 +1,10 @@ +#[test] +fn fmt() { + super::super::test_formatting( + r#" + a.field_name; + a[5]; + a["other_field_name"]; + "#, + ); +} From c568bf68f464d759e1e3bdf202bbb5397aedbb93 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Thu, 10 Jun 2021 23:12:45 -0700 Subject: [PATCH 28/46] Added formatting test for 'for' loops --- boa/src/syntax/ast/node/iteration/tests.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/boa/src/syntax/ast/node/iteration/tests.rs b/boa/src/syntax/ast/node/iteration/tests.rs index 9dc9bb61541..080e2073805 100644 --- a/boa/src/syntax/ast/node/iteration/tests.rs +++ b/boa/src/syntax/ast/node/iteration/tests.rs @@ -502,3 +502,22 @@ fn for_in_continue_label() { "#; assert_eq!(&exec(scenario), "\"00\"") } + +#[test] +fn fmt() { + super::super::test_formatting( + r#" + var str = ""; + outer: for (let i in [1, 2]) { + inner: for (let b in [2, 3, 4]) { + if (b === "1") { + continue outer; + } + str = str + b; + }; + str = str + i; + }; + str; + "#, + ); +} From 6c96c08f3bdf4d910654508eea8e52ef6f49c2a7 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Thu, 10 Jun 2021 23:14:56 -0700 Subject: [PATCH 29/46] For in loops now display their label if they have one --- boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs | 3 +++ boa/src/syntax/ast/node/iteration/tests.rs | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs b/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs index 2d596c6cc26..b2b0c91f5d0 100644 --- a/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_in_loop/mod.rs @@ -59,6 +59,9 @@ impl ForInLoop { } pub fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result { + if let Some(ref label) = self.label { + write!(f, "{}: ", label)?; + } write!(f, "for ({} in {}) ", self.variable, self.expr)?; self.body().display(f, indentation) } diff --git a/boa/src/syntax/ast/node/iteration/tests.rs b/boa/src/syntax/ast/node/iteration/tests.rs index 080e2073805..b2e17a22b28 100644 --- a/boa/src/syntax/ast/node/iteration/tests.rs +++ b/boa/src/syntax/ast/node/iteration/tests.rs @@ -505,11 +505,12 @@ fn for_in_continue_label() { #[test] fn fmt() { + // Labeled and unlabeled for in loops super::super::test_formatting( r#" var str = ""; outer: for (let i in [1, 2]) { - inner: for (let b in [2, 3, 4]) { + for (let b in [2, 3, 4]) { if (b === "1") { continue outer; } From 1b9d6900116e111079c282dd4db4e3ede5bf9903 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Thu, 10 Jun 2021 23:28:44 -0700 Subject: [PATCH 30/46] Added test for the rest of the loops --- boa/src/syntax/ast/node/iteration/tests.rs | 53 ++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/boa/src/syntax/ast/node/iteration/tests.rs b/boa/src/syntax/ast/node/iteration/tests.rs index b2e17a22b28..85f48dc0ea6 100644 --- a/boa/src/syntax/ast/node/iteration/tests.rs +++ b/boa/src/syntax/ast/node/iteration/tests.rs @@ -521,4 +521,57 @@ fn fmt() { str; "#, ); + // Labeled and unlabeled for loops + super::super::test_formatting( + r#" + var str = ""; + outer: for (let i = 0; i < 10; i++) { + for (let j = 3; j < 6; j++) { + if (j === "1") { + continue outer; + } + str = str + j; + }; + str = str + i; + }; + str; + "#, + ); + // Labeled and unlabeled for of loops + super::super::test_formatting( + r#" + for (i of [1, 2, 3]) { + if (false) { + break; + } + } + label: for (i of [1, 2, 3]) { + if (false) { + break label; + } + } + "#, + ); + // Labeled and unlabeled do while loops + super::super::test_formatting( + r#" + do { + break; + } while (true); + label: do { + break label; + } while (true); + "#, + ); + // Labeled and unlabeled while loops + super::super::test_formatting( + r#" + while (true) { + break; + } + label: while (true) { + break label; + } + "#, + ); } From a941baf9381601dcb0e8f874c672d8e1b4fc2a67 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Thu, 10 Jun 2021 23:31:28 -0700 Subject: [PATCH 31/46] Added fmt for labels for all the types of loops --- .../syntax/ast/node/iteration/continue_node/mod.rs | 14 +++++--------- .../syntax/ast/node/iteration/do_while_loop/mod.rs | 3 +++ boa/src/syntax/ast/node/iteration/for_loop/mod.rs | 3 +++ .../syntax/ast/node/iteration/for_of_loop/mod.rs | 3 +++ boa/src/syntax/ast/node/iteration/tests.rs | 8 ++++---- .../syntax/ast/node/iteration/while_loop/mod.rs | 3 +++ 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/boa/src/syntax/ast/node/iteration/continue_node/mod.rs b/boa/src/syntax/ast/node/iteration/continue_node/mod.rs index f42864339dd..9322d483106 100644 --- a/boa/src/syntax/ast/node/iteration/continue_node/mod.rs +++ b/boa/src/syntax/ast/node/iteration/continue_node/mod.rs @@ -57,15 +57,11 @@ impl Executable for Continue { impl fmt::Display for Continue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "continue{}", - if let Some(label) = self.label() { - format!(" {}", label) - } else { - String::new() - } - ) + write!(f, "continue")?; + if let Some(label) = self.label() { + write!(f, " {}", label)?; + } + Ok(()) } } diff --git a/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs b/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs index 397dd2f214b..7659cefe60f 100644 --- a/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/do_while_loop/mod.rs @@ -64,6 +64,9 @@ impl DoWhileLoop { f: &mut fmt::Formatter<'_>, indentation: usize, ) -> fmt::Result { + if let Some(ref label) = self.label { + write!(f, "{}: ", label)?; + } write!(f, "do ")?; self.body().display(f, indentation)?; write!(f, " while ({})", self.cond()) diff --git a/boa/src/syntax/ast/node/iteration/for_loop/mod.rs b/boa/src/syntax/ast/node/iteration/for_loop/mod.rs index f992edd924c..8d1dbd435d0 100644 --- a/boa/src/syntax/ast/node/iteration/for_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_loop/mod.rs @@ -69,6 +69,9 @@ impl ForLoop { f: &mut fmt::Formatter<'_>, indentation: usize, ) -> fmt::Result { + if let Some(ref label) = self.label { + write!(f, "{}: ", label)?; + } f.write_str("for (")?; if let Some(init) = self.init() { fmt::Display::fmt(init, f)?; diff --git a/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs b/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs index 34949c1d9d7..48e56cb8ed0 100644 --- a/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/for_of_loop/mod.rs @@ -59,6 +59,9 @@ impl ForOfLoop { } pub fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result { + if let Some(ref label) = self.label { + write!(f, "{}: ", label)?; + } write!(f, "for ({} of {}) ", self.variable, self.iterable)?; self.body().display(f, indentation) } diff --git a/boa/src/syntax/ast/node/iteration/tests.rs b/boa/src/syntax/ast/node/iteration/tests.rs index 85f48dc0ea6..36154b8bddc 100644 --- a/boa/src/syntax/ast/node/iteration/tests.rs +++ b/boa/src/syntax/ast/node/iteration/tests.rs @@ -525,8 +525,8 @@ fn fmt() { super::super::test_formatting( r#" var str = ""; - outer: for (let i = 0; i < 10; i++) { - for (let j = 3; j < 6; j++) { + outer: for (let i = 0; i < 10; ++i) { + for (let j = 3; j < 6; ++j) { if (j === "1") { continue outer; } @@ -544,12 +544,12 @@ fn fmt() { if (false) { break; } - } + }; label: for (i of [1, 2, 3]) { if (false) { break label; } - } + }; "#, ); // Labeled and unlabeled do while loops diff --git a/boa/src/syntax/ast/node/iteration/while_loop/mod.rs b/boa/src/syntax/ast/node/iteration/while_loop/mod.rs index 4323a8b7b61..3c6afbbd97e 100644 --- a/boa/src/syntax/ast/node/iteration/while_loop/mod.rs +++ b/boa/src/syntax/ast/node/iteration/while_loop/mod.rs @@ -63,6 +63,9 @@ impl WhileLoop { f: &mut fmt::Formatter<'_>, indentation: usize, ) -> fmt::Result { + if let Some(ref label) = self.label { + write!(f, "{}: ", label)?; + } write!(f, "while ({}) ", self.cond())?; self.expr().display(f, indentation) } From 0430c399b459a5a22094b18cb8a4d4e41c35e315 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Thu, 10 Jun 2021 23:33:26 -0700 Subject: [PATCH 32/46] Added test for new keyword formatting --- boa/src/syntax/ast/node/new/mod.rs | 3 +++ boa/src/syntax/ast/node/new/tests.rs | 9 +++++++++ 2 files changed, 12 insertions(+) create mode 100644 boa/src/syntax/ast/node/new/tests.rs diff --git a/boa/src/syntax/ast/node/new/mod.rs b/boa/src/syntax/ast/node/new/mod.rs index 37a0100551f..59ce787ee75 100644 --- a/boa/src/syntax/ast/node/new/mod.rs +++ b/boa/src/syntax/ast/node/new/mod.rs @@ -11,6 +11,9 @@ use std::fmt; #[cfg(feature = "deser")] use serde::{Deserialize, Serialize}; +#[cfg(test)] +mod tests; + /// The `new` operator lets developers create an instance of a user-defined object type or of /// one of the built-in object types that has a constructor function. /// diff --git a/boa/src/syntax/ast/node/new/tests.rs b/boa/src/syntax/ast/node/new/tests.rs new file mode 100644 index 00000000000..bd9a233f7ce --- /dev/null +++ b/boa/src/syntax/ast/node/new/tests.rs @@ -0,0 +1,9 @@ +#[test] +fn fmt() { + super::super::test_formatting( + r#" + function MyClass() {}; + let inst = new MyClass(); + "#, + ); +} From b8d870bcc3e84887bf765adc1519d630b85285ea Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Thu, 10 Jun 2021 23:36:47 -0700 Subject: [PATCH 33/46] Added object formatting --- boa/src/syntax/ast/node/object/mod.rs | 3 +++ boa/src/syntax/ast/node/object/tests.rs | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 boa/src/syntax/ast/node/object/tests.rs diff --git a/boa/src/syntax/ast/node/object/mod.rs b/boa/src/syntax/ast/node/object/mod.rs index a56ff811f92..c611a410ad6 100644 --- a/boa/src/syntax/ast/node/object/mod.rs +++ b/boa/src/syntax/ast/node/object/mod.rs @@ -15,6 +15,9 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "vm")] use crate::vm::{compilation::CodeGen, Compiler, Instruction}; +#[cfg(test)] +mod tests; + /// 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/src/syntax/ast/node/object/tests.rs b/boa/src/syntax/ast/node/object/tests.rs new file mode 100644 index 00000000000..25ac1beeba3 --- /dev/null +++ b/boa/src/syntax/ast/node/object/tests.rs @@ -0,0 +1,18 @@ +#[test] +fn fmt() { + super::super::test_formatting( + r#" + let inst = { + a: 5, + b: "hello world", + nested: { + a: 5, + b: 6, + }, + say_hi: function() { + console.log("hello!"); + } + }; + "#, + ); +} From 93fd514c4cf50913185b7c12a5f7a6789e27a83f Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Thu, 10 Jun 2021 23:50:32 -0700 Subject: [PATCH 34/46] Partially fixed object display function --- boa/src/syntax/ast/node/object/mod.rs | 17 ++++++++++++----- boa/src/syntax/ast/node/object/tests.rs | 4 ++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/boa/src/syntax/ast/node/object/mod.rs b/boa/src/syntax/ast/node/object/mod.rs index c611a410ad6..95d0384c078 100644 --- a/boa/src/syntax/ast/node/object/mod.rs +++ b/boa/src/syntax/ast/node/object/mod.rs @@ -56,17 +56,24 @@ impl Object { indent: usize, ) -> fmt::Result { f.write_str("{\n")?; - let indent = " ".repeat(indent + 1); + let indentation = " ".repeat(indent + 1); for property in self.properties().iter() { match property { PropertyDefinition::IdentifierReference(key) => { - writeln!(f, "{}{},", indent, key)?; + writeln!(f, "{}{},", indentation, key)?; } PropertyDefinition::Property(key, value) => { - writeln!(f, "{}{}: {},", indent, key, value)?; + dbg!(&value); + if let Node::Object(ref inner) = value { + write!(f, "{}{}: ", indentation, key)?; + inner.display(f, indent + 1)?; + writeln!(f, ",")?; + } else { + writeln!(f, "{}{}: {},", indentation, key, value)?; + } } PropertyDefinition::SpreadObject(key) => { - writeln!(f, "{}...{},", indent, key)?; + writeln!(f, "{}...{},", indentation, key)?; } PropertyDefinition::MethodDefinition(_kind, _key, _node) => { // TODO: Implement display for PropertyDefinition::MethodDefinition. @@ -74,7 +81,7 @@ impl Object { } } } - f.write_str("}") + write!(f, "{}}}", " ".repeat(indent)) } } diff --git a/boa/src/syntax/ast/node/object/tests.rs b/boa/src/syntax/ast/node/object/tests.rs index 25ac1beeba3..2ba24ffb40b 100644 --- a/boa/src/syntax/ast/node/object/tests.rs +++ b/boa/src/syntax/ast/node/object/tests.rs @@ -2,6 +2,9 @@ fn fmt() { super::super::test_formatting( r#" + let other = { + c: 10, + }; let inst = { a: 5, b: "hello world", @@ -9,6 +12,7 @@ fn fmt() { a: 5, b: 6, }, + ...other, say_hi: function() { console.log("hello!"); } From 8a8a1d047d985ae88a3436b6fa0365cf39a84420 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Mon, 14 Jun 2021 13:21:43 -0700 Subject: [PATCH 35/46] Split Node::display into two functions, allowing objects to be displayed correctly --- boa/src/syntax/ast/node/mod.rs | 16 +++++++++++++++- boa/src/syntax/ast/node/object/mod.rs | 11 +++-------- boa/src/syntax/ast/node/object/tests.rs | 5 ++++- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/boa/src/syntax/ast/node/mod.rs b/boa/src/syntax/ast/node/mod.rs index 3c7745607cb..eef6951ac2b 100644 --- a/boa/src/syntax/ast/node/mod.rs +++ b/boa/src/syntax/ast/node/mod.rs @@ -239,14 +239,28 @@ impl Node { Self::This } - /// Implements the display formatting with indentation. + /// Displays the value of the node with the given indentation. For example, an indent + /// level of 2 would produce this: + /// + /// ```js + /// function hello() { + /// console.log("hello"); + /// } + /// hello(); + /// a = 2; + /// ``` fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result { let indent = " ".repeat(indentation); match *self { Self::Block(_) => {} _ => write!(f, "{}", indent)?, } + self.display_no_indent(f, indentation) + } + /// Implements the display formatting with indentation. This will not prefix the value with + /// any indentation. If you want to prefix this with proper indents, use [`display`](Self::display). + fn display_no_indent(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result { match *self { Self::Call(ref expr) => Display::fmt(expr, f), Self::Const(ref c) => write!(f, "{}", c), diff --git a/boa/src/syntax/ast/node/object/mod.rs b/boa/src/syntax/ast/node/object/mod.rs index 95d0384c078..3cbb1285d10 100644 --- a/boa/src/syntax/ast/node/object/mod.rs +++ b/boa/src/syntax/ast/node/object/mod.rs @@ -63,14 +63,9 @@ impl Object { writeln!(f, "{}{},", indentation, key)?; } PropertyDefinition::Property(key, value) => { - dbg!(&value); - if let Node::Object(ref inner) = value { - write!(f, "{}{}: ", indentation, key)?; - inner.display(f, indent + 1)?; - writeln!(f, ",")?; - } else { - writeln!(f, "{}{}: {},", indentation, key, value)?; - } + write!(f, "{}{}: ", indentation, key,)?; + value.display_no_indent(f, indent + 1)?; + writeln!(f, ",")?; } PropertyDefinition::SpreadObject(key) => { writeln!(f, "{}...{},", indentation, key)?; diff --git a/boa/src/syntax/ast/node/object/tests.rs b/boa/src/syntax/ast/node/object/tests.rs index 2ba24ffb40b..d579c9f091b 100644 --- a/boa/src/syntax/ast/node/object/tests.rs +++ b/boa/src/syntax/ast/node/object/tests.rs @@ -15,7 +15,10 @@ fn fmt() { ...other, say_hi: function() { console.log("hello!"); - } + }, + get a() { + return this.a + 1; + }, }; "#, ); From bf81ee46c890794b6dc6995e85b65a96726ca109 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Mon, 14 Jun 2021 13:39:38 -0700 Subject: [PATCH 36/46] Added a first implementation of a MethodDefinition formatter --- .../ast/node/declaration/function_expr/mod.rs | 15 +++++++++++++-- boa/src/syntax/ast/node/object/mod.rs | 17 +++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/boa/src/syntax/ast/node/declaration/function_expr/mod.rs b/boa/src/syntax/ast/node/declaration/function_expr/mod.rs index 6319feab5be..e5c80c7d99d 100644 --- a/boa/src/syntax/ast/node/declaration/function_expr/mod.rs +++ b/boa/src/syntax/ast/node/declaration/function_expr/mod.rs @@ -76,10 +76,21 @@ impl FunctionExpr { } f.write_str("(")?; join_nodes(f, &self.parameters)?; + f.write_str(") ")?; + self.display_block(f, indentation) + } + + /// Displays the function's body. This includes the curly braces at the start and end. + /// This will not indent the first brace, but will indent the last brace. + pub(in crate::syntax::ast::node) fn display_block( + &self, + f: &mut fmt::Formatter<'_>, + indentation: usize, + ) -> fmt::Result { if self.body().is_empty() { - f.write_str(") {}") + f.write_str("{}") } else { - f.write_str(") {\n")?; + f.write_str("{\n")?; self.body.display(f, indentation + 1)?; write!(f, "{}}}", " ".repeat(indentation)) } diff --git a/boa/src/syntax/ast/node/object/mod.rs b/boa/src/syntax/ast/node/object/mod.rs index 3cbb1285d10..0bdb93147d7 100644 --- a/boa/src/syntax/ast/node/object/mod.rs +++ b/boa/src/syntax/ast/node/object/mod.rs @@ -4,7 +4,7 @@ use crate::{ exec::Executable, gc::{Finalize, Trace}, property::{AccessorDescriptor, Attribute, DataDescriptor, PropertyDescriptor}, - syntax::ast::node::{MethodDefinitionKind, Node, PropertyDefinition}, + syntax::ast::node::{join_nodes, MethodDefinitionKind, Node, PropertyDefinition}, BoaProfiler, Context, Result, Value, }; use std::fmt; @@ -70,9 +70,18 @@ impl Object { PropertyDefinition::SpreadObject(key) => { writeln!(f, "{}...{},", indentation, key)?; } - PropertyDefinition::MethodDefinition(_kind, _key, _node) => { - // TODO: Implement display for PropertyDefinition::MethodDefinition. - unimplemented!("Display for PropertyDefinition::MethodDefinition"); + PropertyDefinition::MethodDefinition(kind, key, node) => { + write!(f, "{}", indentation)?; + match &kind { + MethodDefinitionKind::Get => write!(f, "get ")?, + MethodDefinitionKind::Set => write!(f, "set ")?, + MethodDefinitionKind::Ordinary => (), + } + write!(f, "{}(", key)?; + join_nodes(f, &node.parameters())?; + write!(f, ") ")?; + node.display_block(f, indent + 1)?; + writeln!(f, ",")?; } } } From cd1adab57be32fd4fcc2b1dcab3f35be243721c6 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Mon, 14 Jun 2021 13:49:21 -0700 Subject: [PATCH 37/46] Added tests for the rest of object function fields (every branch of MethodDefinitionField) --- boa/src/syntax/ast/node/object/tests.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/boa/src/syntax/ast/node/object/tests.rs b/boa/src/syntax/ast/node/object/tests.rs index d579c9f091b..64b4594ba9a 100644 --- a/boa/src/syntax/ast/node/object/tests.rs +++ b/boa/src/syntax/ast/node/object/tests.rs @@ -6,7 +6,7 @@ fn fmt() { c: 10, }; let inst = { - a: 5, + val: 5, b: "hello world", nested: { a: 5, @@ -17,9 +17,18 @@ fn fmt() { console.log("hello!"); }, get a() { - return this.a + 1; + return this.val + 1; + }, + set a(new_value) { + this.val = new_value; + }, + say_hello(msg) { + console.log("hello " + msg); }, }; + inst.a = 20; + inst.a; + inst.say_hello("humans"); "#, ); } From 923875e6281ca4e8a50aa0341f39efd4f419ae40 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Mon, 14 Jun 2021 13:51:26 -0700 Subject: [PATCH 38/46] Operator test uses propper formatting test --- boa/src/syntax/ast/node/operator/tests.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/boa/src/syntax/ast/node/operator/tests.rs b/boa/src/syntax/ast/node/operator/tests.rs index f25c0ffa495..90e1544a64e 100644 --- a/boa/src/syntax/ast/node/operator/tests.rs +++ b/boa/src/syntax/ast/node/operator/tests.rs @@ -116,7 +116,8 @@ fn logical_assignment() { #[test] fn fmt() { - let scenario = r#" + super::super::test_formatting( + r#" let a = 20; a += 10; a -= 10; @@ -134,10 +135,6 @@ fn fmt() { a ||= 10; a ??= 10; a; - "#[1..] // Remove the preceding newline - .lines() - .map(|l| l.trim()) // Remove trailing whitespace from each line - .collect::>() - .join("\n"); - assert_eq!(format!("{}", parse(&scenario, false).unwrap()), scenario); + "#, + ); } From f024c685edbc6d7a85723c0b83e388d920845e68 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Mon, 14 Jun 2021 13:54:23 -0700 Subject: [PATCH 39/46] Added return statment formatter test --- boa/src/syntax/ast/node/return_smt/mod.rs | 3 +++ boa/src/syntax/ast/node/return_smt/tests.rs | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 boa/src/syntax/ast/node/return_smt/tests.rs diff --git a/boa/src/syntax/ast/node/return_smt/mod.rs b/boa/src/syntax/ast/node/return_smt/mod.rs index 6201624b52c..adb0f71f4a5 100644 --- a/boa/src/syntax/ast/node/return_smt/mod.rs +++ b/boa/src/syntax/ast/node/return_smt/mod.rs @@ -9,6 +9,9 @@ use std::fmt; #[cfg(feature = "deser")] use serde::{Deserialize, Serialize}; +#[cfg(test)] +mod tests; + /// The `return` statement ends function execution and specifies a value to be returned to the /// function caller. /// diff --git a/boa/src/syntax/ast/node/return_smt/tests.rs b/boa/src/syntax/ast/node/return_smt/tests.rs new file mode 100644 index 00000000000..8e4ecb1f5d8 --- /dev/null +++ b/boa/src/syntax/ast/node/return_smt/tests.rs @@ -0,0 +1,16 @@ +#[test] +fn fmt() { + super::super::test_formatting( + r#" + function say_hello(msg) { + if (msg === "") { + return 0; + } + console.log("hello " + msg); + return; + }; + say_hello(""); + say_hello("world"); + "#, + ); +} From 94008d8162b5b28da4cb729ee86cf7c69644873d Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Mon, 14 Jun 2021 13:56:19 -0700 Subject: [PATCH 40/46] Added spread argument formatting test --- boa/src/syntax/ast/node/spread/tests.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/boa/src/syntax/ast/node/spread/tests.rs b/boa/src/syntax/ast/node/spread/tests.rs index 4da380c622e..04d554d65e1 100644 --- a/boa/src/syntax/ast/node/spread/tests.rs +++ b/boa/src/syntax/ast/node/spread/tests.rs @@ -29,3 +29,19 @@ fn spread_with_call() { "#; assert_eq!(&exec(scenario), r#""message""#); } + +#[test] +fn fmt() { + super::super::test_formatting( + r#" + function f(m) { + return m; + }; + function g(...args) { + return f(...args); + }; + let a = g("message"); + a; + "#, + ); +} From f6882c8baf59edfe4a04114477bde732a9335f25 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Mon, 14 Jun 2021 13:58:35 -0700 Subject: [PATCH 41/46] Added switch statement formatting test --- boa/src/syntax/ast/node/switch/tests.rs | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/boa/src/syntax/ast/node/switch/tests.rs b/boa/src/syntax/ast/node/switch/tests.rs index ead275bc836..4d52794d00c 100644 --- a/boa/src/syntax/ast/node/switch/tests.rs +++ b/boa/src/syntax/ast/node/switch/tests.rs @@ -206,3 +206,39 @@ fn bigger_switch_example() { assert_eq!(&exec(&scenario), val); } } + +#[test] +fn fmt() { + super::super::test_formatting( + r#" + let a = 3; + let b = "unknown"; + switch (a) { + case 0: + b = "Mon"; + break; + case 1: + b = "Tue"; + break; + case 2: + b = "Wed"; + break; + case 3: + b = "Thurs"; + break; + case 4: + b = "Fri"; + break; + case 5: + b = "Sat"; + break; + case 6: + b = "Sun"; + break; + default: + b = "Unknown"; + } + b; + "#, + ); +} From 094c5b9faf9f850de09a3cdcbd80bad3896db234 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Mon, 14 Jun 2021 14:01:01 -0700 Subject: [PATCH 42/46] Added a formatting test for templates --- boa/src/syntax/ast/node/template/tests.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/boa/src/syntax/ast/node/template/tests.rs b/boa/src/syntax/ast/node/template/tests.rs index 9f9a299ee6d..1696c29fcc0 100644 --- a/boa/src/syntax/ast/node/template/tests.rs +++ b/boa/src/syntax/ast/node/template/tests.rs @@ -29,3 +29,20 @@ fn tagged_template() { r#"[ "result: ", " & ", "", "result: ", " \x26 ", "", 10, 20 ]"# ); } + +#[test] +fn fmt() { + super::super::test_formatting( + r#" + function tag(t, ...args) { + let a = []; + a = a.concat([t[0], t[1], t[2]]); + a = a.concat([t.raw[0], t.raw[1], t.raw[2]]); + a = a.concat([args[0], args[1]]); + return a; + }; + let a = 10; + tag`result: ${a} \x26 ${a + 10}`; + "#, + ); +} From 1cd9d9a8e3282230da922532c945ec4f245010fd Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Mon, 14 Jun 2021 14:04:01 -0700 Subject: [PATCH 43/46] Added a throw statement formatter test --- boa/src/syntax/ast/node/throw/mod.rs | 3 +++ boa/src/syntax/ast/node/throw/tests.rs | 12 ++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 boa/src/syntax/ast/node/throw/tests.rs diff --git a/boa/src/syntax/ast/node/throw/mod.rs b/boa/src/syntax/ast/node/throw/mod.rs index 486b5129439..e430e0a0189 100644 --- a/boa/src/syntax/ast/node/throw/mod.rs +++ b/boa/src/syntax/ast/node/throw/mod.rs @@ -9,6 +9,9 @@ use std::fmt; #[cfg(feature = "deser")] use serde::{Deserialize, Serialize}; +#[cfg(test)] +mod tests; + /// The `throw` statement throws a user-defined exception. /// /// Syntax: `throw expression;` diff --git a/boa/src/syntax/ast/node/throw/tests.rs b/boa/src/syntax/ast/node/throw/tests.rs new file mode 100644 index 00000000000..076352822f2 --- /dev/null +++ b/boa/src/syntax/ast/node/throw/tests.rs @@ -0,0 +1,12 @@ +#[test] +fn fmt() { + super::super::test_formatting( + r#" + try { + throw "hello"; + } catch(e) { + console.log(e); + }; + "#, + ); +} From 5d9ec8941f2ea542b2869a5309fbb59306446d81 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Mon, 14 Jun 2021 14:05:35 -0700 Subject: [PATCH 44/46] Added try catch test --- boa/src/syntax/ast/node/try_node/tests.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/boa/src/syntax/ast/node/try_node/tests.rs b/boa/src/syntax/ast/node/try_node/tests.rs index e5d2af85d3f..87654c81a4f 100644 --- a/boa/src/syntax/ast/node/try_node/tests.rs +++ b/boa/src/syntax/ast/node/try_node/tests.rs @@ -93,3 +93,23 @@ fn catch_binding_finally() { "#; assert_eq!(&exec(scenario), "30"); } + +#[test] +fn fmt() { + super::super::test_formatting( + r#" + try { + throw "hello"; + } catch(e) { + console.log(e); + } finally { + console.log("things"); + }; + try { + throw "hello"; + } catch { + console.log("something went wrong"); + }; + "#, + ); +} From 32c140f9801f2fd14feb1ced24a9cca455944a38 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Thu, 17 Jun 2021 17:04:36 -0700 Subject: [PATCH 45/46] Removed unused import --- boa/src/syntax/ast/node/operator/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa/src/syntax/ast/node/operator/tests.rs b/boa/src/syntax/ast/node/operator/tests.rs index 90e1544a64e..f5f9815f469 100644 --- a/boa/src/syntax/ast/node/operator/tests.rs +++ b/boa/src/syntax/ast/node/operator/tests.rs @@ -1,4 +1,4 @@ -use crate::{exec, parse}; +use crate::exec; #[test] fn assignmentoperator_lhs_not_defined() { From d56b22c2a1a23d3177422f341ccae5929ae965b0 Mon Sep 17 00:00:00 2001 From: Neil Macneale Date: Thu, 17 Jun 2021 17:05:26 -0700 Subject: [PATCH 46/46] Formatting test now uses eprintln! instead of println! --- boa/src/syntax/ast/node/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/boa/src/syntax/ast/node/mod.rs b/boa/src/syntax/ast/node/mod.rs index eef6951ac2b..6545a5f0133 100644 --- a/boa/src/syntax/ast/node/mod.rs +++ b/boa/src/syntax/ast/node/mod.rs @@ -629,11 +629,11 @@ fn test_formatting(source: &'static str) { .join("\n"); let result = format!("{}", crate::parse(&scenario, false).unwrap()); if scenario != result { - print!("========= Expected:\n{}", scenario); - print!("========= Got:\n{}", result); + eprint!("========= Expected:\n{}", scenario); + eprint!("========= Got:\n{}", result); // Might be helpful to find differing whitespace - println!("========= Expected: {:?}", scenario); - println!("========= Got: {:?}", result); + eprintln!("========= Expected: {:?}", scenario); + eprintln!("========= Got: {:?}", result); panic!("parsing test did not give the correct result (see above)"); } }