Browse Source

Optimised all `Vec<Node>` in `Node` to be `Box<[Node]>` (#370)

pull/372/head
Iban Eguia 4 years ago committed by GitHub
parent
commit
422d0b7ea1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      boa/src/builtins/function/mod.rs
  2. 8
      boa/src/builtins/object/mod.rs
  3. 3
      boa/src/exec/mod.rs
  4. 48
      boa/src/syntax/ast/node.rs
  5. 2
      boa/src/syntax/parser/expression/assignment/arrow_function.rs
  6. 2
      boa/src/syntax/parser/expression/primary/array_initializer/mod.rs
  7. 16
      boa/src/syntax/parser/expression/primary/array_initializer/tests.rs
  8. 2
      boa/src/syntax/parser/expression/primary/function_expression.rs
  9. 6
      boa/src/syntax/parser/expression/primary/object_initializer/mod.rs
  10. 38
      boa/src/syntax/parser/expression/primary/object_initializer/tests.rs
  11. 4
      boa/src/syntax/parser/expression/primary/tests.rs
  12. 80
      boa/src/syntax/parser/expression/tests.rs
  13. 44
      boa/src/syntax/parser/function/tests.rs
  14. 2
      boa/src/syntax/parser/mod.rs
  15. 4
      boa/src/syntax/parser/statement/block.rs
  16. 28
      boa/src/syntax/parser/statement/break_stm/tests.rs
  17. 28
      boa/src/syntax/parser/statement/continue_stm/tests.rs
  18. 2
      boa/src/syntax/parser/statement/declaration/hoistable.rs
  19. 4
      boa/src/syntax/parser/statement/declaration/lexical.rs
  20. 28
      boa/src/syntax/parser/statement/declaration/tests.rs
  21. 2
      boa/src/syntax/parser/statement/iteration/for_statement.rs
  22. 10
      boa/src/syntax/parser/statement/iteration/tests.rs
  23. 5
      boa/src/syntax/parser/statement/switch/mod.rs
  24. 5
      boa/src/syntax/parser/statement/throw/tests.rs
  25. 2
      boa/src/syntax/parser/statement/variable.rs
  26. 9
      boa/src/syntax/parser/tests.rs

20
boa/src/builtins/function/mod.rs

@ -92,7 +92,7 @@ pub struct Function {
/// Call/Construct Function body
pub body: FunctionBody,
/// Formal Paramaters
pub params: Vec<FormalParameter>,
pub params: Box<[FormalParameter]>,
/// This Mode
pub this_mode: ThisMode,
/// Function kind
@ -105,16 +105,19 @@ impl Function {
/// This will create an ordinary function object
///
/// <https://tc39.es/ecma262/#sec-ordinaryfunctioncreate>
pub fn create_ordinary(
parameter_list: Vec<FormalParameter>,
pub fn create_ordinary<P>(
parameter_list: P,
scope: Environment,
body: FunctionBody,
this_mode: ThisMode,
) -> Self {
) -> Self
where
P: Into<Box<[FormalParameter]>>,
{
Self {
body,
environment: Some(scope),
params: parameter_list,
params: parameter_list.into(),
kind: FunctionKind::Ordinary,
this_mode,
}
@ -123,10 +126,13 @@ impl Function {
/// This will create a built-in function object
///
/// <https://tc39.es/ecma262/#sec-createbuiltinfunction>
pub fn create_builtin(parameter_list: Vec<FormalParameter>, body: FunctionBody) -> Self {
pub fn create_builtin<P>(parameter_list: P, body: FunctionBody) -> Self
where
P: Into<Box<[FormalParameter]>>,
{
Self {
body,
params: parameter_list,
params: parameter_list.into(),
this_mode: ThisMode::NonLexical,
kind: FunctionKind::BuiltIn,
environment: None,

8
boa/src/builtins/object/mod.rs

@ -23,9 +23,11 @@ use crate::{
};
use gc::{unsafe_empty_trace, Finalize, Gc, Trace};
use rustc_hash::FxHashMap;
use std::fmt::{self, Debug};
use std::fmt::{Display, Error, Formatter};
use std::{borrow::Borrow, ops::Deref};
use std::{
borrow::Borrow,
fmt::{self, Debug, Display, Error, Formatter},
ops::Deref,
};
pub use internal_methods_trait::ObjectInternalMethods;
pub use internal_state::{InternalState, InternalStateCell};

3
boa/src/exec/mod.rs

@ -208,7 +208,6 @@ impl Executor for Interpreter {
let mut result = Gc::new(ValueData::Null);
let mut matched = false;
for tup in vals.iter() {
let tup: &(Node, Vec<Node>) = tup;
let cond = &tup.0;
let block = &tup.1;
if val == self.run(cond)? {
@ -240,7 +239,7 @@ impl Executor for Interpreter {
let obj = ValueData::new_obj(Some(global_val));
// TODO: Implement the rest of the property types.
for property in properties {
for property in properties.iter() {
match property {
PropertyDefinition::Property(key, value) => {
obj.borrow().set_field_slice(&key.clone(), self.run(value)?);

48
boa/src/syntax/ast/node.rs

@ -28,7 +28,7 @@ pub enum Node {
///
/// [spec]: https://tc39.es/ecma262/#prod-ArrayLiteral
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
ArrayDecl(Vec<Node>),
ArrayDecl(Box<[Node]>),
/// An arrow function expression is a syntactically compact alternative to a regular function expression.
///
@ -41,7 +41,7 @@ pub enum Node {
///
/// [spec]: https://tc39.es/ecma262/#prod-ArrowFunction
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
ArrowFunctionDecl(Vec<FormalParameter>, Box<Node>),
ArrowFunctionDecl(Box<[FormalParameter]>, Box<Node>),
/// An assignment operator assigns a value to its left operand based on the value of its right operand.
///
@ -76,7 +76,7 @@ pub enum Node {
///
/// [spec]: https://tc39.es/ecma262/#prod-BlockStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block
Block(Vec<Node>),
Block(Box<[Node]>),
/// The `break` statement terminates the current loop, switch, or label statement and transfers program control to the statement following the terminated statement.
///
@ -104,7 +104,7 @@ pub enum Node {
///
/// [spec]: https://tc39.es/ecma262/#prod-CallExpression
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Calling_functions
Call(Box<Node>, Vec<Node>),
Call(Box<Node>, Box<[Node]>),
/// The `conditional` (ternary) operator is the only JavaScript operator that takes three operands.
///
@ -148,7 +148,7 @@ pub enum Node {
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
/// [identifier]: https://developer.mozilla.org/en-US/docs/Glossary/identifier
/// [expression]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions
ConstDecl(Vec<(String, Node)>),
ConstDecl(Box<[(String, Node)]>),
/// 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.
@ -190,7 +190,7 @@ pub enum Node {
///
/// [spec]: https://tc39.es/ecma262/#sec-terms-and-definitions-function
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function
FunctionDecl(Option<String>, Vec<FormalParameter>, Box<Node>),
FunctionDecl(Option<String>, Box<[FormalParameter]>, Box<Node>),
/// This property accessor provides access to an object's properties by using the [dot notation][mdn].
///
@ -282,7 +282,7 @@ pub enum Node {
///
/// [spec]: https://tc39.es/ecma262/#sec-let-and-const-declarations
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
LetDecl(Vec<(String, Option<Node>)>),
LetDecl(Box<[(String, Option<Node>)]>),
/// An `identifier` is a sequence of characters in the code that identifies a variable, function, or property.
///
@ -331,7 +331,7 @@ pub enum Node {
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer
/// [object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
/// [primitive]: https://developer.mozilla.org/en-US/docs/Glossary/primitive
Object(Vec<PropertyDefinition>),
Object(Box<[PropertyDefinition]>),
/// The `return` statement ends function execution and specifies a value to be returned to the function caller.
///
@ -365,7 +365,7 @@ pub enum Node {
///
/// [spec]: https://tc39.es/ecma262/#prod-SwitchStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch
Switch(Box<Node>, Vec<(Node, Vec<Node>)>, Option<Box<Node>>),
Switch(Box<Node>, Box<[(Node, Box<[Node]>)]>, Option<Box<Node>>),
/// The `spread` operator allows an iterable such as an array expression or string to be expanded.
///
@ -388,7 +388,7 @@ pub enum Node {
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#prod-StatementList
StatementList(Vec<Node>),
StatementList(Box<[Node]>),
/// The `throw` statement throws a user-defined exception.
///
@ -478,7 +478,7 @@ pub enum Node {
///
/// [spec]: https://tc39.es/ecma262/#prod-VariableStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
VarDecl(Vec<(String, Option<Node>)>),
VarDecl(Box<[(String, Option<Node>)]>),
/// The `while` statement creates a loop that executes a specified statement as long as the test condition evaluates to `true`.
///
@ -532,7 +532,7 @@ impl Node {
/// Creates an `ArrayDecl` AST node.
pub fn array_decl<N>(nodes: N) -> Self
where
N: Into<Vec<Self>>,
N: Into<Box<[Self]>>,
{
Self::ArrayDecl(nodes.into())
}
@ -540,7 +540,7 @@ impl Node {
/// Creates an `ArraowFunctionDecl` AST node.
pub fn arrow_function_decl<P, B>(params: P, body: B) -> Self
where
P: Into<Vec<FormalParameter>>,
P: Into<Box<[FormalParameter]>>,
B: Into<Box<Self>>,
{
Self::ArrowFunctionDecl(params.into(), body.into())
@ -568,7 +568,7 @@ impl Node {
/// Creates a `Block` AST node.
pub fn block<N>(nodes: N) -> Self
where
N: Into<Vec<Self>>,
N: Into<Box<[Self]>>,
{
Self::Block(nodes.into())
}
@ -586,7 +586,7 @@ impl Node {
pub fn call<F, P>(function: F, params: P) -> Self
where
F: Into<Box<Self>>,
P: Into<Vec<Self>>,
P: Into<Box<[Self]>>,
{
Self::Call(function.into(), params.into())
}
@ -612,7 +612,7 @@ impl Node {
/// Creates a `ConstDecl` AST node.
pub fn const_decl<D>(decl: D) -> Self
where
D: Into<Vec<(String, Self)>>,
D: Into<Box<[(String, Self)]>>,
{
Self::ConstDecl(decl.into())
}
@ -640,7 +640,7 @@ impl Node {
where
N: Into<String>,
ON: Into<Option<N>>,
P: Into<Vec<FormalParameter>>,
P: Into<Box<[FormalParameter]>>,
B: Into<Box<Self>>,
{
Self::FunctionDecl(name.into().map(N::into), params.into(), body.into())
@ -697,7 +697,7 @@ impl Node {
/// Creates a `LetDecl` AST node.
pub fn let_decl<I>(init: I) -> Self
where
I: Into<Vec<(String, Option<Self>)>>,
I: Into<Box<[(String, Option<Self>)]>>,
{
Self::LetDecl(init.into())
}
@ -721,7 +721,7 @@ impl Node {
/// Creates an `Object` AST node.
pub fn object<D>(def: D) -> Self
where
D: Into<Vec<PropertyDefinition>>,
D: Into<Box<[PropertyDefinition]>>,
{
Self::Object(def.into())
}
@ -739,7 +739,7 @@ impl Node {
pub fn switch<V, C, OD, D>(val: V, cases: C, default: OD) -> Self
where
V: Into<Box<Self>>,
C: Into<Vec<(Self, Vec<Self>)>>,
C: Into<Box<[(Self, Box<[Self]>)]>>,
OD: Into<Option<D>>,
D: Into<Box<Self>>,
{
@ -757,7 +757,7 @@ impl Node {
/// Creates a `StatementList` AST node.
pub fn statement_list<L>(list: L) -> Self
where
L: Into<Vec<Self>>,
L: Into<Box<[Self]>>,
{
Self::StatementList(list.into())
}
@ -816,7 +816,7 @@ impl Node {
/// Creates a `VarDecl` AST node.
pub fn var_decl<I>(init: I) -> Self
where
I: Into<Vec<(String, Option<Self>)>>,
I: Into<Box<[(String, Option<Self>)]>>,
{
Self::VarDecl(init.into())
}
@ -905,7 +905,7 @@ impl Node {
Self::GetField(ref ex, ref field) => write!(f, "{}[{}]", ex, field),
Self::Call(ref ex, ref args) => {
write!(f, "{}(", ex)?;
let arg_strs: Vec<String> = args.iter().map(ToString::to_string).collect();
let arg_strs: Box<[String]> = args.iter().map(ToString::to_string).collect();
write!(f, "{})", arg_strs.join(", "))
}
Self::New(ref call) => {
@ -965,7 +965,7 @@ impl Node {
}
Self::Object(ref properties) => {
f.write_str("{\n")?;
for property in properties {
for property in properties.iter() {
match property {
PropertyDefinition::IdentifierReference(key) => {
write!(f, "{} {},", indent, key)?;

2
boa/src/syntax/parser/expression/assignment/arrow_function.rs

@ -120,7 +120,7 @@ impl TokenParser for ConciseBody {
let _ = cursor.next();
let body = FunctionBody::new(false, false)
.parse(cursor)
.map(Node::StatementList)?;
.map(Node::statement_list)?;
cursor.expect(Punctuator::CloseBlock, "arrow function")?;
Ok(body)
}

2
boa/src/syntax/parser/expression/primary/array_initializer/mod.rs

@ -77,6 +77,6 @@ impl TokenParser for ArrayLiteral {
cursor.next_if(Punctuator::Comma);
}
Ok(Node::ArrayDecl(elements))
Ok(Node::array_decl(elements))
}
}

16
boa/src/syntax/parser/expression/primary/array_initializer/tests.rs

@ -8,7 +8,7 @@ use crate::syntax::{
/// Checks an empty array.
#[test]
fn check_empty() {
check_parser("[]", &[Node::ArrayDecl(Vec::new())]);
check_parser("[]", vec![Node::array_decl(Vec::new())]);
}
/// Checks an array with empty slot.
@ -16,7 +16,7 @@ fn check_empty() {
fn check_empty_slot() {
check_parser(
"[,]",
&[Node::ArrayDecl(vec![Node::Const(Const::Undefined)])],
vec![Node::array_decl(vec![Node::Const(Const::Undefined)])],
);
}
@ -25,7 +25,7 @@ fn check_empty_slot() {
fn check_numeric_array() {
check_parser(
"[1, 2, 3]",
&[Node::ArrayDecl(vec![
vec![Node::array_decl(vec![
Node::const_node(1),
Node::const_node(2),
Node::const_node(3),
@ -38,7 +38,7 @@ fn check_numeric_array() {
fn check_numeric_array_trailing() {
check_parser(
"[1, 2, 3,]",
&[Node::ArrayDecl(vec![
vec![Node::array_decl(vec![
Node::const_node(1),
Node::const_node(2),
Node::const_node(3),
@ -51,7 +51,7 @@ fn check_numeric_array_trailing() {
fn check_numeric_array_elision() {
check_parser(
"[1, 2, , 3]",
&[Node::ArrayDecl(vec![
vec![Node::array_decl(vec![
Node::const_node(1),
Node::const_node(2),
Node::Const(Const::Undefined),
@ -65,7 +65,7 @@ fn check_numeric_array_elision() {
fn check_numeric_array_repeated_elision() {
check_parser(
"[1, 2, ,, 3]",
&[Node::ArrayDecl(vec![
vec![Node::array_decl(vec![
Node::const_node(1),
Node::const_node(2),
Node::Const(Const::Undefined),
@ -80,7 +80,7 @@ fn check_numeric_array_repeated_elision() {
fn check_combined() {
check_parser(
"[1, \"a\", 2]",
&[Node::ArrayDecl(vec![
vec![Node::array_decl(vec![
Node::const_node(1),
Node::const_node("a"),
Node::const_node(2),
@ -93,7 +93,7 @@ fn check_combined() {
fn check_combined_empty_str() {
check_parser(
"[1, \"\", 2]",
&[Node::ArrayDecl(vec![
vec![Node::array_decl(vec![
Node::const_node(1),
Node::const_node(""),
Node::const_node(2),

2
boa/src/syntax/parser/expression/primary/function_expression.rs

@ -51,7 +51,7 @@ impl TokenParser for FunctionExpression {
let body = FunctionBody::new(false, false)
.parse(cursor)
.map(Node::StatementList)?;
.map(Node::statement_list)?;
cursor.expect(Punctuator::CloseBlock, "function expression")?;

6
boa/src/syntax/parser/expression/primary/object_initializer/mod.rs

@ -82,7 +82,7 @@ impl TokenParser for ObjectLiteral {
}
}
Ok(Node::Object(elements))
Ok(Node::object(elements))
}
}
@ -233,7 +233,7 @@ impl TokenParser for MethodDefinition {
)?;
let body = FunctionBody::new(false, false)
.parse(cursor)
.map(Node::StatementList)?;
.map(Node::statement_list)?;
cursor.expect(
TokenKind::Punctuator(Punctuator::CloseBlock),
"property method definition",
@ -242,7 +242,7 @@ impl TokenParser for MethodDefinition {
Ok(node::PropertyDefinition::MethodDefinition(
methodkind,
prop_name,
Node::FunctionDecl(None, params, Box::new(body)),
Node::function_decl::<_, String, _, _>(None, params, body),
))
}
}

38
boa/src/syntax/parser/expression/primary/object_initializer/tests.rs

@ -17,9 +17,9 @@ fn check_object_literal() {
b: false,
};
",
&[Node::const_decl(vec![(
vec![Node::const_decl(vec![(
String::from("x"),
Node::Object(object_properties),
Node::object(object_properties),
)])],
);
}
@ -32,7 +32,7 @@ fn check_object_short_function() {
PropertyDefinition::method_definition(
MethodDefinitionKind::Ordinary,
"b",
Node::function_decl::<_, String, _, _>(None, Vec::new(), Node::StatementList(vec![])),
Node::function_decl::<_, String, _, _>(None, Vec::new(), Node::statement_list(vec![])),
),
];
@ -42,9 +42,9 @@ fn check_object_short_function() {
b() {},
};
",
&[Node::ConstDecl(vec![(
vec![Node::const_decl(vec![(
String::from("x"),
Node::Object(object_properties),
Node::object(object_properties),
)])],
);
}
@ -57,10 +57,10 @@ fn check_object_short_function_arguments() {
PropertyDefinition::method_definition(
MethodDefinitionKind::Ordinary,
"b",
Node::function_decl::<_, String, _, _>(
Node::FunctionDecl(
None,
vec![FormalParameter::new("test", None, false)],
Node::StatementList(Vec::new()),
Box::new([FormalParameter::new("test", None, false)]),
Box::new(Node::StatementList(Box::new([]))),
),
),
];
@ -71,9 +71,9 @@ fn check_object_short_function_arguments() {
b(test) {}
};
",
&[Node::ConstDecl(vec![(
vec![Node::const_decl(vec![(
String::from("x"),
Node::Object(object_properties),
Node::object(object_properties),
)])],
);
}
@ -85,7 +85,11 @@ fn check_object_getter() {
PropertyDefinition::method_definition(
MethodDefinitionKind::Get,
"b",
Node::FunctionDecl(None, Vec::new(), Box::new(Node::StatementList(Vec::new()))),
Node::FunctionDecl(
None,
Box::new([]),
Box::new(Node::statement_list(Vec::new())),
),
),
];
@ -95,9 +99,9 @@ fn check_object_getter() {
get b() {}
};
",
&[Node::ConstDecl(vec![(
vec![Node::const_decl(vec![(
String::from("x"),
Node::Object(object_properties),
Node::object(object_properties),
)])],
);
}
@ -109,10 +113,10 @@ fn check_object_setter() {
PropertyDefinition::method_definition(
MethodDefinitionKind::Set,
"b",
Node::FunctionDecl(
Node::function_decl::<_, String, _, _>(
None,
vec![FormalParameter::new("test", None, false)],
Box::new(Node::StatementList(Vec::new())),
Node::statement_list(Vec::new()),
),
),
];
@ -123,9 +127,9 @@ fn check_object_setter() {
set b(test) {}
};
",
&[Node::ConstDecl(vec![(
vec![Node::const_decl(vec![(
String::from("x"),
Node::Object(object_properties),
Node::object(object_properties),
)])],
);
}

4
boa/src/syntax/parser/expression/primary/tests.rs

@ -3,8 +3,8 @@ use crate::syntax::{ast::node::Node, parser::tests::check_parser};
#[test]
fn check_string() {
// Check empty string
check_parser("\"\"", &[Node::const_node("")]);
check_parser("\"\"", vec![Node::const_node("")]);
// Check non-empty string
check_parser("\"hello\"", &[Node::const_node("hello")]);
check_parser("\"hello\"", vec![Node::const_node("hello")]);
}

80
boa/src/syntax/parser/expression/tests.rs

@ -9,11 +9,11 @@ use crate::syntax::{
fn check_numeric_operations() {
check_parser(
"a + b",
&[Node::bin_op(NumOp::Add, Node::local("a"), Node::local("b"))],
vec![Node::bin_op(NumOp::Add, Node::local("a"), Node::local("b"))],
);
check_parser(
"a+1",
&[Node::bin_op(
vec![Node::bin_op(
NumOp::Add,
Node::local("a"),
Node::const_node(1),
@ -21,11 +21,11 @@ fn check_numeric_operations() {
);
check_parser(
"a - b",
&[Node::bin_op(NumOp::Sub, Node::local("a"), Node::local("b"))],
vec![Node::bin_op(NumOp::Sub, Node::local("a"), Node::local("b"))],
);
check_parser(
"a-1",
&[Node::bin_op(
vec![Node::bin_op(
NumOp::Sub,
Node::local("a"),
Node::const_node(1),
@ -33,11 +33,11 @@ fn check_numeric_operations() {
);
check_parser(
"a / b",
&[Node::bin_op(NumOp::Div, Node::local("a"), Node::local("b"))],
vec![Node::bin_op(NumOp::Div, Node::local("a"), Node::local("b"))],
);
check_parser(
"a/2",
&[Node::bin_op(
vec![Node::bin_op(
NumOp::Div,
Node::local("a"),
Node::const_node(2),
@ -45,11 +45,11 @@ fn check_numeric_operations() {
);
check_parser(
"a * b",
&[Node::bin_op(NumOp::Mul, Node::local("a"), Node::local("b"))],
vec![Node::bin_op(NumOp::Mul, Node::local("a"), Node::local("b"))],
);
check_parser(
"a*2",
&[Node::bin_op(
vec![Node::bin_op(
NumOp::Mul,
Node::local("a"),
Node::const_node(2),
@ -57,11 +57,11 @@ fn check_numeric_operations() {
);
check_parser(
"a ** b",
&[Node::bin_op(NumOp::Exp, Node::local("a"), Node::local("b"))],
vec![Node::bin_op(NumOp::Exp, Node::local("a"), Node::local("b"))],
);
check_parser(
"a**2",
&[Node::bin_op(
vec![Node::bin_op(
NumOp::Exp,
Node::local("a"),
Node::const_node(2),
@ -69,11 +69,11 @@ fn check_numeric_operations() {
);
check_parser(
"a % b",
&[Node::bin_op(NumOp::Mod, Node::local("a"), Node::local("b"))],
vec![Node::bin_op(NumOp::Mod, Node::local("a"), Node::local("b"))],
);
check_parser(
"a%2",
&[Node::bin_op(
vec![Node::bin_op(
NumOp::Mod,
Node::local("a"),
Node::const_node(2),
@ -86,7 +86,7 @@ fn check_numeric_operations() {
fn check_complex_numeric_operations() {
check_parser(
"a + d*(b-3)+1",
&[Node::bin_op(
vec![Node::bin_op(
NumOp::Add,
Node::bin_op(
NumOp::Add,
@ -107,7 +107,7 @@ fn check_complex_numeric_operations() {
fn check_bitwise_operations() {
check_parser(
"a & b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Bit(BitOp::And),
Node::local("a"),
Node::local("b"),
@ -115,7 +115,7 @@ fn check_bitwise_operations() {
);
check_parser(
"a&b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Bit(BitOp::And),
Node::local("a"),
Node::local("b"),
@ -124,7 +124,7 @@ fn check_bitwise_operations() {
check_parser(
"a | b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Bit(BitOp::Or),
Node::local("a"),
Node::local("b"),
@ -132,7 +132,7 @@ fn check_bitwise_operations() {
);
check_parser(
"a|b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Bit(BitOp::Or),
Node::local("a"),
Node::local("b"),
@ -141,7 +141,7 @@ fn check_bitwise_operations() {
check_parser(
"a ^ b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Bit(BitOp::Xor),
Node::local("a"),
Node::local("b"),
@ -149,7 +149,7 @@ fn check_bitwise_operations() {
);
check_parser(
"a^b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Bit(BitOp::Xor),
Node::local("a"),
Node::local("b"),
@ -158,7 +158,7 @@ fn check_bitwise_operations() {
check_parser(
"a << b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Bit(BitOp::Shl),
Node::local("a"),
Node::local("b"),
@ -166,7 +166,7 @@ fn check_bitwise_operations() {
);
check_parser(
"a<<b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Bit(BitOp::Shl),
Node::local("a"),
Node::local("b"),
@ -175,7 +175,7 @@ fn check_bitwise_operations() {
check_parser(
"a >> b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Bit(BitOp::Shr),
Node::local("a"),
Node::local("b"),
@ -183,7 +183,7 @@ fn check_bitwise_operations() {
);
check_parser(
"a>>b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Bit(BitOp::Shr),
Node::local("a"),
Node::local("b"),
@ -196,7 +196,7 @@ fn check_bitwise_operations() {
fn check_assign_operations() {
check_parser(
"a += b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::Add),
Node::local("a"),
Node::local("b"),
@ -204,7 +204,7 @@ fn check_assign_operations() {
);
check_parser(
"a -= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::Sub),
Node::local("a"),
Node::local("b"),
@ -212,7 +212,7 @@ fn check_assign_operations() {
);
check_parser(
"a *= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::Mul),
Node::local("a"),
Node::local("b"),
@ -220,7 +220,7 @@ fn check_assign_operations() {
);
check_parser(
"a **= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::Exp),
Node::local("a"),
Node::local("b"),
@ -228,7 +228,7 @@ fn check_assign_operations() {
);
check_parser(
"a /= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::Div),
Node::local("a"),
Node::local("b"),
@ -236,7 +236,7 @@ fn check_assign_operations() {
);
check_parser(
"a %= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::Mod),
Node::local("a"),
Node::local("b"),
@ -244,7 +244,7 @@ fn check_assign_operations() {
);
check_parser(
"a &= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::And),
Node::local("a"),
Node::local("b"),
@ -252,7 +252,7 @@ fn check_assign_operations() {
);
check_parser(
"a |= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::Or),
Node::local("a"),
Node::local("b"),
@ -260,7 +260,7 @@ fn check_assign_operations() {
);
check_parser(
"a ^= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::Xor),
Node::local("a"),
Node::local("b"),
@ -268,7 +268,7 @@ fn check_assign_operations() {
);
check_parser(
"a <<= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::Shl),
Node::local("a"),
Node::local("b"),
@ -276,7 +276,7 @@ fn check_assign_operations() {
);
check_parser(
"a >>= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::Shr),
Node::local("a"),
Node::local("b"),
@ -284,7 +284,7 @@ fn check_assign_operations() {
);
check_parser(
"a %= 10 / 2",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Assign(AssignOp::Mod),
Node::local("a"),
Node::bin_op(NumOp::Div, Node::const_node(10), Node::const_node(2)),
@ -296,7 +296,7 @@ fn check_assign_operations() {
fn check_relational_operations() {
check_parser(
"a < b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Comp(CompOp::LessThan),
Node::Local(String::from("a")),
Node::Local(String::from("b")),
@ -304,7 +304,7 @@ fn check_relational_operations() {
);
check_parser(
"a > b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Comp(CompOp::GreaterThan),
Node::Local(String::from("a")),
Node::Local(String::from("b")),
@ -312,7 +312,7 @@ fn check_relational_operations() {
);
check_parser(
"a <= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Comp(CompOp::LessThanOrEqual),
Node::Local(String::from("a")),
Node::Local(String::from("b")),
@ -320,7 +320,7 @@ fn check_relational_operations() {
);
check_parser(
"a >= b",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Comp(CompOp::GreaterThanOrEqual),
Node::Local(String::from("a")),
Node::Local(String::from("b")),
@ -328,7 +328,7 @@ fn check_relational_operations() {
);
check_parser(
"p in o",
&[Node::bin_op(
vec![Node::bin_op(
BinOp::Comp(CompOp::In),
Node::Local(String::from("p")),
Node::Local(String::from("o")),

44
boa/src/syntax/parser/function/tests.rs

@ -9,10 +9,10 @@ use crate::syntax::{
fn check_basic() {
check_parser(
"function foo(a) { return a; }",
&[Node::function_decl(
vec![Node::function_decl(
"foo",
vec![FormalParameter::new("a", None, false)],
Node::StatementList(vec![Node::return_node(Node::local("a"))]),
Node::statement_list(vec![Node::return_node(Node::local("a"))]),
)],
);
}
@ -22,10 +22,10 @@ fn check_basic() {
fn check_basic_semicolon_insertion() {
check_parser(
"function foo(a) { return a }",
&[Node::function_decl(
vec![Node::function_decl(
"foo",
vec![FormalParameter::new("a", None, false)],
Node::StatementList(vec![Node::return_node(Node::local("a"))]),
Node::statement_list(vec![Node::return_node(Node::local("a"))]),
)],
);
}
@ -35,10 +35,10 @@ fn check_basic_semicolon_insertion() {
fn check_empty_return() {
check_parser(
"function foo(a) { return; }",
&[Node::function_decl(
vec![Node::function_decl(
"foo",
vec![FormalParameter::new("a", None, false)],
Node::StatementList(vec![Node::Return(None)]),
Node::statement_list(vec![Node::Return(None)]),
)],
);
}
@ -48,10 +48,10 @@ fn check_empty_return() {
fn check_empty_return_semicolon_insertion() {
check_parser(
"function foo(a) { return }",
&[Node::function_decl(
vec![Node::function_decl(
"foo",
vec![FormalParameter::new("a", None, false)],
Node::StatementList(vec![Node::Return(None)]),
Node::statement_list(vec![Node::Return(None)]),
)],
);
}
@ -61,13 +61,13 @@ fn check_empty_return_semicolon_insertion() {
fn check_rest_operator() {
check_parser(
"function foo(a, ...b) {}",
&[Node::function_decl(
vec![Node::function_decl(
"foo",
vec![
FormalParameter::new("a", None, false),
FormalParameter::new("b", None, true),
],
Node::StatementList(Vec::new()),
Node::StatementList(Box::new([])),
)],
);
}
@ -77,9 +77,9 @@ fn check_rest_operator() {
fn check_arrow_only_rest() {
check_parser(
"(...a) => {}",
&[Node::arrow_function_decl(
vec![Node::arrow_function_decl(
vec![FormalParameter::new("a", None, true)],
Node::StatementList(Vec::new()),
Node::StatementList(Box::new([])),
)],
);
}
@ -89,13 +89,13 @@ fn check_arrow_only_rest() {
fn check_arrow_rest() {
check_parser(
"(a, b, ...c) => {}",
&[Node::arrow_function_decl(
vec![Node::arrow_function_decl(
vec![
FormalParameter::new("a", None, false),
FormalParameter::new("b", None, false),
FormalParameter::new("c", None, true),
],
Node::StatementList(Vec::new()),
Node::StatementList(Box::new([])),
)],
);
}
@ -105,12 +105,12 @@ fn check_arrow_rest() {
fn check_arrow() {
check_parser(
"(a, b) => { return a + b; }",
&[Node::arrow_function_decl(
vec![Node::arrow_function_decl(
vec![
FormalParameter::new("a", None, false),
FormalParameter::new("b", None, false),
],
Node::StatementList(vec![Node::return_node(Node::bin_op(
Node::statement_list(vec![Node::return_node(Node::bin_op(
NumOp::Add,
Node::local("a"),
Node::local("b"),
@ -124,12 +124,12 @@ fn check_arrow() {
fn check_arrow_semicolon_insertion() {
check_parser(
"(a, b) => { return a + b }",
&[Node::arrow_function_decl(
vec![Node::arrow_function_decl(
vec![
FormalParameter::new("a", None, false),
FormalParameter::new("b", None, false),
],
Node::StatementList(vec![Node::return_node(Node::bin_op(
Node::statement_list(vec![Node::return_node(Node::bin_op(
NumOp::Add,
Node::local("a"),
Node::local("b"),
@ -143,12 +143,12 @@ fn check_arrow_semicolon_insertion() {
fn check_arrow_epty_return() {
check_parser(
"(a, b) => { return; }",
&[Node::arrow_function_decl(
vec![Node::arrow_function_decl(
vec![
FormalParameter::new("a", None, false),
FormalParameter::new("b", None, false),
],
Node::StatementList(vec![Node::Return(None)]),
Node::statement_list(vec![Node::Return(None)]),
)],
);
}
@ -158,12 +158,12 @@ fn check_arrow_epty_return() {
fn check_arrow_empty_return_semicolon_insertion() {
check_parser(
"(a, b) => { return }",
&[Node::arrow_function_decl(
vec![Node::arrow_function_decl(
vec![
FormalParameter::new("a", None, false),
FormalParameter::new("b", None, false),
],
Node::StatementList(vec![Node::Return(None)]),
Node::statement_list(vec![Node::Return(None)]),
)],
);
}

2
boa/src/syntax/parser/mod.rs

@ -104,7 +104,7 @@ impl<'a> Parser<'a> {
/// Parse all expressions in the token array
pub fn parse_all(&mut self) -> ParseResult {
Script.parse(&mut self.cursor).map(Node::StatementList)
Script.parse(&mut self.cursor).map(Node::statement_list)
}
}

4
boa/src/syntax/parser/statement/block.rs

@ -60,14 +60,14 @@ impl TokenParser for Block {
if let Some(tk) = cursor.peek(0) {
if tk.kind == TokenKind::Punctuator(Punctuator::CloseBlock) {
cursor.next();
return Ok(Node::Block(Vec::new()));
return Ok(Node::Block(Box::new([])));
}
}
let statement_list =
StatementList::new(self.allow_yield, self.allow_await, self.allow_return, true)
.parse(cursor)
.map(Node::Block)?;
.map(Node::block)?;
cursor.expect(Punctuator::CloseBlock, "block")?;
Ok(statement_list)

28
boa/src/syntax/parser/statement/break_stm/tests.rs

@ -4,7 +4,7 @@ use crate::syntax::{ast::node::Node, parser::tests::check_parser};
fn check_inline() {
check_parser(
"while (true) break;",
&[Node::while_loop(Node::const_node(true), Node::Break(None))],
vec![Node::while_loop(Node::const_node(true), Node::Break(None))],
);
}
@ -13,7 +13,7 @@ fn check_new_line() {
check_parser(
"while (true)
break;",
&[Node::while_loop(Node::const_node(true), Node::Break(None))],
vec![Node::while_loop(Node::const_node(true), Node::Break(None))],
);
}
@ -21,9 +21,9 @@ fn check_new_line() {
fn check_inline_block_semicolon_insertion() {
check_parser(
"while (true) {break}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::Break(None)]),
Node::block(vec![Node::Break(None)]),
)],
);
}
@ -34,9 +34,9 @@ fn check_new_line_semicolon_insertion() {
"while (true) {
break test
}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::break_node("test")]),
Node::block(vec![Node::break_node("test")]),
)],
);
}
@ -45,9 +45,9 @@ fn check_new_line_semicolon_insertion() {
fn check_inline_block() {
check_parser(
"while (true) {break;}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::Break(None)]),
Node::block(vec![Node::Break(None)]),
)],
);
}
@ -58,9 +58,9 @@ fn check_new_line_block() {
"while (true) {
break test;
}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::break_node("test")]),
Node::block(vec![Node::break_node("test")]),
)],
);
}
@ -71,9 +71,9 @@ fn check_new_line_block_empty() {
"while (true) {
break;
}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::Break(None)]),
Node::block(vec![Node::Break(None)]),
)],
);
}
@ -84,9 +84,9 @@ fn check_new_line_block_empty_semicolon_insertion() {
"while (true) {
break
}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::Break(None)]),
Node::block(vec![Node::Break(None)]),
)],
);
}

28
boa/src/syntax/parser/statement/continue_stm/tests.rs

@ -4,7 +4,7 @@ use crate::syntax::{ast::node::Node, parser::tests::check_parser};
fn check_inline() {
check_parser(
"while (true) continue;",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Continue(None),
)],
@ -16,7 +16,7 @@ fn check_new_line() {
check_parser(
"while (true)
continue;",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Continue(None),
)],
@ -27,9 +27,9 @@ fn check_new_line() {
fn check_inline_block_semicolon_insertion() {
check_parser(
"while (true) {continue}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::Continue(None)]),
Node::block(vec![Node::Continue(None)]),
)],
);
}
@ -40,9 +40,9 @@ fn check_new_line_semicolon_insertion() {
"while (true) {
continue test
}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::continue_node("test")]),
Node::block(vec![Node::continue_node("test")]),
)],
);
}
@ -51,9 +51,9 @@ fn check_new_line_semicolon_insertion() {
fn check_inline_block() {
check_parser(
"while (true) {continue;}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::Continue(None)]),
Node::block(vec![Node::Continue(None)]),
)],
);
}
@ -64,9 +64,9 @@ fn check_new_line_block() {
"while (true) {
continue test;
}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::continue_node("test")]),
Node::block(vec![Node::continue_node("test")]),
)],
);
}
@ -77,9 +77,9 @@ fn check_new_line_block_empty() {
"while (true) {
continue;
}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::Continue(None)]),
Node::block(vec![Node::Continue(None)]),
)],
);
}
@ -90,9 +90,9 @@ fn check_new_line_block_empty_semicolon_insertion() {
"while (true) {
continue
}",
&[Node::while_loop(
vec![Node::while_loop(
Node::const_node(true),
Node::Block(vec![Node::Continue(None)]),
Node::block(vec![Node::Continue(None)]),
)],
);
}

2
boa/src/syntax/parser/statement/declaration/hoistable.rs

@ -109,7 +109,7 @@ impl TokenParser for FunctionDeclaration {
let body = FunctionBody::new(self.allow_yield, self.allow_await)
.parse(cursor)
.map(Node::StatementList)?;
.map(Node::statement_list)?;
cursor.expect(Punctuator::CloseBlock, "function declaration")?;

4
boa/src/syntax/parser/statement/declaration/lexical.rs

@ -164,9 +164,9 @@ impl TokenParser for BindingList {
}
if self.is_const {
Ok(Node::ConstDecl(const_decls))
Ok(Node::const_decl(const_decls))
} else {
Ok(Node::LetDecl(let_decls))
Ok(Node::let_decl(let_decls))
}
}
}

28
boa/src/syntax/parser/statement/declaration/tests.rs

@ -8,7 +8,7 @@ use crate::syntax::{
fn check_var_declaration() {
check_parser(
"var a = 5;",
&[Node::VarDecl(vec![(
vec![Node::var_decl(vec![(
String::from("a"),
Some(Node::const_node(5)),
)])],
@ -20,7 +20,7 @@ fn check_var_declaration() {
fn check_var_declaration_no_spaces() {
check_parser(
"var a=5;",
&[Node::VarDecl(vec![(
vec![Node::var_decl(vec![(
String::from("a"),
Some(Node::const_node(5)),
)])],
@ -30,7 +30,10 @@ fn check_var_declaration_no_spaces() {
/// Checks empty `var` declaration parsing.
#[test]
fn check_empty_var_declaration() {
check_parser("var a;", &[Node::VarDecl(vec![(String::from("a"), None)])]);
check_parser(
"var a;",
vec![Node::var_decl(vec![(String::from("a"), None)])],
);
}
/// Checks multiple `var` declarations.
@ -38,7 +41,7 @@ fn check_empty_var_declaration() {
fn check_multiple_var_declaration() {
check_parser(
"var a = 5, b, c = 6;",
&[Node::VarDecl(vec![
vec![Node::var_decl(vec![
(String::from("a"), Some(Node::const_node(5))),
(String::from("b"), None),
(String::from("c"), Some(Node::const_node(6))),
@ -51,7 +54,7 @@ fn check_multiple_var_declaration() {
fn check_let_declaration() {
check_parser(
"let a = 5;",
&[Node::LetDecl(vec![(
vec![Node::let_decl(vec![(
String::from("a"),
Some(Node::const_node(5)),
)])],
@ -63,7 +66,7 @@ fn check_let_declaration() {
fn check_let_declaration_no_spaces() {
check_parser(
"let a=5;",
&[Node::LetDecl(vec![(
vec![Node::let_decl(vec![(
String::from("a"),
Some(Node::const_node(5)),
)])],
@ -73,7 +76,10 @@ fn check_let_declaration_no_spaces() {
/// Checks empty `let` declaration parsing.
#[test]
fn check_empty_let_declaration() {
check_parser("let a;", &[Node::LetDecl(vec![(String::from("a"), None)])]);
check_parser(
"let a;",
vec![Node::let_decl(vec![(String::from("a"), None)])],
);
}
/// Checks multiple `let` declarations.
@ -81,7 +87,7 @@ fn check_empty_let_declaration() {
fn check_multiple_let_declaration() {
check_parser(
"let a = 5, b, c = 6;",
&[Node::LetDecl(vec![
vec![Node::let_decl(vec![
(String::from("a"), Some(Node::const_node(5))),
(String::from("b"), None),
(String::from("c"), Some(Node::const_node(6))),
@ -94,7 +100,7 @@ fn check_multiple_let_declaration() {
fn check_const_declaration() {
check_parser(
"const a = 5;",
&[Node::ConstDecl(vec![(
vec![Node::const_decl(vec![(
String::from("a"),
Node::const_node(5),
)])],
@ -106,7 +112,7 @@ fn check_const_declaration() {
fn check_const_declaration_no_spaces() {
check_parser(
"const a=5;",
&[Node::ConstDecl(vec![(
vec![Node::const_decl(vec![(
String::from("a"),
Node::const_node(5),
)])],
@ -124,7 +130,7 @@ fn check_empty_const_declaration() {
fn check_multiple_const_declaration() {
check_parser(
"const a = 5, c = 6;",
&[Node::ConstDecl(vec![
vec![Node::const_decl(vec![
(String::from("a"), Node::const_node(5)),
(String::from("c"), Node::const_node(6)),
])],

2
boa/src/syntax/parser/statement/iteration/for_statement.rs

@ -97,6 +97,6 @@ impl TokenParser for ForStatement {
let for_node = Node::for_loop::<_, _, _, Node, Node, Node, _>(init, cond, step, body);
Ok(Node::Block(vec![for_node]))
Ok(Node::Block(Box::new([for_node])))
}
}

10
boa/src/syntax/parser/statement/iteration/tests.rs

@ -11,8 +11,8 @@ fn check_do_while() {
r#"do {
a += 1;
} while (true)"#,
&[Node::do_while_loop(
Node::Block(vec![Node::bin_op(
vec![Node::do_while_loop(
Node::block(vec![Node::bin_op(
BinOp::Assign(AssignOp::Add),
Node::local("a"),
Node::const_node(1),
@ -28,10 +28,10 @@ fn check_do_while_semicolon_insertion() {
check_parser(
r#"var i = 0;
do {console.log("hello");} while(i++ < 10) console.log("end");"#,
&[
Node::VarDecl(vec![(String::from("i"), Some(Node::const_node(0)))]),
vec![
Node::var_decl(vec![(String::from("i"), Some(Node::const_node(0)))]),
Node::do_while_loop(
Node::Block(vec![Node::call(
Node::block(vec![Node::call(
Node::get_const_field(Node::local("console"), "log"),
vec![Node::const_node("hello")],
)]),

5
boa/src/syntax/parser/statement/switch/mod.rs

@ -87,8 +87,11 @@ impl CaseBlock {
}
}
/// Type used for case definition in a switch.
type Case = (Node, Box<[Node]>);
impl TokenParser for CaseBlock {
type Output = (Vec<(Node, Vec<Node>)>, Option<Node>);
type Output = (Box<[Case]>, Option<Node>);
fn parse(self, cursor: &mut Cursor<'_>) -> Result<Self::Output, ParseError> {
cursor.expect(Punctuator::OpenBlock, "switch case block")?;

5
boa/src/syntax/parser/statement/throw/tests.rs

@ -2,5 +2,8 @@ use crate::syntax::{ast::node::Node, parser::tests::check_parser};
#[test]
fn check_throw_parsing() {
check_parser("throw 'error';", &[Node::throw(Node::const_node("error"))]);
check_parser(
"throw 'error';",
vec![Node::throw(Node::const_node("error"))],
);
}

2
boa/src/syntax/parser/statement/variable.rs

@ -117,7 +117,7 @@ impl TokenParser for VariableDeclarationList {
}
}
Ok(Node::VarDecl(list))
Ok(Node::var_decl(list))
}
}

9
boa/src/syntax/parser/tests.rs

@ -4,7 +4,10 @@ use super::Parser;
use crate::syntax::{ast::node::Node, ast::op::NumOp, lexer::Lexer};
#[allow(clippy::result_unwrap_used)]
pub(super) fn check_parser(js: &str, expr: &[Node]) {
pub(super) fn check_parser<L>(js: &str, expr: L)
where
L: Into<Box<[Node]>>,
{
let mut lexer = Lexer::new(js);
lexer.lex().expect("failed to lex");
@ -28,7 +31,7 @@ pub(super) fn check_invalid(js: &str) {
fn check_construct_call_precedence() {
check_parser(
"new Date().getTime()",
&[Node::call(
vec![Node::call(
Node::get_const_field(
Node::new(Node::call(Node::local("Date"), Vec::new())),
"getTime",
@ -42,7 +45,7 @@ fn check_construct_call_precedence() {
fn assign_operator_precedence() {
check_parser(
"a = a + 1",
&[Node::assign(
vec![Node::assign(
Node::local("a"),
Node::bin_op(NumOp::Add, Node::local("a"), Node::const_node(1)),
)],

Loading…
Cancel
Save