From 82ef06afb8cc7ef912afb11bba2293e1d0cd91fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 6 May 2021 14:56:54 +0900 Subject: [PATCH] feat(babel/compat): Improve performance of babelify (#1626) swc_babel_compat: - Optimize. swc: - Improve performance of comment storage. --- .cargo/config | 3 +- .github/workflows/cargo.yml | 7 + Cargo.toml | 2 + {native/babel-ast => babel/ast}/Cargo.toml | 4 +- {native/babel-ast => babel/ast}/README.md | 0 {native/babel-ast => babel/ast}/src/class.rs | 0 .../babel-ast => babel/ast}/src/comment.rs | 0 {native/babel-ast => babel/ast}/src/common.rs | 10 +- {native/babel-ast => babel/ast}/src/decl.rs | 0 {native/babel-ast => babel/ast}/src/expr.rs | 10 +- {native/babel-ast => babel/ast}/src/flow.rs | 5 +- {native/babel-ast => babel/ast}/src/jsx.rs | 5 +- {native/babel-ast => babel/ast}/src/lib.rs | 3 + {native/babel-ast => babel/ast}/src/lit.rs | 22 +- {native/babel-ast => babel/ast}/src/module.rs | 10 +- {native/babel-ast => babel/ast}/src/object.rs | 0 {native/babel-ast => babel/ast}/src/pat.rs | 0 {native/babel-ast => babel/ast}/src/stmt.rs | 0 .../babel-ast => babel/ast}/src/typescript.rs | 5 +- .../babel-compat => babel/compat}/Cargo.toml | 10 +- .../babel-compat => babel/compat}/README.md | 0 babel/compat/benches/assets/AjaxObservable.ts | 414 ++++++++++++++++++ babel/compat/benches/babelify.rs | 140 ++++++ .../compat}/scripts/update.sh | 0 .../compat}/src/class.rs | 104 ++--- .../babel-compat => babel/compat}/src/decl.rs | 11 +- .../babel-compat => babel/compat}/src/expr.rs | 225 +++++----- .../compat}/src/function.rs | 47 +- .../compat}/src/ident.rs | 8 +- .../babel-compat => babel/compat}/src/jsx.rs | 40 +- .../babel-compat => babel/compat}/src/lib.rs | 46 +- .../babel-compat => babel/compat}/src/lit.rs | 6 +- .../compat}/src/module.rs | 60 +-- .../compat}/src/module_decl.rs | 30 +- .../compat}/src/normalize/mod.rs | 3 +- .../compat}/src/operators.rs | 0 .../babel-compat => babel/compat}/src/pat.rs | 38 +- .../babel-compat => babel/compat}/src/prop.rs | 14 +- .../babel-compat => babel/compat}/src/stmt.rs | 78 ++-- .../compat}/src/typescript.rs | 171 ++++---- .../compat}/tests/README.md | 0 .../compat}/tests/babelgen.js | 0 .../compat}/tests/compare.sh | 0 .../compat}/tests/convert.rs | 10 +- .../fixtures/array-destructuring/input.js | 0 .../fixtures/array-destructuring/output.json | 0 .../tests/fixtures/array-simple/input.js | 0 .../tests/fixtures/array-simple/output.json | 0 .../tests/fixtures/class-extends/input.js | 0 .../tests/fixtures/class-extends/output.json | 0 .../fixtures/class-getter-setter/input.js | 0 .../fixtures/class-getter-setter/output.json | 0 .../fixtures/class-method-no-body/input.js | 0 .../fixtures/class-method-no-body/output.json | 0 .../fixtures/class-public-fields/input.js | 0 .../fixtures/class-public-fields/output.json | 0 .../tests/fixtures/class-simple/input.js | 0 .../tests/fixtures/class-simple/output.json | 0 .../tests/fixtures/class-static/input.js | 0 .../tests/fixtures/class-static/output.json | 0 .../tests/fixtures/class-unnamed/input.js | 0 .../tests/fixtures/class-unnamed/output.json | 0 .../comments-block-first-line/input.js | 0 .../comments-block-first-line/output.json | 0 .../tests/fixtures/comments-block/input.js | 0 .../tests/fixtures/comments-block/output.json | 0 .../fixtures/comments-first-line/input.js | 0 .../fixtures/comments-first-line/output.json | 0 .../tests/fixtures/comments-line/input.js | 0 .../tests/fixtures/comments-line/output.json | 0 .../tests/fixtures/delete-operator/input.js | 0 .../fixtures/delete-operator/output.json | 0 .../fixtures/exponentiation-operator/input.js | 0 .../exponentiation-operator/output.json | 0 .../fixtures/function-anonymous/input.js | 0 .../fixtures/function-anonymous/output.json | 0 .../tests/fixtures/function-arrow/input.js | 0 .../tests/fixtures/function-arrow/output.json | 0 .../function-default-parameters/input.js | 0 .../function-default-parameters/output.json | 0 .../function-rest-parameters/input.js | 0 .../function-rest-parameters/output.json | 0 .../tests/fixtures/function-simple/input.js | 0 .../fixtures/function-simple/output.json | 0 .../tests/fixtures/jsx-and-expr/input.jsx | 0 .../tests/fixtures/jsx-and-expr/output.json | 0 .../tests/fixtures/jsx-children/input.jsx | 0 .../tests/fixtures/jsx-children/output.json | 0 .../compat}/tests/fixtures/jsx-map/input.jsx | 0 .../tests/fixtures/jsx-map/output.json | 0 .../tests/fixtures/jsx-props-spread/input.jsx | 0 .../fixtures/jsx-props-spread/output.json | 0 .../tests/fixtures/jsx-props/input.jsx | 0 .../tests/fixtures/jsx-props/output.json | 0 .../tests/fixtures/jsx-self-closing/input.jsx | 0 .../fixtures/jsx-self-closing/output.json | 0 .../tests/fixtures/jsx-simple/input.jsx | 0 .../tests/fixtures/jsx-simple/output.json | 0 .../tests/fixtures/jsx-ternary-expr/input.jsx | 0 .../fixtures/jsx-ternary-expr/output.json | 0 .../tests/fixtures/module-commonjs/input.js | 0 .../fixtures/module-commonjs/output.json | 0 .../fixtures/module-export-default/input.mjs | 0 .../module-export-default/output.json | 0 .../module-export-individual-items/input.mjs | 0 .../output.json | 0 .../fixtures/module-export-named/input.mjs | 0 .../fixtures/module-export-named/output.json | 0 .../fixtures/module-export-renamed/input.mjs | 0 .../module-export-renamed/output.json | 0 .../fixtures/module-import-default/input.mjs | 0 .../module-import-default/output.json | 0 .../fixtures/module-import-multiple/input.mjs | 0 .../module-import-multiple/output.json | 0 .../fixtures/module-import-named/input.mjs | 0 .../fixtures/module-import-named/output.json | 0 .../fixtures/module-import-renamed/input.mjs | 0 .../module-import-renamed/output.json | 0 .../module-import-star-renamed/input.mjs | 0 .../module-import-star-renamed/output.json | 0 .../fixtures/object-destructuring/input.js | 0 .../fixtures/object-destructuring/output.json | 0 .../tests/fixtures/object-simple/input.js | 0 .../tests/fixtures/object-simple/output.json | 0 .../tests/fixtures/object-spread/input.js | 0 .../tests/fixtures/object-spread/output.json | 0 .../tests/fixtures/regex-flags/input.js | 0 .../tests/fixtures/regex-flags/output.json | 0 .../tests/fixtures/regex-simple/input.js | 0 .../tests/fixtures/regex-simple/output.json | 0 .../compat}/tests/fixtures/shebang/input.js | 0 .../tests/fixtures/shebang/output.json | 0 .../tests/fixtures/simple-two-lines/input.js | 0 .../fixtures/simple-two-lines/output.json | 0 .../compat}/tests/fixtures/simple/input.js | 0 .../compat}/tests/fixtures/simple/output.json | 0 .../tests/fixtures/template-literal/input.js | 0 .../fixtures/template-literal/output.json | 0 .../tests/fixtures/ts-function/input.ts | 0 .../compat}/tests/package.json | 0 .../compat}/tests/swcgen.js | 0 .../babel-visit => babel/visit}/Cargo.toml | 5 +- {native/babel-visit => babel/visit}/README.md | 0 .../babel-visit => babel/visit}/src/lib.rs | 39 +- common/src/source_map.rs | 37 +- native/Cargo.toml | 9 +- native/babel-compat/src/main.rs | 174 -------- native/src/lib.rs | 10 +- node-swc/src/babel.ts | 16 + node-swc/src/index.ts | 36 ++ node/base/Cargo.toml | 21 + node/base/src/lib.rs | 11 + package.json | 1 + rust-toolchain | 2 +- spack/Cargo.toml | 9 +- spack/benches/bench.rs | 8 - spack/src/lib.rs | 4 +- src/lib.rs | 9 +- visit/macros/src/lib.rs | 13 +- 159 files changed, 1198 insertions(+), 747 deletions(-) rename {native/babel-ast => babel/ast}/Cargo.toml (76%) rename {native/babel-ast => babel/ast}/README.md (100%) rename {native/babel-ast => babel/ast}/src/class.rs (100%) rename {native/babel-ast => babel/ast}/src/comment.rs (100%) rename {native/babel-ast => babel/ast}/src/common.rs (99%) rename {native/babel-ast => babel/ast}/src/decl.rs (100%) rename {native/babel-ast => babel/ast}/src/expr.rs (99%) rename {native/babel-ast => babel/ast}/src/flow.rs (99%) rename {native/babel-ast => babel/ast}/src/jsx.rs (98%) rename {native/babel-ast => babel/ast}/src/lib.rs (84%) rename {native/babel-ast => babel/ast}/src/lit.rs (95%) rename {native/babel-ast => babel/ast}/src/module.rs (99%) rename {native/babel-ast => babel/ast}/src/object.rs (100%) rename {native/babel-ast => babel/ast}/src/pat.rs (100%) rename {native/babel-ast => babel/ast}/src/stmt.rs (100%) rename {native/babel-ast => babel/ast}/src/typescript.rs (99%) rename {native/babel-compat => babel/compat}/Cargo.toml (75%) rename {native/babel-compat => babel/compat}/README.md (100%) create mode 100644 babel/compat/benches/assets/AjaxObservable.ts create mode 100644 babel/compat/benches/babelify.rs rename {native/babel-compat => babel/compat}/scripts/update.sh (100%) rename {native/babel-compat => babel/compat}/src/class.rs (70%) rename {native/babel-compat => babel/compat}/src/decl.rs (93%) rename {native/babel-compat => babel/compat}/src/expr.rs (67%) rename {native/babel-compat => babel/compat}/src/function.rs (63%) rename {native/babel-compat => babel/compat}/src/ident.rs (83%) rename {native/babel-compat => babel/compat}/src/jsx.rs (90%) rename {native/babel-compat => babel/compat}/src/lib.rs (79%) rename {native/babel-compat => babel/compat}/src/lit.rs (94%) rename {native/babel-compat => babel/compat}/src/module.rs (82%) rename {native/babel-compat => babel/compat}/src/module_decl.rs (94%) rename {native/babel-compat => babel/compat}/src/normalize/mod.rs (98%) rename {native/babel-compat => babel/compat}/src/operators.rs (100%) rename {native/babel-compat => babel/compat}/src/pat.rs (86%) rename {native/babel-compat => babel/compat}/src/prop.rs (90%) rename {native/babel-compat => babel/compat}/src/stmt.rs (79%) rename {native/babel-compat => babel/compat}/src/typescript.rs (87%) rename {native/babel-compat => babel/compat}/tests/README.md (100%) rename {native/babel-compat => babel/compat}/tests/babelgen.js (100%) rename {native/babel-compat => babel/compat}/tests/compare.sh (100%) rename {native/babel-compat => babel/compat}/tests/convert.rs (96%) rename {native/babel-compat => babel/compat}/tests/fixtures/array-destructuring/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/array-destructuring/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/array-simple/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/array-simple/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-extends/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-extends/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-getter-setter/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-getter-setter/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-method-no-body/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-method-no-body/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-public-fields/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-public-fields/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-simple/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-simple/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-static/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-static/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-unnamed/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/class-unnamed/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/comments-block-first-line/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/comments-block-first-line/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/comments-block/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/comments-block/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/comments-first-line/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/comments-first-line/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/comments-line/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/comments-line/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/delete-operator/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/delete-operator/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/exponentiation-operator/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/exponentiation-operator/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/function-anonymous/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/function-anonymous/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/function-arrow/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/function-arrow/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/function-default-parameters/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/function-default-parameters/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/function-rest-parameters/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/function-rest-parameters/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/function-simple/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/function-simple/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-and-expr/input.jsx (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-and-expr/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-children/input.jsx (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-children/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-map/input.jsx (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-map/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-props-spread/input.jsx (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-props-spread/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-props/input.jsx (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-props/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-self-closing/input.jsx (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-self-closing/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-simple/input.jsx (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-simple/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-ternary-expr/input.jsx (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/jsx-ternary-expr/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-commonjs/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-commonjs/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-export-default/input.mjs (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-export-default/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-export-individual-items/input.mjs (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-export-individual-items/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-export-named/input.mjs (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-export-named/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-export-renamed/input.mjs (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-export-renamed/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-import-default/input.mjs (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-import-default/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-import-multiple/input.mjs (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-import-multiple/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-import-named/input.mjs (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-import-named/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-import-renamed/input.mjs (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-import-renamed/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-import-star-renamed/input.mjs (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/module-import-star-renamed/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/object-destructuring/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/object-destructuring/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/object-simple/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/object-simple/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/object-spread/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/object-spread/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/regex-flags/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/regex-flags/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/regex-simple/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/regex-simple/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/shebang/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/shebang/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/simple-two-lines/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/simple-two-lines/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/simple/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/simple/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/template-literal/input.js (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/template-literal/output.json (100%) rename {native/babel-compat => babel/compat}/tests/fixtures/ts-function/input.ts (100%) rename {native/babel-compat => babel/compat}/tests/package.json (100%) rename {native/babel-compat => babel/compat}/tests/swcgen.js (100%) rename {native/babel-visit => babel/visit}/Cargo.toml (79%) rename {native/babel-visit => babel/visit}/README.md (100%) rename {native/babel-visit => babel/visit}/src/lib.rs (99%) delete mode 100644 native/babel-compat/src/main.rs create mode 100644 node-swc/src/babel.ts create mode 100644 node/base/Cargo.toml create mode 100644 node/base/src/lib.rs diff --git a/.cargo/config b/.cargo/config index 1758b307412..750f3f6597d 100644 --- a/.cargo/config +++ b/.cargo/config @@ -2,7 +2,7 @@ [build] rustflags = [ "--cfg", "procmacro2_semver_exempt", - "-C", "target-feature=+sse2", + "-C", "target-feature=+sse2,+aes", ] rustdocflags = [ @@ -12,6 +12,7 @@ rustdocflags = [ [target.aarch64-apple-darwin] rustflags = [ "--cfg", "procmacro2_semver_exempt", + "-C", "target-feature=+sse2,+aes" ] [target.aarch64-unknown-linux-gnu] diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index e3f43a5c2e5..9f660c11e99 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -39,6 +39,8 @@ jobs: fmt: name: fmt runs-on: ubuntu-latest + env: + RUST_LOG: "0" steps: - uses: actions/checkout@v2 @@ -99,10 +101,14 @@ jobs: - enum_kind - from_variant - jsdoc + - node - spack - string_enum - swc - swc_atoms + - swc_babel_ast + - swc_babel_compat + - swc_babel_visit - swc_bundler - swc_common - swc_ecma_ast @@ -132,6 +138,7 @@ jobs: - swc_visit_macros - testing - testing_macros + - wasm exclude: - os: windows-2019 crate: spack diff --git a/Cargo.toml b/Cargo.toml index 31573072b02..3688eee4291 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ version = "0.16.0" name = "swc" [dependencies] +ahash = "0.7.2" anyhow = "1" base64 = "0.12.0" dashmap = "4.0.2" @@ -44,6 +45,7 @@ swc_ecma_transforms = {version = "0.46.0", path = "./ecmascript/transforms", fea ]} swc_ecma_utils = {version = "0.34.1", path = "./ecmascript/utils"} swc_ecma_visit = {version = "0.29.1", path = "./ecmascript/visit"} +swc_node_base = {path = "./node/base"} swc_visit = {version = "0.2.3", path = "./visit"} [dev-dependencies] diff --git a/native/babel-ast/Cargo.toml b/babel/ast/Cargo.toml similarity index 76% rename from native/babel-ast/Cargo.toml rename to babel/ast/Cargo.toml index e3b8a122dd2..25bde910aca 100644 --- a/native/babel-ast/Cargo.toml +++ b/babel/ast/Cargo.toml @@ -12,4 +12,6 @@ version = "0.1.0" [dependencies] serde = {version = "1", features = ["derive"]} serde_json = "1.0.62" -swc_common = {version = "0.10.9", path = "../../common"} +swc_atoms = {path = "../../atoms"} +swc_common = {path = "../../common"} +swc_node_base = {path = "../../node/base"} diff --git a/native/babel-ast/README.md b/babel/ast/README.md similarity index 100% rename from native/babel-ast/README.md rename to babel/ast/README.md diff --git a/native/babel-ast/src/class.rs b/babel/ast/src/class.rs similarity index 100% rename from native/babel-ast/src/class.rs rename to babel/ast/src/class.rs diff --git a/native/babel-ast/src/comment.rs b/babel/ast/src/comment.rs similarity index 100% rename from native/babel-ast/src/comment.rs rename to babel/ast/src/comment.rs diff --git a/native/babel-ast/src/common.rs b/babel/ast/src/common.rs similarity index 99% rename from native/babel-ast/src/common.rs rename to babel/ast/src/common.rs index d112529c38c..d41e887f005 100644 --- a/native/babel-ast/src/common.rs +++ b/babel/ast/src/common.rs @@ -1,10 +1,10 @@ -use serde::{Deserialize, Serialize}; -use swc_common::ast_serde; - use crate::{ class::*, comment::Comment, decl::*, expr::*, flow::*, jsx::*, lit::*, module::*, object::*, pat::*, stmt::*, typescript::*, }; +use serde::{Deserialize, Serialize}; +use swc_atoms::JsWord; +use swc_common::ast_serde; #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] @@ -371,7 +371,7 @@ pub struct Identifier { #[serde(flatten)] pub base: BaseNode, #[serde(default)] - pub name: String, + pub name: JsWord, #[serde(default)] pub decorators: Option>, #[serde(default)] @@ -559,7 +559,7 @@ pub struct DirectiveLiteral { #[serde(flatten)] pub base: BaseNode, #[serde(default)] - pub value: String, + pub value: JsWord, } #[derive(Debug, Clone, PartialEq)] diff --git a/native/babel-ast/src/decl.rs b/babel/ast/src/decl.rs similarity index 100% rename from native/babel-ast/src/decl.rs rename to babel/ast/src/decl.rs diff --git a/native/babel-ast/src/expr.rs b/babel/ast/src/expr.rs similarity index 99% rename from native/babel-ast/src/expr.rs rename to babel/ast/src/expr.rs index 368ccb5a4b8..f07b8ae7baa 100644 --- a/native/babel-ast/src/expr.rs +++ b/babel/ast/src/expr.rs @@ -1,6 +1,3 @@ -use serde::{Deserialize, Serialize}; -use swc_common::ast_serde; - use crate::{ class::{ClassBody, ClassImpl}, common::{ @@ -22,6 +19,9 @@ use crate::{ TSAsExpression, TSNonNullExpression, TSTypeAssertion, TSTypeParameterInstantiation, }, }; +use serde::{Deserialize, Serialize}; +use swc_atoms::JsWord; +use swc_common::ast_serde; #[derive(Debug, Clone, PartialEq)] #[ast_serde] @@ -155,7 +155,7 @@ pub struct AssignmentExpression { #[serde(flatten)] pub base: BaseNode, #[serde(default)] - pub operator: String, + pub operator: JsWord, pub left: Box, pub right: Box, } @@ -258,7 +258,7 @@ pub struct V8IntrinsicIdentifier { #[serde(flatten)] pub base: BaseNode, #[serde(default)] - pub name: String, + pub name: JsWord, } #[derive(Debug, Clone, PartialEq)] diff --git a/native/babel-ast/src/flow.rs b/babel/ast/src/flow.rs similarity index 99% rename from native/babel-ast/src/flow.rs rename to babel/ast/src/flow.rs index bd9f9c59729..0791eecd02f 100644 --- a/native/babel-ast/src/flow.rs +++ b/babel/ast/src/flow.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use swc_atoms::JsWord; use swc_common::ast_serde; use crate::{ @@ -361,7 +362,7 @@ pub struct TypeParameter { #[serde(default)] pub variance: Option, #[serde(default)] - pub name: String, + pub name: JsWord, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -564,7 +565,7 @@ pub struct StringLiteralTypeAnnotation { #[serde(flatten)] pub base: BaseNode, #[serde(default)] - pub value: String, + pub value: JsWord, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] diff --git a/native/babel-ast/src/jsx.rs b/babel/ast/src/jsx.rs similarity index 98% rename from native/babel-ast/src/jsx.rs rename to babel/ast/src/jsx.rs index 951d8dc4efd..7108207633d 100644 --- a/native/babel-ast/src/jsx.rs +++ b/babel/ast/src/jsx.rs @@ -1,3 +1,4 @@ +use swc_atoms::JsWord; use swc_common::ast_serde; use crate::{ @@ -133,7 +134,7 @@ pub struct JSXIdentifier { #[serde(flatten)] pub base: BaseNode, #[serde(default)] - pub name: String, + pub name: JsWord, } impl From for JSXIdentifier { @@ -218,7 +219,7 @@ pub struct JSXSpreadAttribute { pub struct JSXText { #[serde(flatten)] pub base: BaseNode, - pub value: String, + pub value: JsWord, } #[derive(Debug, Clone, PartialEq)] diff --git a/native/babel-ast/src/lib.rs b/babel/ast/src/lib.rs similarity index 84% rename from native/babel-ast/src/lib.rs rename to babel/ast/src/lib.rs index 46210ba0fe9..3b1f807bbe3 100644 --- a/native/babel-ast/src/lib.rs +++ b/babel/ast/src/lib.rs @@ -1,5 +1,8 @@ #![feature(macro_attributes_in_derive_output)] +/// Explicit extern crate to use global allocator. +extern crate swc_node_base; + mod class; mod comment; mod common; diff --git a/native/babel-ast/src/lit.rs b/babel/ast/src/lit.rs similarity index 95% rename from native/babel-ast/src/lit.rs rename to babel/ast/src/lit.rs index 97b32c428dc..381d42a5fe3 100644 --- a/native/babel-ast/src/lit.rs +++ b/babel/ast/src/lit.rs @@ -1,7 +1,7 @@ -use serde::{Deserialize, Serialize}; -use swc_common::ast_serde; - use crate::{common::BaseNode, expr::Expression, typescript::TSType}; +use serde::{Deserialize, Serialize}; +use swc_atoms::JsWord; +use swc_common::ast_serde; #[derive(Debug, Clone, PartialEq)] #[ast_serde] @@ -29,7 +29,7 @@ pub enum Literal { pub struct StringLiteral { #[serde(flatten)] pub base: BaseNode, - pub value: String, + pub value: JsWord, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -69,9 +69,9 @@ pub struct BooleanLiteral { pub struct RegExpLiteral { #[serde(flatten)] pub base: BaseNode, - pub pattern: String, + pub pattern: JsWord, #[serde(default)] - pub flags: String, + pub flags: JsWord, } /// Deprecated. Use RegExpLiteral instead. @@ -80,17 +80,17 @@ pub struct RegExpLiteral { pub struct RegexLiteral { #[serde(flatten)] pub base: BaseNode, - pub pattern: String, + pub pattern: JsWord, #[serde(default)] - pub flags: String, + pub flags: JsWord, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct TemplateElVal { #[serde(default)] - pub raw: String, + pub raw: JsWord, #[serde(default)] - pub cooked: Option, + pub cooked: Option, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -172,5 +172,5 @@ pub struct DecimalLiteral { #[serde(flatten)] pub base: BaseNode, #[serde(default)] - pub value: String, + pub value: JsWord, } diff --git a/native/babel-ast/src/module.rs b/babel/ast/src/module.rs similarity index 99% rename from native/babel-ast/src/module.rs rename to babel/ast/src/module.rs index f4bae60d1fc..3e4e83a08b2 100644 --- a/native/babel-ast/src/module.rs +++ b/babel/ast/src/module.rs @@ -1,7 +1,3 @@ -use serde::{Deserialize, Serialize}; -use serde_json::Value; -use swc_common::ast_serde; - use crate::{ class::ClassDeclaration, comment::Comment, @@ -12,6 +8,10 @@ use crate::{ stmt::Statement, typescript::TSDeclareFunction, }; +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use swc_atoms::JsWord; +use swc_common::ast_serde; #[derive(Debug, Clone, PartialEq)] #[ast_serde] @@ -72,7 +72,7 @@ pub struct InterpreterDirective { #[serde(flatten)] pub base: BaseNode, #[serde(default)] - pub value: String, + pub value: JsWord, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] diff --git a/native/babel-ast/src/object.rs b/babel/ast/src/object.rs similarity index 100% rename from native/babel-ast/src/object.rs rename to babel/ast/src/object.rs diff --git a/native/babel-ast/src/pat.rs b/babel/ast/src/pat.rs similarity index 100% rename from native/babel-ast/src/pat.rs rename to babel/ast/src/pat.rs diff --git a/native/babel-ast/src/stmt.rs b/babel/ast/src/stmt.rs similarity index 100% rename from native/babel-ast/src/stmt.rs rename to babel/ast/src/stmt.rs diff --git a/native/babel-ast/src/typescript.rs b/babel/ast/src/typescript.rs similarity index 99% rename from native/babel-ast/src/typescript.rs rename to babel/ast/src/typescript.rs index 8919be160f6..e0cec77f44f 100644 --- a/native/babel-ast/src/typescript.rs +++ b/babel/ast/src/typescript.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use swc_atoms::JsWord; use swc_common::ast_serde; use crate::{ @@ -641,7 +642,7 @@ pub struct TSTypeOperator { pub base: BaseNode, pub type_annotation: Box, #[serde(default)] - pub operator: String, + pub operator: JsWord, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -913,5 +914,5 @@ pub struct TSTypeParameter { #[serde(default)] pub default: Option>, #[serde(default)] - pub name: String, + pub name: JsWord, } diff --git a/native/babel-compat/Cargo.toml b/babel/compat/Cargo.toml similarity index 75% rename from native/babel-compat/Cargo.toml rename to babel/compat/Cargo.toml index ee32964bddc..8b6cf2ac913 100644 --- a/native/babel-compat/Cargo.toml +++ b/babel/compat/Cargo.toml @@ -10,19 +10,23 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -ahash = "0.7.0" +ahash = {version = "0.7.0", features = ["compile-time-rng"]} anyhow = "1" +copyless = "0.1.5" +rayon = "1.5.0" serde = {version = "1", features = ["derive"]} serde_json = "1.0.62" swc = {path = "../.."} swc_atoms = {version = "0.2.5", path = "../../atoms"} -swc_babel_ast = {path = "../babel-ast"} -swc_babel_visit = {path = "../babel-visit"} +swc_babel_ast = {path = "../ast"} +swc_babel_visit = {path = "../visit"} swc_common = {version = "0.10.9", path = "../../common", features = ["tty-emitter", "sourcemap"]} swc_ecma_ast = {version = "0.43", path = "../../ecmascript/ast"} swc_ecma_parser = {version = "0.54.2", path = "../../ecmascript/parser"} swc_ecma_visit = {version = "0.29.1", path = "../../ecmascript/visit"} +swc_node_base = {path = "../../node/base"} [dev-dependencies] pretty_assertions = "0.7.1" +swc_ecma_transforms = {path = "../../ecmascript/transforms/"} walkdir = "2" diff --git a/native/babel-compat/README.md b/babel/compat/README.md similarity index 100% rename from native/babel-compat/README.md rename to babel/compat/README.md diff --git a/babel/compat/benches/assets/AjaxObservable.ts b/babel/compat/benches/assets/AjaxObservable.ts new file mode 100644 index 00000000000..7ff070c1e4c --- /dev/null +++ b/babel/compat/benches/assets/AjaxObservable.ts @@ -0,0 +1,414 @@ +/** @prettier */ +import { Observable } from '../../Observable'; +import { Subscriber } from '../../Subscriber'; +import { TeardownLogic, PartialObserver } from '../../types'; + +export interface AjaxRequest { + url?: string; + body?: any; + user?: string; + async?: boolean; + method?: string; + headers?: object; + timeout?: number; + password?: string; + hasContent?: boolean; + crossDomain?: boolean; + withCredentials?: boolean; + createXHR?: () => XMLHttpRequest; + progressSubscriber?: PartialObserver; + responseType?: string; +} + +function isFormData(body: any): body is FormData { + return typeof FormData !== 'undefined' && body instanceof FormData; +} + +/** + * We need this JSDoc comment for affecting ESDoc. + * @extends {Ignored} + * @hide true + */ +export class AjaxObservable extends Observable { + private request: AjaxRequest; + + constructor(urlOrRequest: string | AjaxRequest) { + super(); + + const request: AjaxRequest = { + async: true, + createXHR: () => new XMLHttpRequest(), + crossDomain: true, + withCredentials: false, + headers: {}, + method: 'GET', + responseType: 'json', + timeout: 0, + }; + + if (typeof urlOrRequest === 'string') { + request.url = urlOrRequest; + } else { + for (const prop in urlOrRequest) { + if (urlOrRequest.hasOwnProperty(prop)) { + (request as any)[prop] = (urlOrRequest as any)[prop]; + } + } + } + + this.request = request; + } + + /** @deprecated This is an internal implementation detail, do not use. */ + _subscribe(subscriber: Subscriber): TeardownLogic { + return new AjaxSubscriber(subscriber, this.request); + } +} + +/** + * We need this JSDoc comment for affecting ESDoc. + * @ignore + * @extends {Ignored} + */ +export class AjaxSubscriber extends Subscriber { + // @ts-ignore: Property has no initializer and is not definitely assigned + private xhr: XMLHttpRequest; + private done: boolean = false; + + constructor(destination: Subscriber, public request: AjaxRequest) { + super(destination); + + const headers = (request.headers = request.headers || {}); + + // force CORS if requested + if (!request.crossDomain && !this.getHeader(headers, 'X-Requested-With')) { + (headers as any)['X-Requested-With'] = 'XMLHttpRequest'; + } + + // ensure content type is set + let contentTypeHeader = this.getHeader(headers, 'Content-Type'); + if (!contentTypeHeader && typeof request.body !== 'undefined' && !isFormData(request.body)) { + (headers as any)['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; + } + + // properly serialize body + request.body = this.serializeBody(request.body, this.getHeader(request.headers, 'Content-Type')); + + this.send(); + } + + next(e: Event): void { + this.done = true; + const destination = this.destination as Subscriber; + let result: AjaxResponse; + try { + result = new AjaxResponse(e, this.xhr, this.request); + } catch (err) { + return destination.error(err); + } + destination.next(result); + } + + private send(): void { + const { + request, + request: { user, method, url, async, password, headers, body }, + } = this; + try { + const xhr = (this.xhr = request.createXHR!()); + + // set up the events before open XHR + // https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest + // You need to add the event listeners before calling open() on the request. + // Otherwise the progress events will not fire. + this.setupEvents(xhr, request); + // open XHR + if (user) { + xhr.open(method!, url!, async!, user, password); + } else { + xhr.open(method!, url!, async!); + } + + // timeout, responseType and withCredentials can be set once the XHR is open + if (async) { + xhr.timeout = request.timeout!; + xhr.responseType = request.responseType as any; + } + + if ('withCredentials' in xhr) { + xhr.withCredentials = !!request.withCredentials; + } + + // set headers + this.setHeaders(xhr, headers!); + + // finally send the request + if (body) { + xhr.send(body); + } else { + xhr.send(); + } + } catch (err) { + this.error(err); + } + } + + private serializeBody(body: any, contentType?: string) { + if (!body || typeof body === 'string') { + return body; + } else if (isFormData(body)) { + return body; + } + + if (contentType) { + const splitIndex = contentType.indexOf(';'); + if (splitIndex !== -1) { + contentType = contentType.substring(0, splitIndex); + } + } + + switch (contentType) { + case 'application/x-www-form-urlencoded': + return Object.keys(body) + .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(body[key])}`) + .join('&'); + case 'application/json': + return JSON.stringify(body); + default: + return body; + } + } + + private setHeaders(xhr: XMLHttpRequest, headers: Object) { + for (let key in headers) { + if (headers.hasOwnProperty(key)) { + xhr.setRequestHeader(key, (headers as any)[key]); + } + } + } + + private getHeader(headers: {}, headerName: string): any { + for (let key in headers) { + if (key.toLowerCase() === headerName.toLowerCase()) { + return (headers as any)[key]; + } + } + + return undefined; + } + + private setupEvents(xhr: XMLHttpRequest, request: AjaxRequest) { + const progressSubscriber = request.progressSubscriber; + + xhr.ontimeout = (e: ProgressEvent) => { + progressSubscriber?.error?.(e); + let error; + try { + error = new AjaxTimeoutError(xhr, request); // TODO: Make betterer. + } catch (err) { + error = err; + } + this.error(error); + }; + + if (progressSubscriber) { + xhr.upload.onprogress = (e: ProgressEvent) => { + progressSubscriber.next?.(e); + }; + } + + xhr.onerror = (e: ProgressEvent) => { + progressSubscriber?.error?.(e); + this.error(new AjaxError('ajax error', xhr, request)); + }; + + xhr.onload = (e: ProgressEvent) => { + // 4xx and 5xx should error (https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) + if (xhr.status < 400) { + progressSubscriber?.complete?.(); + this.next(e); + this.complete(); + } else { + progressSubscriber?.error?.(e); + let error; + try { + error = new AjaxError('ajax error ' + xhr.status, xhr, request); + } catch (err) { + error = err; + } + this.error(error); + } + }; + } + + unsubscribe() { + const { done, xhr } = this; + if (!done && xhr && xhr.readyState !== 4 && typeof xhr.abort === 'function') { + xhr.abort(); + } + super.unsubscribe(); + } +} + +/** + * A normalized AJAX response. + * + * @see {@link ajax} + * + * @class AjaxResponse + */ +export class AjaxResponse { + /** @type {number} The HTTP status code */ + status: number; + + /** @type {string|ArrayBuffer|Document|object|any} The response data */ + response: any; + + /** @type {string} The raw responseText */ + // @ts-ignore: Property has no initializer and is not definitely assigned + responseText: string; + + /** @type {string} The responseType (e.g. 'json', 'arraybuffer', or 'xml') */ + responseType: string; + + constructor(public originalEvent: Event, public xhr: XMLHttpRequest, public request: AjaxRequest) { + this.status = xhr.status; + this.responseType = xhr.responseType || request.responseType!; + this.response = getXHRResponse(xhr); + } +} + +export type AjaxErrorNames = 'AjaxError' | 'AjaxTimeoutError'; + +/** + * A normalized AJAX error. + * + * @see {@link ajax} + * + * @class AjaxError + */ +export interface AjaxError extends Error { + /** + * The XHR instance associated with the error + */ + xhr: XMLHttpRequest; + + /** + * The AjaxRequest associated with the error + */ + request: AjaxRequest; + + /** + *The HTTP status code + */ + status: number; + + /** + *The responseType (e.g. 'json', 'arraybuffer', or 'xml') + */ + responseType: XMLHttpRequestResponseType; + + /** + * The response data + */ + response: any; +} + +export interface AjaxErrorCtor { + /** + * Internal use only. Do not manually create instances of this type. + * @internal + */ + new (message: string, xhr: XMLHttpRequest, request: AjaxRequest): AjaxError; +} + +const AjaxErrorImpl = (() => { + function AjaxErrorImpl(this: any, message: string, xhr: XMLHttpRequest, request: AjaxRequest): AjaxError { + Error.call(this); + this.message = message; + this.name = 'AjaxError'; + this.xhr = xhr; + this.request = request; + this.status = xhr.status; + this.responseType = xhr.responseType; + let response: any; + try { + response = getXHRResponse(xhr); + } catch (err) { + response = xhr.responseText; + } + this.response = response; + return this; + } + AjaxErrorImpl.prototype = Object.create(Error.prototype); + return AjaxErrorImpl; +})(); + +/** + * Thrown when an error occurs during an AJAX request. + * This is only exported because it is useful for checking to see if an error + * is an `instanceof AjaxError`. DO NOT create new instances of `AjaxError` with + * the constructor. + * + * @class AjaxError + * @see ajax + */ +export const AjaxError: AjaxErrorCtor = AjaxErrorImpl as any; + +function getXHRResponse(xhr: XMLHttpRequest) { + switch (xhr.responseType) { + case 'json': { + if ('response' in xhr) { + return xhr.response; + } else { + // IE + const ieXHR: any = xhr; + return JSON.parse(ieXHR.responseText); + } + } + case 'document': + return xhr.responseXML; + case 'text': + default: { + if ('response' in xhr) { + return xhr.response; + } else { + // IE + const ieXHR: any = xhr; + return ieXHR.responseText; + } + } + } +} + +export interface AjaxTimeoutError extends AjaxError {} + +export interface AjaxTimeoutErrorCtor { + /** + * Internal use only. Do not manually create instances of this type. + * @internal + */ + new (xhr: XMLHttpRequest, request: AjaxRequest): AjaxTimeoutError; +} + +const AjaxTimeoutErrorImpl = (() => { + function AjaxTimeoutErrorImpl(this: any, xhr: XMLHttpRequest, request: AjaxRequest) { + AjaxError.call(this, 'ajax timeout', xhr, request); + this.name = 'AjaxTimeoutError'; + return this; + } + AjaxTimeoutErrorImpl.prototype = Object.create(AjaxError.prototype); + return AjaxTimeoutErrorImpl; +})(); + +/** + * Thrown when an AJAX request timesout. Not to be confused with {@link TimeoutError}. + * + * This is exported only because it is useful for checking to see if errors are an + * `instanceof AjaxTimeoutError`. DO NOT use the constructor to create an instance of + * this type. + * + * @class AjaxTimeoutError + * @see ajax + */ +export const AjaxTimeoutError: AjaxTimeoutErrorCtor = AjaxTimeoutErrorImpl as any; \ No newline at end of file diff --git a/babel/compat/benches/babelify.rs b/babel/compat/benches/babelify.rs new file mode 100644 index 00000000000..307e883268b --- /dev/null +++ b/babel/compat/benches/babelify.rs @@ -0,0 +1,140 @@ +#![feature(test)] + +extern crate test; + +use std::{hint::black_box, sync::Arc}; +use swc_babel_compat::Babelify; +use swc_babel_compat::Context; +use swc_common::SourceFile; +use swc_common::{ + errors::{ColorConfig, Handler}, + FileName, FilePathMapping, SourceMap, +}; +use swc_ecma_ast::Program; +use swc_ecma_parser::{JscTarget, Syntax}; +use swc_ecma_transforms::compat::es2020; +use swc_ecma_transforms::typescript; +use swc_ecma_visit::FoldWith; +use test::Bencher; + +static SOURCE: &str = include_str!("assets/AjaxObservable.ts"); + +fn mk() -> swc::Compiler { + let cm = Arc::new(SourceMap::new(FilePathMapping::empty())); + let handler = Arc::new(Handler::with_tty_emitter( + ColorConfig::Always, + true, + false, + Some(cm.clone()), + )); + + let c = swc::Compiler::new(cm.clone(), handler); + + c +} + +fn parse(c: &swc::Compiler, src: &str) -> (Arc, Program) { + let fm = c.cm.new_source_file( + FileName::Real("rxjs/src/internal/observable/dom/AjaxObservable.ts".into()), + src.to_string(), + ); + let module = c + .parse_js( + fm.clone(), + JscTarget::Es5, + Syntax::Typescript(Default::default()), + true, + true, + ) + .unwrap(); + + (fm, module) +} + +#[bench] +fn babelify_only(b: &mut Bencher) { + b.bytes = SOURCE.len() as _; + + let c = mk(); + let (fm, module) = parse(&c, SOURCE); + let module = c.run_transform(false, || { + module + .fold_with(&mut typescript::strip()) + .fold_with(&mut es2020()) + }); + + b.iter(|| { + let program = module.clone(); + let ctx = Context { + fm: fm.clone(), + cm: c.cm.clone(), + comments: c.comments().clone(), + }; + + let babel_ast = program.babelify(&ctx); + black_box(babel_ast) + }); +} + +fn parse_and_babelify(b: &mut Bencher, _name: &str, src: &str) { + b.bytes = src.len() as _; + + let c = mk(); + + b.iter(|| { + let (fm, program) = parse(&c, src); + let ctx = Context { + fm, + cm: c.cm.clone(), + comments: c.comments().clone(), + }; + + let babel_ast = program.babelify(&ctx); + black_box(babel_ast); + }); +} + +/// https://esprima.org/test/compare.html +macro_rules! src_to_babel_ast { + ($name:ident, $src:expr) => { + #[bench] + fn $name(b: &mut Bencher) { + parse_and_babelify(b, stringify!($name), $src); + } + }; +} + +src_to_babel_ast!( + parse_and_babelify_angular, + include_str!("../../../ecmascript/parser/benches/files/angular-1.2.5.js") +); + +src_to_babel_ast!( + parse_and_babelify_backbone, + include_str!("../../../ecmascript/parser/benches/files/backbone-1.1.0.js") +); + +src_to_babel_ast!( + parse_and_babelify_jquery, + include_str!("../../../ecmascript/parser/benches/files/jquery-1.9.1.js") +); + +src_to_babel_ast!( + parse_and_babelify_jquery_mobile, + include_str!("../../../ecmascript/parser/benches/files/jquery.mobile-1.4.2.js") +); + +src_to_babel_ast!( + parse_and_babelify_mootools, + include_str!("../../../ecmascript/parser/benches/files/mootools-1.4.5.js") +); + +src_to_babel_ast!( + parse_and_babelify_underscore, + include_str!("../../../ecmascript/parser/benches/files/underscore-1.5.2.js") +); + +src_to_babel_ast!( + parse_and_babelify_yui, + include_str!("../../../ecmascript/parser/benches/files/yui-3.12.0.js") +); diff --git a/native/babel-compat/scripts/update.sh b/babel/compat/scripts/update.sh similarity index 100% rename from native/babel-compat/scripts/update.sh rename to babel/compat/scripts/update.sh diff --git a/native/babel-compat/src/class.rs b/babel/compat/src/class.rs similarity index 70% rename from native/babel-compat/src/class.rs rename to babel/compat/src/class.rs index 969491f5e1e..8f14bc6fcea 100644 --- a/native/babel-compat/src/class.rs +++ b/babel/compat/src/class.rs @@ -1,4 +1,5 @@ use crate::{extract_class_body_span, Babelify, Context}; +use copyless::BoxHelper; use serde_json::value::Value; use swc_babel_ast::{ ClassBody, ClassBodyEl, ClassExpression, ClassMethod as BabelClassMethod, ClassMethodKind, @@ -13,26 +14,26 @@ impl Babelify for Class { type Output = ClassExpression; fn babelify(self, ctx: &Context) -> Self::Output { + let body = ClassBody { + base: ctx.base(extract_class_body_span(&self, &ctx)), + body: self.body.babelify(ctx), + }; + ClassExpression { base: ctx.base(self.span), - decorators: Some( - self.decorators - .iter() - .map(|dec| dec.clone().babelify(ctx)) - .collect(), - ), - body: extract_class_body(&self, &ctx), + decorators: Some(self.decorators.babelify(ctx)), + body, super_class: self .super_class - .map(|expr| Box::new(expr.babelify(ctx).into())), + .map(|expr| Box::alloc().init(expr.babelify(ctx).into())), type_parameters: self.type_params.map(|param| param.babelify(ctx).into()), super_type_parameters: self .super_type_params .map(|param| param.babelify(ctx).into()), implements: Some( self.implements - .iter() - .map(|imp| imp.clone().babelify(ctx).into()) + .into_iter() + .map(|imp| imp.babelify(ctx).into()) .collect(), ), id: Default::default(), @@ -60,17 +61,6 @@ impl Babelify for ClassMember { } } -fn extract_class_body(class: &Class, ctx: &Context) -> ClassBody { - ClassBody { - base: ctx.base(extract_class_body_span(&class, &ctx)), - body: class - .body - .iter() - .map(|mem| mem.clone().babelify(ctx)) - .collect(), - } -} - impl Babelify for ClassProp { type Output = ClassProperty; @@ -78,15 +68,14 @@ impl Babelify for ClassProp { ClassProperty { base: ctx.base(self.span), key: self.key.babelify(ctx).into(), - value: self.value.map(|val| Box::new(val.babelify(ctx).into())), - type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx).into())), + value: self + .value + .map(|val| Box::alloc().init(val.babelify(ctx).into())), + type_annotation: self + .type_ann + .map(|ann| Box::alloc().init(ann.babelify(ctx).into())), is_static: Some(self.is_static), - decorators: Some( - self.decorators - .iter() - .map(|dec| dec.clone().babelify(ctx)) - .collect(), - ), + decorators: Some(self.decorators.babelify(ctx)), computed: Some(self.computed), accessibility: self.accessibility.map(|access| access.babelify(ctx)), is_abstract: Some(self.is_abstract), @@ -105,15 +94,14 @@ impl Babelify for PrivateProp { ClassPrivateProperty { base: ctx.base(self.span), key: self.key.babelify(ctx), - value: self.value.map(|expr| Box::new(expr.babelify(ctx).into())), - type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx).into())), + value: self + .value + .map(|expr| Box::alloc().init(expr.babelify(ctx).into())), + type_annotation: self + .type_ann + .map(|ann| Box::alloc().init(ann.babelify(ctx).into())), static_any: Value::Bool(self.is_static), - decorators: Some( - self.decorators - .iter() - .map(|dec| dec.clone().babelify(ctx)) - .collect(), - ), + decorators: Some(self.decorators.babelify(ctx)), } } } @@ -131,27 +119,16 @@ impl Babelify for ClassMethod { accessibility: self.accessibility.map(|access| access.babelify(ctx)), is_abstract: Some(self.is_abstract), optional: Some(self.is_optional), - params: self - .function - .params - .iter() - .map(|param| param.clone().babelify(ctx)) - .collect(), + params: self.function.params.babelify(ctx), body: self.function.body.unwrap().babelify(ctx), generator: Some(self.function.is_generator), is_async: Some(self.function.is_async), - decorators: Some( - self.function - .decorators - .iter() - .map(|dec| dec.clone().babelify(ctx)) - .collect(), - ), + decorators: Some(self.function.decorators.babelify(ctx)), type_parameters: self.function.type_params.map(|t| t.babelify(ctx).into()), return_type: self .function .return_type - .map(|t| Box::new(t.babelify(ctx).into())), + .map(|t| Box::alloc().init(t.babelify(ctx).into())), computed: Default::default(), } } @@ -170,27 +147,16 @@ impl Babelify for PrivateMethod { accessibility: self.accessibility.map(|access| access.babelify(ctx)), is_abstract: Some(self.is_abstract), optional: Some(self.is_optional), - params: self - .function - .params - .iter() - .map(|param| param.clone().babelify(ctx)) - .collect(), + params: self.function.params.babelify(ctx), body: self.function.body.unwrap().babelify(ctx), generator: Some(self.function.is_generator), is_async: Some(self.function.is_async), - decorators: Some( - self.function - .decorators - .iter() - .map(|dec| dec.clone().babelify(ctx)) - .collect(), - ), + decorators: Some(self.function.decorators.babelify(ctx)), type_parameters: self.function.type_params.map(|t| t.babelify(ctx).into()), return_type: self .function .return_type - .map(|t| Box::new(t.babelify(ctx).into())), + .map(|t| Box::alloc().init(t.babelify(ctx).into())), computed: Default::default(), } } @@ -204,11 +170,7 @@ impl Babelify for Constructor { base: ctx.base(self.span), kind: Some(ClassMethodKind::Constructor), key: self.key.babelify(ctx).into(), - params: self - .params - .iter() - .map(|param| param.clone().babelify(ctx)) - .collect(), + params: self.params.babelify(ctx), body: self.body.unwrap().babelify(ctx), access: self.accessibility.map(|access| access.babelify(ctx)), accessibility: self.accessibility.map(|access| access.babelify(ctx)), @@ -231,7 +193,7 @@ impl Babelify for Decorator { fn babelify(self, ctx: &Context) -> Self::Output { BabelDecorator { base: ctx.base(self.span), - expression: Box::new(self.expr.babelify(ctx).into()), + expression: Box::alloc().init(self.expr.babelify(ctx).into()), } } } diff --git a/native/babel-compat/src/decl.rs b/babel/compat/src/decl.rs similarity index 93% rename from native/babel-compat/src/decl.rs rename to babel/compat/src/decl.rs index 5123eff954c..c945ed9911f 100644 --- a/native/babel-compat/src/decl.rs +++ b/babel/compat/src/decl.rs @@ -1,4 +1,5 @@ use crate::{extract_class_body_span, Babelify, Context}; +use copyless::BoxHelper; use swc_babel_ast::{ ClassBody, ClassDeclaration, Declaration, FunctionDeclaration, VariableDeclaration, VariableDeclarationKind, VariableDeclarator, @@ -68,7 +69,7 @@ impl Babelify for ClassDecl { ClassDeclaration { base: class.base, id: self.ident.babelify(ctx), - super_class: class.super_class.map(|s| Box::new(*s)), + super_class: class.super_class.map(|s| Box::alloc().init(*s)), body: ClassBody { base: ctx.base(body_span), ..class.body @@ -92,11 +93,7 @@ impl Babelify for VarDecl { base: ctx.base(self.span), kind: self.kind.babelify(ctx), declare: Some(self.declare), - declarations: self - .decls - .iter() - .map(|decl| decl.clone().babelify(ctx)) - .collect(), + declarations: self.decls.babelify(ctx), } } } @@ -120,7 +117,7 @@ impl Babelify for VarDeclarator { VariableDeclarator { base: ctx.base(self.span), id: self.name.babelify(ctx).into(), - init: self.init.map(|i| Box::new(i.babelify(ctx).into())), + init: self.init.map(|i| Box::alloc().init(i.babelify(ctx).into())), definite: Some(self.definite), } } diff --git a/native/babel-compat/src/expr.rs b/babel/compat/src/expr.rs similarity index 67% rename from native/babel-compat/src/expr.rs rename to babel/compat/src/expr.rs index 2bee72d93cd..b594f998f17 100644 --- a/native/babel-compat/src/expr.rs +++ b/babel/compat/src/expr.rs @@ -1,4 +1,6 @@ use crate::{Babelify, Context}; +use copyless::BoxHelper; +use serde::{Deserialize, Serialize}; use swc_babel_ast::{ ArrayExprEl, ArrayExpression, ArrowFuncExprBody, ArrowFunctionExpression, AssignmentExpression, AwaitExpression, BinaryExprLeft, BinaryExpression, CallExpression, Callee, ClassExpression, @@ -9,8 +11,6 @@ use swc_babel_ast::{ TaggedTemplateExpression, TemplateElVal, TemplateElement, TemplateLiteral, TemplateLiteralExpr, ThisExpression, UnaryExpression, UpdateExpression, YieldExpression, }; - -use serde::{Deserialize, Serialize}; use swc_common::Spanned; use swc_ecma_ast::{ ArrayLit, ArrowExpr, AssignExpr, AwaitExpr, BinExpr, BinaryOp, BlockStmtOrExpr, CallExpr, @@ -30,47 +30,63 @@ impl Babelify for Expr { fn babelify(self, ctx: &Context) -> Self::Output { match self { - Expr::This(t) => ExprOutput::Expr(Box::new(Expression::This(t.babelify(ctx)))), - Expr::Array(a) => ExprOutput::Expr(Box::new(Expression::Array(a.babelify(ctx)))), - Expr::Object(o) => ExprOutput::Expr(Box::new(Expression::Object(o.babelify(ctx)))), - Expr::Fn(f) => ExprOutput::Expr(Box::new(Expression::Func(f.babelify(ctx)))), - Expr::Unary(u) => ExprOutput::Expr(Box::new(Expression::Unary(u.babelify(ctx)))), - Expr::Update(u) => ExprOutput::Expr(Box::new(Expression::Update(u.babelify(ctx)))), + Expr::This(t) => ExprOutput::Expr(Box::alloc().init(Expression::This(t.babelify(ctx)))), + Expr::Array(a) => { + ExprOutput::Expr(Box::alloc().init(Expression::Array(a.babelify(ctx)))) + } + Expr::Object(o) => { + ExprOutput::Expr(Box::alloc().init(Expression::Object(o.babelify(ctx)))) + } + Expr::Fn(f) => ExprOutput::Expr(Box::alloc().init(Expression::Func(f.babelify(ctx)))), + Expr::Unary(u) => { + ExprOutput::Expr(Box::alloc().init(Expression::Unary(u.babelify(ctx)))) + } + Expr::Update(u) => { + ExprOutput::Expr(Box::alloc().init(Expression::Update(u.babelify(ctx)))) + } Expr::Bin(b) => match b.babelify(ctx) { BinaryOrLogicalExpr::Binary(bin) => { - ExprOutput::Expr(Box::new(Expression::Binary(bin))) + ExprOutput::Expr(Box::alloc().init(Expression::Binary(bin))) } BinaryOrLogicalExpr::Logical(log) => { - ExprOutput::Expr(Box::new(Expression::Logical(log))) + ExprOutput::Expr(Box::alloc().init(Expression::Logical(log))) } }, - Expr::Assign(a) => ExprOutput::Expr(Box::new(Expression::Assignment(a.babelify(ctx)))), - Expr::Member(m) => ExprOutput::Expr(Box::new(Expression::Member(m.babelify(ctx)))), - Expr::Cond(c) => ExprOutput::Expr(Box::new(Expression::Conditional(c.babelify(ctx)))), - Expr::Call(c) => ExprOutput::Expr(Box::new(Expression::Call(c.babelify(ctx)))), - Expr::New(n) => ExprOutput::Expr(Box::new(Expression::New(n.babelify(ctx)))), - Expr::Seq(s) => ExprOutput::Expr(Box::new(Expression::Sequence(s.babelify(ctx)))), - Expr::Ident(i) => ExprOutput::Expr(Box::new(Expression::Id(i.babelify(ctx)))), + Expr::Assign(a) => { + ExprOutput::Expr(Box::alloc().init(Expression::Assignment(a.babelify(ctx)))) + } + Expr::Member(m) => { + ExprOutput::Expr(Box::alloc().init(Expression::Member(m.babelify(ctx)))) + } + Expr::Cond(c) => { + ExprOutput::Expr(Box::alloc().init(Expression::Conditional(c.babelify(ctx)))) + } + Expr::Call(c) => ExprOutput::Expr(Box::alloc().init(Expression::Call(c.babelify(ctx)))), + Expr::New(n) => ExprOutput::Expr(Box::alloc().init(Expression::New(n.babelify(ctx)))), + Expr::Seq(s) => { + ExprOutput::Expr(Box::alloc().init(Expression::Sequence(s.babelify(ctx)))) + } + Expr::Ident(i) => ExprOutput::Expr(Box::alloc().init(Expression::Id(i.babelify(ctx)))), Expr::Lit(lit) => { match lit { - Lit::Str(s) => { - ExprOutput::Expr(Box::new(Expression::StringLiteral(s.babelify(ctx)))) - } - Lit::Bool(b) => { - ExprOutput::Expr(Box::new(Expression::BooleanLiteral(b.babelify(ctx)))) - } - Lit::Null(n) => { - ExprOutput::Expr(Box::new(Expression::NullLiteral(n.babelify(ctx)))) - } - Lit::Num(n) => { - ExprOutput::Expr(Box::new(Expression::NumericLiteral(n.babelify(ctx)))) - } - Lit::BigInt(i) => { - ExprOutput::Expr(Box::new(Expression::BigIntLiteral(i.babelify(ctx)))) - } - Lit::Regex(r) => { - ExprOutput::Expr(Box::new(Expression::RegExpLiteral(r.babelify(ctx)))) - } + Lit::Str(s) => ExprOutput::Expr( + Box::alloc().init(Expression::StringLiteral(s.babelify(ctx))), + ), + Lit::Bool(b) => ExprOutput::Expr( + Box::alloc().init(Expression::BooleanLiteral(b.babelify(ctx))), + ), + Lit::Null(n) => ExprOutput::Expr( + Box::alloc().init(Expression::NullLiteral(n.babelify(ctx))), + ), + Lit::Num(n) => ExprOutput::Expr( + Box::alloc().init(Expression::NumericLiteral(n.babelify(ctx))), + ), + Lit::BigInt(i) => ExprOutput::Expr( + Box::alloc().init(Expression::BigIntLiteral(i.babelify(ctx))), + ), + Lit::Regex(r) => ExprOutput::Expr( + Box::alloc().init(Expression::RegExpLiteral(r.babelify(ctx))), + ), Lit::JSXText(_) => panic!( "illegal conversion: Cannot convert {:?} to ExprOutput", &lit @@ -78,32 +94,42 @@ impl Babelify for Expr { } } Expr::Tpl(t) => { - ExprOutput::Expr(Box::new(Expression::TemplateLiteral(t.babelify(ctx)))) + ExprOutput::Expr(Box::alloc().init(Expression::TemplateLiteral(t.babelify(ctx)))) } Expr::TaggedTpl(t) => { - ExprOutput::Expr(Box::new(Expression::TaggedTemplate(t.babelify(ctx)))) + ExprOutput::Expr(Box::alloc().init(Expression::TaggedTemplate(t.babelify(ctx)))) + } + Expr::Arrow(a) => { + ExprOutput::Expr(Box::alloc().init(Expression::ArrowFunc(a.babelify(ctx)))) + } + Expr::Class(c) => { + ExprOutput::Expr(Box::alloc().init(Expression::Class(c.babelify(ctx)))) + } + Expr::Yield(y) => { + ExprOutput::Expr(Box::alloc().init(Expression::Yield(y.babelify(ctx)))) + } + Expr::MetaProp(m) => { + ExprOutput::Expr(Box::alloc().init(Expression::MetaProp(m.babelify(ctx)))) + } + Expr::Await(a) => { + ExprOutput::Expr(Box::alloc().init(Expression::Await(a.babelify(ctx)))) } - Expr::Arrow(a) => ExprOutput::Expr(Box::new(Expression::ArrowFunc(a.babelify(ctx)))), - Expr::Class(c) => ExprOutput::Expr(Box::new(Expression::Class(c.babelify(ctx)))), - Expr::Yield(y) => ExprOutput::Expr(Box::new(Expression::Yield(y.babelify(ctx)))), - Expr::MetaProp(m) => ExprOutput::Expr(Box::new(Expression::MetaProp(m.babelify(ctx)))), - Expr::Await(a) => ExprOutput::Expr(Box::new(Expression::Await(a.babelify(ctx)))), Expr::Paren(p) => { - ExprOutput::Expr(Box::new(Expression::Parenthesized(p.babelify(ctx)))) + ExprOutput::Expr(Box::alloc().init(Expression::Parenthesized(p.babelify(ctx)))) } Expr::JSXElement(e) => { - ExprOutput::Expr(Box::new(Expression::JSXElement(e.babelify(ctx)))) + ExprOutput::Expr(Box::alloc().init(Expression::JSXElement(e.babelify(ctx)))) } Expr::JSXFragment(f) => { - ExprOutput::Expr(Box::new(Expression::JSXFragment(f.babelify(ctx)))) + ExprOutput::Expr(Box::alloc().init(Expression::JSXFragment(f.babelify(ctx)))) } Expr::TsTypeAssertion(a) => { - ExprOutput::Expr(Box::new(Expression::TSTypeAssertion(a.babelify(ctx)))) + ExprOutput::Expr(Box::alloc().init(Expression::TSTypeAssertion(a.babelify(ctx)))) } Expr::TsNonNull(n) => { - ExprOutput::Expr(Box::new(Expression::TSNonNull(n.babelify(ctx)))) + ExprOutput::Expr(Box::alloc().init(Expression::TSNonNull(n.babelify(ctx)))) } - Expr::TsAs(a) => ExprOutput::Expr(Box::new(Expression::TSAs(a.babelify(ctx)))), + Expr::TsAs(a) => ExprOutput::Expr(Box::alloc().init(Expression::TSAs(a.babelify(ctx)))), Expr::PrivateName(p) => ExprOutput::Private(p.babelify(ctx)), // TODO(dwoznicki): how does babel handle these? @@ -201,11 +227,7 @@ impl Babelify for ArrayLit { fn babelify(self, ctx: &Context) -> Self::Output { ArrayExpression { base: ctx.base(self.span), - elements: self - .elems - .iter() - .map(|opt| opt.as_ref().map(|el| el.clone().babelify(ctx))) - .collect(), + elements: self.elems.babelify(ctx), } } } @@ -216,11 +238,7 @@ impl Babelify for ObjectLit { fn babelify(self, ctx: &Context) -> Self::Output { ObjectExpression { base: ctx.base(self.span), - properties: self - .props - .iter() - .map(|prop| prop.clone().babelify(ctx)) - .collect(), + properties: self.props.babelify(ctx), } } } @@ -248,7 +266,7 @@ impl Babelify for SpreadElement { fn babelify(self, ctx: &Context) -> Self::Output { BabelSpreadElement { base: ctx.base(self.span()), - argument: Box::new(self.expr.babelify(ctx).into()), + argument: Box::alloc().init(self.expr.babelify(ctx).into()), } } } @@ -260,7 +278,7 @@ impl Babelify for UnaryExpr { UnaryExpression { base: ctx.base(self.span), operator: self.op.babelify(ctx), - argument: Box::new(self.arg.babelify(ctx).into()), + argument: Box::alloc().init(self.arg.babelify(ctx).into()), prefix: true, } } @@ -274,7 +292,7 @@ impl Babelify for UpdateExpr { base: ctx.base(self.span), operator: self.op.babelify(ctx), prefix: self.prefix, - argument: Box::new(self.arg.babelify(ctx).into()), + argument: Box::alloc().init(self.arg.babelify(ctx).into()), } } } @@ -294,23 +312,23 @@ impl Babelify for BinExpr { BinaryOrLogicalExpr::Logical(LogicalExpression { base: ctx.base(self.span), operator: self.op.babelify(ctx).into(), - left: Box::new(self.left.babelify(ctx).into()), - right: Box::new(self.right.babelify(ctx).into()), + left: Box::alloc().init(self.left.babelify(ctx).into()), + right: Box::alloc().init(self.right.babelify(ctx).into()), }) } _ => BinaryOrLogicalExpr::Binary(BinaryExpression { base: ctx.base(self.span), operator: self.op.babelify(ctx).into(), - left: Box::new(self.left.babelify(ctx).into()), - right: Box::new(self.right.babelify(ctx).into()), + left: Box::alloc().init(self.left.babelify(ctx).into()), + right: Box::alloc().init(self.right.babelify(ctx).into()), }), } // BinaryExpression { // base: ctx.base(self.span), // operator: self.op.babelify(ctx).into(), - // left: Box::new(self.left.babelify(ctx).into()), - // right: Box::new(self.right.babelify(ctx).into()), + // left: Box::alloc().init(self.left.babelify(ctx).into()), + // right: Box::alloc().init(self.right.babelify(ctx).into()), // } } } @@ -343,9 +361,9 @@ impl Babelify for AssignExpr { fn babelify(self, ctx: &Context) -> Self::Output { AssignmentExpression { base: ctx.base(self.span), - operator: self.op.to_string(), - left: Box::new(self.left.babelify(ctx)), - right: Box::new(self.right.babelify(ctx).into()), + operator: self.op.as_str().into(), + left: Box::alloc().init(self.left.babelify(ctx)), + right: Box::alloc().init(self.right.babelify(ctx).into()), } } } @@ -356,8 +374,8 @@ impl Babelify for MemberExpr { fn babelify(self, ctx: &Context) -> Self::Output { MemberExpression { base: ctx.base(self.span), - object: Box::new(self.obj.babelify(ctx)), - property: Box::new(self.prop.babelify(ctx).into()), + object: Box::alloc().init(self.obj.babelify(ctx)), + property: Box::alloc().init(self.prop.babelify(ctx).into()), computed: self.computed, optional: Default::default(), } @@ -370,9 +388,9 @@ impl Babelify for CondExpr { fn babelify(self, ctx: &Context) -> Self::Output { ConditionalExpression { base: ctx.base(self.span), - test: Box::new(self.test.babelify(ctx).into()), - consequent: Box::new(self.cons.babelify(ctx).into()), - alternate: Box::new(self.alt.babelify(ctx).into()), + test: Box::alloc().init(self.test.babelify(ctx).into()), + consequent: Box::alloc().init(self.cons.babelify(ctx).into()), + alternate: Box::alloc().init(self.alt.babelify(ctx).into()), } } } @@ -383,11 +401,11 @@ impl Babelify for CallExpr { fn babelify(self, ctx: &Context) -> Self::Output { CallExpression { base: ctx.base(self.span), - callee: Box::new(self.callee.babelify(ctx).into()), + callee: Box::alloc().init(self.callee.babelify(ctx).into()), arguments: self .args - .iter() - .map(|arg| arg.clone().babelify(ctx).into()) + .into_iter() + .map(|arg| arg.babelify(ctx).into()) .collect(), type_parameters: self.type_args.map(|t| t.babelify(ctx)), type_arguments: Default::default(), @@ -402,11 +420,11 @@ impl Babelify for NewExpr { fn babelify(self, ctx: &Context) -> Self::Output { NewExpression { base: ctx.base(self.span), - callee: Callee::Expr(Box::new(self.callee.babelify(ctx).into())), + callee: Callee::Expr(Box::alloc().init(self.callee.babelify(ctx).into())), arguments: match self.args { Some(args) => args - .iter() - .map(|arg| arg.clone().babelify(ctx).into()) + .into_iter() + .map(|arg| arg.babelify(ctx).into()) .collect(), None => vec![], }, @@ -425,8 +443,8 @@ impl Babelify for SeqExpr { base: ctx.base(self.span), expressions: self .exprs - .iter() - .map(|expr| Box::new(expr.clone().babelify(ctx).into())) + .into_iter() + .map(|expr| Box::alloc().init(expr.babelify(ctx).into())) .collect(), } } @@ -440,15 +458,17 @@ impl Babelify for ArrowExpr { base: ctx.base(self.span), params: self .params - .iter() - .map(|p| p.clone().babelify(ctx).into()) + .into_iter() + .map(|p| p.babelify(ctx).into()) .collect(), - body: Box::new(self.body.babelify(ctx)), + body: Box::alloc().init(self.body.babelify(ctx)), is_async: self.is_async, 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::new(t.babelify(ctx).into())), + return_type: self + .return_type + .map(|t| Box::alloc().init(t.babelify(ctx).into())), } } } @@ -459,7 +479,7 @@ impl Babelify for YieldExpr { fn babelify(self, ctx: &Context) -> Self::Output { YieldExpression { base: ctx.base(self.span), - argument: self.arg.map(|a| Box::new(a.babelify(ctx).into())), + argument: self.arg.map(|a| Box::alloc().init(a.babelify(ctx).into())), delegate: self.delegate, } } @@ -483,7 +503,7 @@ impl Babelify for AwaitExpr { fn babelify(self, ctx: &Context) -> Self::Output { AwaitExpression { base: ctx.base(self.span), - argument: Box::new(self.arg.babelify(ctx).into()), + argument: Box::alloc().init(self.arg.babelify(ctx).into()), } } } @@ -496,14 +516,10 @@ impl Babelify for Tpl { base: ctx.base(self.span), expressions: self .exprs - .iter() - .map(|e| TemplateLiteralExpr::Expr(Box::new(e.clone().babelify(ctx).into()))) - .collect(), - quasis: self - .quasis - .iter() - .map(|q| q.clone().babelify(ctx)) + .into_iter() + .map(|e| TemplateLiteralExpr::Expr(Box::alloc().init(e.babelify(ctx).into()))) .collect(), + quasis: self.quasis.babelify(ctx), } } } @@ -514,7 +530,7 @@ impl Babelify for TaggedTpl { fn babelify(self, ctx: &Context) -> Self::Output { TaggedTemplateExpression { base: ctx.base(self.span), - tag: Box::new(self.tag.babelify(ctx).into()), + tag: Box::alloc().init(self.tag.babelify(ctx).into()), quasi: self.tpl.babelify(ctx), type_parameters: self .type_params @@ -531,8 +547,8 @@ impl Babelify for TplElement { base: ctx.base(self.span), tail: self.tail, value: TemplateElVal { - raw: self.raw.value.to_string(), - cooked: self.cooked.map(|s| s.value.to_string()), + raw: self.raw.value, + cooked: self.cooked.map(|s| s.value), }, } } @@ -544,7 +560,7 @@ impl Babelify for ParenExpr { fn babelify(self, ctx: &Context) -> Self::Output { ParenthesizedExpression { base: ctx.base(self.span), - expression: Box::new(self.expr.babelify(ctx).into()), + expression: Box::alloc().init(self.expr.babelify(ctx).into()), } } } @@ -577,9 +593,9 @@ impl Babelify for ExprOrSpread { match self.spread { Some(_) => ArrayExprEl::Spread(BabelSpreadElement { base: ctx.base(self.span()), - argument: Box::new(self.expr.babelify(ctx).into()), + argument: Box::alloc().init(self.expr.babelify(ctx).into()), }), - None => ArrayExprEl::Expr(Box::new(self.expr.babelify(ctx).into())), + None => ArrayExprEl::Expr(Box::alloc().init(self.expr.babelify(ctx).into())), } } } @@ -590,7 +606,9 @@ impl Babelify for BlockStmtOrExpr { fn babelify(self, ctx: &Context) -> Self::Output { match self { BlockStmtOrExpr::BlockStmt(b) => ArrowFuncExprBody::Block(b.babelify(ctx)), - BlockStmtOrExpr::Expr(e) => ArrowFuncExprBody::Expr(Box::new(e.babelify(ctx).into())), + BlockStmtOrExpr::Expr(e) => { + ArrowFuncExprBody::Expr(Box::alloc().init(e.babelify(ctx).into())) + } } } } @@ -601,6 +619,7 @@ impl Babelify for PatOrExpr { fn babelify(self, ctx: &Context) -> Self::Output { match self { PatOrExpr::Expr(e) => match *e { + Expr::Ident(i) => LVal::Id(i.babelify(ctx)), Expr::Member(me) => LVal::MemberExpr(me.babelify(ctx)), _ => panic!("illegal conversion: Cannot convert {:?} to LVal", &e), }, diff --git a/native/babel-compat/src/function.rs b/babel/compat/src/function.rs similarity index 63% rename from native/babel-compat/src/function.rs rename to babel/compat/src/function.rs index f8cb2a4dc2d..4372e2bf3e7 100644 --- a/native/babel-compat/src/function.rs +++ b/babel/compat/src/function.rs @@ -1,9 +1,9 @@ use crate::{Babelify, Context}; +use copyless::BoxHelper; use swc_babel_ast::{ ArrayPattern, AssignmentPattern, FunctionExpression, Identifier, ObjectPattern, Param as BabelParam, Pattern, RestElement, }; - use swc_ecma_ast::{Function, Param, ParamOrTsParamProp, Pat}; impl Babelify for Function { @@ -12,16 +12,14 @@ impl Babelify for Function { fn babelify(self, ctx: &Context) -> Self::Output { FunctionExpression { base: ctx.base(self.span), - params: self - .params - .iter() - .map(|param| param.clone().babelify(ctx)) - .collect(), + params: self.params.babelify(ctx), body: self.body.unwrap().babelify(ctx), generator: Some(self.is_generator), is_async: Some(self.is_async), type_parameters: self.type_params.map(|t| t.babelify(ctx).into()), - return_type: self.return_type.map(|t| Box::new(t.babelify(ctx).into())), + return_type: self + .return_type + .map(|t| Box::alloc().init(t.babelify(ctx).into())), id: None, } } @@ -34,52 +32,27 @@ impl Babelify for Param { match self.pat { Pat::Ident(i) => BabelParam::Id(Identifier { base: ctx.base(self.span), - decorators: Some( - self.decorators - .iter() - .map(|dec| dec.clone().babelify(ctx)) - .collect(), - ), + decorators: Some(self.decorators.babelify(ctx)), ..i.babelify(ctx) }), Pat::Array(a) => BabelParam::Pat(Pattern::Array(ArrayPattern { base: ctx.base(self.span), - decorators: Some( - self.decorators - .iter() - .map(|dec| dec.clone().babelify(ctx)) - .collect(), - ), + decorators: Some(self.decorators.babelify(ctx)), ..a.babelify(ctx) })), Pat::Rest(r) => BabelParam::Rest(RestElement { base: ctx.base(self.span), - decorators: Some( - self.decorators - .iter() - .map(|dec| dec.clone().babelify(ctx)) - .collect(), - ), + decorators: Some(self.decorators.babelify(ctx)), ..r.babelify(ctx) }), Pat::Object(o) => BabelParam::Pat(Pattern::Object(ObjectPattern { base: ctx.base(self.span), - decorators: Some( - self.decorators - .iter() - .map(|dec| dec.clone().babelify(ctx)) - .collect(), - ), + decorators: Some(self.decorators.babelify(ctx)), ..o.babelify(ctx) })), Pat::Assign(a) => BabelParam::Pat(Pattern::Assignment(AssignmentPattern { base: ctx.base(self.span), - decorators: Some( - self.decorators - .iter() - .map(|dec| dec.clone().babelify(ctx)) - .collect(), - ), + decorators: Some(self.decorators.babelify(ctx)), ..a.babelify(ctx) })), Pat::Expr(_) => panic!( diff --git a/native/babel-compat/src/ident.rs b/babel/compat/src/ident.rs similarity index 83% rename from native/babel-compat/src/ident.rs rename to babel/compat/src/ident.rs index 0a205e1cd74..60243afacae 100644 --- a/native/babel-compat/src/ident.rs +++ b/babel/compat/src/ident.rs @@ -1,6 +1,6 @@ use crate::{Babelify, Context}; +use copyless::BoxHelper; use swc_babel_ast::{Identifier, PrivateName as BabelPrivateName}; - use swc_ecma_ast::{BindingIdent, Ident, PrivateName}; impl Babelify for BindingIdent { @@ -8,7 +8,9 @@ impl Babelify for BindingIdent { fn babelify(self, ctx: &Context) -> Self::Output { Identifier { - type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx).into())), + type_annotation: self + .type_ann + .map(|ann| Box::alloc().init(ann.babelify(ctx).into())), ..self.id.babelify(ctx) } } @@ -20,7 +22,7 @@ impl Babelify for Ident { fn babelify(self, ctx: &Context) -> Self::Output { Identifier { base: ctx.base(self.span), - name: self.sym.to_string(), + name: self.sym, optional: Some(self.optional), decorators: Default::default(), type_annotation: Default::default(), diff --git a/native/babel-compat/src/jsx.rs b/babel/compat/src/jsx.rs similarity index 90% rename from native/babel-compat/src/jsx.rs rename to babel/compat/src/jsx.rs index 694f72c5076..d900ceabcc7 100644 --- a/native/babel-compat/src/jsx.rs +++ b/babel/compat/src/jsx.rs @@ -1,4 +1,5 @@ use crate::{Babelify, Context}; +use copyless::BoxHelper; use swc_babel_ast::{ JSXAttrName as BabelJSXAttrName, JSXAttrVal, JSXAttribute, JSXClosingElement as BabelJSXClosingElement, JSXClosingFragment as BabelJSXClosingFragment, @@ -9,7 +10,6 @@ use swc_babel_ast::{ JSXOpeningElement as BabelJSXOpeningElement, JSXOpeningFragment as BabelJSXOpeningFragment, JSXSpreadAttribute, JSXSpreadChild as BabelJSXSpreadChild, JSXText as BabelJSXText, }; - use swc_common::{BytePos, Span, Spanned}; use swc_ecma_ast::{ JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXClosingElement, JSXClosingFragment, @@ -35,7 +35,7 @@ impl Babelify for JSXMemberExpr { fn babelify(self, ctx: &Context) -> Self::Output { JSXMemberExpression { base: ctx.base(self.span()), - object: Box::new(self.obj.babelify(ctx)), + object: Box::alloc().init(self.obj.babelify(ctx)), property: self.prop.babelify(ctx).into(), } } @@ -80,7 +80,9 @@ impl Babelify for JSXExpr { fn babelify(self, ctx: &Context) -> Self::Output { match self { JSXExpr::JSXEmptyExpr(e) => JSXExprContainerExpr::Empty(e.babelify(ctx)), - JSXExpr::Expr(e) => JSXExprContainerExpr::Expr(Box::new(e.babelify(ctx).into())), + JSXExpr::Expr(e) => { + JSXExprContainerExpr::Expr(Box::alloc().init(e.babelify(ctx).into())) + } } } } @@ -91,7 +93,7 @@ impl Babelify for JSXSpreadChild { fn babelify(self, ctx: &Context) -> Self::Output { BabelJSXSpreadChild { base: ctx.base(self.span), - expression: Box::new(self.expr.babelify(ctx).into()), + expression: Box::alloc().init(self.expr.babelify(ctx).into()), } } } @@ -115,11 +117,7 @@ impl Babelify for JSXOpeningElement { BabelJSXOpeningElement { base: ctx.base(self.span), name: self.name.babelify(ctx), - attributes: self - .attrs - .iter() - .map(|attr| attr.clone().babelify(ctx)) - .collect(), + attributes: self.attrs.babelify(ctx), self_closing: self.self_closing, type_parameters: self.type_args.map(|arg| arg.babelify(ctx).into()), } @@ -138,7 +136,7 @@ impl Babelify for JSXAttrOrSpread { let span = extend_spread_span_to_braces(spread.span(), ctx); JSXOpeningElAttr::Spread(JSXSpreadAttribute { base: ctx.base(span), - argument: Box::new(spread.expr.babelify(ctx).into()), + argument: Box::alloc().init(spread.expr.babelify(ctx).into()), }) } } @@ -147,7 +145,7 @@ impl Babelify for JSXAttrOrSpread { fn extend_spread_span_to_braces(sp: Span, ctx: &Context) -> Span { let mut span = sp; - if let Ok(prev_source) = ctx.cm.span_to_prev_source(sp) { + let _ = ctx.cm.with_span_to_prev_source(sp, |prev_source| { let mut num_chars = 0; for c in prev_source.chars().rev() { num_chars += 1; @@ -157,9 +155,9 @@ fn extend_spread_span_to_braces(sp: Span, ctx: &Context) -> Span { break; } } - } + }); - if let Ok(next_source) = ctx.cm.span_to_next_source(sp) { + let _ = ctx.cm.with_span_to_next_source(sp, |next_source| { let mut num_chars = 0; for c in next_source.chars() { num_chars += 1; @@ -169,7 +167,7 @@ fn extend_spread_span_to_braces(sp: Span, ctx: &Context) -> Span { break; } } - } + }); span } @@ -237,7 +235,7 @@ impl Babelify for JSXText { fn babelify(self, ctx: &Context) -> Self::Output { BabelJSXText { base: ctx.base(self.span), - value: self.value.to_string(), + value: self.value, } } } @@ -251,11 +249,7 @@ impl Babelify for JSXElement { base: ctx.base(self.span), opening_element: self.opening.babelify(ctx), closing_element: self.closing.map(|el| el.babelify(ctx)), - children: self - .children - .iter() - .map(|el| el.clone().babelify(ctx)) - .collect(), + children: self.children.babelify(ctx), self_closing: Some(self_closing), } } @@ -283,11 +277,7 @@ impl Babelify for JSXFragment { base: ctx.base(self.span), opening_fragment: self.opening.babelify(ctx), closing_fragment: self.closing.babelify(ctx), - children: self - .children - .iter() - .map(|el| el.clone().babelify(ctx)) - .collect(), + children: self.children.babelify(ctx), } } } diff --git a/native/babel-compat/src/lib.rs b/babel/compat/src/lib.rs similarity index 79% rename from native/babel-compat/src/lib.rs rename to babel/compat/src/lib.rs index 968a9b81df4..f247a95f175 100644 --- a/native/babel-compat/src/lib.rs +++ b/babel/compat/src/lib.rs @@ -1,11 +1,14 @@ #![feature(type_name_of_val)] +use rayon::prelude::*; use serde::de::DeserializeOwned; use serde::Serialize; use std::sync::Arc; +use swc::SwcComments; use swc_babel_ast::{BaseComment, BaseNode, Comment, LineCol, Loc}; use swc_common::comments::CommentKind; use swc_common::comments::Comments; +use swc_common::sync::Lrc; use swc_common::BytePos; use swc_common::SourceFile; use swc_common::SourceMap; @@ -21,19 +24,18 @@ mod jsx; mod lit; mod module; mod module_decl; +pub mod normalize; mod operators; mod pat; mod prop; mod stmt; mod typescript; -pub mod normalize; - #[derive(Clone)] pub struct Context { pub fm: Arc, - pub cm: Arc, - pub comments: Arc, + pub cm: Lrc, + pub comments: SwcComments, } impl Context { @@ -53,7 +55,7 @@ impl Context { } fn line_col(&self, pos: BytePos) -> Option { - let loc = self.cm.lookup_char_pos(pos); + let loc = self.cm.lookup_char_pos_with(self.fm.clone(), pos); Some(LineCol { line: loc.line, @@ -127,12 +129,42 @@ impl Context { } } -pub trait Babelify { - type Output: Serialize + DeserializeOwned; +pub trait Babelify: Send + Sync { + type Output: Serialize + DeserializeOwned + Send + Sync; + + fn parallel(_cnt: usize) -> bool { + false + } fn babelify(self, ctx: &Context) -> Self::Output; } +impl Babelify for Vec +where + T: Babelify, +{ + type Output = Vec; + + fn babelify(self, ctx: &Context) -> Self::Output { + if T::parallel(self.len()) { + self.into_par_iter().map(|v| v.babelify(ctx)).collect() + } else { + self.into_iter().map(|v| v.babelify(ctx)).collect() + } + } +} + +impl Babelify for Option +where + T: Babelify, +{ + type Output = Option; + + fn babelify(self, ctx: &Context) -> Self::Output { + self.map(|v| v.babelify(ctx)) + } +} + fn extract_class_body_span(class: &Class, ctx: &Context) -> Span { let sp = ctx.cm.span_take_while(class.span, |ch| *ch != '{'); class.span.with_lo(sp.hi()) diff --git a/native/babel-compat/src/lit.rs b/babel/compat/src/lit.rs similarity index 94% rename from native/babel-compat/src/lit.rs rename to babel/compat/src/lit.rs index d21e36f59b1..602b1ca950f 100644 --- a/native/babel-compat/src/lit.rs +++ b/babel/compat/src/lit.rs @@ -35,7 +35,7 @@ impl Babelify for Str { fn babelify(self, ctx: &Context) -> Self::Output { StringLiteral { base: ctx.base(self.span), - value: self.value.to_string(), + value: self.value, } } } @@ -89,8 +89,8 @@ impl Babelify for Regex { fn babelify(self, ctx: &Context) -> Self::Output { RegExpLiteral { base: ctx.base(self.span), - pattern: self.exp.to_string(), - flags: self.flags.to_string(), + pattern: self.exp, + flags: self.flags, } } } diff --git a/native/babel-compat/src/module.rs b/babel/compat/src/module.rs similarity index 82% rename from native/babel-compat/src/module.rs rename to babel/compat/src/module.rs index 800da6afbd7..436ea931725 100644 --- a/native/babel-compat/src/module.rs +++ b/babel/compat/src/module.rs @@ -1,14 +1,11 @@ use crate::{Babelify, Context}; use serde::{Deserialize, Serialize}; -use std::sync::Arc; +use swc::SwcComments; use swc_babel_ast::{ BaseNode, File, InterpreterDirective, LineCol, Loc, ModuleDeclaration, Program as BabelProgram, SrcType, Statement, }; -use swc_common::{ - comments::{Comment, Comments, CommentsExt}, - Span, -}; +use swc_common::{comments::Comment, Span}; use swc_ecma_ast::{Invalid, Module, ModuleItem, Program, Script}; use swc_ecma_visit::{Node, Visit, VisitWith}; @@ -48,16 +45,16 @@ impl Babelify for Module { self.span }; BabelProgram { - base: base_with_trailing_newline(span.clone(), ctx), + base: base_with_trailing_newline(span, ctx), source_type: SrcType::Module, body: self .body - .iter() - .map(|stmt| stmt.clone().babelify(ctx).into()) + .into_iter() + .map(|stmt| stmt.babelify(ctx).into()) .collect(), interpreter: self.shebang.map(|s| InterpreterDirective { base: ctx.base(extract_shebang_span(span, ctx)), - value: s.to_string(), + value: s, }), directives: Default::default(), source_file: Default::default(), @@ -75,16 +72,12 @@ impl Babelify for Script { self.span }; BabelProgram { - base: base_with_trailing_newline(span.clone(), ctx), + base: base_with_trailing_newline(span, ctx), source_type: SrcType::Script, - body: self - .body - .iter() - .map(|stmt| stmt.clone().babelify(ctx)) - .collect(), + body: self.body.babelify(ctx), interpreter: self.shebang.map(|s| InterpreterDirective { base: ctx.base(extract_shebang_span(span, ctx)), - value: s.to_string(), + value: s, }), directives: Default::default(), source_file: Default::default(), @@ -114,12 +107,14 @@ fn base_with_trailing_newline(span: Span, ctx: &Context) -> BaseNode { // line comments. Swc ignores them and starts the program on the next line down, // while babel includes them in the file start/end. fn has_comment_first_line(sp: Span, ctx: &Context) -> bool { - ctx.comments.with_leading(sp.hi, |comments| { + if let Some(comments) = ctx.comments.leading.get(&sp.hi) { !comments .first() .map(|c| c.span.lo == ctx.fm.start_pos) .unwrap_or(false) - }) + } else { + true + } } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -131,6 +126,10 @@ pub enum ModuleItemOutput { impl Babelify for ModuleItem { type Output = ModuleItemOutput; + fn parallel(cnt: usize) -> bool { + cnt >= 4 + } + fn babelify(self, ctx: &Context) -> Self::Output { match self { ModuleItem::ModuleDecl(d) => ModuleItemOutput::ModuleDecl(d.babelify(ctx).into()), @@ -159,7 +158,7 @@ fn extract_shebang_span(span: Span, ctx: &Context) -> Span { fn extract_all_comments(program: &Program, ctx: &Context) -> Vec { let mut collector = CommentCollector { - comments: Arc::clone(&ctx.comments), + comments: ctx.comments.clone(), collected: Vec::new(), }; program.visit_with( @@ -172,7 +171,7 @@ fn extract_all_comments(program: &Program, ctx: &Context) -> Vec { } struct CommentCollector { - comments: Arc, + comments: SwcComments, collected: Vec, } @@ -182,20 +181,21 @@ impl Visit for CommentCollector { // Comments must be deduped since it's possible for a single comment to show up // multiple times since they are not removed from the comments map. // For example, this happens when the first line in a file is a comment. - self.comments.with_leading(sp.lo, |comments| { - for comment in comments.iter().cloned() { - if !self.collected.iter().any(|c| *c == comment) { - span_comments.push(comment); + if let Some(comments) = self.comments.leading.get(&sp.lo) { + for comment in comments.iter() { + if !self.collected.iter().any(|c| *c == *comment) { + span_comments.push(comment.clone()); } } - }); - self.comments.with_trailing(sp.hi, |comments| { - for comment in comments.iter().cloned() { - if !self.collected.iter().any(|c| *c == comment) { - span_comments.push(comment); + } + + if let Some(comments) = self.comments.trailing.get(&sp.hi) { + for comment in comments.iter() { + if !self.collected.iter().any(|c| *c == *comment) { + span_comments.push(comment.clone()); } } - }); + } self.collected.append(&mut span_comments); } } diff --git a/native/babel-compat/src/module_decl.rs b/babel/compat/src/module_decl.rs similarity index 94% rename from native/babel-compat/src/module_decl.rs rename to babel/compat/src/module_decl.rs index a7daca879dc..22b4f4776b6 100644 --- a/native/babel-compat/src/module_decl.rs +++ b/babel/compat/src/module_decl.rs @@ -1,4 +1,6 @@ use crate::{Babelify, Context}; +use copyless::BoxHelper; +use serde::{Deserialize, Serialize}; use swc_babel_ast::{ ExportAllDeclaration, ExportDefaultDeclType, ExportDefaultDeclaration, ExportDefaultSpecifier as BabelExportDefaultSpecifier, ExportKind, ExportNamedDeclaration, @@ -8,8 +10,6 @@ use swc_babel_ast::{ ImportNamespaceSpecifier, ImportSpecifier as BabelImportSpecifier, ImportSpecifierType, ModuleDeclaration, TSExportAssignment, TSImportEqualsDeclaration, TSNamespaceExportDeclaration, }; - -use serde::{Deserialize, Serialize}; use swc_ecma_ast::{ DefaultDecl, ExportAll, ExportDecl, ExportDefaultDecl, ExportDefaultExpr, ExportDefaultSpecifier, ExportNamedSpecifier, ExportNamespaceSpecifier, ExportSpecifier, Expr, @@ -71,7 +71,9 @@ impl Babelify for ExportDefaultExpr { fn babelify(self, ctx: &Context) -> Self::Output { ExportDefaultDeclaration { base: ctx.base(self.span), - declaration: ExportDefaultDeclType::Expr(Box::new(self.expr.babelify(ctx).into())), + declaration: ExportDefaultDeclType::Expr( + Box::alloc().init(self.expr.babelify(ctx).into()), + ), } } } @@ -82,7 +84,7 @@ impl Babelify for ExportDecl { fn babelify(self, ctx: &Context) -> Self::Output { ExportNamedDeclaration { base: ctx.base(self.span), - declaration: Some(Box::new(self.decl.babelify(ctx))), + declaration: Some(Box::alloc().init(self.decl.babelify(ctx))), specifiers: Default::default(), source: Default::default(), assertions: Default::default(), @@ -96,10 +98,12 @@ fn convert_import_asserts( ctx: &Context, ) -> Option> { asserts.map(|obj| { + let obj_span = obj.span; + obj.props - .iter() + .into_iter() .map(|prop_or_spread| { - let prop = match prop_or_spread.clone() { + let prop = match prop_or_spread { PropOrSpread::Prop(p) => p, _ => panic!( "illegal conversion: Cannot convert {:?} to Prop", @@ -137,7 +141,7 @@ fn convert_import_asserts( ), }; ImportAttribute { - base: ctx.base(obj.span), + base: ctx.base(obj_span), key, value: val, } @@ -152,11 +156,7 @@ impl Babelify for ImportDecl { fn babelify(self, ctx: &Context) -> Self::Output { ImportDeclaration { base: ctx.base(self.span), - specifiers: self - .specifiers - .iter() - .map(|spec| spec.clone().babelify(ctx)) - .collect(), + specifiers: self.specifiers.babelify(ctx), source: self.src.babelify(ctx), assertions: convert_import_asserts(self.asserts, ctx), import_kind: if self.type_only { @@ -188,11 +188,7 @@ impl Babelify for NamedExport { ExportNamedDeclaration { base: ctx.base(self.span), declaration: Default::default(), - specifiers: self - .specifiers - .iter() - .map(|spec| spec.clone().babelify(ctx)) - .collect(), + specifiers: self.specifiers.babelify(ctx), source: self.src.map(|s| s.babelify(ctx)), assertions: convert_import_asserts(self.asserts, ctx), export_kind: if self.type_only { diff --git a/native/babel-compat/src/normalize/mod.rs b/babel/compat/src/normalize/mod.rs similarity index 98% rename from native/babel-compat/src/normalize/mod.rs rename to babel/compat/src/normalize/mod.rs index 18202091258..448f24c21b8 100644 --- a/native/babel-compat/src/normalize/mod.rs +++ b/babel/compat/src/normalize/mod.rs @@ -1,3 +1,4 @@ +use swc_atoms::js_word; use swc_babel_ast::*; use swc_babel_visit::{VisitMut, VisitMutWith}; @@ -136,7 +137,7 @@ impl VisitMut for Normalizer { fn visit_mut_jsx_text(&mut self, node: &mut JSXText) { if node.value.trim().is_empty() { - node.value = "".to_owned(); + node.value = js_word!(""); } node.visit_mut_children_with(self); } diff --git a/native/babel-compat/src/operators.rs b/babel/compat/src/operators.rs similarity index 100% rename from native/babel-compat/src/operators.rs rename to babel/compat/src/operators.rs diff --git a/native/babel-compat/src/pat.rs b/babel/compat/src/pat.rs similarity index 86% rename from native/babel-compat/src/pat.rs rename to babel/compat/src/pat.rs index 9269c369176..d4a6cce4180 100644 --- a/native/babel-compat/src/pat.rs +++ b/babel/compat/src/pat.rs @@ -1,11 +1,11 @@ use crate::{Babelify, Context}; +use copyless::BoxHelper; +use serde::{Deserialize, Serialize}; use swc_babel_ast::{ ArrayPattern, AssignmentPattern, AssignmentPatternLeft, CatchClauseParam, Expression, Identifier, LVal, ObjectKey, ObjectPattern, ObjectPatternProp, ObjectPropVal, ObjectProperty, Param, Pattern, PatternLike, RestElement, }; - -use serde::{Deserialize, Serialize}; use swc_common::Spanned; use swc_ecma_ast::{ ArrayPat, AssignPat, AssignPatProp, KeyValuePatProp, ObjectPat, ObjectPatProp, Pat, RestPat, @@ -31,7 +31,7 @@ impl Babelify for Pat { Pat::Rest(r) => PatOutput::Rest(r.babelify(ctx)), Pat::Object(o) => PatOutput::Object(o.babelify(ctx)), Pat::Assign(a) => PatOutput::Assign(a.babelify(ctx)), - Pat::Expr(e) => PatOutput::Expr(Box::new(e.babelify(ctx).into())), + Pat::Expr(e) => PatOutput::Expr(Box::alloc().init(e.babelify(ctx).into())), Pat::Invalid(_) => panic!( "illegal conversion: Cannot convert {:?} to PatOutput", &self @@ -55,7 +55,7 @@ impl From for ObjectPropVal { fn from(pat: PatOutput) -> Self { match pat { PatOutput::Expr(e) => ObjectPropVal::Expr(e), - other => other.into(), + other => ObjectPropVal::Pattern(other.into()), } } } @@ -146,10 +146,12 @@ impl Babelify for ArrayPat { base: ctx.base(self.span), elements: self .elems - .iter() - .map(|opt| opt.as_ref().map(|e| e.clone().babelify(ctx).into())) + .into_iter() + .map(|opt| opt.map(|e| e.babelify(ctx).into())) .collect(), - type_annotation: self.type_ann.map(|a| Box::new(a.babelify(ctx).into())), + type_annotation: self + .type_ann + .map(|a| Box::alloc().init(a.babelify(ctx).into())), decorators: Default::default(), } } @@ -161,8 +163,10 @@ impl Babelify for ObjectPat { fn babelify(self, ctx: &Context) -> Self::Output { ObjectPattern { base: ctx.base(self.span), - properties: self.props.iter().map(|p| p.clone().babelify(ctx)).collect(), - type_annotation: self.type_ann.map(|a| Box::new(a.babelify(ctx).into())), + properties: self.props.babelify(ctx), + type_annotation: self + .type_ann + .map(|a| Box::alloc().init(a.babelify(ctx).into())), decorators: Default::default(), } } @@ -186,7 +190,7 @@ impl Babelify for KeyValuePatProp { fn babelify(self, ctx: &Context) -> Self::Output { ObjectProperty { base: ctx.base(self.span()), - key: self.key.babelify(ctx).into(), + key: self.key.babelify(ctx), value: self.value.babelify(ctx).into(), computed: Default::default(), shorthand: Default::default(), @@ -201,8 +205,10 @@ impl Babelify for RestPat { fn babelify(self, ctx: &Context) -> Self::Output { RestElement { base: ctx.base(self.span), - argument: Box::new(self.arg.babelify(ctx).into()), - type_annotation: self.type_ann.map(|a| Box::new(a.babelify(ctx).into())), + argument: Box::alloc().init(self.arg.babelify(ctx).into()), + type_annotation: self + .type_ann + .map(|a| Box::alloc().init(a.babelify(ctx).into())), decorators: Default::default(), } } @@ -215,8 +221,10 @@ impl Babelify for AssignPat { AssignmentPattern { base: ctx.base(self.span), left: self.left.babelify(ctx).into(), - right: Box::new(self.right.babelify(ctx).into()), - type_annotation: self.type_ann.map(|a| Box::new(a.babelify(ctx).into())), + right: Box::alloc().init(self.right.babelify(ctx).into()), + type_annotation: self + .type_ann + .map(|a| Box::alloc().init(a.babelify(ctx).into())), decorators: Default::default(), } } @@ -233,7 +241,7 @@ impl Babelify for AssignPatProp { value: if is_shorthand { ObjectPropVal::Pattern(PatternLike::Id(self.key.babelify(ctx))) } else { - ObjectPropVal::Expr(Box::new(self.value.unwrap().babelify(ctx).into())) + ObjectPropVal::Expr(Box::alloc().init(self.value.unwrap().babelify(ctx).into())) }, shorthand: is_shorthand, computed: Default::default(), diff --git a/native/babel-compat/src/prop.rs b/babel/compat/src/prop.rs similarity index 90% rename from native/babel-compat/src/prop.rs rename to babel/compat/src/prop.rs index fbe7117c94b..0652898021e 100644 --- a/native/babel-compat/src/prop.rs +++ b/babel/compat/src/prop.rs @@ -1,9 +1,9 @@ use crate::{Babelify, Context}; +use copyless::BoxHelper; use swc_babel_ast::{ AssignmentPattern, AssignmentPatternLeft, Expression, FunctionExpression, ObjectKey, ObjectMember, ObjectMethod, ObjectMethodKind, ObjectPropVal, ObjectProperty, }; - use swc_common::Spanned; use swc_ecma_ast::{ AssignProp, ComputedPropName, GetterProp, KeyValueProp, MethodProp, Prop, PropName, SetterProp, @@ -19,7 +19,7 @@ impl Babelify for Prop { ObjectMember::Prop(ObjectProperty { base: id.base.clone(), key: ObjectKey::Id(id.clone()), - value: ObjectPropVal::Expr(Box::new(Expression::Id(id))), + value: ObjectPropVal::Expr(Box::alloc().init(Expression::Id(id))), computed: Default::default(), shorthand: true, decorators: Default::default(), @@ -44,7 +44,7 @@ impl Babelify for KeyValueProp { ObjectProperty { base: ctx.base(self.span()), key: self.key.babelify(ctx), - value: ObjectPropVal::Expr(Box::new(self.value.babelify(ctx).into())), + value: ObjectPropVal::Expr(Box::alloc().init(self.value.babelify(ctx).into())), computed: Default::default(), shorthand: Default::default(), decorators: Default::default(), @@ -61,7 +61,7 @@ impl Babelify for AssignProp { AssignmentPattern { base: ctx.base(self.span()), left: AssignmentPatternLeft::Id(self.key.babelify(ctx)), - right: Box::new(self.value.babelify(ctx).into()), + right: Box::alloc().init(self.value.babelify(ctx).into()), decorators: Default::default(), type_annotation: Default::default(), } @@ -76,7 +76,9 @@ impl Babelify for GetterProp { base: ctx.base(self.span), kind: ObjectMethodKind::Get, key: self.key.babelify(ctx), - return_type: self.type_ann.map(|ann| Box::new(ann.babelify(ctx).into())), + return_type: self + .type_ann + .map(|ann| Box::alloc().init(ann.babelify(ctx).into())), body: self.body.unwrap().babelify(ctx), params: Default::default(), computed: Default::default(), @@ -137,7 +139,7 @@ impl Babelify for PropName { PropName::Ident(i) => ObjectKey::Id(i.babelify(ctx)), PropName::Str(s) => ObjectKey::String(s.babelify(ctx)), PropName::Num(n) => ObjectKey::Numeric(n.babelify(ctx)), - PropName::Computed(e) => ObjectKey::Expr(Box::new(e.babelify(ctx))), + PropName::Computed(e) => ObjectKey::Expr(Box::alloc().init(e.babelify(ctx))), _ => panic!( "illegal conversion: Cannot convert {:?} to ObjectKey", &self diff --git a/native/babel-compat/src/stmt.rs b/babel/compat/src/stmt.rs similarity index 79% rename from native/babel-compat/src/stmt.rs rename to babel/compat/src/stmt.rs index e1fa60cd56e..a448fc141de 100644 --- a/native/babel-compat/src/stmt.rs +++ b/babel/compat/src/stmt.rs @@ -1,4 +1,5 @@ use crate::{Babelify, Context}; +use copyless::BoxHelper; use swc_babel_ast::{ BlockStatement, BreakStatement, CatchClause as BabelCatchClause, ContinueStatement, DebuggerStatement, DoWhileStatement, EmptyStatement, ExpressionStatement, ForInStatement, @@ -6,7 +7,6 @@ use swc_babel_ast::{ ReturnStatement, Statement, SwitchCase as BabelSwitchCase, SwitchStatement, ThrowStatement, TryStatement, WhileStatement, WithStatement, }; - use swc_ecma_ast::{ BlockStmt, BreakStmt, CatchClause, ContinueStmt, DebuggerStmt, Decl, DoWhileStmt, EmptyStmt, ExprStmt, ForInStmt, ForOfStmt, ForStmt, IfStmt, LabeledStmt, ReturnStmt, Stmt, SwitchCase, @@ -19,11 +19,7 @@ impl Babelify for BlockStmt { fn babelify(self, ctx: &Context) -> Self::Output { BlockStatement { base: ctx.base(self.span), - body: self - .stmts - .iter() - .map(|stmt| stmt.clone().babelify(ctx)) - .collect(), + body: self.stmts.babelify(ctx), directives: Default::default(), } } @@ -32,6 +28,10 @@ impl Babelify for BlockStmt { impl Babelify for Stmt { type Output = Statement; + fn parallel(cnt: usize) -> bool { + cnt >= 16 + } + fn babelify(self, ctx: &Context) -> Self::Output { match self { Stmt::Block(s) => Statement::Block(s.babelify(ctx)), @@ -71,7 +71,7 @@ impl Babelify for ExprStmt { fn babelify(self, ctx: &Context) -> Self::Output { ExpressionStatement { base: ctx.base(self.span), - expression: Box::new(self.expr.babelify(ctx).into()), + expression: Box::alloc().init(self.expr.babelify(ctx).into()), } } } @@ -102,8 +102,8 @@ impl Babelify for WithStmt { fn babelify(self, ctx: &Context) -> Self::Output { WithStatement { base: ctx.base(self.span), - object: Box::new(self.obj.babelify(ctx).into()), - body: Box::new(self.body.babelify(ctx)), + object: Box::alloc().init(self.obj.babelify(ctx).into()), + body: Box::alloc().init(self.body.babelify(ctx)), } } } @@ -114,7 +114,9 @@ impl Babelify for ReturnStmt { fn babelify(self, ctx: &Context) -> Self::Output { ReturnStatement { base: ctx.base(self.span), - argument: self.arg.map(|expr| Box::new(expr.babelify(ctx).into())), + argument: self + .arg + .map(|expr| Box::alloc().init(expr.babelify(ctx).into())), } } } @@ -126,7 +128,7 @@ impl Babelify for LabeledStmt { LabeledStatement { base: ctx.base(self.span), label: self.label.babelify(ctx), - body: Box::new(self.body.babelify(ctx)), + body: Box::alloc().init(self.body.babelify(ctx)), } } } @@ -159,9 +161,9 @@ impl Babelify for IfStmt { fn babelify(self, ctx: &Context) -> Self::Output { IfStatement { base: ctx.base(self.span), - test: Box::new(self.test.babelify(ctx).into()), - consequent: Box::new(self.cons.babelify(ctx)), - alternate: self.alt.map(|a| Box::new(a.babelify(ctx))), + test: Box::alloc().init(self.test.babelify(ctx).into()), + consequent: Box::alloc().init(self.cons.babelify(ctx)), + alternate: self.alt.map(|a| Box::alloc().init(a.babelify(ctx))), } } } @@ -172,12 +174,8 @@ impl Babelify for SwitchStmt { fn babelify(self, ctx: &Context) -> Self::Output { SwitchStatement { base: ctx.base(self.span), - discriminant: Box::new(self.discriminant.babelify(ctx).into()), - cases: self - .cases - .iter() - .map(|case| case.clone().babelify(ctx)) - .collect(), + discriminant: Box::alloc().init(self.discriminant.babelify(ctx).into()), + cases: self.cases.babelify(ctx), } } } @@ -188,7 +186,7 @@ impl Babelify for ThrowStmt { fn babelify(self, ctx: &Context) -> Self::Output { ThrowStatement { base: ctx.base(self.span), - argument: Box::new(self.arg.babelify(ctx).into()), + argument: Box::alloc().init(self.arg.babelify(ctx).into()), } } } @@ -212,8 +210,8 @@ impl Babelify for WhileStmt { fn babelify(self, ctx: &Context) -> Self::Output { WhileStatement { base: ctx.base(self.span), - test: Box::new(self.test.babelify(ctx).into()), - body: Box::new(self.body.babelify(ctx)), + test: Box::alloc().init(self.test.babelify(ctx).into()), + body: Box::alloc().init(self.body.babelify(ctx)), } } } @@ -224,8 +222,8 @@ impl Babelify for DoWhileStmt { fn babelify(self, ctx: &Context) -> Self::Output { DoWhileStatement { base: ctx.base(self.span), - test: Box::new(self.test.babelify(ctx).into()), - body: Box::new(self.body.babelify(ctx)), + test: Box::alloc().init(self.test.babelify(ctx).into()), + body: Box::alloc().init(self.body.babelify(ctx)), } } } @@ -237,9 +235,13 @@ impl Babelify for ForStmt { ForStatement { base: ctx.base(self.span), init: self.init.map(|i| i.babelify(ctx)), - test: self.test.map(|expr| Box::new(expr.babelify(ctx).into())), - update: self.update.map(|expr| Box::new(expr.babelify(ctx).into())), - body: Box::new(self.body.babelify(ctx)), + test: self + .test + .map(|expr| Box::alloc().init(expr.babelify(ctx).into())), + update: self + .update + .map(|expr| Box::alloc().init(expr.babelify(ctx).into())), + body: Box::alloc().init(self.body.babelify(ctx)), } } } @@ -251,8 +253,8 @@ impl Babelify for ForInStmt { ForInStatement { base: ctx.base(self.span), left: self.left.babelify(ctx), - right: Box::new(self.right.babelify(ctx).into()), - body: Box::new(self.body.babelify(ctx)), + right: Box::alloc().init(self.right.babelify(ctx).into()), + body: Box::alloc().init(self.body.babelify(ctx)), } } } @@ -264,8 +266,8 @@ impl Babelify for ForOfStmt { ForOfStatement { base: ctx.base(self.span), left: self.left.babelify(ctx), - right: Box::new(self.right.babelify(ctx).into()), - body: Box::new(self.body.babelify(ctx)), + right: Box::alloc().init(self.right.babelify(ctx).into()), + body: Box::alloc().init(self.body.babelify(ctx)), // await_token not yet implemented } } @@ -277,12 +279,10 @@ impl Babelify for SwitchCase { fn babelify(self, ctx: &Context) -> Self::Output { BabelSwitchCase { base: ctx.base(self.span), - test: self.test.map(|expr| Box::new(expr.babelify(ctx).into())), - consequent: self - .cons - .iter() - .map(|stmt| stmt.clone().babelify(ctx)) - .collect(), + test: self + .test + .map(|expr| Box::alloc().init(expr.babelify(ctx).into())), + consequent: self.cons.babelify(ctx), } } } @@ -316,7 +316,7 @@ impl Babelify for VarDeclOrExpr { fn babelify(self, ctx: &Context) -> Self::Output { match self { VarDeclOrExpr::VarDecl(v) => ForStmtInit::VarDecl(v.babelify(ctx)), - VarDeclOrExpr::Expr(e) => ForStmtInit::Expr(Box::new(e.babelify(ctx).into())), + VarDeclOrExpr::Expr(e) => ForStmtInit::Expr(Box::alloc().init(e.babelify(ctx).into())), } } } diff --git a/native/babel-compat/src/typescript.rs b/babel/compat/src/typescript.rs similarity index 87% rename from native/babel-compat/src/typescript.rs rename to babel/compat/src/typescript.rs index 189b7d1368d..2748acbfdf5 100644 --- a/native/babel-compat/src/typescript.rs +++ b/babel/compat/src/typescript.rs @@ -1,4 +1,7 @@ use crate::{Babelify, Context}; +use copyless::BoxHelper; +use swc_atoms::js_word; +use swc_atoms::JsWord; use swc_babel_ast::{ Access, ArrayPattern, IdOrRest, IdOrString, Identifier, ObjectPattern, RestElement, TSAnyKeyword, TSArrayType, TSAsExpression, TSBigIntKeyword, TSBooleanKeyword, @@ -56,11 +59,11 @@ impl Babelify for TsFnType { base: ctx.base(self.span), parameters: self .params - .iter() - .map(|p| p.clone().babelify(ctx).into()) + .into_iter() + .map(|p| p.babelify(ctx).into()) .collect(), - type_parameters: self.type_params.map(|decl| decl.babelify(ctx)), - type_annotation: Some(Box::new(self.type_ann.babelify(ctx))), + type_parameters: self.type_params.babelify(ctx), + type_annotation: Some(Box::alloc().init(self.type_ann.babelify(ctx))), } } } @@ -111,11 +114,7 @@ impl Babelify for TsTypeParamDecl { fn babelify(self, ctx: &Context) -> Self::Output { TSTypeParameterDeclaration { base: ctx.base(self.span), - params: self - .params - .iter() - .map(|p| p.clone().babelify(ctx)) - .collect(), + params: self.params.babelify(ctx), } } } @@ -126,9 +125,9 @@ impl Babelify for TsTypeParam { fn babelify(self, ctx: &Context) -> Self::Output { TSTypeParameter { base: ctx.base(self.span), - name: self.name.sym.to_string(), - constraint: self.constraint.map(|c| Box::new(c.babelify(ctx))), - default: self.default.map(|d| Box::new(d.babelify(ctx))), + name: self.name.sym, + constraint: self.constraint.map(|c| Box::alloc().init(c.babelify(ctx))), + default: self.default.map(|d| Box::alloc().init(d.babelify(ctx))), } } } @@ -139,11 +138,7 @@ impl Babelify for TsTypeParamInstantiation { fn babelify(self, ctx: &Context) -> Self::Output { TSTypeParameterInstantiation { base: ctx.base(self.span), - params: self - .params - .iter() - .map(|param| param.clone().babelify(ctx)) - .collect(), + params: self.params.into_iter().map(|v| v.babelify(ctx)).collect(), } } } @@ -178,7 +173,7 @@ impl Babelify for TsQualifiedName { fn babelify(self, ctx: &Context) -> Self::Output { TSQualifiedName { base: ctx.base(self.span()), - left: Box::new(self.left.babelify(ctx)), + left: Box::alloc().init(self.left.babelify(ctx)), right: self.right.babelify(ctx), } } @@ -224,10 +219,12 @@ impl Babelify for TsCallSignatureDecl { type_parameters: self.type_params.map(|t| t.babelify(ctx)), parameters: self .params - .iter() - .map(|param| param.clone().babelify(ctx).into()) + .into_iter() + .map(|param| param.babelify(ctx).into()) .collect(), - type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))), + type_annotation: self + .type_ann + .map(|ann| Box::alloc().init(ann.babelify(ctx))), } } } @@ -241,10 +238,12 @@ impl Babelify for TsConstructSignatureDecl { type_parameters: self.type_params.map(|t| t.babelify(ctx)), parameters: self .params - .iter() - .map(|param| param.clone().babelify(ctx).into()) + .into_iter() + .map(|param| param.babelify(ctx).into()) .collect(), - type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))), + type_annotation: self + .type_ann + .map(|ann| Box::alloc().init(ann.babelify(ctx))), } } } @@ -255,9 +254,11 @@ impl Babelify for TsPropertySignature { fn babelify(self, ctx: &Context) -> Self::Output { TSPropertySignature { base: ctx.base(self.span), - key: Box::new(self.key.babelify(ctx).into()), - type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))), - initializer: self.init.map(|i| Box::new(i.babelify(ctx).into())), + key: Box::alloc().init(self.key.babelify(ctx).into()), + type_annotation: self + .type_ann + .map(|ann| Box::alloc().init(ann.babelify(ctx))), + initializer: self.init.map(|i| Box::alloc().init(i.babelify(ctx).into())), computed: Some(self.computed), optional: Some(self.optional), readonly: Some(self.readonly), @@ -271,14 +272,16 @@ impl Babelify for TsMethodSignature { fn babelify(self, ctx: &Context) -> Self::Output { TSMethodSignature { base: ctx.base(self.span), - key: Box::new(self.key.babelify(ctx).into()), + key: Box::alloc().init(self.key.babelify(ctx).into()), type_parameters: self.type_params.map(|t| t.babelify(ctx)), parameters: self .params - .iter() - .map(|param| param.clone().babelify(ctx).into()) + .into_iter() + .map(|param| param.babelify(ctx).into()) .collect(), - type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))), + type_annotation: self + .type_ann + .map(|ann| Box::alloc().init(ann.babelify(ctx))), computed: Some(self.computed), optional: Some(self.optional), } @@ -293,10 +296,12 @@ impl Babelify for TsIndexSignature { base: ctx.base(self.span), paramters: self .params - .iter() - .map(|param| param.clone().babelify(ctx).into()) + .into_iter() + .map(|param| param.babelify(ctx).into()) .collect(), - type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))), + type_annotation: self + .type_ann + .map(|ann| Box::alloc().init(ann.babelify(ctx))), readonly: Some(self.readonly), } } @@ -459,11 +464,11 @@ impl Babelify for TsConstructorType { base: ctx.base(self.span), parameters: self .params - .iter() - .map(|param| param.clone().babelify(ctx).into()) + .into_iter() + .map(|param| param.babelify(ctx).into()) .collect(), type_parameters: self.type_params.map(|decl| decl.babelify(ctx)), - type_annotation: Some(Box::new(self.type_ann.babelify(ctx))), + type_annotation: Some(Box::alloc().init(self.type_ann.babelify(ctx))), is_abstract: Some(self.is_abstract), } } @@ -488,7 +493,9 @@ impl Babelify for TsTypePredicate { TSTypePredicate { base: ctx.base(self.span), parameter_name: self.param_name.babelify(ctx), - type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))), + type_annotation: self + .type_ann + .map(|ann| Box::alloc().init(ann.babelify(ctx))), asserts: Some(self.asserts), } } @@ -546,11 +553,7 @@ impl Babelify for TsTypeLit { fn babelify(self, ctx: &Context) -> Self::Output { TSTypeLiteral { base: ctx.base(self.span), - members: self - .members - .iter() - .map(|memb| memb.clone().babelify(ctx)) - .collect(), + members: self.members.babelify(ctx), } } } @@ -561,7 +564,7 @@ impl Babelify for TsArrayType { fn babelify(self, ctx: &Context) -> Self::Output { TSArrayType { base: ctx.base(self.span), - element_type: Box::new(self.elem_type.babelify(ctx)), + element_type: Box::alloc().init(self.elem_type.babelify(ctx)), } } } @@ -572,11 +575,7 @@ impl Babelify for TsTupleType { fn babelify(self, ctx: &Context) -> Self::Output { TSTupleType { base: ctx.base(self.span), - element_types: self - .elem_types - .iter() - .map(|t| t.clone().babelify(ctx)) - .collect(), + element_types: self.elem_types.babelify(ctx), } } } @@ -616,7 +615,7 @@ impl Babelify for TsOptionalType { fn babelify(self, ctx: &Context) -> Self::Output { TSOptionalType { base: ctx.base(self.span), - type_annotation: Box::new(self.type_ann.babelify(ctx)), + type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)), } } } @@ -627,7 +626,7 @@ impl Babelify for TsRestType { fn babelify(self, ctx: &Context) -> Self::Output { TSRestType { base: ctx.base(self.span), - type_annotation: Box::new(self.type_ann.babelify(ctx)), + type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)), } } } @@ -659,7 +658,7 @@ impl Babelify for TsUnionType { fn babelify(self, ctx: &Context) -> Self::Output { TSUnionType { base: ctx.base(self.span), - types: self.types.iter().map(|t| t.clone().babelify(ctx)).collect(), + types: self.types.into_iter().map(|t| t.babelify(ctx)).collect(), } } } @@ -670,7 +669,7 @@ impl Babelify for TsIntersectionType { fn babelify(self, ctx: &Context) -> Self::Output { TSIntersectionType { base: ctx.base(self.span), - types: self.types.iter().map(|t| t.clone().babelify(ctx)).collect(), + types: self.types.into_iter().map(|t| t.babelify(ctx)).collect(), } } } @@ -681,10 +680,10 @@ impl Babelify for TsConditionalType { fn babelify(self, ctx: &Context) -> Self::Output { TSConditionalType { base: ctx.base(self.span), - check_type: Box::new(self.check_type.babelify(ctx)), - extends_type: Box::new(self.extends_type.babelify(ctx)), - true_type: Box::new(self.true_type.babelify(ctx)), - false_type: Box::new(self.false_type.babelify(ctx)), + check_type: Box::alloc().init(self.check_type.babelify(ctx)), + extends_type: Box::alloc().init(self.extends_type.babelify(ctx)), + true_type: Box::alloc().init(self.true_type.babelify(ctx)), + false_type: Box::alloc().init(self.false_type.babelify(ctx)), } } } @@ -695,7 +694,7 @@ impl Babelify for TsInferType { fn babelify(self, ctx: &Context) -> Self::Output { TSInferType { base: ctx.base(self.span), - type_parameter: Box::new(self.type_param.babelify(ctx)), + type_parameter: Box::alloc().init(self.type_param.babelify(ctx)), } } } @@ -706,7 +705,7 @@ impl Babelify for TsParenthesizedType { fn babelify(self, ctx: &Context) -> Self::Output { TSParenthesizedType { base: ctx.base(self.span), - type_annotation: Box::new(self.type_ann.babelify(ctx)), + type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)), } } } @@ -717,20 +716,20 @@ impl Babelify for TsTypeOperator { fn babelify(self, ctx: &Context) -> Self::Output { TSTypeOperator { base: ctx.base(self.span), - type_annotation: Box::new(self.type_ann.babelify(ctx)), + type_annotation: Box::alloc().init(self.type_ann.babelify(ctx)), operator: self.op.babelify(ctx), } } } impl Babelify for TsTypeOperatorOp { - type Output = String; + type Output = JsWord; fn babelify(self, _ctx: &Context) -> Self::Output { match self { - TsTypeOperatorOp::KeyOf => "keyof".to_string(), - TsTypeOperatorOp::Unique => "unique".to_string(), - TsTypeOperatorOp::ReadOnly => "readonly".to_string(), + TsTypeOperatorOp::KeyOf => js_word!("keyof"), + TsTypeOperatorOp::Unique => js_word!("unique"), + TsTypeOperatorOp::ReadOnly => js_word!("readonly"), } } } @@ -741,8 +740,8 @@ impl Babelify for TsIndexedAccessType { fn babelify(self, ctx: &Context) -> Self::Output { TSIndexedAccessType { base: ctx.base(self.span), - object_type: Box::new(self.obj_type.babelify(ctx)), - index_type: Box::new(self.index_type.babelify(ctx)), + object_type: Box::alloc().init(self.obj_type.babelify(ctx)), + index_type: Box::alloc().init(self.index_type.babelify(ctx)), } } } @@ -755,9 +754,11 @@ impl Babelify for TsMappedType { fn babelify(self, ctx: &Context) -> Self::Output { TSMappedType { base: ctx.base(self.span), - type_parameter: Box::new(self.type_param.babelify(ctx)), - type_annotation: self.type_ann.map(|ann| Box::new(ann.babelify(ctx))), - name_type: self.name_type.map(|t| Box::new(t.babelify(ctx))), + type_parameter: Box::alloc().init(self.type_param.babelify(ctx)), + type_annotation: self + .type_ann + .map(|ann| Box::alloc().init(ann.babelify(ctx))), + name_type: self.name_type.map(|t| Box::alloc().init(t.babelify(ctx))), optional: self.optional.map(|val| val == TruePlusMinus::True), readonly: self.readonly.map(|val| val == TruePlusMinus::True), } @@ -810,7 +811,7 @@ impl Babelify for TsInterfaceDecl { base: ctx.base(self.span), id: self.id.babelify(ctx), type_parameters: self.type_params.map(|t| t.babelify(ctx)), - extends: self.extends.first().map(|ext| ext.clone().babelify(ctx)), + extends: self.extends.into_iter().next().babelify(ctx), body: self.body.babelify(ctx), declare: Some(self.declare), } @@ -823,11 +824,7 @@ impl Babelify for TsInterfaceBody { fn babelify(self, ctx: &Context) -> Self::Output { TSInterfaceBody { base: ctx.base(self.span), - body: self - .body - .iter() - .map(|el| el.clone().babelify(ctx)) - .collect(), + body: self.body.babelify(ctx), } } } @@ -865,11 +862,7 @@ impl Babelify for TsEnumDecl { TSEnumDeclaration { base: ctx.base(self.span), id: self.id.babelify(ctx), - members: self - .members - .iter() - .map(|memb| memb.clone().babelify(ctx)) - .collect(), + members: self.members.babelify(ctx), is_const: Some(self.is_const), declare: Some(self.declare), initializer: Default::default(), @@ -884,7 +877,7 @@ impl Babelify for TsEnumMember { TSEnumMember { base: ctx.base(self.span), id: self.id.babelify(ctx), - initializer: self.init.map(|i| Box::new(i.babelify(ctx).into())), + initializer: self.init.map(|i| Box::alloc().init(i.babelify(ctx).into())), } } } @@ -907,7 +900,7 @@ impl Babelify for TsModuleDecl { TSModuleDeclaration { base: ctx.base(self.span), id: self.id.babelify(ctx), - body: Box::new(self.body.unwrap().babelify(ctx)), + body: Box::alloc().init(self.body.unwrap().babelify(ctx)), declare: Some(self.declare), global: Some(self.global), } @@ -933,8 +926,8 @@ impl Babelify for TsModuleBlock { base: ctx.base(self.span), body: self .body - .iter() - .map(|m| m.clone().babelify(ctx).into()) + .into_iter() + .map(|m| m.babelify(ctx).into()) .collect(), } } @@ -947,7 +940,7 @@ impl Babelify for TsNamespaceDecl { TSModuleDeclaration { base: ctx.base(self.span), id: IdOrString::Id(self.id.babelify(ctx)), - body: Box::new(self.body.babelify(ctx)), + body: Box::alloc().init(self.body.babelify(ctx)), declare: Some(self.declare), global: Some(self.global), } @@ -1008,7 +1001,7 @@ impl Babelify for TsExportAssignment { fn babelify(self, ctx: &Context) -> Self::Output { TSExportAssignment { base: ctx.base(self.span), - expression: Box::new(self.expr.babelify(ctx).into()), + expression: Box::alloc().init(self.expr.babelify(ctx).into()), } } } @@ -1030,7 +1023,7 @@ impl Babelify for TsAsExpr { fn babelify(self, ctx: &Context) -> Self::Output { TSAsExpression { base: ctx.base(self.span), - expression: Box::new(self.expr.babelify(ctx).into()), + expression: Box::alloc().init(self.expr.babelify(ctx).into()), type_annotation: self.type_ann.babelify(ctx), } } @@ -1042,7 +1035,7 @@ impl Babelify for TsTypeAssertion { fn babelify(self, ctx: &Context) -> Self::Output { TSTypeAssertion { base: ctx.base(self.span), - expression: Box::new(self.expr.babelify(ctx).into()), + expression: Box::alloc().init(self.expr.babelify(ctx).into()), type_annotation: self.type_ann.babelify(ctx), } } @@ -1054,7 +1047,7 @@ impl Babelify for TsNonNullExpr { fn babelify(self, ctx: &Context) -> Self::Output { TSNonNullExpression { base: ctx.base(self.span), - expression: Box::new(self.expr.babelify(ctx).into()), + expression: Box::alloc().init(self.expr.babelify(ctx).into()), } } } diff --git a/native/babel-compat/tests/README.md b/babel/compat/tests/README.md similarity index 100% rename from native/babel-compat/tests/README.md rename to babel/compat/tests/README.md diff --git a/native/babel-compat/tests/babelgen.js b/babel/compat/tests/babelgen.js similarity index 100% rename from native/babel-compat/tests/babelgen.js rename to babel/compat/tests/babelgen.js diff --git a/native/babel-compat/tests/compare.sh b/babel/compat/tests/compare.sh similarity index 100% rename from native/babel-compat/tests/compare.sh rename to babel/compat/tests/compare.sh diff --git a/native/babel-compat/tests/convert.rs b/babel/compat/tests/convert.rs similarity index 96% rename from native/babel-compat/tests/convert.rs rename to babel/compat/tests/convert.rs index 8c158e2f55f..2edfdeea66f 100644 --- a/native/babel-compat/tests/convert.rs +++ b/babel/compat/tests/convert.rs @@ -2,6 +2,7 @@ extern crate test; use anyhow::{Context as AnyhowContext, Error}; +use copyless::BoxHelper; use pretty_assertions::assert_eq; use std::{ env, fs, @@ -27,9 +28,7 @@ use walkdir::WalkDir; fn fixtures() -> Result<(), Error> { let mut tests = vec![]; - let fixtures_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?) - .join("tests") - .join("fixtures"); + let fixtures_path = PathBuf::from("tests").join("fixtures"); for entry in WalkDir::new(&fixtures_path).into_iter() { let entry = entry.with_context(|| "Failed to walk dir")?; if !entry.file_type().is_dir() { @@ -76,7 +75,7 @@ fn fixtures() -> Result<(), Error> { should_panic: ShouldPanic::No, allow_fail: false, }, - testfn: DynTestFn(Box::new(move || { + testfn: DynTestFn(Box::alloc().init(move || { let syntax = if is_typescript { Syntax::Typescript(Default::default()) } else if is_jsx { @@ -143,10 +142,11 @@ fn run_test(src: String, expected: String, syntax: Syntax, is_module: bool) { let ctx = Context { fm, cm, - comments: Arc::new(compiler.comments().clone()), + comments: compiler.comments().clone(), }; let mut ast = swc_ast.babelify(&ctx); normalize(&mut ast); + println!("Actaul: {:?}", ast); let mut expected_ast: File = serde_json::from_str(&expected).unwrap(); normalize(&mut expected_ast); diff --git a/native/babel-compat/tests/fixtures/array-destructuring/input.js b/babel/compat/tests/fixtures/array-destructuring/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/array-destructuring/input.js rename to babel/compat/tests/fixtures/array-destructuring/input.js diff --git a/native/babel-compat/tests/fixtures/array-destructuring/output.json b/babel/compat/tests/fixtures/array-destructuring/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/array-destructuring/output.json rename to babel/compat/tests/fixtures/array-destructuring/output.json diff --git a/native/babel-compat/tests/fixtures/array-simple/input.js b/babel/compat/tests/fixtures/array-simple/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/array-simple/input.js rename to babel/compat/tests/fixtures/array-simple/input.js diff --git a/native/babel-compat/tests/fixtures/array-simple/output.json b/babel/compat/tests/fixtures/array-simple/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/array-simple/output.json rename to babel/compat/tests/fixtures/array-simple/output.json diff --git a/native/babel-compat/tests/fixtures/class-extends/input.js b/babel/compat/tests/fixtures/class-extends/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/class-extends/input.js rename to babel/compat/tests/fixtures/class-extends/input.js diff --git a/native/babel-compat/tests/fixtures/class-extends/output.json b/babel/compat/tests/fixtures/class-extends/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/class-extends/output.json rename to babel/compat/tests/fixtures/class-extends/output.json diff --git a/native/babel-compat/tests/fixtures/class-getter-setter/input.js b/babel/compat/tests/fixtures/class-getter-setter/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/class-getter-setter/input.js rename to babel/compat/tests/fixtures/class-getter-setter/input.js diff --git a/native/babel-compat/tests/fixtures/class-getter-setter/output.json b/babel/compat/tests/fixtures/class-getter-setter/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/class-getter-setter/output.json rename to babel/compat/tests/fixtures/class-getter-setter/output.json diff --git a/native/babel-compat/tests/fixtures/class-method-no-body/input.js b/babel/compat/tests/fixtures/class-method-no-body/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/class-method-no-body/input.js rename to babel/compat/tests/fixtures/class-method-no-body/input.js diff --git a/native/babel-compat/tests/fixtures/class-method-no-body/output.json b/babel/compat/tests/fixtures/class-method-no-body/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/class-method-no-body/output.json rename to babel/compat/tests/fixtures/class-method-no-body/output.json diff --git a/native/babel-compat/tests/fixtures/class-public-fields/input.js b/babel/compat/tests/fixtures/class-public-fields/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/class-public-fields/input.js rename to babel/compat/tests/fixtures/class-public-fields/input.js diff --git a/native/babel-compat/tests/fixtures/class-public-fields/output.json b/babel/compat/tests/fixtures/class-public-fields/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/class-public-fields/output.json rename to babel/compat/tests/fixtures/class-public-fields/output.json diff --git a/native/babel-compat/tests/fixtures/class-simple/input.js b/babel/compat/tests/fixtures/class-simple/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/class-simple/input.js rename to babel/compat/tests/fixtures/class-simple/input.js diff --git a/native/babel-compat/tests/fixtures/class-simple/output.json b/babel/compat/tests/fixtures/class-simple/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/class-simple/output.json rename to babel/compat/tests/fixtures/class-simple/output.json diff --git a/native/babel-compat/tests/fixtures/class-static/input.js b/babel/compat/tests/fixtures/class-static/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/class-static/input.js rename to babel/compat/tests/fixtures/class-static/input.js diff --git a/native/babel-compat/tests/fixtures/class-static/output.json b/babel/compat/tests/fixtures/class-static/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/class-static/output.json rename to babel/compat/tests/fixtures/class-static/output.json diff --git a/native/babel-compat/tests/fixtures/class-unnamed/input.js b/babel/compat/tests/fixtures/class-unnamed/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/class-unnamed/input.js rename to babel/compat/tests/fixtures/class-unnamed/input.js diff --git a/native/babel-compat/tests/fixtures/class-unnamed/output.json b/babel/compat/tests/fixtures/class-unnamed/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/class-unnamed/output.json rename to babel/compat/tests/fixtures/class-unnamed/output.json diff --git a/native/babel-compat/tests/fixtures/comments-block-first-line/input.js b/babel/compat/tests/fixtures/comments-block-first-line/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/comments-block-first-line/input.js rename to babel/compat/tests/fixtures/comments-block-first-line/input.js diff --git a/native/babel-compat/tests/fixtures/comments-block-first-line/output.json b/babel/compat/tests/fixtures/comments-block-first-line/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/comments-block-first-line/output.json rename to babel/compat/tests/fixtures/comments-block-first-line/output.json diff --git a/native/babel-compat/tests/fixtures/comments-block/input.js b/babel/compat/tests/fixtures/comments-block/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/comments-block/input.js rename to babel/compat/tests/fixtures/comments-block/input.js diff --git a/native/babel-compat/tests/fixtures/comments-block/output.json b/babel/compat/tests/fixtures/comments-block/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/comments-block/output.json rename to babel/compat/tests/fixtures/comments-block/output.json diff --git a/native/babel-compat/tests/fixtures/comments-first-line/input.js b/babel/compat/tests/fixtures/comments-first-line/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/comments-first-line/input.js rename to babel/compat/tests/fixtures/comments-first-line/input.js diff --git a/native/babel-compat/tests/fixtures/comments-first-line/output.json b/babel/compat/tests/fixtures/comments-first-line/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/comments-first-line/output.json rename to babel/compat/tests/fixtures/comments-first-line/output.json diff --git a/native/babel-compat/tests/fixtures/comments-line/input.js b/babel/compat/tests/fixtures/comments-line/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/comments-line/input.js rename to babel/compat/tests/fixtures/comments-line/input.js diff --git a/native/babel-compat/tests/fixtures/comments-line/output.json b/babel/compat/tests/fixtures/comments-line/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/comments-line/output.json rename to babel/compat/tests/fixtures/comments-line/output.json diff --git a/native/babel-compat/tests/fixtures/delete-operator/input.js b/babel/compat/tests/fixtures/delete-operator/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/delete-operator/input.js rename to babel/compat/tests/fixtures/delete-operator/input.js diff --git a/native/babel-compat/tests/fixtures/delete-operator/output.json b/babel/compat/tests/fixtures/delete-operator/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/delete-operator/output.json rename to babel/compat/tests/fixtures/delete-operator/output.json diff --git a/native/babel-compat/tests/fixtures/exponentiation-operator/input.js b/babel/compat/tests/fixtures/exponentiation-operator/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/exponentiation-operator/input.js rename to babel/compat/tests/fixtures/exponentiation-operator/input.js diff --git a/native/babel-compat/tests/fixtures/exponentiation-operator/output.json b/babel/compat/tests/fixtures/exponentiation-operator/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/exponentiation-operator/output.json rename to babel/compat/tests/fixtures/exponentiation-operator/output.json diff --git a/native/babel-compat/tests/fixtures/function-anonymous/input.js b/babel/compat/tests/fixtures/function-anonymous/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/function-anonymous/input.js rename to babel/compat/tests/fixtures/function-anonymous/input.js diff --git a/native/babel-compat/tests/fixtures/function-anonymous/output.json b/babel/compat/tests/fixtures/function-anonymous/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/function-anonymous/output.json rename to babel/compat/tests/fixtures/function-anonymous/output.json diff --git a/native/babel-compat/tests/fixtures/function-arrow/input.js b/babel/compat/tests/fixtures/function-arrow/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/function-arrow/input.js rename to babel/compat/tests/fixtures/function-arrow/input.js diff --git a/native/babel-compat/tests/fixtures/function-arrow/output.json b/babel/compat/tests/fixtures/function-arrow/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/function-arrow/output.json rename to babel/compat/tests/fixtures/function-arrow/output.json diff --git a/native/babel-compat/tests/fixtures/function-default-parameters/input.js b/babel/compat/tests/fixtures/function-default-parameters/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/function-default-parameters/input.js rename to babel/compat/tests/fixtures/function-default-parameters/input.js diff --git a/native/babel-compat/tests/fixtures/function-default-parameters/output.json b/babel/compat/tests/fixtures/function-default-parameters/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/function-default-parameters/output.json rename to babel/compat/tests/fixtures/function-default-parameters/output.json diff --git a/native/babel-compat/tests/fixtures/function-rest-parameters/input.js b/babel/compat/tests/fixtures/function-rest-parameters/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/function-rest-parameters/input.js rename to babel/compat/tests/fixtures/function-rest-parameters/input.js diff --git a/native/babel-compat/tests/fixtures/function-rest-parameters/output.json b/babel/compat/tests/fixtures/function-rest-parameters/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/function-rest-parameters/output.json rename to babel/compat/tests/fixtures/function-rest-parameters/output.json diff --git a/native/babel-compat/tests/fixtures/function-simple/input.js b/babel/compat/tests/fixtures/function-simple/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/function-simple/input.js rename to babel/compat/tests/fixtures/function-simple/input.js diff --git a/native/babel-compat/tests/fixtures/function-simple/output.json b/babel/compat/tests/fixtures/function-simple/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/function-simple/output.json rename to babel/compat/tests/fixtures/function-simple/output.json diff --git a/native/babel-compat/tests/fixtures/jsx-and-expr/input.jsx b/babel/compat/tests/fixtures/jsx-and-expr/input.jsx similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-and-expr/input.jsx rename to babel/compat/tests/fixtures/jsx-and-expr/input.jsx diff --git a/native/babel-compat/tests/fixtures/jsx-and-expr/output.json b/babel/compat/tests/fixtures/jsx-and-expr/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-and-expr/output.json rename to babel/compat/tests/fixtures/jsx-and-expr/output.json diff --git a/native/babel-compat/tests/fixtures/jsx-children/input.jsx b/babel/compat/tests/fixtures/jsx-children/input.jsx similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-children/input.jsx rename to babel/compat/tests/fixtures/jsx-children/input.jsx diff --git a/native/babel-compat/tests/fixtures/jsx-children/output.json b/babel/compat/tests/fixtures/jsx-children/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-children/output.json rename to babel/compat/tests/fixtures/jsx-children/output.json diff --git a/native/babel-compat/tests/fixtures/jsx-map/input.jsx b/babel/compat/tests/fixtures/jsx-map/input.jsx similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-map/input.jsx rename to babel/compat/tests/fixtures/jsx-map/input.jsx diff --git a/native/babel-compat/tests/fixtures/jsx-map/output.json b/babel/compat/tests/fixtures/jsx-map/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-map/output.json rename to babel/compat/tests/fixtures/jsx-map/output.json diff --git a/native/babel-compat/tests/fixtures/jsx-props-spread/input.jsx b/babel/compat/tests/fixtures/jsx-props-spread/input.jsx similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-props-spread/input.jsx rename to babel/compat/tests/fixtures/jsx-props-spread/input.jsx diff --git a/native/babel-compat/tests/fixtures/jsx-props-spread/output.json b/babel/compat/tests/fixtures/jsx-props-spread/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-props-spread/output.json rename to babel/compat/tests/fixtures/jsx-props-spread/output.json diff --git a/native/babel-compat/tests/fixtures/jsx-props/input.jsx b/babel/compat/tests/fixtures/jsx-props/input.jsx similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-props/input.jsx rename to babel/compat/tests/fixtures/jsx-props/input.jsx diff --git a/native/babel-compat/tests/fixtures/jsx-props/output.json b/babel/compat/tests/fixtures/jsx-props/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-props/output.json rename to babel/compat/tests/fixtures/jsx-props/output.json diff --git a/native/babel-compat/tests/fixtures/jsx-self-closing/input.jsx b/babel/compat/tests/fixtures/jsx-self-closing/input.jsx similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-self-closing/input.jsx rename to babel/compat/tests/fixtures/jsx-self-closing/input.jsx diff --git a/native/babel-compat/tests/fixtures/jsx-self-closing/output.json b/babel/compat/tests/fixtures/jsx-self-closing/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-self-closing/output.json rename to babel/compat/tests/fixtures/jsx-self-closing/output.json diff --git a/native/babel-compat/tests/fixtures/jsx-simple/input.jsx b/babel/compat/tests/fixtures/jsx-simple/input.jsx similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-simple/input.jsx rename to babel/compat/tests/fixtures/jsx-simple/input.jsx diff --git a/native/babel-compat/tests/fixtures/jsx-simple/output.json b/babel/compat/tests/fixtures/jsx-simple/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-simple/output.json rename to babel/compat/tests/fixtures/jsx-simple/output.json diff --git a/native/babel-compat/tests/fixtures/jsx-ternary-expr/input.jsx b/babel/compat/tests/fixtures/jsx-ternary-expr/input.jsx similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-ternary-expr/input.jsx rename to babel/compat/tests/fixtures/jsx-ternary-expr/input.jsx diff --git a/native/babel-compat/tests/fixtures/jsx-ternary-expr/output.json b/babel/compat/tests/fixtures/jsx-ternary-expr/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/jsx-ternary-expr/output.json rename to babel/compat/tests/fixtures/jsx-ternary-expr/output.json diff --git a/native/babel-compat/tests/fixtures/module-commonjs/input.js b/babel/compat/tests/fixtures/module-commonjs/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/module-commonjs/input.js rename to babel/compat/tests/fixtures/module-commonjs/input.js diff --git a/native/babel-compat/tests/fixtures/module-commonjs/output.json b/babel/compat/tests/fixtures/module-commonjs/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/module-commonjs/output.json rename to babel/compat/tests/fixtures/module-commonjs/output.json diff --git a/native/babel-compat/tests/fixtures/module-export-default/input.mjs b/babel/compat/tests/fixtures/module-export-default/input.mjs similarity index 100% rename from native/babel-compat/tests/fixtures/module-export-default/input.mjs rename to babel/compat/tests/fixtures/module-export-default/input.mjs diff --git a/native/babel-compat/tests/fixtures/module-export-default/output.json b/babel/compat/tests/fixtures/module-export-default/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/module-export-default/output.json rename to babel/compat/tests/fixtures/module-export-default/output.json diff --git a/native/babel-compat/tests/fixtures/module-export-individual-items/input.mjs b/babel/compat/tests/fixtures/module-export-individual-items/input.mjs similarity index 100% rename from native/babel-compat/tests/fixtures/module-export-individual-items/input.mjs rename to babel/compat/tests/fixtures/module-export-individual-items/input.mjs diff --git a/native/babel-compat/tests/fixtures/module-export-individual-items/output.json b/babel/compat/tests/fixtures/module-export-individual-items/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/module-export-individual-items/output.json rename to babel/compat/tests/fixtures/module-export-individual-items/output.json diff --git a/native/babel-compat/tests/fixtures/module-export-named/input.mjs b/babel/compat/tests/fixtures/module-export-named/input.mjs similarity index 100% rename from native/babel-compat/tests/fixtures/module-export-named/input.mjs rename to babel/compat/tests/fixtures/module-export-named/input.mjs diff --git a/native/babel-compat/tests/fixtures/module-export-named/output.json b/babel/compat/tests/fixtures/module-export-named/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/module-export-named/output.json rename to babel/compat/tests/fixtures/module-export-named/output.json diff --git a/native/babel-compat/tests/fixtures/module-export-renamed/input.mjs b/babel/compat/tests/fixtures/module-export-renamed/input.mjs similarity index 100% rename from native/babel-compat/tests/fixtures/module-export-renamed/input.mjs rename to babel/compat/tests/fixtures/module-export-renamed/input.mjs diff --git a/native/babel-compat/tests/fixtures/module-export-renamed/output.json b/babel/compat/tests/fixtures/module-export-renamed/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/module-export-renamed/output.json rename to babel/compat/tests/fixtures/module-export-renamed/output.json diff --git a/native/babel-compat/tests/fixtures/module-import-default/input.mjs b/babel/compat/tests/fixtures/module-import-default/input.mjs similarity index 100% rename from native/babel-compat/tests/fixtures/module-import-default/input.mjs rename to babel/compat/tests/fixtures/module-import-default/input.mjs diff --git a/native/babel-compat/tests/fixtures/module-import-default/output.json b/babel/compat/tests/fixtures/module-import-default/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/module-import-default/output.json rename to babel/compat/tests/fixtures/module-import-default/output.json diff --git a/native/babel-compat/tests/fixtures/module-import-multiple/input.mjs b/babel/compat/tests/fixtures/module-import-multiple/input.mjs similarity index 100% rename from native/babel-compat/tests/fixtures/module-import-multiple/input.mjs rename to babel/compat/tests/fixtures/module-import-multiple/input.mjs diff --git a/native/babel-compat/tests/fixtures/module-import-multiple/output.json b/babel/compat/tests/fixtures/module-import-multiple/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/module-import-multiple/output.json rename to babel/compat/tests/fixtures/module-import-multiple/output.json diff --git a/native/babel-compat/tests/fixtures/module-import-named/input.mjs b/babel/compat/tests/fixtures/module-import-named/input.mjs similarity index 100% rename from native/babel-compat/tests/fixtures/module-import-named/input.mjs rename to babel/compat/tests/fixtures/module-import-named/input.mjs diff --git a/native/babel-compat/tests/fixtures/module-import-named/output.json b/babel/compat/tests/fixtures/module-import-named/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/module-import-named/output.json rename to babel/compat/tests/fixtures/module-import-named/output.json diff --git a/native/babel-compat/tests/fixtures/module-import-renamed/input.mjs b/babel/compat/tests/fixtures/module-import-renamed/input.mjs similarity index 100% rename from native/babel-compat/tests/fixtures/module-import-renamed/input.mjs rename to babel/compat/tests/fixtures/module-import-renamed/input.mjs diff --git a/native/babel-compat/tests/fixtures/module-import-renamed/output.json b/babel/compat/tests/fixtures/module-import-renamed/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/module-import-renamed/output.json rename to babel/compat/tests/fixtures/module-import-renamed/output.json diff --git a/native/babel-compat/tests/fixtures/module-import-star-renamed/input.mjs b/babel/compat/tests/fixtures/module-import-star-renamed/input.mjs similarity index 100% rename from native/babel-compat/tests/fixtures/module-import-star-renamed/input.mjs rename to babel/compat/tests/fixtures/module-import-star-renamed/input.mjs diff --git a/native/babel-compat/tests/fixtures/module-import-star-renamed/output.json b/babel/compat/tests/fixtures/module-import-star-renamed/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/module-import-star-renamed/output.json rename to babel/compat/tests/fixtures/module-import-star-renamed/output.json diff --git a/native/babel-compat/tests/fixtures/object-destructuring/input.js b/babel/compat/tests/fixtures/object-destructuring/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/object-destructuring/input.js rename to babel/compat/tests/fixtures/object-destructuring/input.js diff --git a/native/babel-compat/tests/fixtures/object-destructuring/output.json b/babel/compat/tests/fixtures/object-destructuring/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/object-destructuring/output.json rename to babel/compat/tests/fixtures/object-destructuring/output.json diff --git a/native/babel-compat/tests/fixtures/object-simple/input.js b/babel/compat/tests/fixtures/object-simple/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/object-simple/input.js rename to babel/compat/tests/fixtures/object-simple/input.js diff --git a/native/babel-compat/tests/fixtures/object-simple/output.json b/babel/compat/tests/fixtures/object-simple/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/object-simple/output.json rename to babel/compat/tests/fixtures/object-simple/output.json diff --git a/native/babel-compat/tests/fixtures/object-spread/input.js b/babel/compat/tests/fixtures/object-spread/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/object-spread/input.js rename to babel/compat/tests/fixtures/object-spread/input.js diff --git a/native/babel-compat/tests/fixtures/object-spread/output.json b/babel/compat/tests/fixtures/object-spread/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/object-spread/output.json rename to babel/compat/tests/fixtures/object-spread/output.json diff --git a/native/babel-compat/tests/fixtures/regex-flags/input.js b/babel/compat/tests/fixtures/regex-flags/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/regex-flags/input.js rename to babel/compat/tests/fixtures/regex-flags/input.js diff --git a/native/babel-compat/tests/fixtures/regex-flags/output.json b/babel/compat/tests/fixtures/regex-flags/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/regex-flags/output.json rename to babel/compat/tests/fixtures/regex-flags/output.json diff --git a/native/babel-compat/tests/fixtures/regex-simple/input.js b/babel/compat/tests/fixtures/regex-simple/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/regex-simple/input.js rename to babel/compat/tests/fixtures/regex-simple/input.js diff --git a/native/babel-compat/tests/fixtures/regex-simple/output.json b/babel/compat/tests/fixtures/regex-simple/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/regex-simple/output.json rename to babel/compat/tests/fixtures/regex-simple/output.json diff --git a/native/babel-compat/tests/fixtures/shebang/input.js b/babel/compat/tests/fixtures/shebang/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/shebang/input.js rename to babel/compat/tests/fixtures/shebang/input.js diff --git a/native/babel-compat/tests/fixtures/shebang/output.json b/babel/compat/tests/fixtures/shebang/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/shebang/output.json rename to babel/compat/tests/fixtures/shebang/output.json diff --git a/native/babel-compat/tests/fixtures/simple-two-lines/input.js b/babel/compat/tests/fixtures/simple-two-lines/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/simple-two-lines/input.js rename to babel/compat/tests/fixtures/simple-two-lines/input.js diff --git a/native/babel-compat/tests/fixtures/simple-two-lines/output.json b/babel/compat/tests/fixtures/simple-two-lines/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/simple-two-lines/output.json rename to babel/compat/tests/fixtures/simple-two-lines/output.json diff --git a/native/babel-compat/tests/fixtures/simple/input.js b/babel/compat/tests/fixtures/simple/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/simple/input.js rename to babel/compat/tests/fixtures/simple/input.js diff --git a/native/babel-compat/tests/fixtures/simple/output.json b/babel/compat/tests/fixtures/simple/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/simple/output.json rename to babel/compat/tests/fixtures/simple/output.json diff --git a/native/babel-compat/tests/fixtures/template-literal/input.js b/babel/compat/tests/fixtures/template-literal/input.js similarity index 100% rename from native/babel-compat/tests/fixtures/template-literal/input.js rename to babel/compat/tests/fixtures/template-literal/input.js diff --git a/native/babel-compat/tests/fixtures/template-literal/output.json b/babel/compat/tests/fixtures/template-literal/output.json similarity index 100% rename from native/babel-compat/tests/fixtures/template-literal/output.json rename to babel/compat/tests/fixtures/template-literal/output.json diff --git a/native/babel-compat/tests/fixtures/ts-function/input.ts b/babel/compat/tests/fixtures/ts-function/input.ts similarity index 100% rename from native/babel-compat/tests/fixtures/ts-function/input.ts rename to babel/compat/tests/fixtures/ts-function/input.ts diff --git a/native/babel-compat/tests/package.json b/babel/compat/tests/package.json similarity index 100% rename from native/babel-compat/tests/package.json rename to babel/compat/tests/package.json diff --git a/native/babel-compat/tests/swcgen.js b/babel/compat/tests/swcgen.js similarity index 100% rename from native/babel-compat/tests/swcgen.js rename to babel/compat/tests/swcgen.js diff --git a/native/babel-visit/Cargo.toml b/babel/visit/Cargo.toml similarity index 79% rename from native/babel-visit/Cargo.toml rename to babel/visit/Cargo.toml index dd319927cb5..59962d731f2 100644 --- a/native/babel-visit/Cargo.toml +++ b/babel/visit/Cargo.toml @@ -12,5 +12,6 @@ version = "0.1.0" [dependencies] serde = {version = "1", features = ["derive"]} serde_json = "1.0.62" -swc_babel_ast = {path = "../babel-ast"} -swc_visit = {version = "0.2.3", path = "../../visit"} +swc_atoms = {path = "../../atoms"} +swc_babel_ast = {path = "../ast"} +swc_visit = {path = "../../visit"} diff --git a/native/babel-visit/README.md b/babel/visit/README.md similarity index 100% rename from native/babel-visit/README.md rename to babel/visit/README.md diff --git a/native/babel-visit/src/lib.rs b/babel/visit/src/lib.rs similarity index 99% rename from native/babel-visit/src/lib.rs rename to babel/visit/src/lib.rs index e714bd0957d..3c2fdf928e1 100644 --- a/native/babel-visit/src/lib.rs +++ b/babel/visit/src/lib.rs @@ -1,5 +1,6 @@ use serde_json::Value; use std::any::Any; +use swc_atoms::JsWord; use swc_babel_ast::*; use swc_visit::define; @@ -297,7 +298,7 @@ define!({ } pub struct Identifier { pub base: BaseNode, - pub name: String, + pub name: JsWord, pub decorators: Option>, pub optional: Option, pub type_annotation: Option>, @@ -377,7 +378,7 @@ define!({ } pub struct DirectiveLiteral { pub base: BaseNode, - pub value: String, + pub value: JsWord, } pub struct PipelineBareFunction { pub base: BaseNode, @@ -577,7 +578,7 @@ define!({ } pub struct AssignmentExpression { pub base: BaseNode, - pub operator: String, + pub operator: JsWord, pub left: Box, pub right: Box, } @@ -629,7 +630,7 @@ define!({ } pub struct V8IntrinsicIdentifier { pub base: BaseNode, - pub name: String, + pub name: JsWord, } pub enum Callee { Expr(Box), @@ -1004,7 +1005,7 @@ define!({ pub bound: Option, pub default: Option, pub variance: Option, - pub name: String, + pub name: JsWord, } pub struct TypeParameterInstantiation { pub base: BaseNode, @@ -1102,7 +1103,7 @@ define!({ } pub struct StringLiteralTypeAnnotation { pub base: BaseNode, - pub value: String, + pub value: JsWord, } pub struct StringTypeAnnotation { pub base: BaseNode, @@ -1296,7 +1297,7 @@ define!({ } pub struct JSXIdentifier { pub base: BaseNode, - pub name: String, + pub name: JsWord, } pub enum JSXMemberExprObject { Expr(JSXMemberExpression), @@ -1329,7 +1330,7 @@ define!({ } pub struct JSXText { pub base: BaseNode, - pub value: String, + pub value: JsWord, } pub struct JSXFragment { pub base: BaseNode, @@ -1367,7 +1368,7 @@ define!({ } pub struct StringLiteral { pub base: BaseNode, - pub value: String, + pub value: JsWord, } pub struct NumericLiteral { pub base: BaseNode, @@ -1386,17 +1387,17 @@ define!({ } pub struct RegExpLiteral { pub base: BaseNode, - pub pattern: String, - pub flags: String, + pub pattern: JsWord, + pub flags: JsWord, } pub struct RegexLiteral { pub base: BaseNode, - pub pattern: String, - pub flags: String, + pub pattern: JsWord, + pub flags: JsWord, } pub struct TemplateElVal { - pub raw: String, - pub cooked: Option, + pub raw: JsWord, + pub cooked: Option, } pub struct TemplateElement { pub base: BaseNode, @@ -1418,7 +1419,7 @@ define!({ } pub struct DecimalLiteral { pub base: BaseNode, - pub value: String, + pub value: JsWord, } pub enum ModuleDeclaration { ExportAll(ExportAllDeclaration), @@ -1447,7 +1448,7 @@ define!({ } pub struct InterpreterDirective { pub base: BaseNode, - pub value: String, + pub value: JsWord, } pub enum SrcType { Script, @@ -2107,7 +2108,7 @@ define!({ pub struct TSTypeOperator { pub base: BaseNode, pub type_annotation: Box, - pub operator: String, + pub operator: JsWord, } pub struct TSIndexedAccessType { pub base: BaseNode, @@ -2238,6 +2239,6 @@ define!({ pub base: BaseNode, pub constraint: Option>, pub default: Option>, - pub name: String, + pub name: JsWord, } }); diff --git a/common/src/source_map.rs b/common/src/source_map.rs index 34491a4df62..eb09bdfaa8f 100644 --- a/common/src/source_map.rs +++ b/common/src/source_map.rs @@ -507,9 +507,9 @@ impl SourceMap { /// arguments: a string slice containing the source, an index in /// the slice for the beginning of the span and an index in the slice for /// the end of the span. - fn span_to_source(&self, sp: Span, extract_source: F) -> Result + fn span_to_source(&self, sp: Span, extract_source: F) -> Result where - F: Fn(&str, usize, usize) -> String, + F: FnOnce(&str, usize, usize) -> Ret, { if sp.lo() > sp.hi() { return Err(SpanSnippetError::IllFormedSpan(sp)); @@ -561,14 +561,30 @@ impl SourceMap { } } + /// Calls the given closure with the source snippet before the given `Span` + pub fn with_span_to_prev_source(&self, sp: Span, op: F) -> Result + where + F: FnOnce(&str) -> Ret, + { + self.span_to_source(sp, |src, start_index, _| op(&src[..start_index])) + } + /// Return the source snippet as `String` before the given `Span` pub fn span_to_prev_source(&self, sp: Span) -> Result { - self.span_to_source(sp, |src, start_index, _| src[..start_index].to_string()) + self.with_span_to_prev_source(sp, |s| s.to_string()) + } + + /// Calls the given closure with the source snippet after the given `Span` + pub fn with_span_to_next_source(&self, sp: Span, op: F) -> Result + where + F: FnOnce(&str) -> Ret, + { + self.span_to_source(sp, |src, _, end_index| op(&src[end_index..])) } /// Return the source snippet as `String` after the given `Span` pub fn span_to_next_source(&self, sp: Span) -> Result { - self.span_to_source(sp, |src, _, end_index| src[end_index..].to_string()) + self.with_span_to_next_source(sp, |s| s.to_string()) } /// Extend the given `Span` to just after the previous occurrence of `c`. @@ -661,21 +677,22 @@ impl SourceMap { } /// Given a `Span`, get a shorter one until `predicate` yields false. - pub fn span_take_while

(&self, sp: Span, predicate: P) -> Span + pub fn span_take_while

(&self, sp: Span, mut predicate: P) -> Span where P: for<'r> FnMut(&'r char) -> bool, { - if let Ok(snippet) = self.span_to_snippet(sp) { + self.span_to_source(sp, |src, start_index, end_index| { + let snippet = &src[start_index..end_index]; + let offset = snippet .chars() - .take_while(predicate) + .take_while(&mut predicate) .map(|c| c.len_utf8()) .sum::(); sp.with_hi(BytePos(sp.lo().0 + (offset as u32))) - } else { - sp - } + }) + .unwrap_or(sp) } pub fn def_span(&self, sp: Span) -> Span { diff --git a/native/Cargo.toml b/native/Cargo.toml index 92a64a22490..556c16eb654 100644 --- a/native/Cargo.toml +++ b/native/Cargo.toml @@ -26,14 +26,9 @@ serde_json = "1" spack = {path = "../spack"} swc = {path = "../"} swc_atoms = {version = "0.2.4", path = "../atoms"} -swc_babel_compat = {path = "./babel-compat"} +swc_babel_compat = {path = "../babel/compat"} swc_bundler = {path = "../bundler"} swc_common = {path = "../common", features = ["tty-emitter", "sourcemap"]} swc_ecma_ast = {path = "../ecmascript/ast"} swc_ecma_parser = {path = "../ecmascript/parser"} - -[target.'cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64")))'.dependencies] -jemallocator = {version = "0.3", features = ["disable_initial_exec_tls"]} - -[target.'cfg(windows)'.dependencies] -mimalloc = {version = "0.1"} +swc_node_base = {path = "../node/base"} diff --git a/native/babel-compat/src/main.rs b/native/babel-compat/src/main.rs deleted file mode 100644 index 34ab5cd8ec2..00000000000 --- a/native/babel-compat/src/main.rs +++ /dev/null @@ -1,174 +0,0 @@ -/* -#![feature(type_name_of_val, macro_attributes_in_derive_output)] - -use swc_common::{ast_serde}; -use serde::{Serialize, Deserialize}; - -// #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -// #[ast_node] -// #[serde(tag = "type")] -#[derive(Debug)] -#[ast_serde("A")] -struct A { - value: usize, -} - -// #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -// #[serde(tag = "type")] -#[derive(Debug)] -#[ast_serde("B")] -struct B { - value: usize, -} - -// #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -// #[derive(Debug, Clone, SerializeUnion, Deserialize, PartialEq)] -// #[serde(tag = "type")] -#[derive(Debug)] -#[ast_serde] -enum AB { - #[tag("A")] - A(A), - #[tag("B")] - B(B), -} - -// pub use swc_babel_compat_macros::SerializeUnion; -// pub trait SerializeUnion {} - -// #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -// #[serde(tag = "type")] -#[derive(Debug)] -#[ast_serde("C")] -struct C { - value: usize, -} - -// #[derive(Debug, Clone, SerializeUnion, Deserialize, PartialEq)] -// #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -// #[serde(tag = "type")] -// #[serde(untagged)] -#[derive(Debug)] -#[ast_serde] -enum ABC { - #[tag("C")] - C(C), - #[tag("A")] - #[tag("B")] - AB(AB), -} - -fn main() { - let json = r#"{"type": "A", "value": 1}"#; - // let a: A = serde_json::from_str(&json).unwrap(); - // println!("{:#?}", a); - - // let a: AB = serde_json::from_str(&json).unwrap(); - // println!("{:?}", a); - - let a: ABC = serde_json::from_str(&json).unwrap(); - println!("{:#?}", a); - - println!("{}", serde_json::to_string_pretty(&a).unwrap()); -} -*/ - -/* -use swc_babel_compat::{Context, Babelify}; -use swc::Compiler; -use swc_common::{ - FilePathMapping, SourceMap, FileName, SourceFile, - errors::{ColorConfig, Handler}, -}; -use swc_ecma_ast::{Program, Module}; -use anyhow::{anyhow, Result}; -use serde_json::{json, Value}; -use std::sync::Arc; -use std::fs; - - -// ---------------------------------------------------------------------------- -// Visitor -use swc_babel_visit::{Visit, VisitMut, Node, VisitWith, VisitMutWith}; -use swc_babel_ast::Identifier; - -struct IdCollector { - ids: Vec, -} - -impl Visit for IdCollector { - fn visit_identifier(&mut self, id: &Identifier, _parent: &dyn Node) { - self.ids.push(id.clone()); - } -} - -struct IdChanger; - -impl VisitMut for IdChanger { - fn visit_mut_identifier(&mut self, id: &mut Identifier) { - id.name += "_gecko"; - } -} - -// ---------------------------------------------------------------------------- - -fn main() { - let src = fs::read_to_string("tests/fixtures/simple/input.js").unwrap(); - let (cm, compiler, fm) = init(src); - - let program = compile(&compiler, fm.clone()).unwrap(); - - // println!("{:#?}", program); - - // println!("{}", serde_json::to_string_pretty(&program).unwrap()); - - let ctx = Context { - fm: fm, - cm: cm, - comments: Arc::new(compiler.comments().clone()), - }; - let mut ast = program.babelify(&ctx); - // println!("{:#?}", ast); - - // let mut idcoll = IdCollector { ids: vec![] }; - // ast.visit_with(&swc_ecma_ast::Invalid { span: swc_common::DUMMY_SP }, &mut idcoll); - // println!("{:#?}", idcoll.ids); - - // let mut idchanger = IdChanger {}; - // ast.visit_mut_with(&mut idchanger); - // println!("{:#?}", ast); - - // let json = serde_json::to_string_pretty(&ast).unwrap(); - // println!("{}", json); - - // let output = read_fixture_file("simple/output.json".to_owned()).unwrap(); - // let expected: File = serde_json::from_str(&output).unwrap(); - // println!("{:#?}", expected); -} - -fn init(src: String) -> (Arc, Compiler, Arc) { - 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); - - (cm, compiler, fm) -} - -fn compile(compiler: &Compiler, fm: Arc) -> Result { - compiler.parse_js( - fm, - Default::default(), - Default::default(), - false, - Default::default(), - ) -} -*/ - -fn main() {} diff --git a/native/src/lib.rs b/native/src/lib.rs index 1d0ff66fe44..582d53ff9ff 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -2,14 +2,8 @@ #[macro_use] extern crate napi_derive; - -#[cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64")))] -#[global_allocator] -static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; - -#[cfg(windows)] -#[global_allocator] -static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; +/// Explicit extern crate to use allocator. +extern crate swc_node_base; use backtrace::Backtrace; use napi::{CallContext, Env, JsFunction, JsObject, JsUndefined}; diff --git a/node-swc/src/babel.ts b/node-swc/src/babel.ts new file mode 100644 index 00000000000..41cd65ae9e3 --- /dev/null +++ b/node-swc/src/babel.ts @@ -0,0 +1,16 @@ +import { Options, ParseOptions } from './types'; + +export type BabelifyOptions = { + /** + * If it's not specified, transforms will not be applied. + * + * The parser config should be provided via this property when transformations are enabled. + */ + transforms: Options +} | { + + /** + * Option for the parser. + */ + parser: ParseOptions +}; \ No newline at end of file diff --git a/node-swc/src/index.ts b/node-swc/src/index.ts index 05e35e394b4..6e6eaa8baba 100644 --- a/node-swc/src/index.ts +++ b/node-swc/src/index.ts @@ -10,6 +10,8 @@ import { export * from "./types"; import { BundleInput, compileBundleOptions } from "./spack"; import { loadBinding } from "@node-rs/helper"; +import * as babel from '@babel/types'; +import { BabelifyOptions } from './babel'; const bindings = loadBinding(__dirname, "swc", "@swc/core") @@ -29,6 +31,40 @@ export function plugins(ps: Plugin[]): Plugin { } export class Compiler { + // /** + // * Parse source code as a babel ast. + // * + // * If `options.transforms` is specified, this method also applies transforms. + // * + // * @param src Source code + // * @param options + // */ + // babelify(input: string, options?: BabelifyOptions): Promise; + // babelify(input: Program, options?: BabelifyOptions): Promise; + // babelify(input: string | Program, options?: BabelifyOptions): Promise { + // const shouldParseInput = typeof input === 'string'; + // return bindings.babelify({ + // shouldParseInput, + // }, input, options); + // } + + // /** + // * Parse source code as a babel ast. + // * + // * If `options.transforms` is specified, this method also applies transforms. + // * + // * @param src Source code + // * @param options + // */ + // babelifySync(input: string, options?: BabelifyOptions): babel.Program; + // babelifySync(input: Program, options?: BabelifyOptions): babel.Program; + // babelifySync(input: string | Program, options?: BabelifyOptions): babel.Program { + // const shouldParseInput = typeof input === 'string'; + // return bindings.babelifySync({ + // shouldParseInput + // }, input, options); + // } + parse( src: string, options: ParseOptions & { isModule: false } diff --git a/node/base/Cargo.toml b/node/base/Cargo.toml new file mode 100644 index 00000000000..050c385a387 --- /dev/null +++ b/node/base/Cargo.toml @@ -0,0 +1,21 @@ +[package] +authors = ["강동윤 "] +description = "Speedy web compiler" +documentation = "https://rustdoc.swc.rs/swc_node_base/" +edition = "2018" +license = "Apache-2.0/MIT" +name = "swc_node_base" +repository = "https://github.com/swc-project/swc.git" +version = "0.1.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +dashmap = "4.0.2" +swc_common = {version = "0.10", path = "../../common"} + +[target.'cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64")))'.dependencies] +jemallocator = {version = "0.3", features = ["disable_initial_exec_tls"]} + +[target.'cfg(windows)'.dependencies] +mimalloc = {version = "0.1"} diff --git a/node/base/src/lib.rs b/node/base/src/lib.rs new file mode 100644 index 00000000000..a9d1eca2839 --- /dev/null +++ b/node/base/src/lib.rs @@ -0,0 +1,11 @@ +//! This crate configures memery allocator. +//! +//! The swc crates related to the node binding should depend on this crate. + +#[cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64")))] +#[global_allocator] +static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; + +#[cfg(windows)] +#[global_allocator] +static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; diff --git a/package.json b/package.json index 011255e7a1b..8699df0e27e 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "@babel/preset-env": "^7.13.15", "@babel/preset-react": "^7.13.13", "@babel/preset-typescript": "^7.13.0", + "@babel/types": "^7.14.0", "@napi-rs/cli": "^1.0.4", "@swc/helpers": "^0.2.10", "@types/browserslist": "^4.15.0", diff --git a/rust-toolchain b/rust-toolchain index 3e90e47f03c..1cfd57a1d81 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2021-02-19 \ No newline at end of file +nightly-2021-04-25 \ No newline at end of file diff --git a/spack/Cargo.toml b/spack/Cargo.toml index 9558e900e5f..49971539f09 100644 --- a/spack/Cargo.toml +++ b/spack/Cargo.toml @@ -33,6 +33,7 @@ swc_ecma_parser = {path = "../ecmascript/parser"} swc_ecma_transforms = {path = "../ecmascript/transforms"} swc_ecma_utils = {path = "../ecmascript/utils"} swc_ecma_visit = {path = "../ecmascript/visit"} +swc_node_base = {path = "../node/base"} [dev-dependencies] pretty_assertions = "0.6.1" @@ -41,11 +42,5 @@ tempfile = "3" testing = {path = "../testing"} walkdir = "2.3.1" -[target.'cfg(all(unix, not(target_env = "musl")))'.dev-dependencies] -jemallocator = {version = "0.3", features = ["disable_initial_exec_tls"]} - [target.'cfg(windows)'.dependencies] -normpath="0.2" - -[target.'cfg(windows)'.dev-dependencies] -mimalloc = {version = "0.1"} +normpath = "0.2" diff --git a/spack/benches/bench.rs b/spack/benches/bench.rs index ede7fd868c4..019da1f1b14 100644 --- a/spack/benches/bench.rs +++ b/spack/benches/bench.rs @@ -4,14 +4,6 @@ extern crate test; -#[cfg(all(unix, not(target_env = "musl")))] -#[global_allocator] -static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; - -#[cfg(windows)] -#[global_allocator] -static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; - use anyhow::Error; use spack::resolvers::NodeResolver; use std::{ diff --git a/spack/src/lib.rs b/spack/src/lib.rs index 5eee4f1262e..0eb9924fb0d 100644 --- a/spack/src/lib.rs +++ b/spack/src/lib.rs @@ -1,9 +1,11 @@ #![cfg_attr(test, feature(test))] -#![feature(or_patterns)] #[cfg(test)] extern crate test; +/// Explicit extern crate to use allocator. +extern crate swc_node_base; + pub mod config; pub mod loaders; pub mod resolvers; diff --git a/src/lib.rs b/src/lib.rs index ca1aee5e39d..7805afb8417 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,5 @@ #![deny(unused)] -pub use sourcemap; - pub use crate::builder::PassBuilder; use crate::config::{ BuiltConfig, Config, ConfigFile, InputSourceMap, JscTarget, Merge, Options, Rc, RootMode, @@ -11,6 +9,7 @@ use anyhow::{bail, Context, Error}; use dashmap::DashMap; use serde::Serialize; use serde_json::error::Category; +pub use sourcemap; use std::{ fs::{read_to_string, File}, path::{Path, PathBuf}, @@ -582,13 +581,13 @@ fn load_swcrc(path: &Path) -> Result { .map_err(convert_json_err) } -type CommentMap = Arc>>; +type CommentMap = Arc, ahash::RandomState>>; /// Multi-threaded implementation of [Comments] #[derive(Clone, Default)] pub struct SwcComments { - leading: CommentMap, - trailing: CommentMap, + pub leading: CommentMap, + pub trailing: CommentMap, } impl Comments for SwcComments { diff --git a/visit/macros/src/lib.rs b/visit/macros/src/lib.rs index b4d1c974a0c..ace55b5e047 100644 --- a/visit/macros/src/lib.rs +++ b/visit/macros/src/lib.rs @@ -432,14 +432,9 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote { // impl Visit for swc_visit::All where V: VisitAll if mode == Mode::VisitAll { - let mut item = q!( - Vars { - Trait: Ident::new(mode.trait_name(), call_site()), - }, - { - impl Visit for ::swc_visit::All where V: VisitAll {} - } - ) + let mut item = q!(Vars {}, { + impl Visit for ::swc_visit::All where V: VisitAll {} + }) .parse::(); item.items @@ -585,7 +580,6 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote { tokens.push_tokens(&q!( Vars { - method_name, Type: ty, expr, default_body, @@ -619,7 +613,6 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote { tokens.push_tokens(&q!( Vars { - method_name, Type: ty, expr, default_body,