Browse Source

Fully implement EmptyStatement (#1151)

* add EmptyStatement

* add comments

* format code

* add test

* add test

* fmt
pull/1173/head
QZQ 4 years ago committed by GitHub
parent
commit
7262882665
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      boa/src/exec/tests.rs
  2. 14
      boa/src/syntax/ast/node/mod.rs
  3. 5
      boa/src/syntax/parser/statement/mod.rs
  4. 27
      boa/src/syntax/parser/tests.rs

10
boa/src/exec/tests.rs

@ -1519,3 +1519,13 @@ fn test_strict_mode_dup_func_parameters() {
assert!(string.starts_with("Uncaught \"SyntaxError\": ")); assert!(string.starts_with("Uncaught \"SyntaxError\": "));
} }
#[test]
fn test_empty_statement() {
let src = r#"
;;;let a = 10;;
if(a) ;
a
"#;
assert_eq!(&exec(src), "10");
}

14
boa/src/syntax/ast/node/mod.rs

@ -196,6 +196,18 @@ pub enum Node {
/// A 'while {...}' node. [More information](./iteration/struct.WhileLoop.html). /// A 'while {...}' node. [More information](./iteration/struct.WhileLoop.html).
WhileLoop(WhileLoop), WhileLoop(WhileLoop),
/// A empty node.
///
/// Empty statement do nothing, just return undefined.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-EmptyStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/Empty
Empty,
} }
impl Display for Node { impl Display for Node {
@ -274,6 +286,7 @@ impl Node {
Self::AsyncFunctionDecl(ref decl) => decl.display(f, indentation), Self::AsyncFunctionDecl(ref decl) => decl.display(f, indentation),
Self::AsyncFunctionExpr(ref expr) => expr.display(f, indentation), Self::AsyncFunctionExpr(ref expr) => expr.display(f, indentation),
Self::AwaitExpr(ref expr) => expr.display(f, indentation), Self::AwaitExpr(ref expr) => expr.display(f, indentation),
Self::Empty => write!(f, ";"),
} }
} }
} }
@ -338,6 +351,7 @@ impl Executable for Node {
Node::Try(ref try_node) => try_node.run(context), Node::Try(ref try_node) => try_node.run(context),
Node::Break(ref break_node) => break_node.run(context), Node::Break(ref break_node) => break_node.run(context),
Node::Continue(ref continue_node) => continue_node.run(context), Node::Continue(ref continue_node) => continue_node.run(context),
Node::Empty => Ok(Value::Undefined),
} }
} }
} }

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

@ -178,6 +178,11 @@ where
.parse(cursor) .parse(cursor)
.map(Node::from) .map(Node::from)
} }
TokenKind::Punctuator(Punctuator::Semicolon) => {
// parse the EmptyStatement
cursor.next().expect("semicolon disappeared");
Ok(Node::Empty)
}
TokenKind::Identifier(_) => { TokenKind::Identifier(_) => {
// Labelled Statement check // Labelled Statement check
cursor.set_goal(InputElement::Div); cursor.set_goal(InputElement::Div);

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

@ -4,8 +4,8 @@ use super::Parser;
use crate::syntax::ast::{ use crate::syntax::ast::{
node::{ node::{
field::GetConstField, ArrowFunctionDecl, Assign, BinOp, Call, FormalParameter, field::GetConstField, ArrowFunctionDecl, Assign, BinOp, Call, FormalParameter,
FunctionDecl, Identifier, LetDecl, LetDeclList, New, Node, Return, StatementList, UnaryOp, FunctionDecl, Identifier, If, LetDecl, LetDeclList, New, Node, Return, StatementList,
VarDecl, VarDeclList, UnaryOp, VarDecl, VarDeclList,
}, },
op::{self, CompOp, LogOp, NumOp}, op::{self, CompOp, LogOp, NumOp},
Const, Const,
@ -209,7 +209,7 @@ fn assignment_line_terminator() {
let s = r#" let s = r#"
let a = 3; let a = 3;
a = a =
5; 5;
"#; "#;
@ -232,7 +232,7 @@ fn assignment_multiline_terminator() {
let a = 3; let a = 3;
a = a =
5; 5;
@ -292,3 +292,22 @@ fn spread_in_arrow_function() {
], ],
); );
} }
#[test]
fn empty_statement() {
check_parser(
r"
;;var a = 10;
if(a) ;
",
vec![
Node::Empty,
VarDeclList::from(vec![VarDecl::new("a", Node::from(Const::from(10)))]).into(),
Node::If(If::new::<_, _, Node, _>(
Identifier::from("a"),
Node::Empty,
None,
)),
],
);
}

Loading…
Cancel
Save