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] - Extract the ast to a crate #2402

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
members = [
"boa_cli",
"boa_engine",
"boa_ast",
"boa_gc",
"boa_interner",
"boa_profiler",
Expand All @@ -28,6 +29,7 @@ boa_gc = { version = "0.16.0", path = "boa_gc" }
boa_profiler = { version = "0.16.0", path = "boa_profiler" }
boa_unicode = { version = "0.16.0", path = "boa_unicode" }
boa_macros = { version = "0.16.0", path = "boa_macros" }
boa_ast = { version = "0.16.0", path = "boa_ast" }

[workspace.metadata.workspaces]
allow_branch = "main"
Expand Down
22 changes: 22 additions & 0 deletions boa_ast/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "boa_ast"
description = "Abstract Syntax Tree definition for the Boa JavaScript engine."
keywords = ["javascript", "js", "syntax", "ast"]
categories = ["parser-implementations", "compilers"]
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true

[features]
serde = ["boa_interner/serde", "dep:serde"]

[dependencies]
boa_interner.workspace = true
boa_macros.workspace = true
rustc-hash = "1.1.0"
serde = { version = "1.0.147", features = ["derive"], optional = true }
bitflags = "1.3.2"
num-bigint = "0.4.3"
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,16 @@ use super::{
};
use boa_interner::{Interner, ToIndentedString, ToInternedString};
use core::ops::ControlFlow;
use tap::Tap;

mod variable;

use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut};
use crate::visitor::{VisitWith, Visitor, VisitorMut};
pub use variable::*;

