Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Implement LabelledStatement #2349

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
670 changes: 366 additions & 304 deletions boa_engine/src/bytecompiler/mod.rs

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion boa_engine/src/syntax/ast/declaration/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use boa_interner::{Interner, ToInternedString};
use tap::Tap;

use super::{
expression::Identifier,
Expand Down Expand Up @@ -40,7 +41,7 @@ impl Declaration {
Declaration::AsyncFunction(af) => af.to_indented_string(interner, indentation),
Declaration::AsyncGenerator(ag) => ag.to_indented_string(interner, indentation),
Declaration::Class(c) => c.to_indented_string(interner, indentation),
Declaration::Lexical(l) => l.to_interned_string(interner),
Declaration::Lexical(l) => l.to_interned_string(interner).tap_mut(|s| s.push(';')),
}
}

Expand Down
14 changes: 2 additions & 12 deletions boa_engine/src/syntax/ast/statement/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::syntax::ast::{expression::Identifier, ContainsSymbol, StatementList};

use super::Statement;
use boa_interner::{Interner, Sym, ToInternedString};
use boa_interner::{Interner, ToInternedString};

/// A `block` statement (or compound statement in other languages) is used to group zero or
/// more statements.
Expand All @@ -25,7 +25,6 @@ use boa_interner::{Interner, Sym, ToInternedString};
pub struct Block {
#[cfg_attr(feature = "deser", serde(flatten))]
statements: StatementList,
label: Option<Sym>,
}

impl Block {
Expand All @@ -49,20 +48,12 @@ impl Block {
)
}

pub fn label(&self) -> Option<Sym> {
self.label
}

pub fn set_label(&mut self, label: Sym) {
self.label = Some(label);
}

#[inline]
pub(crate) fn contains_arguments(&self) -> bool {
self.statements.contains_arguments()
|| matches!(self.label, Some(label) if label == Sym::ARGUMENTS)
}

#[inline]
pub(crate) fn contains(&self, symbol: ContainsSymbol) -> bool {
self.statements.contains(symbol)
}
Expand All @@ -75,7 +66,6 @@ where
fn from(list: T) -> Self {
Self {
statements: list.into(),
label: None,
}
}
}
Expand Down
28 changes: 4 additions & 24 deletions boa_engine/src/syntax/ast/statement/iteration/do_while_loop.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::syntax::ast::{expression::Expression, statement::Statement, ContainsSymbol};
use boa_interner::{Interner, Sym, ToInternedString};
use boa_interner::{Interner, ToInternedString};

/// The `do...while` statement creates a loop that executes a specified statement until the
/// test condition evaluates to false.
Expand All @@ -18,7 +18,6 @@ use boa_interner::{Interner, Sym, ToInternedString};
pub struct DoWhileLoop {
body: Box<Statement>,
condition: Expression,
label: Option<Sym>,
}

