Skip to content

Commit bff710a

Browse files
feat(es/compiler): Merge optional_chaining into Compiler
This PR merges the `optional_chaining` visitor from `swc_ecma_compat_es2020` into `swc_ecma_compiler::Compiler` to reduce visitor overhead and improve performance by consolidating ECMAScript compatibility transformations. ## Changes ### 1. Created ES2020 Module - Created `crates/swc_ecma_compiler/src/es2020/optional_chaining.rs` with transformation logic - Updated `crates/swc_ecma_compiler/src/es2020/mod.rs` to include the new module ### 2. Integrated into CompilerImpl Added transformation state to `CompilerImpl`: - `es2020_optional_chaining_vars: Vec<VarDeclarator>` - stores generated variable declarators - `es2020_optional_chaining_unresolved_ctxt: SyntaxContext` - tracks unresolved context Implemented visitor methods: - `transform_optional_chaining()` - transforms `?.` and `delete ?.` operators - `visit_mut_expr()` - calls transformation before other transformations - `visit_mut_block_stmt_or_expr()` - converts expressions to block statements when needed - `visit_mut_pat()` - handles optional chaining in assignment patterns - `visit_mut_module_items()` / `visit_mut_stmts()` - hoist generated variables ### 3. Updated swc_ecma_compat_es2020 - Modified `lib.rs` to use `Compiler` with `Features::OPTIONAL_CHAINING` - Simplified `optional_chaining.rs` to a thin wrapper around `Compiler` - Maintained backward compatibility and existing `Config` API - Maps `pure_getter` config to `assumptions.pure_getters` ## Testing All existing tests pass: - ✅ `cargo test -p swc_ecma_compat_es2020` - ✅ `cargo test -p swc_ecma_compiler` ## Performance Impact This change is part of a larger effort to reduce visitor overhead by consolidating transformations into a single Compiler implementation, minimizing the number of AST traversals. ## Related PRs Follows the same pattern as: - #11157: Merged nullish_coalescing - #10914: Merged logical_assignments - #10909: Merged private_in_object and static_blocks 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent dd6f71b commit bff710a

File tree

5 files changed

+540
-24
lines changed

5 files changed

+540
-24
lines changed

crates/swc_ecma_compat_es2020/src/lib.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ mod export_namespace_from;
1313
pub mod nullish_coalescing;
1414
pub mod optional_chaining;
1515

16-
pub fn es2020(config: Config, unresolved_mark: Mark) -> impl Pass {
16+
pub fn es2020(config: Config, _unresolved_mark: Mark) -> impl Pass {
1717
let mut assumptions = Assumptions::default();
1818
assumptions.no_document_all = config.nullish_coalescing.no_document_all;
19+
assumptions.pure_getters = config.optional_chaining.pure_getter;
1920

20-
(
21-
optional_chaining(config.optional_chaining, unresolved_mark),
22-
Compiler::new(swc_ecma_compiler::Config {
23-
includes: Features::EXPORT_NAMESPACE_FROM | Features::NULLISH_COALESCING,
24-
assumptions,
25-
..Default::default()
26-
}),
27-
)
21+
Compiler::new(swc_ecma_compiler::Config {
22+
includes: Features::EXPORT_NAMESPACE_FROM
23+
| Features::NULLISH_COALESCING
24+
| Features::OPTIONAL_CHAINING,
25+
assumptions,
26+
..Default::default()
27+
})
2828
}
2929

3030
#[derive(Debug, Clone, Default, Deserialize)]

crates/swc_ecma_compat_es2020/src/optional_chaining.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
use serde::Deserialize;
22
use swc_common::Mark;
33
use swc_ecma_ast::Pass;
4-
use swc_ecma_compat_es2022::optional_chaining_impl::optional_chaining_impl;
5-
use swc_ecma_visit::visit_mut_pass;
4+
use swc_ecma_compiler::{Compiler, Features};
5+
use swc_ecma_transforms_base::assumptions::Assumptions;
66

7-
pub fn optional_chaining(c: Config, unresolved_mark: Mark) -> impl Pass {
8-
visit_mut_pass(optional_chaining_impl(
9-
swc_ecma_compat_es2022::optional_chaining_impl::Config {
10-
no_document_all: c.no_document_all,
11-
pure_getter: c.pure_getter,
12-
},
13-
unresolved_mark,
14-
))
7+
pub fn optional_chaining(c: Config, _unresolved_mark: Mark) -> impl Pass {
8+
let mut assumptions = Assumptions::default();
9+
assumptions.no_document_all = c.no_document_all;
10+
assumptions.pure_getters = c.pure_getter;
11+
12+
Compiler::new(swc_ecma_compiler::Config {
13+
includes: Features::OPTIONAL_CHAINING,
14+
assumptions,
15+
..Default::default()
16+
})
1517
}
1618

1719
#[derive(Debug, Clone, Copy, Default, Deserialize)]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub(crate) mod export_namespace_from;
22
pub(crate) mod nullish_coalescing;
3+
pub(crate) mod optional_chaining;

0 commit comments

Comments
 (0)