/// The `Declaration` Parse Node.
///
/// See the [module level documentation][self] for more information.
#[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub enum Declaration {
/// See [`Function`]
Expand Down Expand Up @@ -163,7 +162,11 @@ impl ToIndentedString for 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).tap_mut(|s| s.push(';')),
Declaration::Lexical(l) => {
let mut s = l.to_interned_string(interner);
s.push(';');
s
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
use core::ops::ControlFlow;
use std::convert::TryFrom;

use crate::syntax::ast::visitor::{VisitWith, Visitor, VisitorMut};
use crate::syntax::ast::{
use crate::try_break;
use crate::visitor::{VisitWith, Visitor, VisitorMut};
use crate::{
expression::{Expression, Identifier},
join_nodes,
pattern::Pattern,
ContainsSymbol, Statement,
};
use crate::try_break;
use boa_interner::{Interner, ToInternedString};

use super::Declaration;
Expand Down Expand Up @@ -44,7 +44,7 @@ use super::Declaration;
/// [var]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
/// [varstmt]: https://tc39.es/ecma262/#prod-VariableStatement
/// [hoisting]: https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
#[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub struct VarDeclaration(pub VariableList);

Expand Down Expand Up @@ -91,7 +91,7 @@ impl VisitWith for VarDeclaration {
/// the variable declaration.
///
/// [lexical declaration]: https://tc39.es/ecma262/#sec-let-and-const-declarations
#[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub enum LexicalDeclaration {
/// A <code>[const]</code> variable creates a constant whose scope can be either global or local
Expand All @@ -118,6 +118,7 @@ pub enum LexicalDeclaration {

impl LexicalDeclaration {
/// Gets the inner variable list of the `LexicalDeclaration`
#[must_use]
pub fn variable_list(&self) -> &VariableList {
match self {
LexicalDeclaration::Const(list) | LexicalDeclaration::Let(list) => list,
Expand Down Expand Up @@ -185,14 +186,15 @@ impl VisitWith for LexicalDeclaration {
}

/// List of variables in a variable declaration.
#[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub struct VariableList {
list: Box<[Variable]>,
}

impl VariableList {
/// Creates a variable list if the provided list of [`Variable`] is not empty.
#[must_use]
pub fn new(list: Box<[Variable]>) -> Option<Self> {
if list.is_empty() {
return None;
Expand Down Expand Up @@ -274,7 +276,7 @@ impl TryFrom<Vec<Variable>> for VariableList {
/// [spec1]: https://tc39.es/ecma262/#prod-LexicalBinding
/// [spec2]: https://tc39.es/ecma262/#prod-VariableDeclaration
/// [spec3]: https://tc39.es/ecma262/#sec-declarations-and-the-variable-statement
#[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub struct Variable {
binding: Binding,
Expand All @@ -295,7 +297,8 @@ impl ToInternedString for Variable {
impl Variable {
/// Creates a new variable declaration from a `BindingIdentifier`.
#[inline]
pub(in crate::syntax) fn from_identifier(ident: Identifier, init: Option<Expression>) -> Self {
#[must_use]
pub fn from_identifier(ident: Identifier, init: Option<Expression>) -> Self {
Self {
binding: Binding::Identifier(ident),
init,
Expand All @@ -304,23 +307,32 @@ impl Variable {

/// Creates a new variable declaration from a `Pattern`.
#[inline]
pub(in crate::syntax) fn from_pattern(pattern: Pattern, init: Option<Expression>) -> Self {
#[must_use]
pub fn from_pattern(pattern: Pattern, init: Option<Expression>) -> Self {
Self {
binding: Binding::Pattern(pattern),
init,
}
}
/// Gets the variable declaration binding.
pub(crate) fn binding(&self) -> &Binding {
#[must_use]
pub fn binding(&self) -> &Binding {
&self.binding
}

/// Gets the initialization expression for the variable declaration, if any.
#[inline]
pub(crate) fn init(&self) -> Option<&Expression> {
#[must_use]
pub fn init(&self) -> Option<&Expression> {
self.init.as_ref()
}

/// Gets the list of declared identifiers.
#[must_use]
pub fn idents(&self) -> Vec<Identifier> {
self.binding.idents()
}

#[inline]
pub(crate) fn contains_arguments(&self) -> bool {
if let Some(ref node) = self.init {
Expand All @@ -338,19 +350,15 @@ impl Variable {
///
/// [spec]: https://tc39.es/ecma262/#sec-static-semantics-contains
#[inline]
pub(crate) fn contains(&self, symbol: ContainsSymbol) -> bool {
#[must_use]
pub fn contains(&self, symbol: ContainsSymbol) -> bool {
if let Some(ref node) = self.init {
if node.contains(symbol) {
return true;
}
}
self.binding.contains(symbol)
}

/// Gets the list of declared identifiers.
pub(crate) fn idents(&self) -> Vec<Identifier> {
self.binding.idents()
}
}

impl VisitWith for Variable {
Expand Down Expand Up @@ -383,7 +391,7 @@ impl VisitWith for Variable {
/// - [ECMAScript reference: 14.3 Declarations and the Variable Statement][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-declarations-and-the-variable-statement
#[cfg_attr(feature = "deser", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub enum Binding {
/// A single identifier binding.
Expand Down Expand Up @@ -458,47 +466,3 @@ impl VisitWith for Binding {
}
}
}

#[cfg(test)]
mod tests {
#[test]
fn fmt_binding_pattern() {
crate::syntax::ast::test_formatting(
r#"
var { } = {
o: "1",
};
var { o_v1 } = {
o_v1: "1",
};
var { o_v2 = "1" } = {
o_v2: "2",
};
var { a : o_v3 = "1" } = {
a: "2",
};
var { ... o_rest_v1 } = {
a: "2",
};
var { o_v4, o_v5, o_v6 = "1", a : o_v7 = "1", ... o_rest_v2 } = {
o_v4: "1",
o_v5: "1",
};
var [] = [];
var [ , ] = [];
var [ a_v1 ] = [1, 2, 3];
var [ a_v2, a_v3 ] = [1, 2, 3];
var [ a_v2, , a_v3 ] = [1, 2, 3];
var [ ... a_rest_v1 ] = [1, 2, 3];
var [ a_v4, , ... a_rest_v2 ] = [1, 2, 3];
var [ { a_v5 } ] = [{
a_v5: 1,
}, {
a_v5: 2,
}, {
a_v5: 3,
}];
"#,
);
}
}
Loading