impl DoWhileLoop {
Expand All @@ -29,45 +28,26 @@ impl DoWhileLoop {
pub fn cond(&self) -> &Expression {
&self.condition
}

pub fn label(&self) -> Option<Sym> {
self.label
}

pub fn set_label(&mut self, label: Sym) {
self.label = Some(label);
}

/// Creates a `DoWhileLoop` AST node.
pub fn new(body: Statement, condition: Expression) -> Self {
Self {
body: body.into(),
condition,
label: None,
}
}

/// Converts the "do while" loop to a string with the given indentation.
pub(crate) fn to_indented_string(&self, interner: &Interner, indentation: usize) -> String {
let mut buf = if let Some(label) = self.label {
format!("{}: ", interner.resolve_expect(label))
} else {
String::new()
};
buf.push_str(&format!(
format!(
"do {} while ({})",
self.body().to_indented_string(interner, indentation),
self.cond().to_interned_string(interner)
));

buf
)
}

#[inline]
pub(crate) fn contains_arguments(&self) -> bool {
self.body.contains_arguments()
|| self.condition.contains_arguments()
|| matches!(self.label, Some(label) if label == Sym::ARGUMENTS)
self.body.contains_arguments() || self.condition.contains_arguments()
}

#[inline]
Expand Down
22 changes: 3 additions & 19 deletions boa_engine/src/syntax/ast/statement/iteration/for_in_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ use crate::syntax::ast::{
statement::{iteration::IterableLoopInitializer, Statement},
ContainsSymbol,
};
use boa_interner::{Interner, Sym, ToInternedString};
use boa_interner::{Interner, ToInternedString};
#[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub struct ForInLoop {
init: IterableLoopInitializer,
expr: Expression,
body: Box<Statement>,
label: Option<Sym>,
}

impl ForInLoop {
Expand All @@ -19,7 +18,6 @@ impl ForInLoop {
init,
expr,
body: body.into(),
label: None,
}
}

Expand All @@ -35,26 +33,13 @@ impl ForInLoop {
&self.body
}

pub fn label(&self) -> Option<Sym> {
self.label
}

pub fn set_label(&mut self, label: Sym) {
self.label = Some(label);
}

/// Converts the "for in" loop to a string with the given indentation.
pub(crate) fn to_indented_string(&self, interner: &Interner, indentation: usize) -> String {
let mut buf = if let Some(label) = self.label {
format!("{}: ", interner.resolve_expect(label))
} else {
String::new()
};
buf.push_str(&format!(
let mut buf = format!(
"for ({} in {}) ",
self.init.to_interned_string(interner),
self.expr.to_interned_string(interner)
));
);
buf.push_str(&self.body().to_indented_string(interner, indentation));

buf
Expand All @@ -65,7 +50,6 @@ impl ForInLoop {
self.init.contains_arguments()
|| self.expr.contains_arguments()
|| self.body.contains_arguments()
|| matches!(self.label, Some(label) if label == Sym::ARGUMENTS)
}

#[inline]
Expand Down
20 changes: 2 additions & 18 deletions boa_engine/src/syntax/ast/statement/iteration/for_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::syntax::ast::{
statement::Statement,
ContainsSymbol, Expression,
};
use boa_interner::{Interner, Sym, ToInternedString};
use boa_interner::{Interner, ToInternedString};

/// The `for` statement creates a loop that consists of three optional expressions.
///
Expand All @@ -22,7 +22,6 @@ use boa_interner::{Interner, Sym, ToInternedString};
pub struct ForLoop {
#[cfg_attr(feature = "deser", serde(flatten))]
inner: Box<InnerForLoop>,
label: Option<Sym>,
}

impl ForLoop {
Expand All @@ -35,7 +34,6 @@ impl ForLoop {
) -> Self {
Self {
inner: Box::new(InnerForLoop::new(init, condition, final_expr, body)),
label: None,
}
}

Expand All @@ -61,12 +59,7 @@ impl ForLoop {

/// Converts the for loop to a string with the given indentation.
pub(crate) fn to_indented_string(&self, interner: &Interner, indentation: usize) -> String {
let mut buf = if let Some(label) = self.label {
format!("{}: ", interner.resolve_expect(label))
} else {
String::new()
};
buf.push_str("for (");
let mut buf = String::from("for (");
if let Some(init) = self.init() {
buf.push_str(&init.to_interned_string(interner));
}
Expand All @@ -86,22 +79,13 @@ impl ForLoop {
buf
}

pub fn label(&self) -> Option<Sym> {
self.label
}

pub fn set_label(&mut self, label: Sym) {
self.label = Some(label);
}

#[inline]
pub(crate) fn contains_arguments(&self) -> bool {
let inner = &self.inner;
matches!(inner.init, Some(ref init) if init.contains_arguments())
|| matches!(inner.condition, Some(ref expr) if expr.contains_arguments())
|| matches!(inner.final_expr, Some(ref expr) if expr.contains_arguments())
|| inner.body.contains_arguments()
|| matches!(self.label, Some(label) if label == Sym::ARGUMENTS)
}

#[inline]
Expand Down
24 changes: 3 additions & 21 deletions boa_engine/src/syntax/ast/statement/iteration/for_of_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::syntax::ast::{
statement::{iteration::IterableLoopInitializer, Statement},
ContainsSymbol,
};
use boa_interner::{Interner, Sym, ToInternedString};
use boa_interner::{Interner, ToInternedString};

#[cfg(feature = "deser")]
use serde::{Deserialize, Serialize};
Expand All @@ -14,7 +14,6 @@ pub struct ForOfLoop {
init: IterableLoopInitializer,
iterable: Expression,
body: Box<Statement>,
label: Option<Sym>,
r#await: bool,
}

Expand All @@ -30,7 +29,6 @@ impl ForOfLoop {
init,
iterable,
body: body.into(),
label: None,
r#await,
}
}
Expand All @@ -47,42 +45,26 @@ impl ForOfLoop {
&self.body
}

pub fn label(&self) -> Option<Sym> {
self.label
}

pub fn set_label(&mut self, label: Sym) {
self.label = Some(label);
}

/// Returns true if this "for...of" loop is an "for await...of" loop.
pub(crate) fn r#await(&self) -> bool {
self.r#await
}

/// Converts the "for of" loop to a string with the given indentation.
pub(crate) fn to_indented_string(&self, interner: &Interner, indentation: usize) -> String {
let mut buf = if let Some(label) = self.label {
format!("{}: ", interner.resolve_expect(label))
} else {
String::new()
};
buf.push_str(&format!(
format!(
"for ({} of {}) {}",
self.init.to_interned_string(interner),
self.iterable.to_interned_string(interner),
self.body().to_indented_string(interner, indentation)
));

buf
)
}

#[inline]
pub(crate) fn contains_arguments(&self) -> bool {
self.init.contains_arguments()
|| self.iterable.contains_arguments()
|| self.body.contains_arguments()
|| matches!(self.label, Some(label) if label == Sym::ARGUMENTS)
}

#[inline]
Expand Down
28 changes: 4 additions & 24 deletions boa_engine/src/syntax/ast/statement/iteration/while_loop.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::syntax::ast::{expression::Expression, statement::Statement, ContainsSymbol};
use boa_interner::{Interner, Sym, ToInternedString};
use boa_interner::{Interner, ToInternedString};
/// The `while` statement creates a loop that executes a specified statement as long as the
/// test condition evaluates to `true`.
///
Expand All @@ -16,7 +16,6 @@ use boa_interner::{Interner, Sym, ToInternedString};
pub struct WhileLoop {
condition: Expression,
body: Box<Statement>,
label: Option<Sym>,
}

impl WhileLoop {
Expand All @@ -27,44 +26,25 @@ impl WhileLoop {
pub fn body(&self) -> &Statement {
&self.body
}

pub fn label(&self) -> Option<Sym> {
self.label
}

pub fn set_label(&mut self, label: Sym) {
self.label = Some(label);
}

/// Creates a `WhileLoop` AST node.
pub fn new(condition: Expression, body: Statement) -> Self {
Self {
condition,
body: body.into(),
label: None,
}
}

/// Converts the while loop to a string with the given indentation.
pub(crate) fn to_indented_string(&self, interner: &Interner, indentation: usize) -> String {
let mut buf = if let Some(label) = self.label {
format!("{}: ", interner.resolve_expect(label))
} else {
String::new()
};
buf.push_str(&format!(
format!(
"while ({}) {}",
self.condition().to_interned_string(interner),
self.body().to_indented_string(interner, indentation)
));

buf
)
}

pub(crate) fn contains_arguments(&self) -> bool {
self.condition.contains_arguments()
|| self.body.contains_arguments()
|| matches!(self.label, Some(label) if label == Sym::ARGUMENTS)
self.condition.contains_arguments() || self.body.contains_arguments()
}

#[inline]
Expand Down
Loading