From cdef843369a0a35ffecb2ee5272e3805dfadb149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 25 Nov 2021 20:16:46 +0900 Subject: [PATCH] feat(es/estree): Allow emitting `acorn` ast (#2859) swc_estree_ast: - Add `Flavor`. - Adjust serialization based on `Flavor`. swc_estree_visit: - Remove. testing: - Add `diff_json`. testing_macros: - `#[fixture]`: Print input. --- .github/workflows/cargo.yml | 2 - Cargo.lock | 30 +- crates/swc_css_parser/tests/fixture.rs | 7 - crates/swc_estree_ast/Cargo.toml | 10 +- crates/swc_estree_ast/src/class.rs | 184 +- crates/swc_estree_ast/src/comment.rs | 15 +- crates/swc_estree_ast/src/common.rs | 50 +- crates/swc_estree_ast/src/decl.rs | 17 +- crates/swc_estree_ast/src/expr.rs | 52 +- crates/swc_estree_ast/src/flavor.rs | 88 + crates/swc_estree_ast/src/flow.rs | 12 +- crates/swc_estree_ast/src/lib.rs | 2 + crates/swc_estree_ast/src/lit.rs | 156 +- crates/swc_estree_ast/src/module.rs | 6 +- crates/swc_estree_ast/src/object.rs | 71 +- crates/swc_estree_ast/src/pat.rs | 16 +- crates/swc_estree_ast/src/ser.rs | 38 + crates/swc_estree_ast/src/stmt.rs | 2 +- crates/swc_estree_compat/Cargo.toml | 19 +- .../swc_estree_compat/scripts/test-acorn.js | 10 + crates/swc_estree_compat/src/babelify/decl.rs | 1 + crates/swc_estree_compat/src/babelify/expr.rs | 40 +- crates/swc_estree_compat/src/babelify/jsx.rs | 9 +- crates/swc_estree_compat/src/babelify/mod.rs | 20 +- .../swc_estree_compat/src/babelify/module.rs | 18 +- .../src/babelify/normalize/mod.rs | 158 -- crates/swc_estree_compat/src/swcify/expr.rs | 20 +- crates/swc_estree_compat/tests/convert.rs | 130 +- crates/swc_estree_compat/tests/flavor.rs | 152 ++ .../tests/flavor/acorn/1/input.js | 1 + .../tests/flavor/acorn/1/output.json | 76 + .../fixtures/array-destructuring/input.js | 2 + .../fixtures/array-destructuring/output.json | 168 ++ .../acorn/fixtures/array-simple/input.js | 1 + .../acorn/fixtures/array-simple/output.json | 87 + .../acorn/fixtures/class-extends/input.js | 19 + .../acorn/fixtures/class-extends/output.json | 630 +++++ .../fixtures/class-getter-setter/input.js | 22 + .../fixtures/class-getter-setter/output.json | 833 ++++++ .../fixtures/class-method-no-body/input.js | 3 + .../fixtures/class-method-no-body/output.json | 87 + .../fixtures/class-public-fields/input.js | 8 + .../acorn/fixtures/class-simple/input.js | 7 + .../acorn/fixtures/class-simple/output.json | 301 +++ .../acorn/fixtures/class-static/input.js | 15 + .../acorn/fixtures/class-unnamed/input.js | 6 + .../acorn/fixtures/class-unnamed/output.json | 249 ++ .../comments-block-first-line/input.js | 4 + .../comments-block-first-line/output.json | 54 + .../acorn/fixtures/comments-block/input.js | 7 + .../acorn/fixtures/comments-block/output.json | 88 + .../fixtures/comments-first-line/input.js | 2 + .../fixtures/comments-first-line/output.json | 54 + .../acorn/fixtures/comments-line/input.js | 4 + .../acorn/fixtures/comments-line/output.json | 88 + .../acorn/fixtures/delete-operator/input.js | 2 + .../fixtures/delete-operator/output.json | 139 + .../fixtures/exponentiation-operator/input.js | 1 + .../exponentiation-operator/output.json | 75 + .../fixtures/function-anonymous/input.js | 1 + .../fixtures/function-anonymous/output.json | 117 + .../acorn/fixtures/function-arrow/input.js | 7 + .../acorn/fixtures/function-arrow/output.json | 227 ++ .../function-default-parameters/input.js | 3 + .../function-default-parameters/output.json | 126 + .../function-rest-parameters/input.js | 3 + .../function-rest-parameters/output.json | 182 ++ .../acorn/fixtures/function-simple/input.js | 3 + .../fixtures/function-simple/output.json | 96 + .../acorn/fixtures/jsx-and-expr/input.jsx | 6 + .../acorn/fixtures/jsx-children/input.jsx | 5 + .../flavor/acorn/fixtures/jsx-map/input.jsx | 6 + .../acorn/fixtures/jsx-props-spread/input.jsx | 3 + .../flavor/acorn/fixtures/jsx-props/input.jsx | 4 + .../acorn/fixtures/jsx-self-closing/input.jsx | 3 + .../acorn/fixtures/jsx-simple/input.jsx | 3 + .../acorn/fixtures/jsx-ternary-expr/input.jsx | 6 + .../acorn/fixtures/module-commonjs/input.js | 3 + .../fixtures/module-commonjs/output.json | 221 ++ .../fixtures/module-export-default/input.mjs | 2 + .../module-export-individual-items/input.mjs | 3 + .../fixtures/module-export-named/input.mjs | 2 + .../fixtures/module-export-renamed/input.mjs | 2 + .../fixtures/module-import-default/input.mjs | 1 + .../fixtures/module-import-multiple/input.mjs | 4 + .../fixtures/module-import-named/input.mjs | 1 + .../fixtures/module-import-renamed/input.mjs | 1 + .../module-import-star-renamed/input.mjs | 1 + .../fixtures/object-destructuring/input.js | 6 + .../fixtures/object-destructuring/output.json | 283 +++ .../acorn/fixtures/object-simple/input.js | 4 + .../acorn/fixtures/object-simple/output.json | 122 + .../acorn/fixtures/object-spread/input.js | 7 + .../acorn/fixtures/object-spread/output.json | 183 ++ .../acorn/fixtures/regex-flags/input.js | 1 + .../acorn/fixtures/regex-flags/output.json | 57 + .../acorn/fixtures/regex-simple/input.js | 1 + .../acorn/fixtures/regex-simple/output.json | 57 + .../flavor/acorn/fixtures/shebang/input.js | 3 + .../flavor/acorn/fixtures/shebang/output.json | 54 + .../acorn/fixtures/simple-two-lines/input.js | 2 + .../fixtures/simple-two-lines/output.json | 116 + .../flavor/acorn/fixtures/simple/input.js | 1 + .../flavor/acorn/fixtures/simple/output.json | 54 + .../acorn/fixtures/static-blocks/input.js | 6 + .../acorn/fixtures/template-literal/input.js | 2 + .../fixtures/template-literal/output.json | 157 ++ crates/swc_estree_macros/Cargo.toml | 14 - crates/swc_estree_macros/src/lib.rs | 1 - crates/swc_estree_visit/Cargo.toml | 24 - crates/swc_estree_visit/README.md | 24 - crates/swc_estree_visit/src/lib.rs | 2246 ----------------- crates/testing/Cargo.toml | 3 +- crates/testing/src/json.rs | 100 + crates/testing/src/lib.rs | 1 + crates/testing_macros/Cargo.toml | 2 +- crates/testing_macros/src/fixture.rs | 2 + cspell.json | 3 +- package.json | 1 + yarn.lock | 5 + 120 files changed, 6232 insertions(+), 2720 deletions(-) create mode 100644 crates/swc_estree_ast/src/flavor.rs create mode 100644 crates/swc_estree_ast/src/ser.rs create mode 100644 crates/swc_estree_compat/scripts/test-acorn.js delete mode 100644 crates/swc_estree_compat/src/babelify/normalize/mod.rs create mode 100644 crates/swc_estree_compat/tests/flavor.rs create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/1/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/1/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-destructuring/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-destructuring/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-simple/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-simple/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-extends/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-extends/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-getter-setter/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-getter-setter/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-method-no-body/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-method-no-body/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-public-fields/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-simple/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-simple/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-static/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-unnamed/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-unnamed/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block-first-line/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block-first-line/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-first-line/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-first-line/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-line/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-line/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/delete-operator/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/delete-operator/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/exponentiation-operator/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/exponentiation-operator/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-anonymous/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-anonymous/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-arrow/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-arrow/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-default-parameters/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-default-parameters/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-rest-parameters/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-rest-parameters/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-simple/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-simple/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-and-expr/input.jsx create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-children/input.jsx create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-map/input.jsx create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-props-spread/input.jsx create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-props/input.jsx create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-self-closing/input.jsx create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-simple/input.jsx create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-ternary-expr/input.jsx create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-commonjs/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-commonjs/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-default/input.mjs create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-individual-items/input.mjs create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-named/input.mjs create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-renamed/input.mjs create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-default/input.mjs create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-multiple/input.mjs create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-named/input.mjs create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-renamed/input.mjs create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-star-renamed/input.mjs create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-destructuring/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-destructuring/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-simple/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-simple/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-spread/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-spread/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-flags/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-flags/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-simple/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-simple/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/shebang/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/shebang/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple-two-lines/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple-two-lines/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple/output.json create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/static-blocks/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/template-literal/input.js create mode 100644 crates/swc_estree_compat/tests/flavor/acorn/fixtures/template-literal/output.json delete mode 100644 crates/swc_estree_macros/Cargo.toml delete mode 100644 crates/swc_estree_macros/src/lib.rs delete mode 100644 crates/swc_estree_visit/Cargo.toml delete mode 100644 crates/swc_estree_visit/README.md delete mode 100644 crates/swc_estree_visit/src/lib.rs create mode 100644 crates/testing/src/json.rs diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index b10d9af59df..25d4bf62734 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -153,8 +153,6 @@ jobs: - swc_eq_ignore_macros - swc_estree_ast - swc_estree_compat - - swc_estree_macros - - swc_estree_visit - swc_fast_graph - swc_graph_analyzer - swc_macros_common diff --git a/Cargo.lock b/Cargo.lock index c3ba1fe672d..334956816ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3143,18 +3143,18 @@ dependencies = [ [[package]] name = "swc_estree_ast" -version = "0.1.0" +version = "0.2.0" dependencies = [ + "scoped-tls", "serde", "serde_json", "swc_atoms 0.2.9", "swc_common", - "swc_estree_macros", ] [[package]] name = "swc_estree_compat" -version = "0.2.1" +version = "0.3.0" dependencies = [ "ahash", "anyhow", @@ -3172,29 +3172,12 @@ dependencies = [ "swc_ecma_utils", "swc_ecma_visit", "swc_estree_ast", - "swc_estree_macros", - "swc_estree_visit", "swc_node_base", "swc_node_comments", + "testing", "walkdir", ] -[[package]] -name = "swc_estree_macros" -version = "0.1.0" - -[[package]] -name = "swc_estree_visit" -version = "0.1.0" -dependencies = [ - "serde", - "serde_json", - "swc_atoms 0.2.9", - "swc_estree_ast", - "swc_estree_macros", - "swc_visit", -] - [[package]] name = "swc_fast_graph" version = "0.1.0" @@ -3412,13 +3395,14 @@ dependencies = [ [[package]] name = "testing" -version = "0.15.1" +version = "0.15.2" dependencies = [ "ansi_term 0.12.1", "difference", "once_cell", "pretty_assertions 0.7.2", "regex", + "serde_json", "swc_common", "testing_macros", "tracing", @@ -3427,7 +3411,7 @@ dependencies = [ [[package]] name = "testing_macros" -version = "0.2.3" +version = "0.2.4" dependencies = [ "anyhow", "glob", diff --git a/crates/swc_css_parser/tests/fixture.rs b/crates/swc_css_parser/tests/fixture.rs index 0dd018e1fd5..e608ab1c665 100644 --- a/crates/swc_css_parser/tests/fixture.rs +++ b/crates/swc_css_parser/tests/fixture.rs @@ -78,8 +78,6 @@ impl Visit for AssertValid { #[testing::fixture("tests/fixture/**/input.css")] fn tokens_input(input: PathBuf) { - eprintln!("Input: {}", input.display()); - testing::run_test2(false, |cm, handler| { let fm = cm.load_file(&input).unwrap(); @@ -125,8 +123,6 @@ fn tokens_input(input: PathBuf) { } fn test_pass(input: PathBuf, config: ParserConfig) { - eprintln!("Input: {}", input.display()); - testing::run_test2(false, |cm, handler| { let ref_json_path = input.parent().unwrap().join("output.json"); @@ -230,7 +226,6 @@ fn line_commetns(input: PathBuf) { #[testing::fixture("tests/recovery/**/input.css")] fn recovery(input: PathBuf) { - eprintln!("Input: {}", input.display()); let stderr_path = input.parent().unwrap().join("output.swc-stderr"); let mut errored = false; @@ -427,7 +422,6 @@ impl Visit for SpanVisualizer<'_> { #[testing::fixture("tests/fixture/**/input.css")] fn span(input: PathBuf) { - eprintln!("Input: {}", input.display()); let dir = input.parent().unwrap().to_path_buf(); let output = testing::run_test2(false, |cm, handler| { @@ -475,7 +469,6 @@ fn span(input: PathBuf) { #[testing::fixture("tests/errors/**/input.css")] fn fail(input: PathBuf) { - eprintln!("Input: {}", input.display()); let stderr_path = input.parent().unwrap().join("output.stderr"); let stderr = testing::run_test2(false, |cm, handler| -> Result<(), _> { diff --git a/crates/swc_estree_ast/Cargo.toml b/crates/swc_estree_ast/Cargo.toml index 08134f4603a..98c1af9e935 100644 --- a/crates/swc_estree_ast/Cargo.toml +++ b/crates/swc_estree_ast/Cargo.toml @@ -6,18 +6,14 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_estree_ast" repository = "https://github.com/swc-project/swc.git" -version = "0.1.0" +version = "0.2.0" [package.metadata.docs.rs] all-features = true -[features] -flavor-acorn = [] -flavor-babel = [] - [dependencies] +scoped-tls = "1.0.0" serde = {version = "1", features = ["derive"]} -serde_json = "1.0.62" +serde_json = "1" swc_atoms = {version = "0.2", path = "../swc_atoms"} swc_common = {version = "0.14", path = "../swc_common"} -swc_estree_macros = {version = "0.1", path = "../swc_estree_macros/"} diff --git a/crates/swc_estree_ast/src/class.rs b/crates/swc_estree_ast/src/class.rs index 776d1c50d0f..a03ab2b5527 100644 --- a/crates/swc_estree_ast/src/class.rs +++ b/crates/swc_estree_ast/src/class.rs @@ -1,18 +1,18 @@ -use serde::{Deserialize, Serialize}; -use serde_json::Value; -use swc_common::ast_serde; - use crate::{ common::{ Access, BaseNode, Decorator, Identifier, Param, PrivateName, SuperTypeParams, TypeAnnotOrNoop, TypeParamDeclOrNoop, }, expr::{ClassExpression, Expression}, + flavor::Flavor, flow::{ClassImplements, InterfaceExtends}, object::ObjectKey, stmt::{BlockStatement, Statement}, typescript::{TSDeclareMethod, TSExpressionWithTypeArguments, TSIndexSignature}, }; +use serde::{ser::SerializeMap, Deserialize, Serialize}; +use serde_json::Value; +use swc_common::ast_serde; #[derive(Debug, Clone, PartialEq)] #[ast_serde] @@ -32,8 +32,7 @@ pub enum ClassMethodKind { Constructor, } -#[derive(Debug, Clone, PartialEq)] -#[ast_serde("ClassMethod")] +#[derive(Debug, Clone, PartialEq, Deserialize)] pub struct ClassMethod { #[serde(flatten)] pub base: BaseNode, @@ -45,17 +44,32 @@ pub struct ClassMethod { pub body: BlockStatement, #[serde(default)] pub computed: Option, - #[serde(default, rename = "static")] + #[serde( + default, + rename = "static", + skip_serializing_if = "crate::flavor::Flavor::skip_none_and_false" + )] pub is_static: Option, - #[serde(default)] + #[serde( + default, + skip_serializing_if = "crate::flavor::Flavor::skip_none_and_false" + )] pub generator: Option, - #[serde(default, rename = "async")] + #[serde( + default, + rename = "async", + serialize_with = "crate::ser::serialize_as_bool" + )] pub is_async: Option, - #[serde(default, rename = "abstract")] + #[serde( + default, + rename = "abstract", + skip_serializing_if = "crate::flavor::Flavor::skip_none" + )] pub is_abstract: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub access: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub accessibility: Option, #[serde(default)] pub decorators: Option>, @@ -67,6 +81,134 @@ pub struct ClassMethod { pub type_parameters: Option, } +#[derive(Serialize)] +struct BabelClassMethod<'a> { + #[serde(rename = "type")] + type_: &'a str, + #[serde(flatten)] + pub base: &'a BaseNode, + #[serde(default)] + pub kind: Option, + pub key: &'a ObjectKey, + #[serde(default)] + pub params: &'a [Param], + pub body: &'a BlockStatement, + #[serde(default)] + pub computed: Option, + #[serde( + default, + rename = "static", + skip_serializing_if = "crate::flavor::Flavor::skip_none_and_false" + )] + pub is_static: Option, + #[serde( + default, + skip_serializing_if = "crate::flavor::Flavor::skip_none_and_false" + )] + pub generator: Option, + #[serde( + default, + rename = "async", + serialize_with = "crate::ser::serialize_as_bool" + )] + pub is_async: Option, + #[serde( + default, + rename = "abstract", + skip_serializing_if = "crate::flavor::Flavor::skip_none" + )] + pub is_abstract: Option, + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] + pub access: Option<&'a Access>, + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] + pub accessibility: Option<&'a Access>, + #[serde(default)] + pub decorators: Option<&'a [Decorator]>, + #[serde(default)] + pub optional: Option, + #[serde(default)] + pub return_type: Option<&'a TypeAnnotOrNoop>, + #[serde(default)] + pub type_parameters: Option<&'a TypeParamDeclOrNoop>, +} + +#[derive(Serialize)] +struct AcornClassMethodValue<'a> { + /// `FuncionExpression` + #[serde(rename = "type")] + type_: &'a str, + #[serde(flatten)] + base: &'a BaseNode, + + body: &'a BlockStatement, + + params: &'a [Param], + + generator: bool, + #[serde(rename = "async")] + is_async: bool, +} + +impl Serialize for ClassMethod { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + match Flavor::current() { + Flavor::Babel => { + let actual = BabelClassMethod { + type_: "ClassMethod", + base: &self.base, + kind: self.kind, + key: &self.key, + params: &self.params, + body: &self.body, + computed: self.computed, + is_static: self.is_static, + generator: self.generator, + is_async: self.is_async, + is_abstract: self.is_abstract, + access: self.access.as_ref(), + accessibility: self.accessibility.as_ref(), + decorators: self.decorators.as_deref(), + optional: self.optional, + return_type: self.return_type.as_deref(), + type_parameters: self.type_parameters.as_ref(), + }; + actual.serialize(serializer) + } + Flavor::Acorn => { + let mut s = serializer.serialize_map(None)?; + + { + // TODO(kdy1): This is bad. + self.base + .serialize(serde::__private::ser::FlatMapSerializer(&mut s))?; + } + + s.serialize_entry("type", "MethodDefinition")?; + s.serialize_entry("computed", &self.computed.unwrap_or(false))?; + s.serialize_entry("key", &self.key)?; + s.serialize_entry("kind", &self.kind)?; + s.serialize_entry("static", &self.is_static.unwrap_or(false))?; + s.serialize_entry( + "value", + &AcornClassMethodValue { + type_: "FunctionExpression", + base: &self.body.base, + body: &self.body, + params: &self.params, + generator: self.generator.unwrap_or(false), + is_async: self.is_async.unwrap_or(false), + }, + )?; + + s.end() + } + } + } +} + #[derive(Debug, Clone, PartialEq)] #[ast_serde("ClassPrivateProperty")] pub struct ClassPrivateProperty { @@ -209,19 +351,23 @@ pub struct ClassDeclaration { #[serde(default)] pub super_class: Option>, pub body: ClassBody, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub decorators: Option>, - #[serde(default, rename = "abstract")] + #[serde( + default, + rename = "abstract", + skip_serializing_if = "crate::ser::skip_typescript" + )] pub is_abstract: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::ser::skip_typescript")] pub declare: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub implements: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub mixins: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub super_type_parameters: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_parameters: Option, } diff --git a/crates/swc_estree_ast/src/comment.rs b/crates/swc_estree_ast/src/comment.rs index 9658c497626..f26fd03d459 100644 --- a/crates/swc_estree_ast/src/comment.rs +++ b/crates/swc_estree_ast/src/comment.rs @@ -1,11 +1,18 @@ +use crate::common::Loc; use serde::{Deserialize, Serialize}; use swc_common::ast_serde; -use crate::common::Loc; - -#[derive(Debug, Clone, PartialEq)] -#[ast_serde("BaseComment")] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum CommentType { + #[serde(rename = "CommentLine")] + Line, + #[serde(rename = "CommentBlock")] + Block, +} +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct BaseComment { + #[serde(rename = "type")] + pub type_: CommentType, pub value: String, pub start: usize, pub end: usize, diff --git a/crates/swc_estree_ast/src/common.rs b/crates/swc_estree_ast/src/common.rs index d41e887f005..9ad33c915b4 100644 --- a/crates/swc_estree_ast/src/common.rs +++ b/crates/swc_estree_ast/src/common.rs @@ -38,23 +38,23 @@ impl Loc { #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct BaseNode { - #[serde(default)] + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub leading_comments: Vec, - #[serde(default)] + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub inner_comments: Vec, - #[serde(default)] + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub trailing_comments: Vec, #[serde(default)] pub start: Option, #[serde(default)] pub end: Option, - #[serde(default)] + + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_range")] + pub range: Option<[usize; 2]>, + + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_loc")] pub loc: Option, - /* TODO(dwoznicki): I can't figure out what goes in this field, so I'm just - * removing it for now. - * #[serde(default)] - * pub extra: Option>, */ } #[derive(Debug, Clone, PartialEq)] @@ -113,15 +113,12 @@ pub enum FunctionParent { #[ast_serde] pub enum Immutable { #[tag("StringLiteral")] - StringLiteral(StringLiteral), + #[tag("DecimalLiteral")] #[tag("NumericLiteral")] - NumericLiteral(NumericLiteral), #[tag("NullLiteral")] - NullLiteral(NullLiteral), #[tag("BooleanLiteral")] - BooleanLiteral(BooleanLiteral), #[tag("BigIntLiteral")] - BigIntLiteral(BigIntLiteral), + Literal(Literal), #[tag("JSXAttribute")] JSXAttribute(JSXAttribute), #[tag("JSXClosingElement")] @@ -142,8 +139,6 @@ pub enum Immutable { JSXOpeningFragment(JSXOpeningFragment), #[tag("JSXClosingFragment")] JSXClosingFragment(JSXClosingFragment), - #[tag("DecimalLiteral")] - DecimalLiteral(DecimalLiteral), } #[derive(Debug, Clone, PartialEq)] @@ -187,21 +182,15 @@ pub enum Pureish { #[tag("FunctionExpression")] FunctionExpr(FunctionExpression), #[tag("StringLiteral")] - StringLiteral(StringLiteral), #[tag("NumericLiteral")] - NumericLiteral(NumericLiteral), #[tag("NullLiteral")] - NullLiteral(NullLiteral), #[tag("BooleanLiteral")] - BooleanLiteral(BooleanLiteral), #[tag("RegExpLiteral")] - RegExpLiteral(RegExpLiteral), + #[tag("BigIntLiteral")] + #[tag("DecimalLiteral")] + Literal(Literal), #[tag("ArrowFunctionExpression")] ArrowFuncExpr(ArrowFunctionExpression), - #[tag("BigIntLiteral")] - BigIntLiteral(BigIntLiteral), - #[tag("DecimalLiteral")] - DecimalLiteral(DecimalLiteral), } #[derive(Debug, Clone, PartialEq)] @@ -346,9 +335,9 @@ pub struct RestElement { #[serde(flatten)] pub base: BaseNode, pub argument: Box, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub decorators: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_annotation: Option>, } @@ -372,11 +361,14 @@ pub struct Identifier { pub base: BaseNode, #[serde(default)] pub name: JsWord, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub decorators: Option>, - #[serde(default)] + #[serde( + default, + skip_serializing_if = "crate::flavor::Flavor::skip_none_and_false" + )] pub optional: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_annotation: Option>, } diff --git a/crates/swc_estree_ast/src/decl.rs b/crates/swc_estree_ast/src/decl.rs index 39cee0cea25..59d65676aae 100644 --- a/crates/swc_estree_ast/src/decl.rs +++ b/crates/swc_estree_ast/src/decl.rs @@ -94,7 +94,10 @@ pub struct VariableDeclarator { pub id: LVal, #[serde(default)] pub init: Option>, - #[serde(default)] + #[serde( + default, + skip_serializing_if = "crate::flavor::Flavor::skip_none_and_false" + )] pub definite: Option, } @@ -106,7 +109,10 @@ pub struct VariableDeclaration { pub kind: VariableDeclarationKind, #[serde(default)] pub declarations: Vec, - #[serde(default)] + #[serde( + default, + skip_serializing_if = "crate::flavor::Flavor::skip_none_and_false" + )] pub declare: Option, } @@ -124,9 +130,11 @@ pub struct FunctionDeclaration { pub generator: Option, #[serde(default, rename = "async")] pub is_async: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::ser::skip_expression_for_fn")] + pub expression: bool, + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub return_type: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_parameters: Option, } @@ -139,6 +147,7 @@ impl From for FunctionDeclaration { body: expr.body, generator: expr.generator, is_async: expr.is_async, + expression: false, return_type: expr.return_type, type_parameters: expr.type_parameters, } diff --git a/crates/swc_estree_ast/src/expr.rs b/crates/swc_estree_ast/src/expr.rs index f07b8ae7baa..88cd385b7fa 100644 --- a/crates/swc_estree_ast/src/expr.rs +++ b/crates/swc_estree_ast/src/expr.rs @@ -8,10 +8,7 @@ use crate::{ InterfaceExtends, TypeAnnotation, TypeParameterDeclaration, TypeParameterInstantiation, }, jsx::{JSXElement, JSXFragment, JSXNamespacedName}, - lit::{ - BigIntLiteral, BooleanLiteral, DecimalLiteral, NullLiteral, NumericLiteral, RegExpLiteral, - StringLiteral, TemplateLiteral, - }, + lit::{Literal, TemplateLiteral}, module::{Import, Program}, object::{ObjectMethod, ObjectProperty}, stmt::{BlockStatement, ExpressionStatement}, @@ -41,15 +38,13 @@ pub enum Expression { #[tag("Identifier")] Id(Identifier), #[tag("StringLiteral")] - StringLiteral(StringLiteral), #[tag("NumericLiteral")] - NumericLiteral(NumericLiteral), #[tag("NullLiteral")] - NullLiteral(NullLiteral), #[tag("BooleanLiteral")] - BooleanLiteral(BooleanLiteral), #[tag("RegExpLiteral")] - RegExpLiteral(RegExpLiteral), + #[tag("DecimalLiteral")] + #[tag("BigIntLiteral")] + Literal(Literal), #[tag("LogicalExpression")] Logical(LogicalExpression), #[tag("MemberExpression")] @@ -86,8 +81,6 @@ pub enum Expression { Await(AwaitExpression), #[tag("Import")] Import(Import), - #[tag("BigIntLiteral")] - BigIntLiteral(BigIntLiteral), #[tag("OptionalMemberExpression")] OptionalMember(OptionalMemberExpression), #[tag("OptionalCallExpression")] @@ -108,8 +101,6 @@ pub enum Expression { Record(RecordExpression), #[tag("TupleExpression")] Tuple(TupleExpression), - #[tag("DecimalLiteral")] - DecimalLiteral(DecimalLiteral), #[tag("ModuleExpression")] Module(ModuleExpression), #[tag("TSAsExpression")] @@ -180,7 +171,7 @@ pub struct MemberExpression { pub property: Box, #[serde(default)] pub computed: bool, - #[serde(default)] + #[serde(default, serialize_with = "crate::ser::serialize_optional")] pub optional: Option, } @@ -313,11 +304,11 @@ pub struct CallExpression { pub callee: Box, #[serde(default)] pub arguments: Vec, - #[serde(default)] + #[serde(default, serialize_with = "crate::ser::serialize_optional")] pub optional: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_arguments: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_parameters: Option, } @@ -345,9 +336,9 @@ pub struct FunctionExpression { pub generator: Option, #[serde(default, rename = "async")] pub is_async: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub return_type: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_parameters: Option, } @@ -359,11 +350,14 @@ pub struct NewExpression { pub callee: Callee, #[serde(default)] pub arguments: Vec, - #[serde(default)] + #[serde( + default, + skip_serializing_if = "crate::flavor::Flavor::skip_none_and_false" + )] pub optional: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_arguments: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_parameters: Option, } @@ -508,9 +502,9 @@ pub struct ArrowFunctionExpression { pub expression: bool, #[serde(default)] pub generator: bool, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub return_type: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_parameters: Option, } @@ -524,15 +518,15 @@ pub struct ClassExpression { #[serde(default)] pub super_class: Option>, pub body: ClassBody, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub decorators: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub implements: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub mixins: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub super_type_parameters: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_parameters: Option, } diff --git a/crates/swc_estree_ast/src/flavor.rs b/crates/swc_estree_ast/src/flavor.rs new file mode 100644 index 00000000000..4314b452eb5 --- /dev/null +++ b/crates/swc_estree_ast/src/flavor.rs @@ -0,0 +1,88 @@ +use crate::Loc; +use scoped_tls::scoped_thread_local; + +scoped_thread_local!(static FLAVOR: Flavor); + +#[repr(u8)] +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +pub enum Flavor { + Babel, + Acorn, +} + +impl Default for Flavor { + fn default() -> Self { + Flavor::Babel + } +} + +impl Flavor { + pub fn with(self, op: F) -> Ret + where + F: FnOnce() -> Ret, + { + FLAVOR.set(&self, || op()) + } + + pub fn current() -> Self { + if FLAVOR.is_set() { + FLAVOR.with(|v| *v) + } else { + Flavor::default() + } + } + + pub fn emit_loc(&self) -> bool { + matches!(Self::current(), Flavor::Babel) + } + + pub(crate) fn skip_range(_: &Option<[usize; 2]>) -> bool { + matches!(Self::current(), Flavor::Babel) + } + + pub(crate) fn skip_loc(_: &Option) -> bool { + !Self::current().emit_loc() + } + + pub(crate) fn skip_empty(v: &T) -> bool + where + T: IsEmpty, + { + matches!(Self::current(), Flavor::Acorn) && v.is_empty() + } + + pub(crate) fn skip_none(v: &Option) -> bool { + matches!(Self::current(), Flavor::Acorn) && v.is_none() + } + pub(crate) fn skip_none_and_false(v: &Option) -> bool { + matches!(Self::current(), Flavor::Acorn) && matches!(v, None | Some(false)) + } +} + +pub(crate) trait IsEmpty { + fn is_empty(&self) -> bool; +} + +impl IsEmpty for String { + fn is_empty(&self) -> bool { + self.is_empty() + } +} + +impl IsEmpty for Vec { + fn is_empty(&self) -> bool { + self.is_empty() + } +} + +impl IsEmpty for Option +where + T: IsEmpty, +{ + fn is_empty(&self) -> bool { + match self { + Some(v) => v.is_empty(), + None => true, + } + } +} diff --git a/crates/swc_estree_ast/src/flow.rs b/crates/swc_estree_ast/src/flow.rs index 0791eecd02f..2e1f73cf979 100644 --- a/crates/swc_estree_ast/src/flow.rs +++ b/crates/swc_estree_ast/src/flow.rs @@ -679,14 +679,14 @@ pub struct DeclareClass { #[serde(flatten)] pub base: BaseNode, pub id: Identifier, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_parameters: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub extends: Option>, pub body: ObjectTypeAnnotation, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub implements: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub mixins: Option>, } @@ -714,7 +714,7 @@ pub struct DeclareInterface { pub body: ObjectTypeAnnotation, #[serde(default)] pub implements: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub mixins: Option>, } @@ -830,7 +830,7 @@ pub struct InterfaceDeclaration { pub body: ObjectTypeAnnotation, #[serde(default)] pub implements: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub mixins: Option>, } diff --git a/crates/swc_estree_ast/src/lib.rs b/crates/swc_estree_ast/src/lib.rs index 315358aba52..3655fdf43d7 100644 --- a/crates/swc_estree_ast/src/lib.rs +++ b/crates/swc_estree_ast/src/lib.rs @@ -17,11 +17,13 @@ mod comment; mod common; mod decl; mod expr; +pub mod flavor; mod flow; mod jsx; mod lit; mod module; mod object; mod pat; +mod ser; mod stmt; mod typescript; diff --git a/crates/swc_estree_ast/src/lit.rs b/crates/swc_estree_ast/src/lit.rs index 381d42a5fe3..5d8bfb91669 100644 --- a/crates/swc_estree_ast/src/lit.rs +++ b/crates/swc_estree_ast/src/lit.rs @@ -1,11 +1,139 @@ -use crate::{common::BaseNode, expr::Expression, typescript::TSType}; -use serde::{Deserialize, Serialize}; +use crate::{common::BaseNode, expr::Expression, flavor::Flavor, typescript::TSType}; +use serde::{ser::SerializeMap, Deserialize, Serialize}; +use std::borrow::Cow; use swc_atoms::JsWord; use swc_common::ast_serde; #[derive(Debug, Clone, PartialEq)] -#[ast_serde] pub enum Literal { + String(StringLiteral), + Numeric(NumericLiteral), + Null(NullLiteral), + Boolean(BooleanLiteral), + RegExp(RegExpLiteral), + Template(TemplateLiteral), + BigInt(BigIntLiteral), + Decimal(DecimalLiteral), +} +#[derive(Serialize)] +struct AcornRegex<'a> { + flags: &'a str, + pattern: &'a str, +} + +#[derive(Serialize)] +struct Empty {} + +impl Serialize for Literal { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + match Flavor::current() { + Flavor::Babel => { + let b = match self { + Literal::String(l) => BabelLiteral::String(l.clone()), + Literal::Numeric(l) => BabelLiteral::Numeric(l.clone()), + Literal::Null(l) => BabelLiteral::Null(l.clone()), + Literal::Boolean(l) => BabelLiteral::Boolean(l.clone()), + Literal::RegExp(l) => BabelLiteral::RegExp(l.clone()), + Literal::Template(l) => BabelLiteral::Template(l.clone()), + Literal::BigInt(l) => BabelLiteral::BigInt(l.clone()), + Literal::Decimal(l) => BabelLiteral::Decimal(l.clone()), + }; + BabelLiteral::serialize(&b, serializer) + } + Flavor::Acorn => { + let (base, value, raw) = match self { + Literal::String(l) => ( + &l.base, + AcornLiteralValue::String(l.value.clone()), + Cow::Borrowed(&*l.value), + ), + Literal::Numeric(l) => ( + &l.base, + AcornLiteralValue::Numeric(l.value.clone()), + Cow::Owned(l.value.to_string()), + ), + Literal::Null(l) => ( + &l.base, + AcornLiteralValue::Null(None), + Cow::Borrowed("null"), + ), + Literal::Boolean(l) => ( + &l.base, + AcornLiteralValue::Boolean(l.value.clone()), + if l.value { + Cow::Borrowed("true") + } else { + Cow::Borrowed("false") + }, + ), + Literal::RegExp(l) => { + let mut s = serializer.serialize_map(None)?; + { + // TODO(kdy1): This is bad. + l.base + .serialize(serde::__private::ser::FlatMapSerializer(&mut s))?; + } + s.serialize_entry("type", "Literal")?; + + s.serialize_entry( + "regex", + &AcornRegex { + flags: &l.flags, + pattern: &l.pattern, + }, + )?; + s.serialize_entry("value", &Empty {})?; + return s.end(); + } + Literal::Template(..) => todo!(), + Literal::BigInt(l) => ( + &l.base, + AcornLiteralValue::BigInt(l.value.clone()), + Cow::Owned(l.value.to_string()), + ), + Literal::Decimal(l) => ( + &l.base, + AcornLiteralValue::Decimal(l.value.clone()), + Cow::Owned(l.value.to_string()), + ), + }; + let acorn = AcornLiteral { + type_: "Literal", + raw: &raw, + base, + value, + }; + + AcornLiteral::serialize(&acorn, serializer) + } + } + } +} + +impl<'de> Deserialize<'de> for Literal { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + BabelLiteral::deserialize(deserializer).map(|b| match b { + BabelLiteral::String(l) => Literal::String(l), + BabelLiteral::Numeric(l) => Literal::Numeric(l), + BabelLiteral::Null(l) => Literal::Null(l), + BabelLiteral::Boolean(l) => Literal::Boolean(l), + BabelLiteral::RegExp(l) => Literal::RegExp(l), + BabelLiteral::Template(l) => Literal::Template(l), + BabelLiteral::BigInt(l) => Literal::BigInt(l), + BabelLiteral::Decimal(l) => Literal::Decimal(l), + }) + } +} + +/// Used for serialization/deserialization +#[ast_serde] +enum BabelLiteral { #[tag("StringLiteral")] String(StringLiteral), #[tag("NumericLiteral")] @@ -24,6 +152,28 @@ pub enum Literal { Decimal(DecimalLiteral), } +#[derive(Serialize)] +struct AcornLiteral<'a> { + /// `Literal`. + #[serde(rename = "type")] + type_: &'a str, + raw: &'a str, + #[serde(flatten)] + base: &'a BaseNode, + value: AcornLiteralValue, +} + +#[derive(Serialize)] +#[serde(untagged)] +enum AcornLiteralValue { + String(JsWord), + Numeric(f64), + Null(Option<()>), + Boolean(bool), + BigInt(String), + Decimal(JsWord), +} + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(tag = "type")] pub struct StringLiteral { diff --git a/crates/swc_estree_ast/src/module.rs b/crates/swc_estree_ast/src/module.rs index b33069a4a9c..4e8185d3382 100644 --- a/crates/swc_estree_ast/src/module.rs +++ b/crates/swc_estree_ast/src/module.rs @@ -89,12 +89,12 @@ pub struct Program { #[serde(flatten)] pub base: BaseNode, pub body: Vec, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub directives: Vec, pub source_type: SrcType, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::ser::skip_interpreter")] pub interpreter: Option, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub source_file: String, } diff --git a/crates/swc_estree_ast/src/object.rs b/crates/swc_estree_ast/src/object.rs index 414c94261f6..56757ebb2ff 100644 --- a/crates/swc_estree_ast/src/object.rs +++ b/crates/swc_estree_ast/src/object.rs @@ -1,4 +1,4 @@ -use serde::{Deserialize, Serialize}; +use serde::{ser::SerializeMap, Deserialize, Serialize}; use swc_common::ast_serde; use crate::{ @@ -6,6 +6,7 @@ use crate::{ BaseNode, Decorator, Identifier, Param, PatternLike, TypeAnnotOrNoop, TypeParamDeclOrNoop, }, expr::Expression, + flavor::Flavor, flow::{ ObjectTypeCallProperty, ObjectTypeIndexer, ObjectTypeInternalSlot, ObjectTypeProperty, ObjectTypeSpreadProperty, @@ -101,8 +102,7 @@ pub enum ObjectPropVal { Expr(Box), } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -#[serde(tag = "type")] +#[derive(Debug, Clone, Deserialize, PartialEq)] pub struct ObjectProperty { #[serde(flatten)] pub base: BaseNode, @@ -112,6 +112,69 @@ pub struct ObjectProperty { pub computed: bool, #[serde(default)] pub shorthand: bool, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub decorators: Option>, } + +#[derive(Serialize)] +struct BabelObjectProperty<'a> { + #[serde(rename = "type")] + type_: &'a str, + #[serde(flatten)] + base: &'a BaseNode, + key: &'a ObjectKey, + value: &'a ObjectPropVal, + method: bool, + computed: bool, + shorthand: bool, + #[serde(skip_serializing_if = "crate::flavor::Flavor::skip_none")] + decorators: Option<&'a [Decorator]>, +} + +impl Serialize for ObjectProperty { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + match Flavor::current() { + Flavor::Babel => { + let actual = BabelObjectProperty { + type_: "ObjectProperty", + base: &self.base, + key: &self.key, + value: &self.value, + method: false, + computed: self.computed, + shorthand: self.shorthand, + decorators: self.decorators.as_deref(), + }; + actual.serialize(serializer) + } + Flavor::Acorn => { + let mut s = serializer.serialize_map(None)?; + + { + // TODO(kdy1): This is bad. + self.base + .serialize(serde::__private::ser::FlatMapSerializer(&mut s))?; + } + + s.serialize_entry("type", "Property")?; + s.serialize_entry("kind", "init")?; + s.serialize_entry("method", &false)?; + s.serialize_entry("shorthand", &self.shorthand)?; + s.serialize_entry("key", &self.key)?; + s.serialize_entry("value", &self.value)?; + s.serialize_entry("computed", &self.computed)?; + if let Some(decorators) = &self.decorators { + if !decorators.is_empty() { + s.serialize_entry("decorators", decorators)?; + } + } + s.serialize_entry("computed", &self.computed)?; + + s.end() + } + } + } +} diff --git a/crates/swc_estree_ast/src/pat.rs b/crates/swc_estree_ast/src/pat.rs index ea8e1e35b0c..72ccdb3cf35 100644 --- a/crates/swc_estree_ast/src/pat.rs +++ b/crates/swc_estree_ast/src/pat.rs @@ -35,9 +35,9 @@ pub struct ObjectPattern { pub base: BaseNode, #[serde(default)] pub properties: Vec, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub decorators: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_annotation: Option>, } @@ -55,27 +55,27 @@ pub enum AssignmentPatternLeft { } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -#[serde(tag = "type")] +#[serde(tag = "type", rename_all = "camelCase")] pub struct AssignmentPattern { #[serde(flatten)] pub base: BaseNode, pub left: AssignmentPatternLeft, pub right: Box, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub decorators: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_annotation: Option>, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -#[serde(tag = "type")] +#[serde(tag = "type", rename_all = "camelCase")] pub struct ArrayPattern { #[serde(flatten)] pub base: BaseNode, #[serde(default)] pub elements: Vec>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub decorators: Option>, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_none")] pub type_annotation: Option>, } diff --git a/crates/swc_estree_ast/src/ser.rs b/crates/swc_estree_ast/src/ser.rs new file mode 100644 index 00000000000..6f4b27e94df --- /dev/null +++ b/crates/swc_estree_ast/src/ser.rs @@ -0,0 +1,38 @@ +use crate::flavor::Flavor; +use serde::Serializer; + +pub(crate) fn serialize_optional(o: &Option, s: S) -> Result +where + S: Serializer, +{ + return s.serialize_some(&o.unwrap_or(false)); +} + +/// Always serializes as a boolean value. +pub(crate) fn serialize_as_bool(o: &Option, s: S) -> Result +where + S: Serializer, +{ + s.serialize_bool(o.unwrap_or(false)) +} + +pub(crate) fn skip_expression_for_fn(_: T) -> bool { + match Flavor::current() { + Flavor::Acorn => false, + Flavor::Babel => true, + } +} + +pub(crate) fn skip_interpreter(_: T) -> bool { + match Flavor::current() { + Flavor::Acorn => true, + Flavor::Babel => false, + } +} + +pub(crate) fn skip_typescript(_: T) -> bool { + match Flavor::current() { + Flavor::Acorn => true, + Flavor::Babel => false, + } +} diff --git a/crates/swc_estree_ast/src/stmt.rs b/crates/swc_estree_ast/src/stmt.rs index e4a2b17f6b2..ca2a3a7e67a 100644 --- a/crates/swc_estree_ast/src/stmt.rs +++ b/crates/swc_estree_ast/src/stmt.rs @@ -185,7 +185,7 @@ pub struct BlockStatement { pub base: BaseNode, #[serde(default)] pub body: Vec, - #[serde(default)] + #[serde(default, skip_serializing_if = "crate::flavor::Flavor::skip_empty")] pub directives: Vec, } diff --git a/crates/swc_estree_compat/Cargo.toml b/crates/swc_estree_compat/Cargo.toml index 5dde0e1973b..51aff9639c5 100644 --- a/crates/swc_estree_compat/Cargo.toml +++ b/crates/swc_estree_compat/Cargo.toml @@ -6,21 +6,11 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_estree_compat" repository = "https://github.com/swc-project/swc.git" -version = "0.2.1" +version = "0.3.0" [package.metadata.docs.rs] all-features = true -[features] -flavor-acorn = [ - "swc_estree_ast/flavor-acorn", - "swc_estree_visit/flavor-acorn", -] -flavor-babel = [ - "swc_estree_ast/flavor-babel", - "swc_estree_visit/flavor-babel", -] - [dependencies] ahash = {version = "0.7.0", features = ["compile-time-rng"]} anyhow = "1" @@ -34,14 +24,15 @@ swc_ecma_ast = {version = "0.58", path = "../swc_ecma_ast"} swc_ecma_parser = {version = "0.78", path = "../swc_ecma_parser"} swc_ecma_utils = {version = "0.52.3", path = "../swc_ecma_utils"} swc_ecma_visit = {version = "0.44", path = "../swc_ecma_visit"} -swc_estree_ast = {version = "0.1", path = "../swc_estree_ast"} -swc_estree_macros = {version = "0.1", path = "../swc_estree_macros/"} -swc_estree_visit = {version = "0.1", path = "../swc_estree_visit"} +swc_estree_ast = {version = "0.2.0", path = "../swc_estree_ast"} swc_node_comments = {version = "0.1", path = "../swc_node_comments/"} [dev-dependencies] pretty_assertions = "0.7.1" swc = {version = "0.87.1", path = "../swc"} +swc_ecma_ast = {version = "0.58.0", path = "../swc_ecma_ast"} +swc_ecma_parser = {version = "0.78.7", path = "../swc_ecma_parser"} swc_ecma_transforms = {version = "0.95.1", path = "../swc_ecma_transforms/"} swc_node_base = {version = "0.5", path = "../swc_node_base"} +testing = {version = "0.15.1", path = "../testing"} walkdir = "2" diff --git a/crates/swc_estree_compat/scripts/test-acorn.js b/crates/swc_estree_compat/scripts/test-acorn.js new file mode 100644 index 00000000000..ee82f567ee3 --- /dev/null +++ b/crates/swc_estree_compat/scripts/test-acorn.js @@ -0,0 +1,10 @@ +// File to parse input as an AST using acorn + + +const acorn = require("acorn"); +const res = acorn.parse(process.argv[1], { + ecmaVersion: 2020, + ranges: true, + allowHashBang: true +}) +console.log(JSON.stringify(res, void 0, 2)); \ No newline at end of file diff --git a/crates/swc_estree_compat/src/babelify/decl.rs b/crates/swc_estree_compat/src/babelify/decl.rs index c4663646c31..4bd26636076 100644 --- a/crates/swc_estree_compat/src/babelify/decl.rs +++ b/crates/swc_estree_compat/src/babelify/decl.rs @@ -35,6 +35,7 @@ impl Babelify for FnDecl { body: func.body, generator: func.generator, is_async: func.is_async, + expression: false, return_type: func.return_type, type_parameters: func.type_parameters, } diff --git a/crates/swc_estree_compat/src/babelify/expr.rs b/crates/swc_estree_compat/src/babelify/expr.rs index ec30da1a3bb..8fadd1fe473 100644 --- a/crates/swc_estree_compat/src/babelify/expr.rs +++ b/crates/swc_estree_compat/src/babelify/expr.rs @@ -9,14 +9,15 @@ use swc_ecma_ast::{ TaggedTpl, ThisExpr, Tpl, TplElement, UnaryExpr, UpdateExpr, YieldExpr, }; use swc_estree_ast::{ - ArrayExprEl, ArrayExpression, ArrowFuncExprBody, ArrowFunctionExpression, AssignmentExpression, - AwaitExpression, BinaryExprLeft, BinaryExpression, CallExpression, Callee, ClassExpression, - ConditionalExpression, Expression, FunctionExpression, LVal, LogicalExpression, MemberExprProp, - MemberExpression, MetaProperty, NewExpression, ObjectExprProp, ObjectExpression, ObjectKey, - ObjectMember, ParenthesizedExpression, PrivateName, SequenceExpression, - SpreadElement as BabelSpreadElement, Super as BabelSuper, TaggedTemplateExprTypeParams, - TaggedTemplateExpression, TemplateElVal, TemplateElement, TemplateLiteral, TemplateLiteralExpr, - ThisExpression, UnaryExpression, UpdateExpression, YieldExpression, + flavor::Flavor, ArrayExprEl, ArrayExpression, ArrowFuncExprBody, ArrowFunctionExpression, + AssignmentExpression, AwaitExpression, BinaryExprLeft, BinaryExpression, CallExpression, + Callee, ClassExpression, ConditionalExpression, Expression, FunctionExpression, LVal, Literal, + LogicalExpression, MemberExprProp, MemberExpression, MetaProperty, NewExpression, + ObjectExprProp, ObjectExpression, ObjectKey, ObjectMember, ParenthesizedExpression, + PrivateName, SequenceExpression, SpreadElement as BabelSpreadElement, Super as BabelSuper, + TaggedTemplateExprTypeParams, TaggedTemplateExpression, TemplateElVal, TemplateElement, + TemplateLiteral, TemplateLiteralExpr, ThisExpression, UnaryExpression, UpdateExpression, + YieldExpression, }; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -70,22 +71,22 @@ impl Babelify for Expr { Expr::Lit(lit) => { match lit { Lit::Str(s) => ExprOutput::Expr( - Box::alloc().init(Expression::StringLiteral(s.babelify(ctx))), + Box::alloc().init(Expression::Literal(Literal::String(s.babelify(ctx)))), ), Lit::Bool(b) => ExprOutput::Expr( - Box::alloc().init(Expression::BooleanLiteral(b.babelify(ctx))), + Box::alloc().init(Expression::Literal(Literal::Boolean(b.babelify(ctx)))), ), Lit::Null(n) => ExprOutput::Expr( - Box::alloc().init(Expression::NullLiteral(n.babelify(ctx))), + Box::alloc().init(Expression::Literal(Literal::Null(n.babelify(ctx)))), ), Lit::Num(n) => ExprOutput::Expr( - Box::alloc().init(Expression::NumericLiteral(n.babelify(ctx))), + Box::alloc().init(Expression::Literal(Literal::Numeric(n.babelify(ctx)))), ), Lit::BigInt(i) => ExprOutput::Expr( - Box::alloc().init(Expression::BigIntLiteral(i.babelify(ctx))), + Box::alloc().init(Expression::Literal(Literal::BigInt(i.babelify(ctx)))), ), Lit::Regex(r) => ExprOutput::Expr( - Box::alloc().init(Expression::RegExpLiteral(r.babelify(ctx))), + Box::alloc().init(Expression::Literal(Literal::RegExp(r.babelify(ctx)))), ), Lit::JSXText(_) => panic!( "illegal conversion: Cannot convert {:?} to ExprOutput", @@ -187,8 +188,8 @@ impl From for ObjectKey { match o { ExprOutput::Expr(e) => match *e { Expression::Id(i) => ObjectKey::Id(i), - Expression::StringLiteral(s) => ObjectKey::String(s), - Expression::NumericLiteral(n) => ObjectKey::Numeric(n), + Expression::Literal(Literal::String(s)) => ObjectKey::String(s), + Expression::Literal(Literal::Numeric(n)) => ObjectKey::Numeric(n), _ => ObjectKey::Expr(e), }, ExprOutput::Private(_) => panic!( @@ -463,12 +464,15 @@ impl Babelify for ArrowExpr { .collect(), body: Box::alloc().init(self.body.babelify(ctx)), is_async: self.is_async, + expression: match Flavor::current() { + Flavor::Babel => Default::default(), + Flavor::Acorn => true, + }, generator: self.is_generator, - expression: Default::default(), - type_parameters: self.type_params.map(|t| t.babelify(ctx).into()), return_type: self .return_type .map(|t| Box::alloc().init(t.babelify(ctx).into())), + type_parameters: self.type_params.map(|t| t.babelify(ctx).into()), } } } diff --git a/crates/swc_estree_compat/src/babelify/jsx.rs b/crates/swc_estree_compat/src/babelify/jsx.rs index a214759bf37..7e0eb50ae29 100644 --- a/crates/swc_estree_compat/src/babelify/jsx.rs +++ b/crates/swc_estree_compat/src/babelify/jsx.rs @@ -8,7 +8,7 @@ use swc_ecma_ast::{ JSXOpeningFragment, JSXSpreadChild, JSXText, Lit, }; use swc_estree_ast::{ - JSXAttrName as BabelJSXAttrName, JSXAttrVal, JSXAttribute, + flavor::Flavor, JSXAttrName as BabelJSXAttrName, JSXAttrVal, JSXAttribute, JSXClosingElement as BabelJSXClosingElement, JSXClosingFragment as BabelJSXClosingFragment, JSXElement as BabelJSXElement, JSXElementChild as BabelJSXElementChild, JSXElementName as BabelJSXElementName, JSXEmptyExpression, JSXExprContainerExpr, @@ -244,13 +244,16 @@ impl Babelify for JSXElement { type Output = BabelJSXElement; fn babelify(self, ctx: &Context) -> Self::Output { - let self_closing = self.closing != None; + let self_closing = match Flavor::current() { + Flavor::Babel => None, + Flavor::Acorn => Some(self.closing.is_some()), + }; BabelJSXElement { base: ctx.base(self.span), opening_element: self.opening.babelify(ctx), closing_element: self.closing.map(|el| el.babelify(ctx)), children: self.children.babelify(ctx), - self_closing: Some(self_closing), + self_closing, } } } diff --git a/crates/swc_estree_compat/src/babelify/mod.rs b/crates/swc_estree_compat/src/babelify/mod.rs index f193e9743ce..105a0da23c0 100644 --- a/crates/swc_estree_compat/src/babelify/mod.rs +++ b/crates/swc_estree_compat/src/babelify/mod.rs @@ -7,7 +7,7 @@ use swc_common::{ BytePos, SourceFile, SourceMap, Span, }; use swc_ecma_ast::Class; -use swc_estree_ast::{BaseComment, BaseNode, Comment, LineCol, Loc}; +use swc_estree_ast::{flavor::Flavor, BaseComment, BaseNode, Comment, CommentType, LineCol, Loc}; use swc_node_comments::SwcComments; mod class; @@ -19,7 +19,6 @@ mod jsx; mod lit; mod module; mod module_decl; -pub mod normalize; mod operators; mod pat; mod prop; @@ -62,6 +61,9 @@ impl Context { if span.is_dummy() { return None; } + if !Flavor::current().emit_loc() { + return None; + } let start = self.line_col(span.lo)?; let end = self.line_col(span.hi)?; @@ -77,6 +79,10 @@ impl Context { let loc = self.loc(c.span).unwrap_or_else(Loc::dummy); let comment = BaseComment { + type_: match c.kind { + CommentKind::Line => CommentType::Line, + CommentKind::Block => CommentType::Block, + }, value: c.text, start: start.unwrap_or_default(), end: end.unwrap_or_default(), @@ -118,8 +124,14 @@ impl Context { start, end, loc, - /* TODO(kdy1): Use this field. - * extra: Default::default(), */ + range: if matches!(Flavor::current(), Flavor::Acorn) { + match (start, end) { + (Some(start), Some(end)) => Some([start, end]), + _ => None, + } + } else { + None + }, } } } diff --git a/crates/swc_estree_compat/src/babelify/module.rs b/crates/swc_estree_compat/src/babelify/module.rs index e8176e4ed90..9148e38a72b 100644 --- a/crates/swc_estree_compat/src/babelify/module.rs +++ b/crates/swc_estree_compat/src/babelify/module.rs @@ -4,8 +4,8 @@ use swc_common::{comments::Comment, Span}; use swc_ecma_ast::{Invalid, Module, ModuleItem, Program, Script}; use swc_ecma_visit::{Node, Visit, VisitWith}; use swc_estree_ast::{ - BaseNode, File, InterpreterDirective, LineCol, Loc, ModuleDeclaration, Program as BabelProgram, - SrcType, Statement, + flavor::Flavor, BaseNode, File, InterpreterDirective, LineCol, Loc, ModuleDeclaration, + Program as BabelProgram, SrcType, Statement, }; use swc_node_comments::SwcComments; @@ -27,6 +27,14 @@ impl Babelify for Program { start: program.base.start, end: program.base.end, loc: program.base.loc, + range: if matches!(Flavor::current(), Flavor::Acorn) { + match (program.base.start, program.base.end) { + (Some(start), Some(end)) => Some([start, end]), + _ => None, + } + } else { + None + }, }, program, comments: Some(ctx.convert_comments(comments)), @@ -91,6 +99,10 @@ impl Babelify for Script { /// Module nodes. fn base_with_trailing_newline(span: Span, ctx: &Context) -> BaseNode { let mut base = ctx.base(span); + if matches!(Flavor::current(), Flavor::Acorn) { + return base; + } + base.end = base.end.map(|num| num + 1); base.loc = base.loc.map(|loc| Loc { end: LineCol { @@ -99,6 +111,8 @@ fn base_with_trailing_newline(span: Span, ctx: &Context) -> BaseNode { }, ..loc }); + base.range = base.range.map(|range| [range[0], range[1] + 1]); + base } diff --git a/crates/swc_estree_compat/src/babelify/normalize/mod.rs b/crates/swc_estree_compat/src/babelify/normalize/mod.rs deleted file mode 100644 index c343b39acc9..00000000000 --- a/crates/swc_estree_compat/src/babelify/normalize/mod.rs +++ /dev/null @@ -1,158 +0,0 @@ -use swc_atoms::js_word; -use swc_estree_ast::*; -use swc_estree_visit::{VisitMut, VisitMutWith}; - -struct Normalizer; - -// NOTE: When adding a visitor function, don't forget to add -// ``` -// node.visit_mut_children_with(self); -// ``` -// at the end! Failing to do so breaks the walk chain and other functions never -// get called. -impl VisitMut for Normalizer { - // ------------------------------------------------------------------------ - // class - fn visit_mut_class_declaration(&mut self, node: &mut ClassDeclaration) { - if node.decorators == None { - node.decorators = Some(vec![]); - } - if node.is_abstract == None { - node.is_abstract = Some(false); - } - if node.declare == None { - node.declare = Some(false); - } - if node.implements == None { - node.implements = Some(vec![]); - } - node.visit_mut_children_with(self); - } - - fn visit_mut_class_method(&mut self, node: &mut ClassMethod) { - if node.computed == None { - node.computed = Some(false); - } - if node.is_static == None { - node.is_static = Some(false); - } - if node.generator == None { - node.generator = Some(false); - } - if node.is_async == None { - node.is_async = Some(false); - } - if node.optional == None { - node.optional = Some(false); - } - if node.is_abstract == None { - node.is_abstract = Some(false); - } - if node.decorators == None { - node.decorators = Some(vec![]); - } - node.visit_mut_children_with(self); - } - - fn visit_mut_class_property(&mut self, node: &mut ClassProperty) { - if node.readonly == None { - node.readonly = Some(false); - } - if node.optional == None { - node.optional = Some(false); - } - if node.definite == None { - node.definite = Some(false); - } - if node.declare == None { - node.declare = Some(false); - } - if node.is_abstract == None { - node.is_abstract = Some(false); - } - if node.decorators == None { - node.decorators = Some(vec![]); - } - node.visit_mut_children_with(self); - } - - // ------------------------------------------------------------------------ - // common - fn visit_mut_rest_element(&mut self, node: &mut RestElement) { - if node.decorators == None { - node.decorators = Some(vec![]); - } - node.visit_mut_children_with(self); - } - - // ------------------------------------------------------------------------ - // decl - fn visit_mut_variable_declarator(&mut self, node: &mut VariableDeclarator) { - if node.definite == None { - node.definite = Some(false); - } - node.visit_mut_children_with(self); - } - - fn visit_mut_variable_declaration(&mut self, node: &mut VariableDeclaration) { - if node.declare == None { - node.declare = Some(false); - } - node.visit_mut_children_with(self); - } - - // ------------------------------------------------------------------------ - // expr - fn visit_mut_class_expression(&mut self, node: &mut ClassExpression) { - if node.decorators == None { - node.decorators = Some(vec![]); - } - if node.implements == None { - node.implements = Some(vec![]); - } - node.visit_mut_children_with(self); - } - - // ------------------------------------------------------------------------ - // ident - fn visit_mut_identifier(&mut self, node: &mut Identifier) { - if node.optional == None { - node.optional = Some(false); - } - if node.decorators == None { - node.decorators = Some(vec![]); - } - node.visit_mut_children_with(self); - } - - // ------------------------------------------------------------------------ - // jsx - fn visit_mut_jsx_element(&mut self, node: &mut JSXElement) { - // From what I can tell, babel just ignores this field, whereas swc sets it, - // causing the trees to diverge. So we just normalize it to always None to - // match babel. - node.self_closing = None; - node.visit_mut_children_with(self); - } - - fn visit_mut_jsx_text(&mut self, node: &mut JSXText) { - if node.value.trim().is_empty() { - node.value = js_word!(""); - } - node.visit_mut_children_with(self); - } - - // ------------------------------------------------------------------------ - // pat - fn visit_mut_assignment_pattern(&mut self, node: &mut AssignmentPattern) { - if node.decorators == None { - node.decorators = Some(vec![]); - } - node.visit_mut_children_with(self); - } -} - -pub fn normalize(ast: &mut File) { - let mut normalizer = Normalizer {}; - ast.visit_mut_with(&mut normalizer); -} diff --git a/crates/swc_estree_compat/src/swcify/expr.rs b/crates/swc_estree_compat/src/swcify/expr.rs index 065556f4ac5..aa108f464f3 100644 --- a/crates/swc_estree_compat/src/swcify/expr.rs +++ b/crates/swc_estree_compat/src/swcify/expr.rs @@ -16,9 +16,9 @@ use swc_estree_ast::{ BindExpression, CallExpression, Callee, ClassExpression, ConditionalExpression, DoExpression, Expression, FunctionExpression, Identifier, Import, JSXAttrVal, JSXAttribute, JSXEmptyExpression, JSXExprContainerExpr, JSXExpressionContainer, JSXMemberExprObject, - JSXMemberExpression, JSXSpreadAttribute, LogicalExprOp, LogicalExpression, MemberExprProp, - MemberExpression, MetaProperty, ModuleExpression, NewExpression, ObjectExprProp, - ObjectExpression, ObjectKey, ObjectMethod, ObjectPropVal, ObjectProperty, + JSXMemberExpression, JSXSpreadAttribute, Literal, LogicalExprOp, LogicalExpression, + MemberExprProp, MemberExpression, MetaProperty, ModuleExpression, NewExpression, + ObjectExprProp, ObjectExpression, ObjectKey, ObjectMethod, ObjectPropVal, ObjectProperty, OptionalCallExpression, OptionalMemberExprProp, OptionalMemberExpression, ParenthesizedExpression, PatternLike, PipelinePrimaryTopicReference, RecordExpression, SequenceExpression, TSAsExpression, TSNonNullExpression, TSTypeAssertion, @@ -41,11 +41,11 @@ impl Swcify for Expression { Expression::Conditional(e) => e.swcify(ctx).into(), Expression::Func(e) => e.swcify(ctx).into(), Expression::Id(e) => e.swcify(ctx).id.into(), - Expression::StringLiteral(e) => e.swcify(ctx).into(), - Expression::NumericLiteral(e) => e.swcify(ctx).into(), - Expression::NullLiteral(e) => Lit::from(e.swcify(ctx)).into(), - Expression::BooleanLiteral(e) => Lit::from(e.swcify(ctx)).into(), - Expression::RegExpLiteral(e) => Lit::from(e.swcify(ctx)).into(), + Expression::Literal(Literal::String(e)) => e.swcify(ctx).into(), + Expression::Literal(Literal::Numeric(e)) => e.swcify(ctx).into(), + Expression::Literal(Literal::Null(e)) => Lit::from(e.swcify(ctx)).into(), + Expression::Literal(Literal::Boolean(e)) => Lit::from(e.swcify(ctx)).into(), + Expression::Literal(Literal::RegExp(e)) => Lit::from(e.swcify(ctx)).into(), Expression::Logical(e) => e.swcify(ctx).into(), Expression::Member(e) => e.swcify(ctx).into(), Expression::New(e) => e.swcify(ctx).into(), @@ -63,12 +63,12 @@ impl Swcify for Expression { Expression::TemplateLiteral(e) => e.swcify(ctx).into(), Expression::Yield(e) => e.swcify(ctx).into(), Expression::Await(e) => e.swcify(ctx).into(), - Expression::BigIntLiteral(e) => Expr::Lit(e.swcify(ctx).into()), + Expression::Literal(Literal::BigInt(e)) => Expr::Lit(e.swcify(ctx).into()), Expression::OptionalMember(e) => e.swcify(ctx).into(), Expression::OptionalCall(e) => e.swcify(ctx).into(), Expression::JSXElement(e) => Box::new(e.swcify(ctx)).into(), Expression::JSXFragment(e) => e.swcify(ctx).into(), - Expression::DecimalLiteral(e) => e.swcify(ctx).into(), + Expression::Literal(Literal::Decimal(e)) => e.swcify(ctx).into(), Expression::TSAs(e) => e.swcify(ctx).into(), Expression::TSTypeAssertion(e) => e.swcify(ctx).into(), Expression::TSNonNull(e) => e.swcify(ctx).into(), diff --git a/crates/swc_estree_compat/tests/convert.rs b/crates/swc_estree_compat/tests/convert.rs index 305edc95b5d..efde85b796b 100644 --- a/crates/swc_estree_compat/tests/convert.rs +++ b/crates/swc_estree_compat/tests/convert.rs @@ -4,6 +4,7 @@ extern crate test; use anyhow::{Context as AnyhowContext, Error}; use copyless::BoxHelper; use pretty_assertions::assert_eq; +use serde_json::{Number, Value}; use std::{ env, fs, path::{Path, PathBuf}, @@ -15,9 +16,9 @@ use swc_common::{ FileName, FilePathMapping, SourceMap, }; use swc_ecma_parser::{EsConfig, Syntax}; -use swc_estree_ast::File; -use swc_estree_compat::babelify::{normalize::normalize, Babelify, Context}; +use swc_estree_compat::babelify::{Babelify, Context}; use test::{test_main, DynTestFn, ShouldPanic, TestDesc, TestDescAndFn, TestName, TestType}; +use testing::{json::diff_json_value, DebugUsingDisplay}; use walkdir::WalkDir; #[test] @@ -146,59 +147,88 @@ fn run_test(src: String, expected: String, syntax: Syntax, is_module: bool) { cm, comments: compiler.comments().clone(), }; - let mut ast = swc_ast.babelify(&ctx); - normalize(&mut ast); - println!("Actual: {:?}", ast); + let ast = swc_ast.babelify(&ctx); - let mut expected_ast: File = serde_json::from_str(&expected).unwrap(); - normalize(&mut expected_ast); + let mut actual = serde_json::to_value(&ast).unwrap(); - assert_eq!(expected_ast, ast); + println!( + "Actual: \n{}", + serde_json::to_string_pretty(&actual).unwrap() + ); + + let mut expected: Value = serde_json::from_str(&expected).unwrap(); + + diff_json_value(&mut actual, &mut expected, &mut |k, v| match k { + "identifierName" | "extra" | "errors" => { + // Remove + *v = Value::Null; + } + + "optional" | "computed" | "static" | "abstract" | "declare" | "definite" | "generator" + | "readonly" | "expression" => { + // TODO(kdy1): Remove this + match v { + Value::Bool(false) => { + *v = Value::Null; + } + + _ => {} + } + } + + "decorators" | "implements" => { + // TODO(kdy1): Remove this + match v { + Value::Array(arr) => { + if arr.is_empty() { + *v = Value::Null; + } + } + + _ => {} + } + } + + "sourceFile" => { + // TODO(kdy1): Remove this + match v { + Value::String(s) => { + if s.is_empty() { + *v = Value::Null; + } + } + + _ => {} + } + } + + "value" => { + // Normalize numbers + match v { + Value::Number(n) => { + *n = Number::from_f64(n.as_f64().unwrap()).unwrap(); + } + + Value::String(s) => { + // TODO(kdy1): Remove this + // This is wrong, but we are not babel ast at the moment + *s = s.replace("\n", ""); + } + + _ => {} + } + } + + _ => {} + }); + + let actual = serde_json::to_string_pretty(&actual).unwrap(); + let expected = serde_json::to_string_pretty(&expected).unwrap(); + + assert_eq!(DebugUsingDisplay(&actual), DebugUsingDisplay(&expected)); } fn get_test_name(path: &Path, fixture_path: &Path) -> Result { let s: String = path.strip_prefix(fixture_path)?.to_string_lossy().into(); Ok(s) } - -/* -#[test] -pub fn t1() -> Result<()> { - // let src = fs::read_to_string("x.js")?; - let src = fs::read_to_string("tests/fixture/simple/input.js")?; - - let cm = Arc::new(SourceMap::new(FilePathMapping::empty())); - let handler = Arc::new(Handler::with_tty_emitter( - ColorConfig::Always, - true, - false, - Some(cm.clone()), - )); - let compiler = Compiler::new(cm.clone(), handler); - let fm = compiler.cm.new_source_file(FileName::Anon, src); - - let swc_ast = compiler.parse_js( - fm.clone(), - Default::default(), - Default::default(), - false, - true, // parse conmments - )?; - - let ctx = Context { - fm: fm, - cm: cm, - comments: Arc::new(compiler.comments().clone()), - }; - let ast = swc_ast.babelify(&ctx); - - // let output = fs::read_to_string("x.json")?; - let output = fs::read_to_string("tests/fixture/simple/output.json")?; - let expected_ast: File = serde_json::from_str(&output)?; - - assert_eq!(expected_ast, ast); - // println!("FROM SWC\n\n{:#?}\n\nFROM BABEL\n\n{:#?}", ast, expected_ast); - - Ok(()) -} -*/ diff --git a/crates/swc_estree_compat/tests/flavor.rs b/crates/swc_estree_compat/tests/flavor.rs new file mode 100644 index 00000000000..0154aa22d50 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor.rs @@ -0,0 +1,152 @@ +use anyhow::Context; +use serde_json::{Number, Value}; +use std::{ + path::{Path, PathBuf}, + process::{Command, Stdio}, +}; +use swc::SwcComments; +use swc_ecma_ast::EsVersion; +use swc_ecma_parser::{lexer::Lexer, EsConfig, Parser, StringInput, Syntax}; +use swc_estree_ast::flavor::Flavor; +use swc_estree_compat::babelify::Babelify; +use testing::{assert_eq, json::diff_json_value, DebugUsingDisplay, NormalizedOutput}; + +fn assert_flavor(flavor: Flavor, input: &Path, output_json_path: &Path) { + testing::run_test(false, |cm, _handler| { + let fm = cm.load_file(input).unwrap(); + + let lexer = Lexer::new( + Syntax::Es(EsConfig { + static_blocks: true, + ..Default::default() + }), + EsVersion::latest(), + StringInput::from(&*fm), + None, + ); + let mut parser = Parser::new_from(lexer); + + let program = parser.parse_program().unwrap(); + + let ctx = swc_estree_compat::babelify::Context { + fm: fm.clone(), + cm: cm.clone(), + comments: SwcComments::default(), + }; + let mut actual = flavor.with(|| { + let program = program.babelify(&ctx).program; + serde_json::to_value(&program).unwrap() + }); + let actual_str = serde_json::to_string_pretty(&actual).unwrap(); + + println!("----- swc output -----\n{}", actual_str); + let output = { + let mut cmd = Command::new("node"); + cmd.arg("-e") + .arg(include_str!("../scripts/test-acorn.js")) + .arg(&*fm.src) + .stderr(Stdio::inherit()); + cmd.output().unwrap() + }; + + let expected = + String::from_utf8(output.stdout).expect("./acorn.js generated non-utf8 output"); + + // We don't care about these cases + if expected.trim().is_empty() { + return Ok(()); + } + + { + let mut expected = serde_json::from_str::(&expected) + .with_context(|| format!("acorn.js generated invalid json:\n {}", expected)) + .unwrap(); + + println!( + "----- Expected output -----\n{}", + serde_json::to_string_pretty(&expected).unwrap() + ); + + // We don't try to match fully. + actual["end"] = Value::Null; + expected["end"] = Value::Null; + + actual["range"] = Value::Null; + expected["range"] = Value::Null; + + diff_json_value(&mut actual, &mut expected, &mut |key, value| { + match &mut *value { + Value::Object(v) => { + if let Some("FunctionExpression") = + v.get("type").and_then(|v| v.as_str()).as_deref() + { + v["range"] = Value::Null; + v["start"] = Value::Null; + v["end"] = Value::Null; + } + } + __ => {} + } + + match key { + "expression" => { + // Normalize false to null + match value { + Value::Bool(false) => *value = Value::Null, + _ => {} + } + } + + "raw" => { + // Remove `'` and `"` from raw strings. + match value { + Value::String(s) => { + if s.starts_with('\'') && s.ends_with('\'') { + *s = s[1..s.len() - 1].to_string(); + } else if s.starts_with('"') && s.ends_with('"') { + *s = s[1..s.len() - 1].to_string(); + } else if s.starts_with("/") { + // We don't need raw value of regex at the moment. + *value = Value::Null; + } + } + + _ => {} + } + } + + "value" => { + // Normalize numbers + match value { + Value::Number(n) => { + *n = Number::from_f64(n.as_f64().unwrap()).unwrap(); + } + _ => {} + } + } + + _ => {} + } + }); + + let actual = serde_json::to_string_pretty(&actual).unwrap(); + let expected = serde_json::to_string_pretty(&expected).unwrap(); + + assert_eq!(DebugUsingDisplay(&actual), DebugUsingDisplay(&expected)); + } + + NormalizedOutput::from(actual_str.clone()) + .compare_to_file(&output_json_path) + .unwrap(); + + Ok(()) + }) + .unwrap(); +} + +#[testing::fixture("tests/flavor/acorn/**/input.js")] +fn acorn(input: PathBuf) { + let output = input.parent().unwrap().join("output.json"); + + assert_flavor(Flavor::Acorn, &input, &output); +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/1/input.js b/crates/swc_estree_compat/tests/flavor/acorn/1/input.js new file mode 100644 index 00000000000..3a4a08db00f --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/1/input.js @@ -0,0 +1 @@ +const foo = require('acorn'); \ No newline at end of file diff --git a/crates/swc_estree_compat/tests/flavor/acorn/1/output.json b/crates/swc_estree_compat/tests/flavor/acorn/1/output.json new file mode 100644 index 00000000000..7f696940f49 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/1/output.json @@ -0,0 +1,76 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 28, + "id": { + "end": 9, + "name": "foo", + "range": [ + 6, + 9 + ], + "start": 6, + "type": "Identifier" + }, + "init": { + "arguments": [ + { + "end": 27, + "range": [ + 20, + 27 + ], + "raw": "acorn", + "start": 20, + "type": "Literal", + "value": "acorn" + } + ], + "callee": { + "end": 19, + "name": "require", + "range": [ + 12, + 19 + ], + "start": 12, + "type": "Identifier" + }, + "end": 28, + "optional": false, + "range": [ + 12, + 28 + ], + "start": 12, + "type": "CallExpression" + }, + "range": [ + 6, + 28 + ], + "start": 6, + "type": "VariableDeclarator" + } + ], + "end": 29, + "kind": "const", + "range": [ + 0, + 29 + ], + "start": 0, + "type": "VariableDeclaration" + } + ], + "end": 29, + "range": [ + 0, + 29 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-destructuring/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-destructuring/input.js new file mode 100644 index 00000000000..b488171c891 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-destructuring/input.js @@ -0,0 +1,2 @@ +const arr = [ 1, 2, 3 ]; +const [ a, b, ...other ] = arr; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-destructuring/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-destructuring/output.json new file mode 100644 index 00000000000..63ecbeacdf0 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-destructuring/output.json @@ -0,0 +1,168 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 23, + "id": { + "end": 9, + "name": "arr", + "range": [ + 6, + 9 + ], + "start": 6, + "type": "Identifier" + }, + "init": { + "elements": [ + { + "end": 15, + "range": [ + 14, + 15 + ], + "raw": "1", + "start": 14, + "type": "Literal", + "value": 1.0 + }, + { + "end": 18, + "range": [ + 17, + 18 + ], + "raw": "2", + "start": 17, + "type": "Literal", + "value": 2.0 + }, + { + "end": 21, + "range": [ + 20, + 21 + ], + "raw": "3", + "start": 20, + "type": "Literal", + "value": 3.0 + } + ], + "end": 23, + "range": [ + 12, + 23 + ], + "start": 12, + "type": "ArrayExpression" + }, + "range": [ + 6, + 23 + ], + "start": 6, + "type": "VariableDeclarator" + } + ], + "end": 24, + "kind": "const", + "range": [ + 0, + 24 + ], + "start": 0, + "type": "VariableDeclaration" + }, + { + "declarations": [ + { + "end": 55, + "id": { + "elements": [ + { + "end": 34, + "name": "a", + "range": [ + 33, + 34 + ], + "start": 33, + "type": "Identifier" + }, + { + "end": 37, + "name": "b", + "range": [ + 36, + 37 + ], + "start": 36, + "type": "Identifier" + }, + { + "argument": { + "end": 47, + "name": "other", + "range": [ + 42, + 47 + ], + "start": 42, + "type": "Identifier" + }, + "end": 47, + "range": [ + 39, + 47 + ], + "start": 39, + "type": "RestElement" + } + ], + "end": 49, + "range": [ + 31, + 49 + ], + "start": 31, + "type": "ArrayPattern" + }, + "init": { + "end": 55, + "name": "arr", + "range": [ + 52, + 55 + ], + "start": 52, + "type": "Identifier" + }, + "range": [ + 31, + 55 + ], + "start": 31, + "type": "VariableDeclarator" + } + ], + "end": 56, + "kind": "const", + "range": [ + 25, + 56 + ], + "start": 25, + "type": "VariableDeclaration" + } + ], + "end": 56, + "range": [ + 0, + 56 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-simple/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-simple/input.js new file mode 100644 index 00000000000..0b712412707 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-simple/input.js @@ -0,0 +1 @@ +const arr = [ 1, 2, 3 ]; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-simple/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-simple/output.json new file mode 100644 index 00000000000..c9a886f790d --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/array-simple/output.json @@ -0,0 +1,87 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 23, + "id": { + "end": 9, + "name": "arr", + "range": [ + 6, + 9 + ], + "start": 6, + "type": "Identifier" + }, + "init": { + "elements": [ + { + "end": 15, + "range": [ + 14, + 15 + ], + "raw": "1", + "start": 14, + "type": "Literal", + "value": 1.0 + }, + { + "end": 18, + "range": [ + 17, + 18 + ], + "raw": "2", + "start": 17, + "type": "Literal", + "value": 2.0 + }, + { + "end": 21, + "range": [ + 20, + 21 + ], + "raw": "3", + "start": 20, + "type": "Literal", + "value": 3.0 + } + ], + "end": 23, + "range": [ + 12, + 23 + ], + "start": 12, + "type": "ArrayExpression" + }, + "range": [ + 6, + 23 + ], + "start": 6, + "type": "VariableDeclarator" + } + ], + "end": 24, + "kind": "const", + "range": [ + 0, + 24 + ], + "start": 0, + "type": "VariableDeclaration" + } + ], + "end": 24, + "range": [ + 0, + 24 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-extends/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-extends/input.js new file mode 100644 index 00000000000..b3fcaeab4dd --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-extends/input.js @@ -0,0 +1,19 @@ +class Animal { + constructor(name) { + this.name = name; + } + + speak() { + console.log(`${this.name} makes a noise.`); + } +} + +class Dog extends Animal { + constructor(name) { + super(name); + } + + speak() { + console.log(`${this.name} barks.`); + } +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-extends/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-extends/output.json new file mode 100644 index 00000000000..cb283b61fa2 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-extends/output.json @@ -0,0 +1,630 @@ +{ + "body": [ + { + "body": { + "body": [ + { + "computed": false, + "end": 70, + "key": { + "end": 30, + "name": "constructor", + "range": [ + 19, + 30 + ], + "start": 19, + "type": "Identifier" + }, + "kind": "constructor", + "range": [ + 19, + 70 + ], + "start": 19, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [ + { + "end": 64, + "expression": { + "end": 63, + "left": { + "computed": false, + "end": 56, + "object": { + "end": 51, + "range": [ + 47, + 51 + ], + "start": 47, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 56, + "name": "name", + "range": [ + 52, + 56 + ], + "start": 52, + "type": "Identifier" + }, + "range": [ + 47, + 56 + ], + "start": 47, + "type": "MemberExpression" + }, + "operator": "=", + "range": [ + 47, + 63 + ], + "right": { + "end": 63, + "name": "name", + "range": [ + 59, + 63 + ], + "start": 59, + "type": "Identifier" + }, + "start": 47, + "type": "AssignmentExpression" + }, + "range": [ + 47, + 64 + ], + "start": 47, + "type": "ExpressionStatement" + } + ], + "end": 70, + "range": [ + 37, + 70 + ], + "start": 37, + "type": "BlockStatement" + }, + "end": 70, + "generator": false, + "params": [ + { + "end": 35, + "name": "name", + "range": [ + 31, + 35 + ], + "start": 31, + "type": "Identifier" + } + ], + "range": [ + 37, + 70 + ], + "start": 37, + "type": "FunctionExpression" + } + }, + { + "computed": false, + "end": 143, + "key": { + "end": 81, + "name": "speak", + "range": [ + 76, + 81 + ], + "start": 76, + "type": "Identifier" + }, + "kind": "method", + "range": [ + 76, + 143 + ], + "start": 76, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [ + { + "end": 137, + "expression": { + "arguments": [ + { + "end": 135, + "expressions": [ + { + "computed": false, + "end": 118, + "object": { + "end": 113, + "range": [ + 109, + 113 + ], + "start": 109, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 118, + "name": "name", + "range": [ + 114, + 118 + ], + "start": 114, + "type": "Identifier" + }, + "range": [ + 109, + 118 + ], + "start": 109, + "type": "MemberExpression" + } + ], + "quasis": [ + { + "end": 107, + "range": [ + 107, + 107 + ], + "start": 107, + "tail": false, + "type": "TemplateElement", + "value": { + "cooked": "", + "raw": "" + } + }, + { + "end": 134, + "range": [ + 119, + 134 + ], + "start": 119, + "tail": true, + "type": "TemplateElement", + "value": { + "cooked": " makes a noise.", + "raw": " makes a noise." + } + } + ], + "range": [ + 106, + 135 + ], + "start": 106, + "type": "TemplateLiteral" + } + ], + "callee": { + "computed": false, + "end": 105, + "object": { + "end": 101, + "name": "console", + "range": [ + 94, + 101 + ], + "start": 94, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 105, + "name": "log", + "range": [ + 102, + 105 + ], + "start": 102, + "type": "Identifier" + }, + "range": [ + 94, + 105 + ], + "start": 94, + "type": "MemberExpression" + }, + "end": 136, + "optional": false, + "range": [ + 94, + 136 + ], + "start": 94, + "type": "CallExpression" + }, + "range": [ + 94, + 137 + ], + "start": 94, + "type": "ExpressionStatement" + } + ], + "end": 143, + "range": [ + 84, + 143 + ], + "start": 84, + "type": "BlockStatement" + }, + "end": 143, + "generator": false, + "params": [], + "range": [ + 84, + 143 + ], + "start": 84, + "type": "FunctionExpression" + } + } + ], + "end": 145, + "range": [ + 13, + 145 + ], + "start": 13, + "type": "ClassBody" + }, + "end": 145, + "id": { + "end": 12, + "name": "Animal", + "range": [ + 6, + 12 + ], + "start": 6, + "type": "Identifier" + }, + "range": [ + 0, + 145 + ], + "start": 0, + "superClass": null, + "type": "ClassDeclaration" + }, + { + "body": { + "body": [ + { + "computed": false, + "end": 224, + "key": { + "end": 189, + "name": "constructor", + "range": [ + 178, + 189 + ], + "start": 178, + "type": "Identifier" + }, + "kind": "constructor", + "range": [ + 178, + 224 + ], + "start": 178, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [ + { + "end": 218, + "expression": { + "arguments": [ + { + "end": 216, + "name": "name", + "range": [ + 212, + 216 + ], + "start": 212, + "type": "Identifier" + } + ], + "callee": { + "end": 211, + "range": [ + 206, + 211 + ], + "start": 206, + "type": "Super" + }, + "end": 217, + "optional": false, + "range": [ + 206, + 217 + ], + "start": 206, + "type": "CallExpression" + }, + "range": [ + 206, + 218 + ], + "start": 206, + "type": "ExpressionStatement" + } + ], + "end": 224, + "range": [ + 196, + 224 + ], + "start": 196, + "type": "BlockStatement" + }, + "end": 224, + "generator": false, + "params": [ + { + "end": 194, + "name": "name", + "range": [ + 190, + 194 + ], + "start": 190, + "type": "Identifier" + } + ], + "range": [ + 196, + 224 + ], + "start": 196, + "type": "FunctionExpression" + } + }, + { + "computed": false, + "end": 289, + "key": { + "end": 235, + "name": "speak", + "range": [ + 230, + 235 + ], + "start": 230, + "type": "Identifier" + }, + "kind": "method", + "range": [ + 230, + 289 + ], + "start": 230, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [ + { + "end": 283, + "expression": { + "arguments": [ + { + "end": 281, + "expressions": [ + { + "computed": false, + "end": 272, + "object": { + "end": 267, + "range": [ + 263, + 267 + ], + "start": 263, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 272, + "name": "name", + "range": [ + 268, + 272 + ], + "start": 268, + "type": "Identifier" + }, + "range": [ + 263, + 272 + ], + "start": 263, + "type": "MemberExpression" + } + ], + "quasis": [ + { + "end": 261, + "range": [ + 261, + 261 + ], + "start": 261, + "tail": false, + "type": "TemplateElement", + "value": { + "cooked": "", + "raw": "" + } + }, + { + "end": 280, + "range": [ + 273, + 280 + ], + "start": 273, + "tail": true, + "type": "TemplateElement", + "value": { + "cooked": " barks.", + "raw": " barks." + } + } + ], + "range": [ + 260, + 281 + ], + "start": 260, + "type": "TemplateLiteral" + } + ], + "callee": { + "computed": false, + "end": 259, + "object": { + "end": 255, + "name": "console", + "range": [ + 248, + 255 + ], + "start": 248, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 259, + "name": "log", + "range": [ + 256, + 259 + ], + "start": 256, + "type": "Identifier" + }, + "range": [ + 248, + 259 + ], + "start": 248, + "type": "MemberExpression" + }, + "end": 282, + "optional": false, + "range": [ + 248, + 282 + ], + "start": 248, + "type": "CallExpression" + }, + "range": [ + 248, + 283 + ], + "start": 248, + "type": "ExpressionStatement" + } + ], + "end": 289, + "range": [ + 238, + 289 + ], + "start": 238, + "type": "BlockStatement" + }, + "end": 289, + "generator": false, + "params": [], + "range": [ + 238, + 289 + ], + "start": 238, + "type": "FunctionExpression" + } + } + ], + "end": 291, + "range": [ + 172, + 291 + ], + "start": 172, + "type": "ClassBody" + }, + "end": 291, + "id": { + "end": 156, + "name": "Dog", + "range": [ + 153, + 156 + ], + "start": 153, + "type": "Identifier" + }, + "range": [ + 147, + 291 + ], + "start": 147, + "superClass": { + "end": 171, + "name": "Animal", + "range": [ + 165, + 171 + ], + "start": 165, + "type": "Identifier" + }, + "type": "ClassDeclaration" + } + ], + "end": 291, + "range": [ + 0, + 291 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-getter-setter/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-getter-setter/input.js new file mode 100644 index 00000000000..fed9d7bbf88 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-getter-setter/input.js @@ -0,0 +1,22 @@ +class Rectangle { + constructor(height, width) { + this.height = height; + this.width = width; + } + + set height(height) { this.height = height; } + + set width(width) { this.width = width; } + + get area() { + return this.calcArea(); + } + + calcArea() { + return this.height * this.width; + } +} + +const square = new Rectangle(10, 10); + +console.log(square.area); diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-getter-setter/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-getter-setter/output.json new file mode 100644 index 00000000000..fa3be204e4d --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-getter-setter/output.json @@ -0,0 +1,833 @@ +{ + "body": [ + { + "body": { + "body": [ + { + "computed": false, + "end": 114, + "key": { + "end": 33, + "name": "constructor", + "range": [ + 22, + 33 + ], + "start": 22, + "type": "Identifier" + }, + "kind": "constructor", + "range": [ + 22, + 114 + ], + "start": 22, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [ + { + "end": 80, + "expression": { + "end": 79, + "left": { + "computed": false, + "end": 70, + "object": { + "end": 63, + "range": [ + 59, + 63 + ], + "start": 59, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 70, + "name": "height", + "range": [ + 64, + 70 + ], + "start": 64, + "type": "Identifier" + }, + "range": [ + 59, + 70 + ], + "start": 59, + "type": "MemberExpression" + }, + "operator": "=", + "range": [ + 59, + 79 + ], + "right": { + "end": 79, + "name": "height", + "range": [ + 73, + 79 + ], + "start": 73, + "type": "Identifier" + }, + "start": 59, + "type": "AssignmentExpression" + }, + "range": [ + 59, + 80 + ], + "start": 59, + "type": "ExpressionStatement" + }, + { + "end": 108, + "expression": { + "end": 107, + "left": { + "computed": false, + "end": 99, + "object": { + "end": 93, + "range": [ + 89, + 93 + ], + "start": 89, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 99, + "name": "width", + "range": [ + 94, + 99 + ], + "start": 94, + "type": "Identifier" + }, + "range": [ + 89, + 99 + ], + "start": 89, + "type": "MemberExpression" + }, + "operator": "=", + "range": [ + 89, + 107 + ], + "right": { + "end": 107, + "name": "width", + "range": [ + 102, + 107 + ], + "start": 102, + "type": "Identifier" + }, + "start": 89, + "type": "AssignmentExpression" + }, + "range": [ + 89, + 108 + ], + "start": 89, + "type": "ExpressionStatement" + } + ], + "end": 114, + "range": [ + 49, + 114 + ], + "start": 49, + "type": "BlockStatement" + }, + "end": 114, + "generator": false, + "params": [ + { + "end": 40, + "name": "height", + "range": [ + 34, + 40 + ], + "start": 34, + "type": "Identifier" + }, + { + "end": 47, + "name": "width", + "range": [ + 42, + 47 + ], + "start": 42, + "type": "Identifier" + } + ], + "range": [ + 49, + 114 + ], + "start": 49, + "type": "FunctionExpression" + } + }, + { + "computed": false, + "end": 164, + "key": { + "end": 130, + "name": "height", + "range": [ + 124, + 130 + ], + "start": 124, + "type": "Identifier" + }, + "kind": "set", + "range": [ + 120, + 164 + ], + "start": 120, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [ + { + "end": 162, + "expression": { + "end": 161, + "left": { + "computed": false, + "end": 152, + "object": { + "end": 145, + "range": [ + 141, + 145 + ], + "start": 141, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 152, + "name": "height", + "range": [ + 146, + 152 + ], + "start": 146, + "type": "Identifier" + }, + "range": [ + 141, + 152 + ], + "start": 141, + "type": "MemberExpression" + }, + "operator": "=", + "range": [ + 141, + 161 + ], + "right": { + "end": 161, + "name": "height", + "range": [ + 155, + 161 + ], + "start": 155, + "type": "Identifier" + }, + "start": 141, + "type": "AssignmentExpression" + }, + "range": [ + 141, + 162 + ], + "start": 141, + "type": "ExpressionStatement" + } + ], + "end": 164, + "range": [ + 139, + 164 + ], + "start": 139, + "type": "BlockStatement" + }, + "end": 164, + "generator": false, + "params": [ + { + "end": 137, + "name": "height", + "range": [ + 131, + 137 + ], + "start": 131, + "type": "Identifier" + } + ], + "range": [ + 139, + 164 + ], + "start": 139, + "type": "FunctionExpression" + } + }, + { + "computed": false, + "end": 210, + "key": { + "end": 179, + "name": "width", + "range": [ + 174, + 179 + ], + "start": 174, + "type": "Identifier" + }, + "kind": "set", + "range": [ + 170, + 210 + ], + "start": 170, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [ + { + "end": 208, + "expression": { + "end": 207, + "left": { + "computed": false, + "end": 199, + "object": { + "end": 193, + "range": [ + 189, + 193 + ], + "start": 189, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 199, + "name": "width", + "range": [ + 194, + 199 + ], + "start": 194, + "type": "Identifier" + }, + "range": [ + 189, + 199 + ], + "start": 189, + "type": "MemberExpression" + }, + "operator": "=", + "range": [ + 189, + 207 + ], + "right": { + "end": 207, + "name": "width", + "range": [ + 202, + 207 + ], + "start": 202, + "type": "Identifier" + }, + "start": 189, + "type": "AssignmentExpression" + }, + "range": [ + 189, + 208 + ], + "start": 189, + "type": "ExpressionStatement" + } + ], + "end": 210, + "range": [ + 187, + 210 + ], + "start": 187, + "type": "BlockStatement" + }, + "end": 210, + "generator": false, + "params": [ + { + "end": 185, + "name": "width", + "range": [ + 180, + 185 + ], + "start": 180, + "type": "Identifier" + } + ], + "range": [ + 187, + 210 + ], + "start": 187, + "type": "FunctionExpression" + } + }, + { + "computed": false, + "end": 266, + "key": { + "end": 224, + "name": "area", + "range": [ + 220, + 224 + ], + "start": 220, + "type": "Identifier" + }, + "kind": "get", + "range": [ + 216, + 266 + ], + "start": 216, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [ + { + "argument": { + "arguments": [], + "callee": { + "computed": false, + "end": 257, + "object": { + "end": 248, + "range": [ + 244, + 248 + ], + "start": 244, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 257, + "name": "calcArea", + "range": [ + 249, + 257 + ], + "start": 249, + "type": "Identifier" + }, + "range": [ + 244, + 257 + ], + "start": 244, + "type": "MemberExpression" + }, + "end": 259, + "optional": false, + "range": [ + 244, + 259 + ], + "start": 244, + "type": "CallExpression" + }, + "end": 260, + "range": [ + 237, + 260 + ], + "start": 237, + "type": "ReturnStatement" + } + ], + "end": 266, + "range": [ + 227, + 266 + ], + "start": 227, + "type": "BlockStatement" + }, + "end": 266, + "generator": false, + "params": [], + "range": [ + 227, + 266 + ], + "start": 227, + "type": "FunctionExpression" + } + }, + { + "computed": false, + "end": 331, + "key": { + "end": 280, + "name": "calcArea", + "range": [ + 272, + 280 + ], + "start": 272, + "type": "Identifier" + }, + "kind": "method", + "range": [ + 272, + 331 + ], + "start": 272, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [ + { + "argument": { + "end": 324, + "left": { + "computed": false, + "end": 311, + "object": { + "end": 304, + "range": [ + 300, + 304 + ], + "start": 300, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 311, + "name": "height", + "range": [ + 305, + 311 + ], + "start": 305, + "type": "Identifier" + }, + "range": [ + 300, + 311 + ], + "start": 300, + "type": "MemberExpression" + }, + "operator": "*", + "range": [ + 300, + 324 + ], + "right": { + "computed": false, + "end": 324, + "object": { + "end": 318, + "range": [ + 314, + 318 + ], + "start": 314, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 324, + "name": "width", + "range": [ + 319, + 324 + ], + "start": 319, + "type": "Identifier" + }, + "range": [ + 314, + 324 + ], + "start": 314, + "type": "MemberExpression" + }, + "start": 300, + "type": "BinaryExpression" + }, + "end": 325, + "range": [ + 293, + 325 + ], + "start": 293, + "type": "ReturnStatement" + } + ], + "end": 331, + "range": [ + 283, + 331 + ], + "start": 283, + "type": "BlockStatement" + }, + "end": 331, + "generator": false, + "params": [], + "range": [ + 283, + 331 + ], + "start": 283, + "type": "FunctionExpression" + } + } + ], + "end": 333, + "range": [ + 16, + 333 + ], + "start": 16, + "type": "ClassBody" + }, + "end": 333, + "id": { + "end": 15, + "name": "Rectangle", + "range": [ + 6, + 15 + ], + "start": 6, + "type": "Identifier" + }, + "range": [ + 0, + 333 + ], + "start": 0, + "superClass": null, + "type": "ClassDeclaration" + }, + { + "declarations": [ + { + "end": 371, + "id": { + "end": 347, + "name": "square", + "range": [ + 341, + 347 + ], + "start": 341, + "type": "Identifier" + }, + "init": { + "arguments": [ + { + "end": 366, + "range": [ + 364, + 366 + ], + "raw": "10", + "start": 364, + "type": "Literal", + "value": 10.0 + }, + { + "end": 370, + "range": [ + 368, + 370 + ], + "raw": "10", + "start": 368, + "type": "Literal", + "value": 10.0 + } + ], + "callee": { + "end": 363, + "name": "Rectangle", + "range": [ + 354, + 363 + ], + "start": 354, + "type": "Identifier" + }, + "end": 371, + "range": [ + 350, + 371 + ], + "start": 350, + "type": "NewExpression" + }, + "range": [ + 341, + 371 + ], + "start": 341, + "type": "VariableDeclarator" + } + ], + "end": 372, + "kind": "const", + "range": [ + 335, + 372 + ], + "start": 335, + "type": "VariableDeclaration" + }, + { + "end": 399, + "expression": { + "arguments": [ + { + "computed": false, + "end": 397, + "object": { + "end": 392, + "name": "square", + "range": [ + 386, + 392 + ], + "start": 386, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 397, + "name": "area", + "range": [ + 393, + 397 + ], + "start": 393, + "type": "Identifier" + }, + "range": [ + 386, + 397 + ], + "start": 386, + "type": "MemberExpression" + } + ], + "callee": { + "computed": false, + "end": 385, + "object": { + "end": 381, + "name": "console", + "range": [ + 374, + 381 + ], + "start": 374, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 385, + "name": "log", + "range": [ + 382, + 385 + ], + "start": 382, + "type": "Identifier" + }, + "range": [ + 374, + 385 + ], + "start": 374, + "type": "MemberExpression" + }, + "end": 398, + "optional": false, + "range": [ + 374, + 398 + ], + "start": 374, + "type": "CallExpression" + }, + "range": [ + 374, + 399 + ], + "start": 374, + "type": "ExpressionStatement" + } + ], + "end": 399, + "range": [ + 0, + 399 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-method-no-body/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-method-no-body/input.js new file mode 100644 index 00000000000..5fc692b89e0 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-method-no-body/input.js @@ -0,0 +1,3 @@ +class None { + stub() {} +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-method-no-body/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-method-no-body/output.json new file mode 100644 index 00000000000..ad79a97b2ae --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-method-no-body/output.json @@ -0,0 +1,87 @@ +{ + "body": [ + { + "body": { + "body": [ + { + "computed": false, + "end": 26, + "key": { + "end": 21, + "name": "stub", + "range": [ + 17, + 21 + ], + "start": 17, + "type": "Identifier" + }, + "kind": "method", + "range": [ + 17, + 26 + ], + "start": 17, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [], + "end": 26, + "range": [ + 24, + 26 + ], + "start": 24, + "type": "BlockStatement" + }, + "end": 26, + "generator": false, + "params": [], + "range": [ + 24, + 26 + ], + "start": 24, + "type": "FunctionExpression" + } + } + ], + "end": 28, + "range": [ + 11, + 28 + ], + "start": 11, + "type": "ClassBody" + }, + "end": 28, + "id": { + "end": 10, + "name": "None", + "range": [ + 6, + 10 + ], + "start": 6, + "type": "Identifier" + }, + "range": [ + 0, + 28 + ], + "start": 0, + "superClass": null, + "type": "ClassDeclaration" + } + ], + "end": 28, + "range": [ + 0, + 28 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-public-fields/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-public-fields/input.js new file mode 100644 index 00000000000..730a805c870 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-public-fields/input.js @@ -0,0 +1,8 @@ +class Rectangle { + height = 0; + width; + constructor(height, width) { + this.height = height; + this.width = width; + } +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-simple/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-simple/input.js new file mode 100644 index 00000000000..be6d4e66834 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-simple/input.js @@ -0,0 +1,7 @@ +class Rectangle { + constructor(height, width) { + this.height = height; + this.width = width; + } +} +const rect = new Rectangle(2, 3); diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-simple/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-simple/output.json new file mode 100644 index 00000000000..dd0b836dd30 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-simple/output.json @@ -0,0 +1,301 @@ +{ + "body": [ + { + "body": { + "body": [ + { + "computed": false, + "end": 114, + "key": { + "end": 33, + "name": "constructor", + "range": [ + 22, + 33 + ], + "start": 22, + "type": "Identifier" + }, + "kind": "constructor", + "range": [ + 22, + 114 + ], + "start": 22, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [ + { + "end": 80, + "expression": { + "end": 79, + "left": { + "computed": false, + "end": 70, + "object": { + "end": 63, + "range": [ + 59, + 63 + ], + "start": 59, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 70, + "name": "height", + "range": [ + 64, + 70 + ], + "start": 64, + "type": "Identifier" + }, + "range": [ + 59, + 70 + ], + "start": 59, + "type": "MemberExpression" + }, + "operator": "=", + "range": [ + 59, + 79 + ], + "right": { + "end": 79, + "name": "height", + "range": [ + 73, + 79 + ], + "start": 73, + "type": "Identifier" + }, + "start": 59, + "type": "AssignmentExpression" + }, + "range": [ + 59, + 80 + ], + "start": 59, + "type": "ExpressionStatement" + }, + { + "end": 108, + "expression": { + "end": 107, + "left": { + "computed": false, + "end": 99, + "object": { + "end": 93, + "range": [ + 89, + 93 + ], + "start": 89, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 99, + "name": "width", + "range": [ + 94, + 99 + ], + "start": 94, + "type": "Identifier" + }, + "range": [ + 89, + 99 + ], + "start": 89, + "type": "MemberExpression" + }, + "operator": "=", + "range": [ + 89, + 107 + ], + "right": { + "end": 107, + "name": "width", + "range": [ + 102, + 107 + ], + "start": 102, + "type": "Identifier" + }, + "start": 89, + "type": "AssignmentExpression" + }, + "range": [ + 89, + 108 + ], + "start": 89, + "type": "ExpressionStatement" + } + ], + "end": 114, + "range": [ + 49, + 114 + ], + "start": 49, + "type": "BlockStatement" + }, + "end": 114, + "generator": false, + "params": [ + { + "end": 40, + "name": "height", + "range": [ + 34, + 40 + ], + "start": 34, + "type": "Identifier" + }, + { + "end": 47, + "name": "width", + "range": [ + 42, + 47 + ], + "start": 42, + "type": "Identifier" + } + ], + "range": [ + 49, + 114 + ], + "start": 49, + "type": "FunctionExpression" + } + } + ], + "end": 116, + "range": [ + 16, + 116 + ], + "start": 16, + "type": "ClassBody" + }, + "end": 116, + "id": { + "end": 15, + "name": "Rectangle", + "range": [ + 6, + 15 + ], + "start": 6, + "type": "Identifier" + }, + "range": [ + 0, + 116 + ], + "start": 0, + "superClass": null, + "type": "ClassDeclaration" + }, + { + "declarations": [ + { + "end": 149, + "id": { + "end": 127, + "name": "rect", + "range": [ + 123, + 127 + ], + "start": 123, + "type": "Identifier" + }, + "init": { + "arguments": [ + { + "end": 145, + "range": [ + 144, + 145 + ], + "raw": "2", + "start": 144, + "type": "Literal", + "value": 2.0 + }, + { + "end": 148, + "range": [ + 147, + 148 + ], + "raw": "3", + "start": 147, + "type": "Literal", + "value": 3.0 + } + ], + "callee": { + "end": 143, + "name": "Rectangle", + "range": [ + 134, + 143 + ], + "start": 134, + "type": "Identifier" + }, + "end": 149, + "range": [ + 130, + 149 + ], + "start": 130, + "type": "NewExpression" + }, + "range": [ + 123, + 149 + ], + "start": 123, + "type": "VariableDeclarator" + } + ], + "end": 150, + "kind": "const", + "range": [ + 117, + 150 + ], + "start": 117, + "type": "VariableDeclaration" + } + ], + "end": 150, + "range": [ + 0, + 150 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-static/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-static/input.js new file mode 100644 index 00000000000..c7c02fa3662 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-static/input.js @@ -0,0 +1,15 @@ +class Point { + constructor(x, y) { + this.x = x; + this.y = y; + } + + static displayName = "Point"; + + static distance(a, b) { + const dx = a.x - b.x; + const dy = a.y - b.y; + + return Math.hypot(dx, dy); + } +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-unnamed/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-unnamed/input.js new file mode 100644 index 00000000000..fcda43a759a --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-unnamed/input.js @@ -0,0 +1,6 @@ +let Rectangle = class { + constructor(height, width) { + this.height = height; + this.width = width; + } +}; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-unnamed/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-unnamed/output.json new file mode 100644 index 00000000000..6068e88642c --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/class-unnamed/output.json @@ -0,0 +1,249 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 122, + "id": { + "end": 13, + "name": "Rectangle", + "range": [ + 4, + 13 + ], + "start": 4, + "type": "Identifier" + }, + "init": { + "body": { + "body": [ + { + "computed": false, + "end": 120, + "key": { + "end": 39, + "name": "constructor", + "range": [ + 28, + 39 + ], + "start": 28, + "type": "Identifier" + }, + "kind": "constructor", + "range": [ + 28, + 120 + ], + "start": 28, + "static": false, + "type": "MethodDefinition", + "value": { + "async": false, + "body": { + "body": [ + { + "end": 86, + "expression": { + "end": 85, + "left": { + "computed": false, + "end": 76, + "object": { + "end": 69, + "range": [ + 65, + 69 + ], + "start": 65, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 76, + "name": "height", + "range": [ + 70, + 76 + ], + "start": 70, + "type": "Identifier" + }, + "range": [ + 65, + 76 + ], + "start": 65, + "type": "MemberExpression" + }, + "operator": "=", + "range": [ + 65, + 85 + ], + "right": { + "end": 85, + "name": "height", + "range": [ + 79, + 85 + ], + "start": 79, + "type": "Identifier" + }, + "start": 65, + "type": "AssignmentExpression" + }, + "range": [ + 65, + 86 + ], + "start": 65, + "type": "ExpressionStatement" + }, + { + "end": 114, + "expression": { + "end": 113, + "left": { + "computed": false, + "end": 105, + "object": { + "end": 99, + "range": [ + 95, + 99 + ], + "start": 95, + "type": "ThisExpression" + }, + "optional": false, + "property": { + "end": 105, + "name": "width", + "range": [ + 100, + 105 + ], + "start": 100, + "type": "Identifier" + }, + "range": [ + 95, + 105 + ], + "start": 95, + "type": "MemberExpression" + }, + "operator": "=", + "range": [ + 95, + 113 + ], + "right": { + "end": 113, + "name": "width", + "range": [ + 108, + 113 + ], + "start": 108, + "type": "Identifier" + }, + "start": 95, + "type": "AssignmentExpression" + }, + "range": [ + 95, + 114 + ], + "start": 95, + "type": "ExpressionStatement" + } + ], + "end": 120, + "range": [ + 55, + 120 + ], + "start": 55, + "type": "BlockStatement" + }, + "end": 120, + "generator": false, + "params": [ + { + "end": 46, + "name": "height", + "range": [ + 40, + 46 + ], + "start": 40, + "type": "Identifier" + }, + { + "end": 53, + "name": "width", + "range": [ + 48, + 53 + ], + "start": 48, + "type": "Identifier" + } + ], + "range": [ + 55, + 120 + ], + "start": 55, + "type": "FunctionExpression" + } + } + ], + "end": 122, + "range": [ + 22, + 122 + ], + "start": 22, + "type": "ClassBody" + }, + "end": 122, + "id": null, + "range": [ + 16, + 122 + ], + "start": 16, + "superClass": null, + "type": "ClassExpression" + }, + "range": [ + 4, + 122 + ], + "start": 4, + "type": "VariableDeclarator" + } + ], + "end": 123, + "kind": "let", + "range": [ + 0, + 123 + ], + "start": 0, + "type": "VariableDeclaration" + } + ], + "end": 123, + "range": [ + 0, + 123 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block-first-line/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block-first-line/input.js new file mode 100644 index 00000000000..6871a05bdae --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block-first-line/input.js @@ -0,0 +1,4 @@ +/* +A block comment. +*/ +let a = false; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block-first-line/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block-first-line/output.json new file mode 100644 index 00000000000..aa8868afb1f --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block-first-line/output.json @@ -0,0 +1,54 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 36, + "id": { + "end": 28, + "name": "a", + "range": [ + 27, + 28 + ], + "start": 27, + "type": "Identifier" + }, + "init": { + "end": 36, + "range": [ + 31, + 36 + ], + "raw": "false", + "start": 31, + "type": "Literal", + "value": false + }, + "range": [ + 27, + 36 + ], + "start": 27, + "type": "VariableDeclarator" + } + ], + "end": 37, + "kind": "let", + "range": [ + 23, + 37 + ], + "start": 23, + "type": "VariableDeclaration" + } + ], + "end": 37, + "range": [ + 0, + 37 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block/input.js new file mode 100644 index 00000000000..22d551cfd49 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block/input.js @@ -0,0 +1,7 @@ +function x() { + /* + This is a + block comment. + */ + let a = false; +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block/output.json new file mode 100644 index 00000000000..6fdfa68b4d3 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-block/output.json @@ -0,0 +1,88 @@ +{ + "body": [ + { + "async": false, + "body": { + "body": [ + { + "declarations": [ + { + "end": 79, + "id": { + "end": 71, + "name": "a", + "range": [ + 70, + 71 + ], + "start": 70, + "type": "Identifier" + }, + "init": { + "end": 79, + "range": [ + 74, + 79 + ], + "raw": "false", + "start": 74, + "type": "Literal", + "value": false + }, + "range": [ + 70, + 79 + ], + "start": 70, + "type": "VariableDeclarator" + } + ], + "end": 80, + "kind": "let", + "range": [ + 66, + 80 + ], + "start": 66, + "type": "VariableDeclaration" + } + ], + "end": 82, + "range": [ + 13, + 82 + ], + "start": 13, + "type": "BlockStatement" + }, + "end": 82, + "expression": false, + "generator": false, + "id": { + "end": 10, + "name": "x", + "range": [ + 9, + 10 + ], + "start": 9, + "type": "Identifier" + }, + "params": [], + "range": [ + 0, + 82 + ], + "start": 0, + "type": "FunctionDeclaration" + } + ], + "end": 82, + "range": [ + 0, + 82 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-first-line/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-first-line/input.js new file mode 100644 index 00000000000..66c72e09d6c --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-first-line/input.js @@ -0,0 +1,2 @@ +// a top level comment +let a = false; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-first-line/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-first-line/output.json new file mode 100644 index 00000000000..aa8868afb1f --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-first-line/output.json @@ -0,0 +1,54 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 36, + "id": { + "end": 28, + "name": "a", + "range": [ + 27, + 28 + ], + "start": 27, + "type": "Identifier" + }, + "init": { + "end": 36, + "range": [ + 31, + 36 + ], + "raw": "false", + "start": 31, + "type": "Literal", + "value": false + }, + "range": [ + 27, + 36 + ], + "start": 27, + "type": "VariableDeclarator" + } + ], + "end": 37, + "kind": "let", + "range": [ + 23, + 37 + ], + "start": 23, + "type": "VariableDeclaration" + } + ], + "end": 37, + "range": [ + 0, + 37 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-line/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-line/input.js new file mode 100644 index 00000000000..2fc491f6893 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-line/input.js @@ -0,0 +1,4 @@ +function x() { + // some comment + let a = true; // trailing comment +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-line/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-line/output.json new file mode 100644 index 00000000000..60d27a94d48 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/comments-line/output.json @@ -0,0 +1,88 @@ +{ + "body": [ + { + "async": false, + "body": { + "body": [ + { + "declarations": [ + { + "end": 51, + "id": { + "end": 44, + "name": "a", + "range": [ + 43, + 44 + ], + "start": 43, + "type": "Identifier" + }, + "init": { + "end": 51, + "range": [ + 47, + 51 + ], + "raw": "true", + "start": 47, + "type": "Literal", + "value": true + }, + "range": [ + 43, + 51 + ], + "start": 43, + "type": "VariableDeclarator" + } + ], + "end": 52, + "kind": "let", + "range": [ + 39, + 52 + ], + "start": 39, + "type": "VariableDeclaration" + } + ], + "end": 74, + "range": [ + 13, + 74 + ], + "start": 13, + "type": "BlockStatement" + }, + "end": 74, + "expression": false, + "generator": false, + "id": { + "end": 10, + "name": "x", + "range": [ + 9, + 10 + ], + "start": 9, + "type": "Identifier" + }, + "params": [], + "range": [ + 0, + 74 + ], + "start": 0, + "type": "FunctionDeclaration" + } + ], + "end": 74, + "range": [ + 0, + 74 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/delete-operator/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/delete-operator/input.js new file mode 100644 index 00000000000..aa12759484f --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/delete-operator/input.js @@ -0,0 +1,2 @@ +let obj = {a: 10}; +delete obj.a; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/delete-operator/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/delete-operator/output.json new file mode 100644 index 00000000000..73ebd3bf416 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/delete-operator/output.json @@ -0,0 +1,139 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 17, + "id": { + "end": 7, + "name": "obj", + "range": [ + 4, + 7 + ], + "start": 4, + "type": "Identifier" + }, + "init": { + "end": 17, + "properties": [ + { + "computed": false, + "end": 16, + "key": { + "end": 12, + "name": "a", + "range": [ + 11, + 12 + ], + "start": 11, + "type": "Identifier" + }, + "kind": "init", + "method": false, + "range": [ + 11, + 16 + ], + "shorthand": false, + "start": 11, + "type": "Property", + "value": { + "end": 16, + "range": [ + 14, + 16 + ], + "raw": "10", + "start": 14, + "type": "Literal", + "value": 10.0 + } + } + ], + "range": [ + 10, + 17 + ], + "start": 10, + "type": "ObjectExpression" + }, + "range": [ + 4, + 17 + ], + "start": 4, + "type": "VariableDeclarator" + } + ], + "end": 18, + "kind": "let", + "range": [ + 0, + 18 + ], + "start": 0, + "type": "VariableDeclaration" + }, + { + "end": 32, + "expression": { + "argument": { + "computed": false, + "end": 31, + "object": { + "end": 29, + "name": "obj", + "range": [ + 26, + 29 + ], + "start": 26, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 31, + "name": "a", + "range": [ + 30, + 31 + ], + "start": 30, + "type": "Identifier" + }, + "range": [ + 26, + 31 + ], + "start": 26, + "type": "MemberExpression" + }, + "end": 31, + "operator": "delete", + "prefix": true, + "range": [ + 19, + 31 + ], + "start": 19, + "type": "UnaryExpression" + }, + "range": [ + 19, + 32 + ], + "start": 19, + "type": "ExpressionStatement" + } + ], + "end": 32, + "range": [ + 0, + 32 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/exponentiation-operator/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/exponentiation-operator/input.js new file mode 100644 index 00000000000..7eefca88345 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/exponentiation-operator/input.js @@ -0,0 +1 @@ +const x = 2 ** 3; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/exponentiation-operator/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/exponentiation-operator/output.json new file mode 100644 index 00000000000..03d81f8e545 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/exponentiation-operator/output.json @@ -0,0 +1,75 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 16, + "id": { + "end": 7, + "name": "x", + "range": [ + 6, + 7 + ], + "start": 6, + "type": "Identifier" + }, + "init": { + "end": 16, + "left": { + "end": 11, + "range": [ + 10, + 11 + ], + "raw": "2", + "start": 10, + "type": "Literal", + "value": 2.0 + }, + "operator": "**", + "range": [ + 10, + 16 + ], + "right": { + "end": 16, + "range": [ + 15, + 16 + ], + "raw": "3", + "start": 15, + "type": "Literal", + "value": 3.0 + }, + "start": 10, + "type": "BinaryExpression" + }, + "range": [ + 6, + 16 + ], + "start": 6, + "type": "VariableDeclarator" + } + ], + "end": 17, + "kind": "const", + "range": [ + 0, + 17 + ], + "start": 0, + "type": "VariableDeclaration" + } + ], + "end": 17, + "range": [ + 0, + 17 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-anonymous/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-anonymous/input.js new file mode 100644 index 00000000000..19ff9341d3c --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-anonymous/input.js @@ -0,0 +1 @@ +const square = function(number) { return number * number } diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-anonymous/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-anonymous/output.json new file mode 100644 index 00000000000..aca0dab6265 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-anonymous/output.json @@ -0,0 +1,117 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 58, + "id": { + "end": 12, + "name": "square", + "range": [ + 6, + 12 + ], + "start": 6, + "type": "Identifier" + }, + "init": { + "async": false, + "body": { + "body": [ + { + "argument": { + "end": 56, + "left": { + "end": 47, + "name": "number", + "range": [ + 41, + 47 + ], + "start": 41, + "type": "Identifier" + }, + "operator": "*", + "range": [ + 41, + 56 + ], + "right": { + "end": 56, + "name": "number", + "range": [ + 50, + 56 + ], + "start": 50, + "type": "Identifier" + }, + "start": 41, + "type": "BinaryExpression" + }, + "end": 56, + "range": [ + 34, + 56 + ], + "start": 34, + "type": "ReturnStatement" + } + ], + "end": 58, + "range": [ + 32, + 58 + ], + "start": 32, + "type": "BlockStatement" + }, + "end": 58, + "generator": false, + "id": null, + "params": [ + { + "end": 30, + "name": "number", + "range": [ + 24, + 30 + ], + "start": 24, + "type": "Identifier" + } + ], + "range": [ + 15, + 58 + ], + "start": 15, + "type": "FunctionExpression" + }, + "range": [ + 6, + 58 + ], + "start": 6, + "type": "VariableDeclarator" + } + ], + "end": 58, + "kind": "const", + "range": [ + 0, + 58 + ], + "start": 0, + "type": "VariableDeclaration" + } + ], + "end": 58, + "range": [ + 0, + 58 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-arrow/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-arrow/input.js new file mode 100644 index 00000000000..270a8ffe9bc --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-arrow/input.js @@ -0,0 +1,7 @@ +var a = [ + 'Hydrogen', + 'Helium', + 'Lithium', + 'Beryllium' +]; +var a3 = a.map(s => s.length); diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-arrow/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-arrow/output.json new file mode 100644 index 00000000000..076b09f5a09 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-arrow/output.json @@ -0,0 +1,227 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 72, + "id": { + "end": 5, + "name": "a", + "range": [ + 4, + 5 + ], + "start": 4, + "type": "Identifier" + }, + "init": { + "elements": [ + { + "end": 24, + "range": [ + 14, + 24 + ], + "raw": "Hydrogen", + "start": 14, + "type": "Literal", + "value": "Hydrogen" + }, + { + "end": 38, + "range": [ + 30, + 38 + ], + "raw": "Helium", + "start": 30, + "type": "Literal", + "value": "Helium" + }, + { + "end": 53, + "range": [ + 44, + 53 + ], + "raw": "Lithium", + "start": 44, + "type": "Literal", + "value": "Lithium" + }, + { + "end": 70, + "range": [ + 59, + 70 + ], + "raw": "Beryllium", + "start": 59, + "type": "Literal", + "value": "Beryllium" + } + ], + "end": 72, + "range": [ + 8, + 72 + ], + "start": 8, + "type": "ArrayExpression" + }, + "range": [ + 4, + 72 + ], + "start": 4, + "type": "VariableDeclarator" + } + ], + "end": 73, + "kind": "var", + "range": [ + 0, + 73 + ], + "start": 0, + "type": "VariableDeclaration" + }, + { + "declarations": [ + { + "end": 103, + "id": { + "end": 80, + "name": "a3", + "range": [ + 78, + 80 + ], + "start": 78, + "type": "Identifier" + }, + "init": { + "arguments": [ + { + "async": false, + "body": { + "computed": false, + "end": 102, + "object": { + "end": 95, + "name": "s", + "range": [ + 94, + 95 + ], + "start": 94, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 102, + "name": "length", + "range": [ + 96, + 102 + ], + "start": 96, + "type": "Identifier" + }, + "range": [ + 94, + 102 + ], + "start": 94, + "type": "MemberExpression" + }, + "end": 102, + "expression": true, + "generator": false, + "params": [ + { + "end": 90, + "name": "s", + "range": [ + 89, + 90 + ], + "start": 89, + "type": "Identifier" + } + ], + "range": [ + 89, + 102 + ], + "start": 89, + "type": "ArrowFunctionExpression" + } + ], + "callee": { + "computed": false, + "end": 88, + "object": { + "end": 84, + "name": "a", + "range": [ + 83, + 84 + ], + "start": 83, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 88, + "name": "map", + "range": [ + 85, + 88 + ], + "start": 85, + "type": "Identifier" + }, + "range": [ + 83, + 88 + ], + "start": 83, + "type": "MemberExpression" + }, + "end": 103, + "optional": false, + "range": [ + 83, + 103 + ], + "start": 83, + "type": "CallExpression" + }, + "range": [ + 78, + 103 + ], + "start": 78, + "type": "VariableDeclarator" + } + ], + "end": 104, + "kind": "var", + "range": [ + 74, + 104 + ], + "start": 74, + "type": "VariableDeclaration" + } + ], + "end": 104, + "range": [ + 0, + 104 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-default-parameters/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-default-parameters/input.js new file mode 100644 index 00000000000..6da17d77ccc --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-default-parameters/input.js @@ -0,0 +1,3 @@ +function multiply(a, b = 1) { + return a * b; +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-default-parameters/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-default-parameters/output.json new file mode 100644 index 00000000000..e374ce5f0c0 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-default-parameters/output.json @@ -0,0 +1,126 @@ +{ + "body": [ + { + "async": false, + "body": { + "body": [ + { + "argument": { + "end": 44, + "left": { + "end": 40, + "name": "a", + "range": [ + 39, + 40 + ], + "start": 39, + "type": "Identifier" + }, + "operator": "*", + "range": [ + 39, + 44 + ], + "right": { + "end": 44, + "name": "b", + "range": [ + 43, + 44 + ], + "start": 43, + "type": "Identifier" + }, + "start": 39, + "type": "BinaryExpression" + }, + "end": 45, + "range": [ + 32, + 45 + ], + "start": 32, + "type": "ReturnStatement" + } + ], + "end": 47, + "range": [ + 28, + 47 + ], + "start": 28, + "type": "BlockStatement" + }, + "end": 47, + "expression": false, + "generator": false, + "id": { + "end": 17, + "name": "multiply", + "range": [ + 9, + 17 + ], + "start": 9, + "type": "Identifier" + }, + "params": [ + { + "end": 19, + "name": "a", + "range": [ + 18, + 19 + ], + "start": 18, + "type": "Identifier" + }, + { + "end": 26, + "left": { + "end": 22, + "name": "b", + "range": [ + 21, + 22 + ], + "start": 21, + "type": "Identifier" + }, + "range": [ + 21, + 26 + ], + "right": { + "end": 26, + "range": [ + 25, + 26 + ], + "raw": "1", + "start": 25, + "type": "Literal", + "value": 1.0 + }, + "start": 21, + "type": "AssignmentPattern" + } + ], + "range": [ + 0, + 47 + ], + "start": 0, + "type": "FunctionDeclaration" + } + ], + "end": 47, + "range": [ + 0, + 47 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-rest-parameters/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-rest-parameters/input.js new file mode 100644 index 00000000000..78b51df426d --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-rest-parameters/input.js @@ -0,0 +1,3 @@ +function multiply(multiplier, ...theArgs) { + return theArgs.map(x => multiplier * x); +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-rest-parameters/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-rest-parameters/output.json new file mode 100644 index 00000000000..fdeed2c95a4 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-rest-parameters/output.json @@ -0,0 +1,182 @@ +{ + "body": [ + { + "async": false, + "body": { + "body": [ + { + "argument": { + "arguments": [ + { + "async": false, + "body": { + "end": 86, + "left": { + "end": 82, + "name": "multiplier", + "range": [ + 72, + 82 + ], + "start": 72, + "type": "Identifier" + }, + "operator": "*", + "range": [ + 72, + 86 + ], + "right": { + "end": 86, + "name": "x", + "range": [ + 85, + 86 + ], + "start": 85, + "type": "Identifier" + }, + "start": 72, + "type": "BinaryExpression" + }, + "end": 86, + "expression": true, + "generator": false, + "params": [ + { + "end": 68, + "name": "x", + "range": [ + 67, + 68 + ], + "start": 67, + "type": "Identifier" + } + ], + "range": [ + 67, + 86 + ], + "start": 67, + "type": "ArrowFunctionExpression" + } + ], + "callee": { + "computed": false, + "end": 66, + "object": { + "end": 62, + "name": "theArgs", + "range": [ + 55, + 62 + ], + "start": 55, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 66, + "name": "map", + "range": [ + 63, + 66 + ], + "start": 63, + "type": "Identifier" + }, + "range": [ + 55, + 66 + ], + "start": 55, + "type": "MemberExpression" + }, + "end": 87, + "optional": false, + "range": [ + 55, + 87 + ], + "start": 55, + "type": "CallExpression" + }, + "end": 88, + "range": [ + 48, + 88 + ], + "start": 48, + "type": "ReturnStatement" + } + ], + "end": 90, + "range": [ + 42, + 90 + ], + "start": 42, + "type": "BlockStatement" + }, + "end": 90, + "expression": false, + "generator": false, + "id": { + "end": 17, + "name": "multiply", + "range": [ + 9, + 17 + ], + "start": 9, + "type": "Identifier" + }, + "params": [ + { + "end": 28, + "name": "multiplier", + "range": [ + 18, + 28 + ], + "start": 18, + "type": "Identifier" + }, + { + "argument": { + "end": 40, + "name": "theArgs", + "range": [ + 33, + 40 + ], + "start": 33, + "type": "Identifier" + }, + "end": 40, + "range": [ + 30, + 40 + ], + "start": 30, + "type": "RestElement" + } + ], + "range": [ + 0, + 90 + ], + "start": 0, + "type": "FunctionDeclaration" + } + ], + "end": 90, + "range": [ + 0, + 90 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-simple/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-simple/input.js new file mode 100644 index 00000000000..61fb859ef6f --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-simple/input.js @@ -0,0 +1,3 @@ +function square(number) { + return number * number; +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-simple/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-simple/output.json new file mode 100644 index 00000000000..0c67fc94393 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/function-simple/output.json @@ -0,0 +1,96 @@ +{ + "body": [ + { + "async": false, + "body": { + "body": [ + { + "argument": { + "end": 50, + "left": { + "end": 41, + "name": "number", + "range": [ + 35, + 41 + ], + "start": 35, + "type": "Identifier" + }, + "operator": "*", + "range": [ + 35, + 50 + ], + "right": { + "end": 50, + "name": "number", + "range": [ + 44, + 50 + ], + "start": 44, + "type": "Identifier" + }, + "start": 35, + "type": "BinaryExpression" + }, + "end": 51, + "range": [ + 28, + 51 + ], + "start": 28, + "type": "ReturnStatement" + } + ], + "end": 53, + "range": [ + 24, + 53 + ], + "start": 24, + "type": "BlockStatement" + }, + "end": 53, + "expression": false, + "generator": false, + "id": { + "end": 15, + "name": "square", + "range": [ + 9, + 15 + ], + "start": 9, + "type": "Identifier" + }, + "params": [ + { + "end": 22, + "name": "number", + "range": [ + 16, + 22 + ], + "start": 16, + "type": "Identifier" + } + ], + "range": [ + 0, + 53 + ], + "start": 0, + "type": "FunctionDeclaration" + } + ], + "end": 53, + "range": [ + 0, + 53 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-and-expr/input.jsx b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-and-expr/input.jsx new file mode 100644 index 00000000000..fd9e28ddd78 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-and-expr/input.jsx @@ -0,0 +1,6 @@ +const App = () => { + let t = true; + return
+ { t && t } +
+}; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-children/input.jsx b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-children/input.jsx new file mode 100644 index 00000000000..3f40a6918af --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-children/input.jsx @@ -0,0 +1,5 @@ +const App = () => { + return
+
testing
+
+}; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-map/input.jsx b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-map/input.jsx new file mode 100644 index 00000000000..823da418b8e --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-map/input.jsx @@ -0,0 +1,6 @@ +const App = () => { + let a = [1, 2, 3]; + return
    + {a.map(item =>
  • {item}
  • )} +
+}; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-props-spread/input.jsx b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-props-spread/input.jsx new file mode 100644 index 00000000000..6b95b9ecb27 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-props-spread/input.jsx @@ -0,0 +1,3 @@ +const App = props => { + return
+}; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-props/input.jsx b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-props/input.jsx new file mode 100644 index 00000000000..9b4e6afb059 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-props/input.jsx @@ -0,0 +1,4 @@ +const App = () => { + let name = "thing"; + return
+}; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-self-closing/input.jsx b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-self-closing/input.jsx new file mode 100644 index 00000000000..0f20333033f --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-self-closing/input.jsx @@ -0,0 +1,3 @@ +const App = () => { + return
+}; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-simple/input.jsx b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-simple/input.jsx new file mode 100644 index 00000000000..37f10a65a71 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-simple/input.jsx @@ -0,0 +1,3 @@ +const Component = () => { + return hello +}; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-ternary-expr/input.jsx b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-ternary-expr/input.jsx new file mode 100644 index 00000000000..3fe7f068588 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/jsx-ternary-expr/input.jsx @@ -0,0 +1,6 @@ +const App = () => { + let t = "a"; + return
+ { t === "a" ? a : b } +
+}; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-commonjs/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-commonjs/input.js new file mode 100644 index 00000000000..dc7185d3a69 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-commonjs/input.js @@ -0,0 +1,3 @@ +const fs = require("fs"); +const s = fs.readFileSync("_placeholder"); +module.exports = s; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-commonjs/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-commonjs/output.json new file mode 100644 index 00000000000..0b276b668f4 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-commonjs/output.json @@ -0,0 +1,221 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 24, + "id": { + "end": 8, + "name": "fs", + "range": [ + 6, + 8 + ], + "start": 6, + "type": "Identifier" + }, + "init": { + "arguments": [ + { + "end": 23, + "range": [ + 19, + 23 + ], + "raw": "fs", + "start": 19, + "type": "Literal", + "value": "fs" + } + ], + "callee": { + "end": 18, + "name": "require", + "range": [ + 11, + 18 + ], + "start": 11, + "type": "Identifier" + }, + "end": 24, + "optional": false, + "range": [ + 11, + 24 + ], + "start": 11, + "type": "CallExpression" + }, + "range": [ + 6, + 24 + ], + "start": 6, + "type": "VariableDeclarator" + } + ], + "end": 25, + "kind": "const", + "range": [ + 0, + 25 + ], + "start": 0, + "type": "VariableDeclaration" + }, + { + "declarations": [ + { + "end": 67, + "id": { + "end": 33, + "name": "s", + "range": [ + 32, + 33 + ], + "start": 32, + "type": "Identifier" + }, + "init": { + "arguments": [ + { + "end": 66, + "range": [ + 52, + 66 + ], + "raw": "_placeholder", + "start": 52, + "type": "Literal", + "value": "_placeholder" + } + ], + "callee": { + "computed": false, + "end": 51, + "object": { + "end": 38, + "name": "fs", + "range": [ + 36, + 38 + ], + "start": 36, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 51, + "name": "readFileSync", + "range": [ + 39, + 51 + ], + "start": 39, + "type": "Identifier" + }, + "range": [ + 36, + 51 + ], + "start": 36, + "type": "MemberExpression" + }, + "end": 67, + "optional": false, + "range": [ + 36, + 67 + ], + "start": 36, + "type": "CallExpression" + }, + "range": [ + 32, + 67 + ], + "start": 32, + "type": "VariableDeclarator" + } + ], + "end": 68, + "kind": "const", + "range": [ + 26, + 68 + ], + "start": 26, + "type": "VariableDeclaration" + }, + { + "end": 88, + "expression": { + "end": 87, + "left": { + "computed": false, + "end": 83, + "object": { + "end": 75, + "name": "module", + "range": [ + 69, + 75 + ], + "start": 69, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 83, + "name": "exports", + "range": [ + 76, + 83 + ], + "start": 76, + "type": "Identifier" + }, + "range": [ + 69, + 83 + ], + "start": 69, + "type": "MemberExpression" + }, + "operator": "=", + "range": [ + 69, + 87 + ], + "right": { + "end": 87, + "name": "s", + "range": [ + 86, + 87 + ], + "start": 86, + "type": "Identifier" + }, + "start": 69, + "type": "AssignmentExpression" + }, + "range": [ + 69, + 88 + ], + "start": 69, + "type": "ExpressionStatement" + } + ], + "end": 88, + "range": [ + 0, + 88 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-default/input.mjs b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-default/input.mjs new file mode 100644 index 00000000000..ea26727cf8e --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-default/input.mjs @@ -0,0 +1,2 @@ +const a = 1; +export default a; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-individual-items/input.mjs b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-individual-items/input.mjs new file mode 100644 index 00000000000..f23da21955e --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-individual-items/input.mjs @@ -0,0 +1,3 @@ +export const name = "a"; +export function functionName() {} +export class ClassName {} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-named/input.mjs b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-named/input.mjs new file mode 100644 index 00000000000..36a0703a495 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-named/input.mjs @@ -0,0 +1,2 @@ +const a = 1; +export { a }; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-renamed/input.mjs b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-renamed/input.mjs new file mode 100644 index 00000000000..9ec06b28df0 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-export-renamed/input.mjs @@ -0,0 +1,2 @@ +const x = 1; +export { x as y }; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-default/input.mjs b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-default/input.mjs new file mode 100644 index 00000000000..e604fae7864 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-default/input.mjs @@ -0,0 +1 @@ +import a from "b"; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-multiple/input.mjs b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-multiple/input.mjs new file mode 100644 index 00000000000..96f56017a66 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-multiple/input.mjs @@ -0,0 +1,4 @@ +import a, { + b, + c, +} from "d"; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-named/input.mjs b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-named/input.mjs new file mode 100644 index 00000000000..947e540cd76 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-named/input.mjs @@ -0,0 +1 @@ +import { a } from "b"; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-renamed/input.mjs b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-renamed/input.mjs new file mode 100644 index 00000000000..61ed93c8f18 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-renamed/input.mjs @@ -0,0 +1 @@ +import { a as b } from "c"; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-star-renamed/input.mjs b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-star-renamed/input.mjs new file mode 100644 index 00000000000..cb8bc5ecf53 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/module-import-star-renamed/input.mjs @@ -0,0 +1 @@ +import * as name from "module-name"; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-destructuring/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-destructuring/input.js new file mode 100644 index 00000000000..c2cba27636b --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-destructuring/input.js @@ -0,0 +1,6 @@ +const obj = { + a: true, + b: false, + c: null, +}; +const { a, b, ...other } = obj; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-destructuring/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-destructuring/output.json new file mode 100644 index 00000000000..79b1991a15d --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-destructuring/output.json @@ -0,0 +1,283 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 55, + "id": { + "end": 9, + "name": "obj", + "range": [ + 6, + 9 + ], + "start": 6, + "type": "Identifier" + }, + "init": { + "end": 55, + "properties": [ + { + "computed": false, + "end": 25, + "key": { + "end": 19, + "name": "a", + "range": [ + 18, + 19 + ], + "start": 18, + "type": "Identifier" + }, + "kind": "init", + "method": false, + "range": [ + 18, + 25 + ], + "shorthand": false, + "start": 18, + "type": "Property", + "value": { + "end": 25, + "range": [ + 21, + 25 + ], + "raw": "true", + "start": 21, + "type": "Literal", + "value": true + } + }, + { + "computed": false, + "end": 39, + "key": { + "end": 32, + "name": "b", + "range": [ + 31, + 32 + ], + "start": 31, + "type": "Identifier" + }, + "kind": "init", + "method": false, + "range": [ + 31, + 39 + ], + "shorthand": false, + "start": 31, + "type": "Property", + "value": { + "end": 39, + "range": [ + 34, + 39 + ], + "raw": "false", + "start": 34, + "type": "Literal", + "value": false + } + }, + { + "computed": false, + "end": 52, + "key": { + "end": 46, + "name": "c", + "range": [ + 45, + 46 + ], + "start": 45, + "type": "Identifier" + }, + "kind": "init", + "method": false, + "range": [ + 45, + 52 + ], + "shorthand": false, + "start": 45, + "type": "Property", + "value": { + "end": 52, + "range": [ + 48, + 52 + ], + "raw": "null", + "start": 48, + "type": "Literal", + "value": null + } + } + ], + "range": [ + 12, + 55 + ], + "start": 12, + "type": "ObjectExpression" + }, + "range": [ + 6, + 55 + ], + "start": 6, + "type": "VariableDeclarator" + } + ], + "end": 56, + "kind": "const", + "range": [ + 0, + 56 + ], + "start": 0, + "type": "VariableDeclaration" + }, + { + "declarations": [ + { + "end": 87, + "id": { + "end": 81, + "properties": [ + { + "computed": false, + "end": 66, + "key": { + "end": 66, + "name": "a", + "range": [ + 65, + 66 + ], + "start": 65, + "type": "Identifier" + }, + "kind": "init", + "method": false, + "range": [ + 65, + 66 + ], + "shorthand": true, + "start": 65, + "type": "Property", + "value": { + "end": 66, + "name": "a", + "range": [ + 65, + 66 + ], + "start": 65, + "type": "Identifier" + } + }, + { + "computed": false, + "end": 69, + "key": { + "end": 69, + "name": "b", + "range": [ + 68, + 69 + ], + "start": 68, + "type": "Identifier" + }, + "kind": "init", + "method": false, + "range": [ + 68, + 69 + ], + "shorthand": true, + "start": 68, + "type": "Property", + "value": { + "end": 69, + "name": "b", + "range": [ + 68, + 69 + ], + "start": 68, + "type": "Identifier" + } + }, + { + "argument": { + "end": 79, + "name": "other", + "range": [ + 74, + 79 + ], + "start": 74, + "type": "Identifier" + }, + "end": 79, + "range": [ + 71, + 79 + ], + "start": 71, + "type": "RestElement" + } + ], + "range": [ + 63, + 81 + ], + "start": 63, + "type": "ObjectPattern" + }, + "init": { + "end": 87, + "name": "obj", + "range": [ + 84, + 87 + ], + "start": 84, + "type": "Identifier" + }, + "range": [ + 63, + 87 + ], + "start": 63, + "type": "VariableDeclarator" + } + ], + "end": 88, + "kind": "const", + "range": [ + 57, + 88 + ], + "start": 57, + "type": "VariableDeclaration" + } + ], + "end": 88, + "range": [ + 0, + 88 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-simple/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-simple/input.js new file mode 100644 index 00000000000..146da039470 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-simple/input.js @@ -0,0 +1,4 @@ +let obj = { + a: 1, + b: false, +}; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-simple/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-simple/output.json new file mode 100644 index 00000000000..66d44da60d5 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-simple/output.json @@ -0,0 +1,122 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 37, + "id": { + "end": 7, + "name": "obj", + "range": [ + 4, + 7 + ], + "start": 4, + "type": "Identifier" + }, + "init": { + "end": 37, + "properties": [ + { + "computed": false, + "end": 20, + "key": { + "end": 17, + "name": "a", + "range": [ + 16, + 17 + ], + "start": 16, + "type": "Identifier" + }, + "kind": "init", + "method": false, + "range": [ + 16, + 20 + ], + "shorthand": false, + "start": 16, + "type": "Property", + "value": { + "end": 20, + "range": [ + 19, + 20 + ], + "raw": "1", + "start": 19, + "type": "Literal", + "value": 1.0 + } + }, + { + "computed": false, + "end": 34, + "key": { + "end": 27, + "name": "b", + "range": [ + 26, + 27 + ], + "start": 26, + "type": "Identifier" + }, + "kind": "init", + "method": false, + "range": [ + 26, + 34 + ], + "shorthand": false, + "start": 26, + "type": "Property", + "value": { + "end": 34, + "range": [ + 29, + 34 + ], + "raw": "false", + "start": 29, + "type": "Literal", + "value": false + } + } + ], + "range": [ + 10, + 37 + ], + "start": 10, + "type": "ObjectExpression" + }, + "range": [ + 4, + 37 + ], + "start": 4, + "type": "VariableDeclarator" + } + ], + "end": 38, + "kind": "let", + "range": [ + 0, + 38 + ], + "start": 0, + "type": "VariableDeclaration" + } + ], + "end": 38, + "range": [ + 0, + 38 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-spread/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-spread/input.js new file mode 100644 index 00000000000..5e23bb4ebd9 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-spread/input.js @@ -0,0 +1,7 @@ +const a = { + name: "a", +}; +const b = { + ...a, + name: "b", +}; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-spread/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-spread/output.json new file mode 100644 index 00000000000..13a1cebc457 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/object-spread/output.json @@ -0,0 +1,183 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 28, + "id": { + "end": 7, + "name": "a", + "range": [ + 6, + 7 + ], + "start": 6, + "type": "Identifier" + }, + "init": { + "end": 28, + "properties": [ + { + "computed": false, + "end": 25, + "key": { + "end": 20, + "name": "name", + "range": [ + 16, + 20 + ], + "start": 16, + "type": "Identifier" + }, + "kind": "init", + "method": false, + "range": [ + 16, + 25 + ], + "shorthand": false, + "start": 16, + "type": "Property", + "value": { + "end": 25, + "range": [ + 22, + 25 + ], + "raw": "a", + "start": 22, + "type": "Literal", + "value": "a" + } + } + ], + "range": [ + 10, + 28 + ], + "start": 10, + "type": "ObjectExpression" + }, + "range": [ + 6, + 28 + ], + "start": 6, + "type": "VariableDeclarator" + } + ], + "end": 29, + "kind": "const", + "range": [ + 0, + 29 + ], + "start": 0, + "type": "VariableDeclaration" + }, + { + "declarations": [ + { + "end": 68, + "id": { + "end": 37, + "name": "b", + "range": [ + 36, + 37 + ], + "start": 36, + "type": "Identifier" + }, + "init": { + "end": 68, + "properties": [ + { + "argument": { + "end": 50, + "name": "a", + "range": [ + 49, + 50 + ], + "start": 49, + "type": "Identifier" + }, + "end": 50, + "range": [ + 46, + 50 + ], + "start": 46, + "type": "SpreadElement" + }, + { + "computed": false, + "end": 65, + "key": { + "end": 60, + "name": "name", + "range": [ + 56, + 60 + ], + "start": 56, + "type": "Identifier" + }, + "kind": "init", + "method": false, + "range": [ + 56, + 65 + ], + "shorthand": false, + "start": 56, + "type": "Property", + "value": { + "end": 65, + "range": [ + 62, + 65 + ], + "raw": "b", + "start": 62, + "type": "Literal", + "value": "b" + } + } + ], + "range": [ + 40, + 68 + ], + "start": 40, + "type": "ObjectExpression" + }, + "range": [ + 36, + 68 + ], + "start": 36, + "type": "VariableDeclarator" + } + ], + "end": 69, + "kind": "const", + "range": [ + 30, + 69 + ], + "start": 30, + "type": "VariableDeclaration" + } + ], + "end": 69, + "range": [ + 0, + 69 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-flags/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-flags/input.js new file mode 100644 index 00000000000..ae57e955dab --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-flags/input.js @@ -0,0 +1 @@ +let r = /[0-9]+/im; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-flags/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-flags/output.json new file mode 100644 index 00000000000..10dbb174fe9 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-flags/output.json @@ -0,0 +1,57 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 18, + "id": { + "end": 5, + "name": "r", + "range": [ + 4, + 5 + ], + "start": 4, + "type": "Identifier" + }, + "init": { + "end": 18, + "range": [ + 8, + 18 + ], + "regex": { + "flags": "im", + "pattern": "[0-9]+" + }, + "start": 8, + "type": "Literal", + "value": {} + }, + "range": [ + 4, + 18 + ], + "start": 4, + "type": "VariableDeclarator" + } + ], + "end": 19, + "kind": "let", + "range": [ + 0, + 19 + ], + "start": 0, + "type": "VariableDeclaration" + } + ], + "end": 19, + "range": [ + 0, + 19 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-simple/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-simple/input.js new file mode 100644 index 00000000000..aadeff77b3e --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-simple/input.js @@ -0,0 +1 @@ +let r = /[0-9]+/; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-simple/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-simple/output.json new file mode 100644 index 00000000000..1d64040fb33 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/regex-simple/output.json @@ -0,0 +1,57 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 16, + "id": { + "end": 5, + "name": "r", + "range": [ + 4, + 5 + ], + "start": 4, + "type": "Identifier" + }, + "init": { + "end": 16, + "range": [ + 8, + 16 + ], + "regex": { + "flags": "", + "pattern": "[0-9]+" + }, + "start": 8, + "type": "Literal", + "value": {} + }, + "range": [ + 4, + 16 + ], + "start": 4, + "type": "VariableDeclarator" + } + ], + "end": 17, + "kind": "let", + "range": [ + 0, + 17 + ], + "start": 0, + "type": "VariableDeclaration" + } + ], + "end": 17, + "range": [ + 0, + 17 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/shebang/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/shebang/input.js new file mode 100644 index 00000000000..4d10371b7de --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/shebang/input.js @@ -0,0 +1,3 @@ +#! /usr/bin/env node + +const x = "abc"; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/shebang/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/shebang/output.json new file mode 100644 index 00000000000..75221f47252 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/shebang/output.json @@ -0,0 +1,54 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 37, + "id": { + "end": 29, + "name": "x", + "range": [ + 28, + 29 + ], + "start": 28, + "type": "Identifier" + }, + "init": { + "end": 37, + "range": [ + 32, + 37 + ], + "raw": "abc", + "start": 32, + "type": "Literal", + "value": "abc" + }, + "range": [ + 28, + 37 + ], + "start": 28, + "type": "VariableDeclarator" + } + ], + "end": 38, + "kind": "const", + "range": [ + 22, + 38 + ], + "start": 22, + "type": "VariableDeclaration" + } + ], + "end": 38, + "range": [ + 0, + 38 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple-two-lines/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple-two-lines/input.js new file mode 100644 index 00000000000..1990376cd89 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple-two-lines/input.js @@ -0,0 +1,2 @@ +const n = "hello"; +console.log(n); diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple-two-lines/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple-two-lines/output.json new file mode 100644 index 00000000000..99bf3c81963 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple-two-lines/output.json @@ -0,0 +1,116 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 17, + "id": { + "end": 7, + "name": "n", + "range": [ + 6, + 7 + ], + "start": 6, + "type": "Identifier" + }, + "init": { + "end": 17, + "range": [ + 10, + 17 + ], + "raw": "hello", + "start": 10, + "type": "Literal", + "value": "hello" + }, + "range": [ + 6, + 17 + ], + "start": 6, + "type": "VariableDeclarator" + } + ], + "end": 18, + "kind": "const", + "range": [ + 0, + 18 + ], + "start": 0, + "type": "VariableDeclaration" + }, + { + "end": 34, + "expression": { + "arguments": [ + { + "end": 32, + "name": "n", + "range": [ + 31, + 32 + ], + "start": 31, + "type": "Identifier" + } + ], + "callee": { + "computed": false, + "end": 30, + "object": { + "end": 26, + "name": "console", + "range": [ + 19, + 26 + ], + "start": 19, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 30, + "name": "log", + "range": [ + 27, + 30 + ], + "start": 27, + "type": "Identifier" + }, + "range": [ + 19, + 30 + ], + "start": 19, + "type": "MemberExpression" + }, + "end": 33, + "optional": false, + "range": [ + 19, + 33 + ], + "start": 19, + "type": "CallExpression" + }, + "range": [ + 19, + 34 + ], + "start": 19, + "type": "ExpressionStatement" + } + ], + "end": 34, + "range": [ + 0, + 34 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple/input.js new file mode 100644 index 00000000000..9225ccf43fc --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple/input.js @@ -0,0 +1 @@ +const n = 1; diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple/output.json new file mode 100644 index 00000000000..4d630023267 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/simple/output.json @@ -0,0 +1,54 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 11, + "id": { + "end": 7, + "name": "n", + "range": [ + 6, + 7 + ], + "start": 6, + "type": "Identifier" + }, + "init": { + "end": 11, + "range": [ + 10, + 11 + ], + "raw": "1", + "start": 10, + "type": "Literal", + "value": 1.0 + }, + "range": [ + 6, + 11 + ], + "start": 6, + "type": "VariableDeclarator" + } + ], + "end": 12, + "kind": "const", + "range": [ + 0, + 12 + ], + "start": 0, + "type": "VariableDeclaration" + } + ], + "end": 12, + "range": [ + 0, + 12 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/static-blocks/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/static-blocks/input.js new file mode 100644 index 00000000000..f25698ac06f --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/static-blocks/input.js @@ -0,0 +1,6 @@ +class C { + static foo; + static { + this.foo = "foo"; + } +} diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/template-literal/input.js b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/template-literal/input.js new file mode 100644 index 00000000000..f000e80d4b1 --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/template-literal/input.js @@ -0,0 +1,2 @@ +let a = "hello"; +console.log(`${a} world!`); diff --git a/crates/swc_estree_compat/tests/flavor/acorn/fixtures/template-literal/output.json b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/template-literal/output.json new file mode 100644 index 00000000000..3cd720dbf6e --- /dev/null +++ b/crates/swc_estree_compat/tests/flavor/acorn/fixtures/template-literal/output.json @@ -0,0 +1,157 @@ +{ + "body": [ + { + "declarations": [ + { + "end": 15, + "id": { + "end": 5, + "name": "a", + "range": [ + 4, + 5 + ], + "start": 4, + "type": "Identifier" + }, + "init": { + "end": 15, + "range": [ + 8, + 15 + ], + "raw": "hello", + "start": 8, + "type": "Literal", + "value": "hello" + }, + "range": [ + 4, + 15 + ], + "start": 4, + "type": "VariableDeclarator" + } + ], + "end": 16, + "kind": "let", + "range": [ + 0, + 16 + ], + "start": 0, + "type": "VariableDeclaration" + }, + { + "end": 44, + "expression": { + "arguments": [ + { + "end": 42, + "expressions": [ + { + "end": 33, + "name": "a", + "range": [ + 32, + 33 + ], + "start": 32, + "type": "Identifier" + } + ], + "quasis": [ + { + "end": 30, + "range": [ + 30, + 30 + ], + "start": 30, + "tail": false, + "type": "TemplateElement", + "value": { + "cooked": "", + "raw": "" + } + }, + { + "end": 41, + "range": [ + 34, + 41 + ], + "start": 34, + "tail": true, + "type": "TemplateElement", + "value": { + "cooked": " world!", + "raw": " world!" + } + } + ], + "range": [ + 29, + 42 + ], + "start": 29, + "type": "TemplateLiteral" + } + ], + "callee": { + "computed": false, + "end": 28, + "object": { + "end": 24, + "name": "console", + "range": [ + 17, + 24 + ], + "start": 17, + "type": "Identifier" + }, + "optional": false, + "property": { + "end": 28, + "name": "log", + "range": [ + 25, + 28 + ], + "start": 25, + "type": "Identifier" + }, + "range": [ + 17, + 28 + ], + "start": 17, + "type": "MemberExpression" + }, + "end": 43, + "optional": false, + "range": [ + 17, + 43 + ], + "start": 17, + "type": "CallExpression" + }, + "range": [ + 17, + 44 + ], + "start": 17, + "type": "ExpressionStatement" + } + ], + "end": 44, + "range": [ + 0, + 44 + ], + "sourceType": "script", + "start": 0, + "type": "Program" +} diff --git a/crates/swc_estree_macros/Cargo.toml b/crates/swc_estree_macros/Cargo.toml deleted file mode 100644 index c81f049ae7d..00000000000 --- a/crates/swc_estree_macros/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -authors = ["강동윤 "] -description = "Utility for AST converters" -documentation = "https://rustdoc.swc.rs/swc_estree_macros/" -edition = "2018" -license = "Apache-2.0/MIT" -name = "swc_estree_macros" -repository = "https://github.com/swc-project/swc.git" -version = "0.1.0" - -[lib] -proc-macro = true - -[dependencies] diff --git a/crates/swc_estree_macros/src/lib.rs b/crates/swc_estree_macros/src/lib.rs deleted file mode 100644 index b8d7be179e8..00000000000 --- a/crates/swc_estree_macros/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -extern crate proc_macro; diff --git a/crates/swc_estree_visit/Cargo.toml b/crates/swc_estree_visit/Cargo.toml deleted file mode 100644 index b29ec964aeb..00000000000 --- a/crates/swc_estree_visit/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -authors = ["강동윤 ", "Daniel Woznicki "] -description = "Visitor implementation for estree nodes" -documentation = "https://rustdoc.swc.rs/swc_estree_visit/" -edition = "2018" -license = "Apache-2.0/MIT" -name = "swc_estree_visit" -repository = "https://github.com/swc-project/swc.git" -version = "0.1.0" - -[package.metadata.docs.rs] -all-features = true - -[features] -flavor-acorn = ["swc_estree_ast/flavor-acorn"] -flavor-babel = ["swc_estree_ast/flavor-babel"] - -[dependencies] -serde = {version = "1", features = ["derive"]} -serde_json = "1.0.62" -swc_atoms = {version = "0.2", path = "../swc_atoms"} -swc_estree_ast = {version = "0.1", path = "../swc_estree_ast"} -swc_estree_macros = {version = "0.1", path = "../swc_estree_macros/"} -swc_visit = {version = "0.2", path = "../swc_visit"} diff --git a/crates/swc_estree_visit/README.md b/crates/swc_estree_visit/README.md deleted file mode 100644 index e50c05c20ac..00000000000 --- a/crates/swc_estree_visit/README.md +++ /dev/null @@ -1,24 +0,0 @@ -Visitor pattern implementation for Babel AST. - -### Example - -```rust -// Visit all Identifier nodes in the Babel AST and change the optional field to -// Some(true) for each of them. - -use swc_babel_visit::{VisitMut, VisitMutWith}; -use swc_babel_ast::{Identifier, File}; - -struct Visitor; - -impl VisitMut for Visitor { - fn visit_mut_identifier(&mut self, node: &mut Identifier) { - node.optional = Some(true); - } -} - -let ast: File = get_babel_ast(); -let mut v = Visitor {}; -ast.visit_mut_with(&mut v); -``` - diff --git a/crates/swc_estree_visit/src/lib.rs b/crates/swc_estree_visit/src/lib.rs deleted file mode 100644 index 7e3da54b077..00000000000 --- a/crates/swc_estree_visit/src/lib.rs +++ /dev/null @@ -1,2246 +0,0 @@ -use serde_json::Value; -use std::any::Any; -use swc_atoms::JsWord; -use swc_estree_ast::*; -use swc_visit::define; - -pub trait Node: Any {} - -impl Node for T where T: Any {} - -define!({ - pub enum Class { - Expr(ClassExpression), - Decl(ClassDeclaration), - } - pub enum ClassMethodKind { - Get, - Set, - Method, - Constructor, - } - pub struct ClassMethod { - pub base: BaseNode, - pub kind: Option, - pub key: ObjectKey, - pub params: Vec, - pub body: BlockStatement, - pub computed: Option, - pub is_static: Option, - pub generator: Option, - pub is_async: Option, - pub is_abstract: Option, - pub access: Option, - pub accessibility: Option, - pub decorators: Option>, - pub optional: Option, - pub return_type: Option>, - pub type_parameters: Option, - } - pub struct ClassPrivateProperty { - pub base: BaseNode, - pub key: PrivateName, - pub value: Option>, - pub decorators: Option>, - pub static_any: Value, - pub type_annotation: Option>, - } - pub struct ClassPrivateMethod { - pub base: BaseNode, - pub kind: Option, - pub key: PrivateName, - pub params: Vec, - pub body: BlockStatement, - pub is_static: Option, - pub is_abstract: Option, - pub access: Option, - pub accessibility: Option, - pub is_async: Option, - pub computed: Option, - pub decorators: Option>, - pub generator: Option, - pub optional: Option, - pub return_type: Option>, - pub type_parameters: Option, - } - pub struct ClassProperty { - pub base: BaseNode, - pub key: ObjectKey, - pub value: Option>, - pub type_annotation: Option>, - pub decorators: Option>, - pub computed: Option, - pub is_static: Option, - pub is_abstract: Option, - pub accessibility: Option, - pub declare: Option, - pub definite: Option, - pub optional: Option, - pub readonly: Option, - } - pub struct StaticBlock { - pub base: BaseNode, - pub body: Vec, - } - pub enum ClassBodyEl { - Method(ClassMethod), - PrivateMethod(ClassPrivateMethod), - Prop(ClassProperty), - PrivateProp(ClassPrivateProperty), - TSMethod(TSDeclareMethod), - TSIndex(TSIndexSignature), - StaticBlock(StaticBlock), - } - pub struct ClassBody { - pub base: BaseNode, - pub body: Vec, - } - pub enum ClassImpl { - TSExpr(TSExpressionWithTypeArguments), - Implements(ClassImplements), - } - pub struct ClassDeclaration { - pub base: BaseNode, - pub id: Identifier, - pub super_class: Option>, - pub body: ClassBody, - pub decorators: Option>, - pub is_abstract: Option, - pub declare: Option, - pub implements: Option>, - pub mixins: Option, - pub super_type_parameters: Option, - pub type_parameters: Option, - } - pub struct BaseComment { - pub value: String, - pub start: usize, - pub end: usize, - pub loc: Loc, - } - pub enum Comment { - Block(BaseComment), - Line(BaseComment), - } - pub enum CommentTypeShorthand { - Leading, - Inner, - Trailing, - } - pub struct LineCol { - pub line: usize, - pub column: usize, - } - pub struct Loc { - pub start: LineCol, - pub end: LineCol, - } - pub struct BaseNode { - pub leading_comments: Vec, - pub inner_comments: Vec, - pub trailing_comments: Vec, - pub start: Option, - pub end: Option, - pub loc: Option, - } - pub enum Binary { - BinaryExpr(BinaryExpression), - LogicalExpr(LogicalExpression), - } - pub enum Conditional { - Expr(ConditionalExpression), - If(IfStatement), - } - pub enum EnumBody { - Boolean(EnumBooleanBody), - Number(EnumNumberBody), - String(EnumStringBody), - Symbol(EnumSymbolBody), - } - pub enum EnumMember { - Boolean(EnumBooleanMember), - Number(EnumNumberMember), - String(EnumStringMember), - Defaulted(EnumDefaultedMember), - } - pub enum Function { - Decl(FunctionDeclaration), - Expr(FunctionExpression), - ObjectMethod(ObjectMethod), - Arrow(ArrowFunctionExpression), - ClassMethod(ClassMethod), - ClassPrivateMethod(ClassPrivateMethod), - } - pub enum FunctionParent { - Decl(FunctionDeclaration), - Expr(FunctionExpression), - ObjectMethod(ObjectMethod), - Arrow(ArrowFunctionExpression), - ClassMethod(ClassMethod), - ClassPrivateMethod(ClassPrivateMethod), - } - pub enum Immutable { - StringLiteral(StringLiteral), - NumericLiteral(NumericLiteral), - NullLiteral(NullLiteral), - BooleanLiteral(BooleanLiteral), - BigIntLiteral(BigIntLiteral), - JSXAttribute(JSXAttribute), - JSXClosingElement(JSXClosingElement), - JSXElement(JSXElement), - JSXExpressionContainer(JSXExpressionContainer), - JSXSpreadChild(JSXSpreadChild), - JSXOpeningElement(JSXOpeningElement), - JSXText(JSXText), - JSXFragment(JSXFragment), - JSXOpeningFragment(JSXOpeningFragment), - JSXClosingFragment(JSXClosingFragment), - DecimalLiteral(DecimalLiteral), - } - pub enum Method { - Object(ObjectMethod), - Class(ClassMethod), - ClassPrivate(ClassPrivateMethod), - } - pub enum Private { - ClassProp(ClassPrivateProperty), - ClassMethod(ClassPrivateMethod), - Name(PrivateName), - } - pub enum Property { - ObjectProp(ObjectProperty), - ClassProp(ClassProperty), - ClassPrivateProp(ClassPrivateProperty), - } - pub enum Pureish { - FunctionDecl(FunctionDeclaration), - FunctionExpr(FunctionExpression), - StringLiteral(StringLiteral), - NumericLiteral(NumericLiteral), - NullLiteral(NullLiteral), - BooleanLiteral(BooleanLiteral), - RegExpLiteral(RegExpLiteral), - ArrowFuncExpr(ArrowFunctionExpression), - BigIntLiteral(BigIntLiteral), - DecimalLiteral(DecimalLiteral), - } - pub enum Scopable { - BlockStmt(BlockStatement), - CatchClause(CatchClause), - DoWhileStmt(DoWhileStatement), - ForInStmt(ForInStatement), - ForStmt(ForStatement), - FuncDecl(FunctionDeclaration), - FuncExpr(FunctionExpression), - Program(Program), - ObjectMethod(ObjectMethod), - SwitchStmt(SwitchStatement), - WhileStmt(WhileStatement), - ArrowFuncExpr(ArrowFunctionExpression), - ClassExpr(ClassExpression), - ClassDecl(ClassDeclaration), - ForOfStmt(ForOfStatement), - ClassMethod(ClassMethod), - ClassPrivateMethod(ClassPrivateMethod), - StaticBlock(StaticBlock), - TSModuleBlock(TSModuleBlock), - } - pub enum BlockParent { - BlockStmt(BlockStatement), - CatchClause(CatchClause), - DoWhileStmt(DoWhileStatement), - ForInStmt(ForInStatement), - ForStmt(ForStatement), - FuncDecl(FunctionDeclaration), - FuncExpr(FunctionExpression), - Program(Program), - ObjectMethod(ObjectMethod), - SwitchStmt(SwitchStatement), - WhileStmt(WhileStatement), - ArrowFuncExpr(ArrowFunctionExpression), - ForOfStmt(ForOfStatement), - ClassMethod(ClassMethod), - ClassPrivateMethod(ClassPrivateMethod), - StaticBlock(StaticBlock), - TSModuleBlock(TSModuleBlock), - } - pub enum Block { - BlockStmt(BlockStatement), - Program(Program), - TSModuleBlock(TSModuleBlock), - } - pub enum Terminatorless { - Break(BreakStatement), - Continue(ContinueStatement), - Return(ReturnStatement), - Throw(ThrowStatement), - Yield(YieldExpression), - Await(AwaitExpression), - } - pub enum UnaryLike { - Expr(UnaryExpression), - Spread(SpreadElement), - } - pub struct SpreadElement { - pub base: BaseNode, - pub argument: Box, - } - pub struct SpreadProperty { - pub base: BaseNode, - pub argument: Box, - } - pub struct RestElement { - pub base: BaseNode, - pub argument: Box, - pub decorators: Option>, - pub type_annotation: Option>, - } - pub struct RestProperty { - pub base: BaseNode, - pub argument: LVal, - pub decorators: Option>, - pub type_annotation: Option>, - } - pub struct Identifier { - pub base: BaseNode, - pub name: JsWord, - pub decorators: Option>, - pub optional: Option, - pub type_annotation: Option>, - } - pub enum IdOrQualifiedId { - Id(Identifier), - QualifiedId(QualifiedTypeIdentifier), - } - pub enum IdOrString { - Id(Identifier), - String(StringLiteral), - } - pub enum IdOrRest { - Id(Identifier), - Rest(RestElement), - } - pub struct Decorator { - pub base: BaseNode, - pub expression: Box, - } - pub struct Noop { - pub base: BaseNode, - } - pub enum Param { - Id(Identifier), - Pat(Pattern), - Rest(RestElement), - TSProp(TSParameterProperty), - } - pub enum LVal { - Id(Identifier), - MemberExpr(MemberExpression), - RestEl(RestElement), - AssignmentPat(AssignmentPattern), - ArrayPat(ArrayPattern), - ObjectPat(ObjectPattern), - TSParamProp(TSParameterProperty), - } - pub enum PatternLike { - Id(Identifier), - RestEl(RestElement), - AssignmentPat(AssignmentPattern), - ArrayPat(ArrayPattern), - ObjectPat(ObjectPattern), - } - pub enum TypeAnnotOrNoop { - Flow(TypeAnnotation), - TS(Box), - Noop(Noop), - } - pub enum TypeParamDeclOrNoop { - Flow(TypeParameterDeclaration), - TS(TSTypeParameterDeclaration), - Noop(Noop), - } - pub enum SuperTypeParams { - Flow(TypeParameterInstantiation), - TS(TSTypeParameterInstantiation), - } - pub struct PrivateName { - pub base: BaseNode, - pub id: Identifier, - } - pub enum Access { - Public, - Private, - Protected, - } - pub struct MetaProperty { - pub base: BaseNode, - pub meta: Identifier, - pub property: Identifier, - } - pub struct Directive { - pub base: BaseNode, - pub value: DirectiveLiteral, - } - pub struct DirectiveLiteral { - pub base: BaseNode, - pub value: JsWord, - } - pub struct PipelineBareFunction { - pub base: BaseNode, - pub callee: Box, - } - pub struct PipelineTopicExpression { - pub base: BaseNode, - pub expression: Box, - } - pub enum PlaceholderExpectedNode { - Identifier, - StringLiteral, - Expression, - Statement, - Declaration, - BlockStatement, - ClassBody, - Pattern, - } - pub struct Placeholder { - pub base: BaseNode, - pub expected_node: PlaceholderExpectedNode, - pub name: Identifier, - } - pub enum Declaration { - FuncDecl(FunctionDeclaration), - VarDecl(VariableDeclaration), - ClassDecl(ClassDeclaration), - ExportAllDecl(ExportAllDeclaration), - ExportDefaultDecl(ExportDefaultDeclaration), - ExportNamedDecl(ExportNamedDeclaration), - ImportDecl(ImportDeclaration), - DeclClass(DeclareClass), - DeclFunc(DeclareFunction), - DeclInterface(DeclareInterface), - DeclModule(DeclareModule), - DeclModuleExports(DeclareModuleExports), - DeclTypeAlias(DeclareTypeAlias), - DeclOpaqueType(DeclareOpaqueType), - DeclVar(DeclareVariable), - DeclExportDecl(DeclareExportDeclaration), - DeclExportAllDecl(DeclareExportAllDeclaration), - InterfaceDecl(InterfaceDeclaration), - OpaqueType(OpaqueType), - TypeAlias(TypeAlias), - EnumDecl(EnumDeclaration), - TSDeclFunc(TSDeclareFunction), - TSInterfaceDecl(TSInterfaceDeclaration), - TSTypeAliasDecl(TSTypeAliasDeclaration), - TSEnumDecl(TSEnumDeclaration), - TSModuleDecl(TSModuleDeclaration), - } - pub enum VariableDeclarationKind { - Var, - Let, - Const, - } - pub struct VariableDeclarator { - pub base: BaseNode, - pub id: LVal, - pub init: Option>, - pub definite: Option, - } - pub struct VariableDeclaration { - pub base: BaseNode, - pub kind: VariableDeclarationKind, - pub declarations: Vec, - pub declare: Option, - } - pub struct FunctionDeclaration { - pub base: BaseNode, - pub id: Option, - pub params: Vec, - pub body: BlockStatement, - pub generator: Option, - pub is_async: Option, - pub return_type: Option>, - pub type_parameters: Option, - } - pub struct EnumBooleanMember { - pub base: BaseNode, - pub id: Identifier, - pub init: BooleanLiteral, - } - pub struct EnumNumberMember { - pub base: BaseNode, - pub id: Identifier, - pub init: NumericLiteral, - } - pub struct EnumStringMember { - pub base: BaseNode, - pub id: Identifier, - pub init: StringLiteral, - } - pub enum EnumStringBodyMember { - String(EnumStringMember), - Defaulted(EnumDefaultedMember), - } - pub struct EnumDefaultedMember { - pub base: BaseNode, - pub id: Identifier, - } - pub struct EnumBooleanBody { - pub base: BaseNode, - pub members: Vec, - pub explicit_type: bool, - pub has_unknown_members: bool, - } - pub struct EnumNumberBody { - pub base: BaseNode, - pub members: Vec, - pub explicit_type: bool, - pub has_unknown_members: bool, - } - pub struct EnumStringBody { - pub base: BaseNode, - pub members: Vec, - pub explicit_type: bool, - pub has_unknown_members: bool, - } - pub struct EnumSymbolBody { - pub base: BaseNode, - pub members: Vec, - pub has_unknown_members: bool, - } - pub enum EnumBody { - Boolean(EnumBooleanBody), - Number(EnumNumberBody), - String(EnumStringBody), - Symbol(EnumSymbolBody), - } - pub struct EnumDeclaration { - pub base: BaseNode, - pub id: Identifier, - pub body: EnumBody, - } - pub enum Expression { - Array(ArrayExpression), - Assignment(AssignmentExpression), - Binary(BinaryExpression), - Call(CallExpression), - Conditional(ConditionalExpression), - Func(FunctionExpression), - Id(Identifier), - StringLiteral(StringLiteral), - NumericLiteral(NumericLiteral), - NullLiteral(NullLiteral), - BooleanLiteral(BooleanLiteral), - RegExpLiteral(RegExpLiteral), - Logical(LogicalExpression), - Member(MemberExpression), - New(NewExpression), - Object(ObjectExpression), - Sequence(SequenceExpression), - Parenthesized(ParenthesizedExpression), - This(ThisExpression), - Unary(UnaryExpression), - Update(UpdateExpression), - ArrowFunc(ArrowFunctionExpression), - Class(ClassExpression), - MetaProp(MetaProperty), - Super(Super), - TaggedTemplate(TaggedTemplateExpression), - TemplateLiteral(TemplateLiteral), - Yield(YieldExpression), - Await(AwaitExpression), - Import(Import), - BigIntLiteral(BigIntLiteral), - OptionalMember(OptionalMemberExpression), - OptionalCall(OptionalCallExpression), - TypeCast(TypeCastExpression), - JSXElement(JSXElement), - JSXFragment(JSXFragment), - Bind(BindExpression), - PipelinePrimaryTopicRef(PipelinePrimaryTopicReference), - Do(DoExpression), - Record(RecordExpression), - Tuple(TupleExpression), - DecimalLiteral(DecimalLiteral), - Module(ModuleExpression), - TSAs(TSAsExpression), - TSTypeAssertion(TSTypeAssertion), - TSNonNull(TSNonNullExpression), - } - pub enum ExpressionWrapper { - Stmt(ExpressionStatement), - Parenthesized(ParenthesizedExpression), - TypeCast(TypeCastExpression), - } - pub enum ArrayExprEl { - Expr(Box), - Spread(SpreadElement), - } - pub struct ArrayExpression { - pub base: BaseNode, - pub elements: Vec>, - } - pub struct AssignmentExpression { - pub base: BaseNode, - pub operator: JsWord, - pub left: Box, - pub right: Box, - } - pub enum MemberExprProp { - Expr(Box), - Id(Identifier), - PrivateName(PrivateName), - } - pub struct MemberExpression { - pub base: BaseNode, - pub object: Box, - pub property: Box, - pub computed: bool, - pub optional: Option, - } - pub enum BinaryExprOp { - Addition, - Subtraction, - Division, - Remainder, - Multiplication, - Exponentiation, - And, - Or, - RightShift, - UnsignedRightShift, - LeftShift, - Xor, - Equal, - StrictEqual, - NotEqual, - StrictNotEqual, - In, - Instanceof, - GreaterThan, - LessThan, - GreaterThanOrEqual, - LessThanOrEqual, - } - pub enum BinaryExprLeft { - Expr(Box), - Private(PrivateName), - } - pub struct BinaryExpression { - pub base: BaseNode, - pub operator: BinaryExprOp, - pub left: Box, - pub right: Box, - } - pub struct V8IntrinsicIdentifier { - pub base: BaseNode, - pub name: JsWord, - } - pub enum Callee { - Expr(Box), - V8Id(V8IntrinsicIdentifier), - } - pub struct ArgumentPlaceholder { - pub base: BaseNode, - } - pub enum Arg { - Expr(Box), - Spread(SpreadElement), - JSXName(JSXNamespacedName), - Placeholder(ArgumentPlaceholder), - } - pub struct CallExpression { - pub base: BaseNode, - pub callee: Box, - pub arguments: Vec, - pub optional: Option, - pub type_arguments: Option, - pub type_parameters: Option, - } - pub struct ConditionalExpression { - pub base: BaseNode, - pub test: Box, - pub consequent: Box, - pub alternate: Box, - } - pub struct FunctionExpression { - pub base: BaseNode, - pub id: Option, - pub params: Vec, - pub body: BlockStatement, - pub generator: Option, - pub is_async: Option, - pub return_type: Option>, - pub type_parameters: Option, - } - pub struct NewExpression { - pub base: BaseNode, - pub callee: Callee, - pub arguments: Vec, - pub optional: Option, - pub type_arguments: Option, - pub type_parameters: Option, - } - pub enum LogicalExprOp { - Or, - And, - Nullish, - } - pub struct LogicalExpression { - pub base: BaseNode, - pub operator: LogicalExprOp, - pub left: Box, - pub right: Box, - } - pub enum ObjectExprProp { - Method(ObjectMethod), - Prop(ObjectProperty), - Spread(SpreadElement), - } - pub struct ObjectExpression { - pub base: BaseNode, - pub properties: Vec, - } - pub struct SequenceExpression { - pub base: BaseNode, - pub expressions: Vec>, - } - pub struct ParenthesizedExpression { - pub base: BaseNode, - pub expression: Box, - } - pub struct ThisExpression { - pub base: BaseNode, - } - pub enum UnaryExprOp { - Void, - Throw, - Delete, - LogicalNot, - Plus, - Negation, - BitwiseNot, - Typeof, - } - pub struct UnaryExpression { - pub base: BaseNode, - pub operator: UnaryExprOp, - pub argument: Box, - pub prefix: bool, - } - pub enum UpdateExprOp { - Increment, - Decrement, - } - pub struct UpdateExpression { - pub base: BaseNode, - pub operator: UpdateExprOp, - pub argument: Box, - pub prefix: bool, - } - pub enum ArrowFuncExprBody { - Block(BlockStatement), - Expr(Box), - } - pub struct ArrowFunctionExpression { - pub base: BaseNode, - pub params: Vec, - pub body: Box, - pub is_async: bool, - pub expression: bool, - pub generator: bool, - pub return_type: Option>, - pub type_parameters: Option, - } - pub struct ClassExpression { - pub base: BaseNode, - pub id: Option, - pub super_class: Option>, - pub body: ClassBody, - pub decorators: Option>, - pub implements: Option>, - pub mixins: Option, - pub super_type_parameters: Option, - pub type_parameters: Option, - } - pub enum TaggedTemplateExprTypeParams { - Flow(TypeParameterDeclaration), - TS(TSTypeParameterInstantiation), - } - pub struct TaggedTemplateExpression { - pub base: BaseNode, - pub tag: Box, - pub quasi: TemplateLiteral, - pub type_parameters: Option, - } - pub struct YieldExpression { - pub base: BaseNode, - pub argument: Option>, - pub delegate: bool, - } - pub struct AwaitExpression { - pub base: BaseNode, - pub argument: Box, - } - pub enum OptionalMemberExprProp { - Expr(Box), - Id(Identifier), - } - pub struct OptionalMemberExpression { - pub base: BaseNode, - pub object: Box, - pub property: OptionalMemberExprProp, - pub computed: bool, - pub optional: bool, - } - pub struct OptionalCallExpression { - pub base: BaseNode, - pub callee: Box, - pub arguments: Vec, - pub optional: bool, - pub type_arguments: Option, - pub type_parameters: Option, - } - pub struct TypeCastExpression { - pub base: BaseNode, - pub expression: Box, - pub type_annotation: TypeAnnotation, - } - pub struct BindExpression { - pub base: BaseNode, - pub object: Box, - pub callee: Box, - } - pub struct PipelinePrimaryTopicReference { - pub base: BaseNode, - } - pub struct DoExpression { - pub base: BaseNode, - pub body: BlockStatement, - } - pub enum RecordExprProp { - Prop(ObjectProperty), - Spread(SpreadElement), - } - pub struct RecordExpression { - pub base: BaseNode, - pub properties: Vec, - } - pub enum TupleExprEl { - Expr(Box), - Spread(SpreadElement), - } - pub struct TupleExpression { - pub base: BaseNode, - pub elements: Vec, - } - pub struct ModuleExpression { - pub base: BaseNode, - pub body: Program, - } - pub struct Super { - pub base: BaseNode, - } - pub enum Flow { - AnyTypeAnnotation(AnyTypeAnnotation), - ArrayTypeAnnotation(ArrayTypeAnnotation), - BooleanTypeAnnotation(BooleanTypeAnnotation), - BooleanLiteralTypeAnnotation(BooleanLiteralTypeAnnotation), - NullLiteralTypeAnnotation(NullLiteralTypeAnnotation), - ClassImplements(ClassImplements), - DeclareClass(DeclareClass), - DeclareFunction(DeclareFunction), - DeclareInterface(DeclareInterface), - DeclareModule(DeclareModule), - DeclareModuleExports(DeclareModuleExports), - DeclareTypeAlias(DeclareTypeAlias), - DeclareOpaqueType(DeclareOpaqueType), - DeclareVariable(DeclareVariable), - DeclareExportDeclaration(DeclareExportDeclaration), - DeclareExportAllDeclaration(DeclareExportAllDeclaration), - DeclaredPredicate(DeclaredPredicate), - ExistsTypeAnnotation(ExistsTypeAnnotation), - FunctionTypeAnnotation(FunctionTypeAnnotation), - FunctionTypeParam(FunctionTypeParam), - GenericTypeAnnotation(GenericTypeAnnotation), - InferredPredicate(InferredPredicate), - InterfaceExtends(InterfaceExtends), - InterfaceDeclaration(InterfaceDeclaration), - InterfaceTypeAnnotation(InterfaceTypeAnnotation), - IntersectionTypeAnnotation(IntersectionTypeAnnotation), - MixedTypeAnnotation(MixedTypeAnnotation), - EmptyTypeAnnotation(EmptyTypeAnnotation), - NullableTypeAnnotation(NullableTypeAnnotation), - NumberLiteralTypeAnnotation(NumberLiteralTypeAnnotation), - NumberTypeAnnotation(NumberTypeAnnotation), - ObjectTypeAnnotation(ObjectTypeAnnotation), - ObjectTypeInternalSlot(ObjectTypeInternalSlot), - ObjectTypeCallProperty(ObjectTypeCallProperty), - ObjectTypeIndexer(ObjectTypeIndexer), - ObjectTypeProperty(ObjectTypeProperty), - ObjectTypeSpreadProperty(ObjectTypeSpreadProperty), - OpaqueType(OpaqueType), - QualifiedTypeIdentifier(QualifiedTypeIdentifier), - StringLiteralTypeAnnotation(StringLiteralTypeAnnotation), - StringTypeAnnotation(StringTypeAnnotation), - SymbolTypeAnnotation(SymbolTypeAnnotation), - ThisTypeAnnotation(ThisTypeAnnotation), - TupleTypeAnnotation(TupleTypeAnnotation), - TypeofTypeAnnotation(TypeofTypeAnnotation), - TypeAlias(TypeAlias), - TypeAnnotation(TypeAnnotation), - TypeCastExpression(TypeCastExpression), - TypeParameter(TypeParameter), - TypeParameterDeclaration(TypeParameterDeclaration), - TypeParameterInstantiation(TypeParameterInstantiation), - UnionTypeAnnotation(UnionTypeAnnotation), - Variance(Variance), - VoidTypeAnnotation(VoidTypeAnnotation), - } - pub enum FlowType { - Any(AnyTypeAnnotation), - Array(ArrayTypeAnnotation), - Boolean(BooleanTypeAnnotation), - BooleanLiteral(BooleanLiteralTypeAnnotation), - NullLiteral(NullLiteralTypeAnnotation), - Exists(ExistsTypeAnnotation), - Function(FunctionTypeAnnotation), - Generic(GenericTypeAnnotation), - Interface(InterfaceTypeAnnotation), - Intersection(IntersectionTypeAnnotation), - Mixed(MixedTypeAnnotation), - Empty(EmptyTypeAnnotation), - Nullable(NullableTypeAnnotation), - NumerLiteral(NumberLiteralTypeAnnotation), - Number(NumberTypeAnnotation), - Object(ObjectTypeAnnotation), - StringLiteral(StringLiteralTypeAnnotation), - String(StringTypeAnnotation), - Symbol(SymbolTypeAnnotation), - This(ThisTypeAnnotation), - Tuple(TupleTypeAnnotation), - Typeof(TypeofTypeAnnotation), - Union(UnionTypeAnnotation), - Void(VoidTypeAnnotation), - } - pub enum FlowBaseAnnotation { - Any(AnyTypeAnnotation), - Boolean(BooleanTypeAnnotation), - NullLiteral(NullLiteralTypeAnnotation), - Mixed(MixedTypeAnnotation), - Empty(EmptyTypeAnnotation), - Number(NumberTypeAnnotation), - String(StringTypeAnnotation), - Symbol(SymbolTypeAnnotation), - This(ThisTypeAnnotation), - Void(VoidTypeAnnotation), - } - pub enum FlowDeclaration { - Class(DeclareClass), - Func(DeclareFunction), - Interface(DeclareInterface), - Module(DeclareModule), - ModuleExports(DeclareModuleExports), - DeclareTypeAlias(DeclareTypeAlias), - DeclareOpaqueType(DeclareOpaqueType), - Var(DeclareVariable), - ExportDecl(DeclareExportDeclaration), - ExportAllDecl(DeclareExportAllDeclaration), - InterfaceDeclaration(InterfaceDeclaration), - OpaqueType(OpaqueType), - TypeAlias(TypeAlias), - } - pub enum FlowPredicate { - DeclaredPredicate(DeclaredPredicate), - InferredPredicate(InferredPredicate), - } - pub struct TypeAnnotation { - pub base: BaseNode, - pub type_annotation: FlowType, - } - pub struct AnyTypeAnnotation { - pub base: BaseNode, - } - pub struct ArrayTypeAnnotation { - pub base: BaseNode, - pub element_type: Box, - } - pub struct BooleanTypeAnnotation { - pub base: BaseNode, - } - pub struct BooleanLiteralTypeAnnotation { - pub base: BaseNode, - pub value: bool, - } - pub struct NullLiteralTypeAnnotation { - pub base: BaseNode, - } - pub struct ExistsTypeAnnotation { - pub base: BaseNode, - } - pub struct FunctionTypeParam { - pub base: BaseNode, - pub name: Option, - pub type_annotation: Box, - pub optional: Option, - } - pub struct FunctionTypeAnnotation { - pub base: BaseNode, - pub type_parameters: Option, - pub params: Vec, - pub rest: Option>, - pub return_type: Box, - pub optional: Option, - } - pub struct TypeParameterDeclaration { - pub base: BaseNode, - pub params: Vec, - } - pub enum PlusOrMinus { - Plus, - Minus, - } - pub struct Variance { - pub base: BaseNode, - pub kind: PlusOrMinus, - } - pub struct TypeParameter { - pub base: BaseNode, - pub bound: Option, - pub default: Option, - pub variance: Option, - pub name: JsWord, - } - pub struct TypeParameterInstantiation { - pub base: BaseNode, - pub params: Vec, - } - pub struct GenericTypeAnnotation { - pub base: BaseNode, - pub id: IdOrQualifiedId, - pub type_parameters: Option, - } - pub struct InterfaceExtends { - pub base: BaseNode, - pub id: IdOrQualifiedId, - pub type_parameters: Option, - } - pub enum ObjectTypePropKind { - Init, - Get, - Set, - } - pub struct ObjectTypeProperty { - pub base: BaseNode, - pub key: IdOrString, - pub value: FlowType, - pub variance: Option, - pub kind: ObjectTypePropKind, - pub method: bool, - pub optional: bool, - pub proto: bool, - pub is_static: bool, - } - pub struct ObjectTypeSpreadProperty { - pub base: BaseNode, - pub argument: FlowType, - } - pub enum ObjectTypeAnnotProp { - Prop(ObjectTypeProperty), - Spread(ObjectTypeSpreadProperty), - } - pub struct ObjectTypeIndexer { - pub base: BaseNode, - pub id: Option, - pub key: FlowType, - pub value: FlowType, - pub variance: Option, - pub is_static: bool, - } - pub struct ObjectTypeCallProperty { - pub base: BaseNode, - pub value: FlowType, - pub is_static: bool, - } - pub struct ObjectTypeInternalSlot { - pub base: BaseNode, - pub id: Identifier, - pub value: FlowType, - pub optional: bool, - pub is_static: bool, - pub method: bool, - } - pub struct ObjectTypeAnnotation { - pub base: BaseNode, - pub properties: Vec, - pub indexers: Option>, - pub call_properties: Option>, - pub internal_slots: Option>, - pub exact: bool, - pub inexact: Option, - } - pub struct InterfaceTypeAnnotation { - pub base: BaseNode, - pub extends: Option>, - pub body: ObjectTypeAnnotation, - } - pub struct IntersectionTypeAnnotation { - pub base: BaseNode, - pub types: Vec, - } - pub struct MixedTypeAnnotation { - pub base: BaseNode, - } - pub struct EmptyTypeAnnotation { - pub base: BaseNode, - } - pub struct NullableTypeAnnotation { - pub base: BaseNode, - pub type_annotation: Box, - } - pub struct NumberLiteralTypeAnnotation { - pub base: BaseNode, - pub value: f64, - } - pub struct NumberTypeAnnotation { - pub base: BaseNode, - } - pub struct StringLiteralTypeAnnotation { - pub base: BaseNode, - pub value: JsWord, - } - pub struct StringTypeAnnotation { - pub base: BaseNode, - } - pub struct SymbolTypeAnnotation { - pub base: BaseNode, - } - pub struct ThisTypeAnnotation { - pub base: BaseNode, - } - pub struct TupleTypeAnnotation { - pub base: BaseNode, - pub types: Vec, - } - pub struct TypeofTypeAnnotation { - pub base: BaseNode, - pub argument: Box, - } - pub struct UnionTypeAnnotation { - pub base: BaseNode, - pub types: Vec, - } - pub struct VoidTypeAnnotation { - pub base: BaseNode, - } - pub struct OpaqueType { - pub base: BaseNode, - pub id: Identifier, - pub type_parameters: Option, - pub supertype: Option, - pub impltype: FlowType, - } - pub struct DeclareOpaqueType { - pub base: BaseNode, - pub id: Identifier, - pub type_parameters: Option, - pub supertype: Option, - } - pub struct TypeAlias { - pub base: BaseNode, - pub id: Identifier, - pub type_parameters: Option, - pub right: FlowType, - } - pub struct ClassImplements { - pub base: BaseNode, - pub id: Identifier, - pub type_parameters: Option, - } - pub struct DeclareClass { - pub base: BaseNode, - pub id: Identifier, - pub type_parameters: Option, - pub extends: Option>, - pub body: ObjectTypeAnnotation, - pub implements: Option>, - pub mixins: Option>, - } - pub struct DeclareFunction { - pub base: BaseNode, - pub id: Identifier, - pub predicate: Option>, - } - pub struct DeclareInterface { - pub base: BaseNode, - pub id: Identifier, - pub type_parameters: Option, - pub extends: Option>, - pub body: ObjectTypeAnnotation, - pub implements: Option>, - pub mixins: Option>, - } - pub enum ModuleKind { - CommonJs, - Es, - } - pub struct DeclareModule { - pub base: BaseNode, - pub id: IdOrString, - pub body: BlockStatement, - pub kind: Option, - } - pub struct DeclareModuleExports { - pub base: BaseNode, - pub type_annotation: TypeAnnotation, - } - pub struct DeclareTypeAlias { - pub base: BaseNode, - pub id: Identifier, - pub type_parameters: Option, - pub right: FlowType, - } - pub struct DeclareVariable { - pub base: BaseNode, - pub id: Identifier, - } - pub enum DeclareExportDeclSpecifier { - Export(ExportSpecifier), - Namespace(ExportNamespaceSpecifier), - } - pub struct DeclareExportDeclaration { - pub base: BaseNode, - pub declaration: Option>, - pub specifiers: Option>, - pub source: Option, - pub default: Option, - } - pub struct DeclareExportAllDeclaration { - pub base: BaseNode, - pub source: StringLiteral, - pub export_kind: Option, - } - pub struct DeclaredPredicate { - pub base: BaseNode, - pub value: Box, - } - pub struct InferredPredicate { - pub base: BaseNode, - } - pub struct InterfaceDeclaration { - pub base: BaseNode, - pub id: Identifier, - pub type_parameters: Option, - pub extends: Option>, - pub body: ObjectTypeAnnotation, - pub implements: Option>, - pub mixins: Option>, - } - pub struct QualifiedTypeIdentifier { - pub base: BaseNode, - pub id: Identifier, - pub qualification: Box, - } - pub enum JSX { - Attr(JSXAttribute), - ClosingEl(JSXClosingElement), - El(JSXElement), - EmptyExpr(JSXEmptyExpression), - ExprContainer(JSXExpressionContainer), - SpreadChild(JSXSpreadChild), - Id(JSXIdentifier), - MemberExpr(JSXMemberExpression), - NamespacedName(JSXNamespacedName), - OpeningEl(JSXOpeningElement), - SpreadAttr(JSXSpreadAttribute), - Text(JSXText), - Fragment(JSXFragment), - OpeningFragment(JSXOpeningFragment), - ClosingFragment(JSXClosingFragment), - } - pub enum JSXAttrName { - Id(JSXIdentifier), - Name(JSXNamespacedName), - } - pub enum JSXAttrVal { - Element(JSXElement), - Fragment(JSXFragment), - String(StringLiteral), - Expr(JSXExpressionContainer), - } - pub struct JSXAttribute { - pub base: BaseNode, - pub name: JSXAttrName, - pub value: Option, - } - pub struct JSXClosingElement { - pub base: BaseNode, - pub name: JSXElementName, - } - pub struct JSXElement { - pub base: BaseNode, - pub opening_element: JSXOpeningElement, - pub closing_element: Option, - pub children: Vec, - pub self_closing: Option, - } - pub struct JSXEmptyExpression { - pub base: BaseNode, - } - pub enum JSXExprContainerExpr { - Expr(Box), - Empty(JSXEmptyExpression), - } - pub struct JSXExpressionContainer { - pub base: BaseNode, - pub expression: JSXExprContainerExpr, - } - pub struct JSXSpreadChild { - pub base: BaseNode, - pub expression: Box, - } - pub struct JSXIdentifier { - pub base: BaseNode, - pub name: JsWord, - } - pub enum JSXMemberExprObject { - Expr(JSXMemberExpression), - Id(JSXIdentifier), - } - pub struct JSXMemberExpression { - pub base: BaseNode, - pub object: Box, - pub property: JSXIdentifier, - } - pub struct JSXNamespacedName { - pub base: BaseNode, - pub namespace: JSXIdentifier, - pub name: JSXIdentifier, - } - pub enum JSXOpeningElAttr { - Attr(JSXAttribute), - Spread(JSXSpreadAttribute), - } - pub struct JSXOpeningElement { - pub base: BaseNode, - pub name: JSXElementName, - pub attributes: Vec, - pub self_closing: bool, - pub type_parameters: Option, - } - pub struct JSXSpreadAttribute { - pub base: BaseNode, - pub argument: Box, - } - pub struct JSXText { - pub base: BaseNode, - pub value: JsWord, - } - pub struct JSXFragment { - pub base: BaseNode, - pub opening_fragment: JSXOpeningFragment, - pub closing_fragment: JSXClosingFragment, - pub children: Vec, - } - pub struct JSXOpeningFragment { - pub base: BaseNode, - } - pub struct JSXClosingFragment { - pub base: BaseNode, - } - pub enum JSXElementName { - Id(JSXIdentifier), - Expr(JSXMemberExpression), - Name(JSXNamespacedName), - } - pub enum JSXElementChild { - Text(JSXText), - Expr(JSXExpressionContainer), - Spread(JSXSpreadChild), - Element(JSXElement), - Fragment(JSXFragment), - } - pub enum Literal { - String(StringLiteral), - Numeric(NumericLiteral), - Null(NullLiteral), - Boolean(BooleanLiteral), - RegExp(RegExpLiteral), - Template(TemplateLiteral), - BigInt(BigIntLiteral), - Decimal(DecimalLiteral), - } - pub struct StringLiteral { - pub base: BaseNode, - pub value: JsWord, - } - pub struct NumericLiteral { - pub base: BaseNode, - pub value: f64, - } - pub struct NumberLiteral { - pub base: BaseNode, - pub value: f64, - } - pub struct NullLiteral { - pub base: BaseNode, - } - pub struct BooleanLiteral { - pub base: BaseNode, - pub value: bool, - } - pub struct RegExpLiteral { - pub base: BaseNode, - pub pattern: JsWord, - pub flags: JsWord, - } - pub struct RegexLiteral { - pub base: BaseNode, - pub pattern: JsWord, - pub flags: JsWord, - } - pub struct TemplateElVal { - pub raw: JsWord, - pub cooked: Option, - } - pub struct TemplateElement { - pub base: BaseNode, - pub value: TemplateElVal, - pub tail: bool, - } - pub enum TemplateLiteralExpr { - Expr(Box), - TSType(TSType), - } - pub struct TemplateLiteral { - pub base: BaseNode, - pub quasis: Vec, - pub expressions: Vec, - } - pub struct BigIntLiteral { - pub base: BaseNode, - pub value: String, - } - pub struct DecimalLiteral { - pub base: BaseNode, - pub value: JsWord, - } - pub enum ModuleDeclaration { - ExportAll(ExportAllDeclaration), - ExportDefault(ExportDefaultDeclaration), - ExportNamed(ExportNamedDeclaration), - Import(ImportDeclaration), - } - pub enum ExportDeclaration { - ExportAll(ExportAllDeclaration), - ExportDefault(ExportDefaultDeclaration), - ExportNamed(ExportNamedDeclaration), - } - pub enum ModuleSpecifier { - Export(ExportSpecifier), - ImportDefault(ImportDefaultSpecifier), - ImportNamespace(ImportNamespaceSpecifier), - Import(ImportSpecifier), - ExportNamespace(ExportNamespaceSpecifier), - ExportDefault(ExportDefaultSpecifier), - } - pub struct File { - pub base: BaseNode, - pub program: Program, - pub comments: Option>, - pub tokens: Option>, - } - pub struct InterpreterDirective { - pub base: BaseNode, - pub value: JsWord, - } - pub enum SrcType { - Script, - Module, - } - pub struct Program { - pub base: BaseNode, - pub body: Vec, - pub directives: Vec, - pub source_type: SrcType, - pub interpreter: Option, - pub source_file: String, - } - pub enum ExportKind { - Type, - Value, - } - pub struct ExportSpecifier { - pub base: BaseNode, - pub local: Identifier, - pub exported: IdOrString, - pub export_kind: ExportKind, - } - pub struct ExportDefaultSpecifier { - pub base: BaseNode, - pub exported: Identifier, - } - pub struct ExportNamespaceSpecifier { - pub base: BaseNode, - pub exported: Identifier, - } - pub struct ExportAllDeclaration { - pub base: BaseNode, - pub source: StringLiteral, - pub assertions: Option>, - pub export_kind: Option, - } - pub enum ExportDefaultDeclType { - Func(FunctionDeclaration), - TSFunc(TSDeclareFunction), - Class(ClassDeclaration), - Expr(Box), - } - pub struct ExportDefaultDeclaration { - pub base: BaseNode, - pub declaration: ExportDefaultDeclType, - } - pub enum ExportSpecifierType { - Export(ExportSpecifier), - Default(ExportDefaultSpecifier), - Namespace(ExportNamespaceSpecifier), - } - pub struct ExportNamedDeclaration { - pub base: BaseNode, - pub declaration: Option>, - pub specifiers: Vec, - pub source: Option, - pub assertions: Option>, - pub export_kind: Option, - } - pub struct Import { - pub base: BaseNode, - } - pub struct ImportAttribute { - pub base: BaseNode, - pub key: IdOrString, - pub value: StringLiteral, - } - pub struct ImportSpecifier { - pub base: BaseNode, - pub local: Identifier, - pub imported: IdOrString, - pub import_kind: Option, - } - pub struct ImportDefaultSpecifier { - pub base: BaseNode, - pub local: Identifier, - } - pub struct ImportNamespaceSpecifier { - pub base: BaseNode, - pub local: Identifier, - } - pub enum ImportSpecifierType { - Import(ImportSpecifier), - Default(ImportDefaultSpecifier), - Namespace(ImportNamespaceSpecifier), - } - pub enum ImportKind { - Type, - Typeof, - Value, - } - pub struct ImportDeclaration { - pub base: BaseNode, - pub specifiers: Vec, - pub source: StringLiteral, - pub assertions: Option>, - pub import_kind: Option, - } - pub enum UserWhitespacable { - ObjectMethod(ObjectMethod), - ObjectProperty(ObjectProperty), - ObjectTypeInternalSlot(ObjectTypeInternalSlot), - ObjectTypeCallProperty(ObjectTypeCallProperty), - ObjectTypeIndexer(ObjectTypeIndexer), - ObjectTypeProperty(ObjectTypeProperty), - ObjectTypeSpreadProperty(ObjectTypeSpreadProperty), - } - pub enum ObjectMember { - Method(ObjectMethod), - Prop(ObjectProperty), - } - pub enum ObjectMethodKind { - Method, - Get, - Set, - } - pub enum ObjectKey { - Expr(Box), - Id(Identifier), - String(StringLiteral), - Numeric(NumericLiteral), - } - pub struct ObjectMethod { - pub base: BaseNode, - pub kind: ObjectMethodKind, - pub key: ObjectKey, - pub params: Vec, - pub body: BlockStatement, - pub computed: bool, - pub generator: Option, - pub is_async: Option, - pub decorator: Option>, - pub return_type: Option>, - pub type_parameters: Option, - } - pub enum ObjectPropVal { - Expr(Box), - Pattern(PatternLike), - } - pub struct ObjectProperty { - pub base: BaseNode, - pub key: ObjectKey, - pub value: ObjectPropVal, - pub computed: bool, - pub shorthand: bool, - pub decorators: Option>, - } - pub enum Pattern { - Assignment(AssignmentPattern), - Array(ArrayPattern), - Object(ObjectPattern), - } - pub enum ObjectPatternProp { - Rest(RestElement), - Prop(ObjectProperty), - } - pub struct ObjectPattern { - pub base: BaseNode, - pub properties: Vec, - pub decorators: Option>, - pub type_annotation: Option>, - } - pub enum AssignmentPatternLeft { - Id(Identifier), - Object(ObjectPattern), - Array(ArrayPattern), - Member(MemberExpression), - } - pub struct AssignmentPattern { - pub base: BaseNode, - pub left: AssignmentPatternLeft, - pub right: Box, - pub decorators: Option>, - pub type_annotation: Option>, - } - pub struct ArrayPattern { - pub base: BaseNode, - pub elements: Vec>, - pub decorators: Option>, - pub type_annotation: Option>, - } - pub enum Statement { - Block(BlockStatement), - Break(BreakStatement), - Continue(ContinueStatement), - Debugger(DebuggerStatement), - DoWhile(DoWhileStatement), - Empty(EmptyStatement), - Expr(ExpressionStatement), - ForIn(ForInStatement), - For(ForStatement), - FuncDecl(FunctionDeclaration), - If(IfStatement), - Labeled(LabeledStatement), - Return(ReturnStatement), - Switch(SwitchStatement), - Throw(ThrowStatement), - Try(TryStatement), - VarDecl(VariableDeclaration), - While(WhileStatement), - With(WithStatement), - ClassDecl(ClassDeclaration), - ExportAllDecl(ExportAllDeclaration), - ExportDefaultDecl(ExportDefaultDeclaration), - ExportNamedDecl(ExportNamedDeclaration), - ForOf(ForOfStatement), - ImportDecl(ImportDeclaration), - DeclClass(DeclareClass), - DeclFunc(DeclareFunction), - DeclInterface(DeclareInterface), - DeclModule(DeclareModule), - DeclareModuleExports(DeclareModuleExports), - DeclTypeAlias(DeclareTypeAlias), - DeclOpaqueType(DeclareOpaqueType), - DeclVar(DeclareVariable), - DeclExportDeclaration(DeclareExportDeclaration), - DeclExportAllDeclaration(DeclareExportAllDeclaration), - InterfaceDecl(InterfaceDeclaration), - OpaqueType(OpaqueType), - TypeAlias(TypeAlias), - EnumDecl(EnumDeclaration), - TSDeclFunc(TSDeclareFunction), - TSInterfaceDecl(TSInterfaceDeclaration), - TSTypeAliasDecl(TSTypeAliasDeclaration), - TSEnumDecl(TSEnumDeclaration), - TSModuleDecl(TSModuleDeclaration), - TSImportEqualsDecl(TSImportEqualsDeclaration), - TSExportAssignment(TSExportAssignment), - TSNamespaceExportDecl(TSNamespaceExportDeclaration), - } - pub enum CompletionStatement { - Break(BreakStatement), - Continue(ContinueStatement), - Return(ReturnStatement), - Throw(ThrowStatement), - } - pub enum Loop { - DoWhile(DoWhileStatement), - ForIn(ForInStatement), - For(ForStatement), - While(WhileStatement), - ForOf(ForOfStatement), - } - pub enum For { - InStmt(ForInStatement), - Stmt(ForStatement), - OfStmt(ForOfStatement), - } - pub enum ForXStatement { - ForIn(ForInStatement), - ForOf(ForOfStatement), - } - pub enum While { - DoWhile(DoWhileStatement), - While(WhileStatement), - } - pub struct BlockStatement { - pub base: BaseNode, - pub body: Vec, - pub directives: Vec, - } - pub struct BreakStatement { - pub base: BaseNode, - pub label: Option, - } - pub struct ContinueStatement { - pub base: BaseNode, - pub label: Option, - } - pub struct DebuggerStatement { - pub base: BaseNode, - } - pub struct DoWhileStatement { - pub base: BaseNode, - pub test: Box, - pub body: Box, - } - pub struct EmptyStatement { - pub base: BaseNode, - } - pub struct ExpressionStatement { - pub base: BaseNode, - pub expression: Box, - } - pub enum ForStmtInit { - VarDecl(VariableDeclaration), - Expr(Box), - } - pub enum ForStmtLeft { - VarDecl(VariableDeclaration), - LVal(LVal), - } - pub struct ForInStatement { - pub base: BaseNode, - pub left: ForStmtLeft, - pub right: Box, - pub body: Box, - } - pub struct ForStatement { - pub base: BaseNode, - pub init: Option, - pub test: Option>, - pub update: Option>, - pub body: Box, - } - pub struct ForOfStatement { - pub base: BaseNode, - pub left: ForStmtLeft, - pub right: Box, - pub body: Box, - } - pub struct IfStatement { - pub base: BaseNode, - pub test: Box, - pub consequent: Box, - pub alternate: Option>, - } - pub struct LabeledStatement { - pub base: BaseNode, - pub label: Identifier, - pub body: Box, - } - pub struct ReturnStatement { - pub base: BaseNode, - pub argument: Option>, - } - pub struct SwitchCase { - pub base: BaseNode, - pub test: Option>, - pub consequent: Vec, - } - pub struct SwitchStatement { - pub base: BaseNode, - pub discriminant: Box, - pub cases: Vec, - } - pub struct ThrowStatement { - pub base: BaseNode, - pub argument: Box, - } - pub enum CatchClauseParam { - Id(Identifier), - Array(ArrayPattern), - Object(ObjectPattern), - } - pub struct CatchClause { - pub base: BaseNode, - pub param: Option, - pub body: BlockStatement, - } - pub struct TryStatement { - pub base: BaseNode, - pub block: BlockStatement, - pub handler: Option, - pub finalizer: Option, - } - pub struct WhileStatement { - pub base: BaseNode, - pub test: Box, - pub body: Box, - } - pub struct WithStatement { - pub base: BaseNode, - pub object: Box, - pub body: Box, - } - pub enum TSTypeElement { - CallSignatureDecl(TSCallSignatureDeclaration), - ConstructSignatureDecl(TSConstructSignatureDeclaration), - PropSignature(TSPropertySignature), - MethodSignature(TSMethodSignature), - IndexSignature(TSIndexSignature), - } - pub enum TSType { - AnyKeyword(TSAnyKeyword), - BooleanKeyword(TSBooleanKeyword), - BigIntKeyword(TSBigIntKeyword), - IntrinsicKeyword(TSIntrinsicKeyword), - NeverKeyword(TSNeverKeyword), - NullKeyword(TSNullKeyword), - NumberKeyword(TSNumberKeyword), - ObjectKeyword(TSObjectKeyword), - StringKeyword(TSStringKeyword), - SymbolKeyword(TSSymbolKeyword), - UndefinedKeyword(TSUndefinedKeyword), - UnknownKeyword(TSUnknownKeyword), - VoidKeyword(TSVoidKeyword), - This(TSThisType), - Function(TSFunctionType), - Constructor(TSConstructorType), - TypeRef(TSTypeReference), - TypePredicate(TSTypePredicate), - TypeQuery(TSTypeQuery), - TypeLiteral(TSTypeLiteral), - Array(TSArrayType), - Tuple(TSTupleType), - Optional(TSOptionalType), - Rest(TSRestType), - Union(TSUnionType), - Intersection(TSIntersectionType), - Conditional(TSConditionalType), - Infer(TSInferType), - Parenthesized(TSParenthesizedType), - TypeOp(TSTypeOperator), - IndexedAccess(TSIndexedAccessType), - Mapped(TSMappedType), - Literal(TSLiteralType), - ExprWithArgs(TSExpressionWithTypeArguments), - Import(TSImportType), - } - pub enum TSBaseType { - Any(TSAnyKeyword), - Boolean(TSBooleanKeyword), - BigInt(TSBigIntKeyword), - Intrinsic(TSIntrinsicKeyword), - Never(TSNeverKeyword), - Null(TSNullKeyword), - Number(TSNumberKeyword), - Object(TSObjectKeyword), - String(TSStringKeyword), - Symbol(TSSymbolKeyword), - Undefined(TSUndefinedKeyword), - Unknown(TSUnknownKeyword), - Void(TSVoidKeyword), - This(TSThisType), - Literal(TSLiteralType), - } - pub struct TSTypeAnnotation { - pub base: BaseNode, - pub type_annotation: TSType, - } - pub enum TSParamPropParam { - Id(Identifier), - Assignment(AssignmentPattern), - } - pub struct TSParameterProperty { - pub base: BaseNode, - pub parameter: TSParamPropParam, - pub accessibility: Option, - pub readonly: Option, - } - pub enum TSFuncDeclTypeParams { - Type(TSTypeParameterDeclaration), - Noop(Noop), - } - pub enum TSFuncDeclTypeAnnot { - Type(Box), - Noop(Noop), - } - pub struct TSDeclareFunction { - pub base: BaseNode, - pub id: Option, - pub type_parameters: Option, - pub params: Vec, - pub return_type: Option, - pub is_async: Option, - pub declare: Option, - pub generator: Option, - } - pub struct TSDeclareMethod { - pub base: BaseNode, - pub decorators: Option>, - pub key: ObjectKey, - pub type_parameters: Option, - pub params: Vec, - pub return_type: Option, - pub is_abstract: Option, - pub access: Option, - pub accessibility: Option, - pub is_async: Option, - pub computed: Option, - pub generator: Option, - pub kind: Option, - pub optional: Option, - pub is_static: Option, - } - pub struct TSQualifiedName { - pub base: BaseNode, - pub left: Box, - pub right: Identifier, - } - pub struct TSCallSignatureDeclaration { - pub base: BaseNode, - pub type_parameters: Option, - pub parameters: Vec, - pub type_annotation: Option>, - } - pub struct TSConstructSignatureDeclaration { - pub base: BaseNode, - pub type_parameters: Option, - pub parameters: Vec, - pub type_annotation: Option>, - } - pub struct TSPropertySignature { - pub base: BaseNode, - pub key: Box, - pub type_annotation: Option>, - pub initializer: Option>, - pub computed: Option, - pub optional: Option, - pub readonly: Option, - } - pub struct TSMethodSignature { - pub base: BaseNode, - pub key: Box, - pub type_parameters: Option, - pub parameters: Vec, - pub type_annotation: Option>, - pub computed: Option, - pub optional: Option, - } - pub struct TSIndexSignature { - pub base: BaseNode, - pub paramters: Vec, - pub type_annotation: Option>, - pub readonly: Option, - } - pub struct TSAnyKeyword { - pub base: BaseNode, - } - pub struct TSBooleanKeyword { - pub base: BaseNode, - } - pub struct TSBigIntKeyword { - pub base: BaseNode, - } - pub struct TSIntrinsicKeyword { - pub base: BaseNode, - } - pub struct TSNeverKeyword { - pub base: BaseNode, - } - pub struct TSNullKeyword { - pub base: BaseNode, - } - pub struct TSNumberKeyword { - pub base: BaseNode, - } - pub struct TSObjectKeyword { - pub base: BaseNode, - } - pub struct TSStringKeyword { - pub base: BaseNode, - } - pub struct TSSymbolKeyword { - pub base: BaseNode, - } - pub struct TSUndefinedKeyword { - pub base: BaseNode, - } - pub struct TSUnknownKeyword { - pub base: BaseNode, - } - pub struct TSVoidKeyword { - pub base: BaseNode, - } - pub struct TSThisType { - pub base: BaseNode, - } - pub struct TSFunctionType { - pub base: BaseNode, - pub type_parameters: Option, - pub parameters: Vec, - pub type_annotation: Option>, - } - pub struct TSConstructorType { - pub base: BaseNode, - pub type_parameters: Option, - pub parameters: Vec, - pub type_annotation: Option>, - pub is_abstract: Option, - } - pub enum TSEntityName { - Id(Identifier), - Qualified(TSQualifiedName), - } - pub struct TSTypeReference { - pub base: BaseNode, - pub type_name: TSEntityName, - pub type_parameters: Option, - } - pub enum TSTypePredicateParamName { - Id(Identifier), - This(TSThisType), - } - pub struct TSTypePredicate { - pub base: BaseNode, - pub parameter_name: TSTypePredicateParamName, - pub type_annotation: Option>, - pub asserts: Option, - } - pub enum TSTypeQueryExprName { - EntityName(TSEntityName), - ImportType(TSImportType), - } - pub struct TSTypeQuery { - pub base: BaseNode, - pub expr_name: TSTypeQueryExprName, - } - pub struct TSTypeLiteral { - pub base: BaseNode, - pub members: Vec, - } - pub struct TSArrayType { - pub base: BaseNode, - pub element_type: Box, - } - pub enum TSTupleTypeElType { - TSType(TSType), - Member(TSNamedTupleMember), - } - pub struct TSTupleType { - pub base: BaseNode, - pub element_types: Vec, - } - pub struct TSOptionalType { - pub base: BaseNode, - pub type_annotation: Box, - } - pub struct TSRestType { - pub base: BaseNode, - pub type_annotation: Box, - } - pub struct TSNamedTupleMember { - pub base: BaseNode, - pub label: Identifier, - pub element_type: TSType, - pub optional: bool, - } - pub struct TSUnionType { - pub base: BaseNode, - pub types: Vec, - } - pub struct TSIntersectionType { - pub base: BaseNode, - pub types: Vec, - } - pub struct TSConditionalType { - pub base: BaseNode, - pub check_type: Box, - pub extends_type: Box, - pub true_type: Box, - pub false_type: Box, - } - pub struct TSInferType { - pub base: BaseNode, - pub type_parameter: Box, - } - pub struct TSParenthesizedType { - pub base: BaseNode, - pub type_annotation: Box, - } - pub struct TSTypeOperator { - pub base: BaseNode, - pub type_annotation: Box, - pub operator: JsWord, - } - pub struct TSIndexedAccessType { - pub base: BaseNode, - pub object_type: Box, - pub index_type: Box, - } - pub struct TSMappedType { - pub base: BaseNode, - pub type_parameter: Box, - pub type_annotation: Option>, - pub name_type: Option>, - pub optional: Option, - pub readonly: Option, - } - pub enum TSLiteralTypeLiteral { - Numeric(NumericLiteral), - String(StringLiteral), - Boolean(BooleanLiteral), - BigInt(BigIntLiteral), - } - pub struct TSLiteralType { - pub base: BaseNode, - pub literal: TSLiteralTypeLiteral, - } - pub struct TSExpressionWithTypeArguments { - pub base: BaseNode, - pub expression: TSEntityName, - pub type_parameters: Option, - } - pub struct TSInterfaceDeclaration { - pub base: BaseNode, - pub id: Identifier, - pub type_parameters: Option, - pub extends: Option, - pub body: TSInterfaceBody, - pub declare: Option, - } - pub struct TSInterfaceBody { - pub base: BaseNode, - pub body: Vec, - } - pub struct TSTypeAliasDeclaration { - pub base: BaseNode, - pub id: Identifier, - pub type_parameters: Option, - pub type_annotation: TSType, - pub declare: Option, - } - pub struct TSAsExpression { - pub base: BaseNode, - pub expression: Box, - pub type_annotation: TSType, - } - pub struct TSTypeAssertion { - pub base: BaseNode, - pub type_annotation: TSType, - pub expression: Box, - } - pub struct TSEnumDeclaration { - pub base: BaseNode, - pub id: Identifier, - pub members: Vec, - pub is_const: Option, - pub declare: Option, - pub initializer: Option>, - } - pub struct TSEnumMember { - pub base: BaseNode, - pub id: IdOrString, - pub initializer: Option>, - } - pub enum TSModuleDeclBody { - Block(TSModuleBlock), - Decl(TSModuleDeclaration), - } - pub struct TSModuleDeclaration { - pub base: BaseNode, - pub id: IdOrString, - pub body: Box, - pub declare: Option, - pub global: Option, - } - pub struct TSModuleBlock { - pub base: BaseNode, - pub body: Vec, - } - pub struct TSImportType { - pub base: BaseNode, - pub argument: StringLiteral, - pub qualifier: Option, - pub type_parameters: Option, - } - pub enum TSImportEqualsDeclModuleRef { - Name(TSEntityName), - External(TSExternalModuleReference), - } - pub struct TSImportEqualsDeclaration { - pub base: BaseNode, - pub id: Identifier, - pub module_reference: TSImportEqualsDeclModuleRef, - pub is_export: bool, - } - pub struct TSExternalModuleReference { - pub base: BaseNode, - pub expression: StringLiteral, - } - pub struct TSNonNullExpression { - pub base: BaseNode, - pub expression: Box, - } - pub struct TSExportAssignment { - pub base: BaseNode, - pub expression: Box, - } - pub struct TSNamespaceExportDeclaration { - pub base: BaseNode, - pub id: Identifier, - } - pub struct TSTypeParameterInstantiation { - pub base: BaseNode, - pub params: Vec, - } - pub struct TSTypeParameterDeclaration { - pub base: BaseNode, - pub params: Vec, - } - pub struct TSTypeParameter { - pub base: BaseNode, - pub constraint: Option>, - pub default: Option>, - pub name: JsWord, - } -}); diff --git a/crates/testing/Cargo.toml b/crates/testing/Cargo.toml index cd284ab60fc..f7f76090a0f 100644 --- a/crates/testing/Cargo.toml +++ b/crates/testing/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "testing" repository = "https://github.com/swc-project/swc.git" -version = "0.15.1" +version = "0.15.2" [dependencies] ansi_term = "0.12.1" @@ -14,6 +14,7 @@ difference = "2" once_cell = "1" pretty_assertions = "0.7.2" regex = "1" +serde_json = "1.0.71" swc_common = {version = "0.14.0", path = "../swc_common", features = ["tty-emitter"]} testing_macros = {version = "0.2.0", path = "../testing_macros"} tracing = "0.1.28" diff --git a/crates/testing/src/json.rs b/crates/testing/src/json.rs new file mode 100644 index 00000000000..f3d550c71ce --- /dev/null +++ b/crates/testing/src/json.rs @@ -0,0 +1,100 @@ +use serde_json::Value; + +fn normalize_value_recursively(v: &mut Value, normalize: &mut dyn FnMut(&str, &mut Value)) { + match v { + Value::Array(arr) => { + for v in arr { + normalize_value_recursively(v, normalize); + } + } + + Value::Object(obj) => { + for (k, v) in obj.iter_mut() { + normalize(k, v); + } + + for (_, v) in obj.iter_mut() { + normalize_value_recursively(v, normalize); + } + } + + _ => {} + } +} + +/// Remove common properties, recursively. You can optionally normalize more by +/// passing a closure. +/// +/// Closure takes `(key, value)`. +/// +/// Returns `true` if `actual` and `expected` are equal. +pub fn diff_json_value( + a: &mut Value, + b: &mut Value, + normalize: &mut dyn FnMut(&str, &mut Value), +) -> bool { + normalize_value_recursively(a, normalize); + normalize_value_recursively(b, normalize); + + remove_common(a, b) +} + +fn remove_common(a: &mut Value, b: &mut Value) -> bool { + if *a == *b { + return true; + } + + match (&mut *a, &mut *b) { + (Value::Object(a), Value::Object(b)) => { + if a.is_empty() && b.is_empty() { + return true; + } + + a.retain(|key, a_v| { + if let Some(b_v) = b.get_mut(key) { + if remove_common(a_v, b_v) { + // Remove from both + b.remove(key); + return false; + } + } else { + // Remove if a.foo is null and b does not have foo + match a_v { + Value::Null => return false, + _ => {} + } + } + + // Preserve by default + true + }); + b.retain(|key, b_v| { + // Remove if b.foo is null and a does not have foo + match b_v { + Value::Null => { + if !a.contains_key(key) { + return false; + } + } + _ => {} + } + + // Preserve by default + + true + }); + } + + (Value::Array(a), Value::Array(b)) => { + if a.len() == b.len() { + for (a_v, b_v) in a.iter_mut().zip(b.iter_mut()) { + remove_common(a_v, b_v); + } + } + } + + _ => {} + } + + false +} diff --git a/crates/testing/src/lib.rs b/crates/testing/src/lib.rs index c28d486e709..9a689b2d17a 100644 --- a/crates/testing/src/lib.rs +++ b/crates/testing/src/lib.rs @@ -21,6 +21,7 @@ use swc_common::{ pub use testing_macros::fixture; use tracing_subscriber::EnvFilter; +pub mod json; #[macro_use] mod macros; mod diag_errors; diff --git a/crates/testing_macros/Cargo.toml b/crates/testing_macros/Cargo.toml index c4f4a3c85cf..a2c79d5428e 100644 --- a/crates/testing_macros/Cargo.toml +++ b/crates/testing_macros/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "testing_macros" repository = "https://github.com/swc-project/swc.git" -version = "0.2.3" +version = "0.2.4" [lib] proc-macro = true diff --git a/crates/testing_macros/src/fixture.rs b/crates/testing_macros/src/fixture.rs index 0edcdaf0a83..8b6c95ead29 100644 --- a/crates/testing_macros/src/fixture.rs +++ b/crates/testing_macros/src/fixture.rs @@ -169,6 +169,8 @@ pub fn expand(callee: &Ident, attr: Config) -> Result, Error> { #[ignore] #[doc(hidden)] fn test_ident() { + eprintln!("Input: {}", path_str); + callee(::std::path::PathBuf::from(path_str)); } } diff --git a/cspell.json b/cspell.json index 414b01ee1ce..4df949545c7 100644 --- a/cspell.json +++ b/cspell.json @@ -41,6 +41,7 @@ "deps", "Deque", "Deser", + "deserialization", "dont", "DWORD", "ecma", @@ -130,4 +131,4 @@ "flagWords": [ "actally" ] -} \ No newline at end of file +} diff --git a/package.json b/package.json index a397ec35550..c86cdb0e57e 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "@swc/helpers": "^0.2.10", "@types/jest": "^26.0.23", "@types/node": "^14.14.41", + "acorn": "^8.6.0", "axios": "^0.21.1", "babel-plugin-transform-node-env-inline": "^0.4.3", "class-validator": "^0.13.1", diff --git a/yarn.lock b/yarn.lock index 8a03375cb44..f6d8721e061 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1745,6 +1745,11 @@ acorn@^8.2.4: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== +acorn@^8.6.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" + integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"