mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(transformer): support optional-catch-binding plugin (#4885)
part of #4754 The implementation copy from the original implementation which removed in https://github.com/oxc-project/oxc/pull/2865.
This commit is contained in:
parent
69da9fda3a
commit
ab1d08ccfb
9 changed files with 128 additions and 5 deletions
35
crates/oxc_transformer/src/es2019/mod.rs
Normal file
35
crates/oxc_transformer/src/es2019/mod.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
mod optional_catch_binding;
|
||||
mod options;
|
||||
|
||||
pub use optional_catch_binding::OptionalCatchBinding;
|
||||
pub use options::ES2019Options;
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_traverse::TraverseCtx;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::context::Ctx;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct ES2019<'a> {
|
||||
ctx: Ctx<'a>,
|
||||
options: ES2019Options,
|
||||
|
||||
// Plugins
|
||||
optional_catch_binding: OptionalCatchBinding<'a>,
|
||||
}
|
||||
|
||||
impl<'a> ES2019<'a> {
|
||||
pub fn new(options: ES2019Options, ctx: Ctx<'a>) -> Self {
|
||||
Self { optional_catch_binding: OptionalCatchBinding::new(Rc::clone(&ctx)), ctx, options }
|
||||
}
|
||||
|
||||
pub fn transform_catch_clause(
|
||||
&mut self,
|
||||
clause: &mut CatchClause<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
if self.options.optional_catch_binding {
|
||||
self.optional_catch_binding.transform_catch_clause(clause, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
52
crates/oxc_transformer/src/es2019/optional_catch_binding.rs
Normal file
52
crates/oxc_transformer/src/es2019/optional_catch_binding.rs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
use std::cell::Cell;
|
||||
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_semantic::SymbolFlags;
|
||||
use oxc_span::SPAN;
|
||||
use oxc_traverse::TraverseCtx;
|
||||
|
||||
use crate::context::Ctx;
|
||||
|
||||
/// ES2019: Optional Catch Binding
|
||||
///
|
||||
/// References:
|
||||
/// * <https://babel.dev/docs/babel-plugin-transform-optional-catch-binding>
|
||||
/// * <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-optional-catch-binding>
|
||||
pub struct OptionalCatchBinding<'a> {
|
||||
_ctx: Ctx<'a>,
|
||||
}
|
||||
|
||||
impl<'a> OptionalCatchBinding<'a> {
|
||||
pub fn new(ctx: Ctx<'a>) -> Self {
|
||||
Self { _ctx: ctx }
|
||||
}
|
||||
|
||||
/// If CatchClause has no param, add a parameter called `unused`.
|
||||
///
|
||||
/// ```ts
|
||||
/// try {}
|
||||
/// catch {}
|
||||
/// ```
|
||||
/// too
|
||||
/// ```ts
|
||||
/// try {}
|
||||
/// catch (_unused) {}
|
||||
/// ```
|
||||
#[allow(clippy::unused_self)]
|
||||
pub fn transform_catch_clause(&self, clause: &mut CatchClause<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if clause.param.is_some() {
|
||||
return;
|
||||
}
|
||||
let symbol_id =
|
||||
ctx.generate_uid("unused", ctx.scoping.current_scope_id(), SymbolFlags::CatchVariable);
|
||||
let name = ctx.ast.atom(ctx.symbols().get_name(symbol_id));
|
||||
let binding_identifier =
|
||||
BindingIdentifier { span: SPAN, symbol_id: Cell::new(Some(symbol_id)), name };
|
||||
let binding_pattern_kind =
|
||||
ctx.ast.binding_pattern_kind_from_binding_identifier(binding_identifier);
|
||||
let binding_pattern =
|
||||
ctx.ast.binding_pattern(binding_pattern_kind, None::<TSTypeAnnotation<'a>>, false);
|
||||
let param = ctx.ast.catch_parameter(SPAN, binding_pattern);
|
||||
clause.param = Some(param);
|
||||
}
|
||||
}
|
||||
16
crates/oxc_transformer/src/es2019/options.rs
Normal file
16
crates/oxc_transformer/src/es2019/options.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize)]
|
||||
#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct ES2019Options {
|
||||
#[serde(skip)]
|
||||
pub optional_catch_binding: bool,
|
||||
}
|
||||
|
||||
impl ES2019Options {
|
||||
#[must_use]
|
||||
pub fn with_optional_catch_binding(mut self, enable: bool) -> Self {
|
||||
self.optional_catch_binding = enable;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ mod options;
|
|||
mod env;
|
||||
mod es2015;
|
||||
mod es2016;
|
||||
mod es2019;
|
||||
mod es2020;
|
||||
mod react;
|
||||
mod typescript;
|
||||
|
|
@ -28,6 +29,7 @@ mod helpers {
|
|||
use std::{path::Path, rc::Rc};
|
||||
|
||||
use es2016::ES2016;
|
||||
use es2019::ES2019;
|
||||
use es2020::ES2020;
|
||||
use oxc_allocator::{Allocator, Vec};
|
||||
use oxc_ast::{ast::*, AstBuilder, Trivias};
|
||||
|
|
@ -63,6 +65,7 @@ pub struct Transformer<'a> {
|
|||
x0_typescript: TypeScript<'a>,
|
||||
x1_react: React<'a>,
|
||||
x2_es2020: ES2020<'a>,
|
||||
x2_es2019: ES2019<'a>,
|
||||
x2_es2016: ES2016<'a>,
|
||||
x3_es2015: ES2015<'a>,
|
||||
}
|
||||
|
|
@ -88,8 +91,9 @@ impl<'a> Transformer<'a> {
|
|||
ctx: Rc::clone(&ctx),
|
||||
x0_typescript: TypeScript::new(options.typescript, Rc::clone(&ctx)),
|
||||
x1_react: React::new(options.react, Rc::clone(&ctx)),
|
||||
x2_es2016: ES2016::new(options.es2016, Rc::clone(&ctx)),
|
||||
x2_es2020: ES2020::new(options.es2020, Rc::clone(&ctx)),
|
||||
x2_es2019: ES2019::new(options.es2019, Rc::clone(&ctx)),
|
||||
x2_es2016: ES2016::new(options.es2016, Rc::clone(&ctx)),
|
||||
x3_es2015: ES2015::new(options.es2015, ctx),
|
||||
}
|
||||
}
|
||||
|
|
@ -317,6 +321,10 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
self.x0_typescript.transform_for_in_statement(stmt, ctx);
|
||||
}
|
||||
|
||||
fn enter_catch_clause(&mut self, clause: &mut CatchClause<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x2_es2019.transform_catch_clause(clause, ctx);
|
||||
}
|
||||
|
||||
fn enter_ts_export_assignment(
|
||||
&mut self,
|
||||
export_assignment: &mut TSExportAssignment<'a>,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use crate::{
|
|||
env::{can_enable_plugin, EnvOptions, Versions},
|
||||
es2015::{ArrowFunctionsOptions, ES2015Options},
|
||||
es2016::ES2016Options,
|
||||
es2019::ES2019Options,
|
||||
es2020::ES2020Options,
|
||||
options::babel::BabelOptions,
|
||||
react::ReactOptions,
|
||||
|
|
@ -39,6 +40,8 @@ pub struct TransformOptions {
|
|||
|
||||
pub es2016: ES2016Options,
|
||||
|
||||
pub es2019: ES2019Options,
|
||||
|
||||
pub es2020: ES2020Options,
|
||||
}
|
||||
|
||||
|
|
@ -115,6 +118,11 @@ impl TransformOptions {
|
|||
enable_plugin(plugin_name, options, &env_options, &targets).is_some()
|
||||
});
|
||||
|
||||
let es2019 = ES2019Options::default().with_optional_catch_binding({
|
||||
let plugin_name = "transform-optional-catch-binding";
|
||||
enable_plugin(plugin_name, options, &env_options, &targets).is_some()
|
||||
});
|
||||
|
||||
let es2020 = ES2020Options::default().with_nullish_coalescing_operator({
|
||||
let plugin_name = "transform-nullish-coalescing-operator";
|
||||
enable_plugin(plugin_name, options, &env_options, &targets).is_some()
|
||||
|
|
@ -152,6 +160,7 @@ impl TransformOptions {
|
|||
react,
|
||||
es2015,
|
||||
es2016,
|
||||
es2019,
|
||||
es2020,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
commit: 12619ffe
|
||||
|
||||
Passed: 458/943
|
||||
Passed: 462/947
|
||||
|
||||
# All Passed:
|
||||
* babel-plugin-transform-optional-catch-binding
|
||||
* babel-preset-react
|
||||
* babel-plugin-transform-react-display-name
|
||||
* babel-plugin-transform-react-jsx-self
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
commit: 12619ffe
|
||||
|
||||
Passed: 12/18
|
||||
Passed: 13/19
|
||||
|
||||
# All Passed:
|
||||
* babel-plugin-transform-nullish-coalescing-operator
|
||||
* babel-plugin-transform-optional-catch-binding
|
||||
* babel-plugin-transform-exponentiation-operator
|
||||
* babel-plugin-transform-arrow-functions
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
commit: 12619ffe
|
||||
|
||||
Passed: 5/8
|
||||
Passed: 6/9
|
||||
|
||||
# All Passed:
|
||||
* babel-plugin-transform-optional-catch-binding
|
||||
* babel-plugin-transform-react-jsx
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ pub(crate) const PLUGINS: &[&str] = &[
|
|||
// // [Syntax] "babel-plugin-transform-syntax-dynamic-import",
|
||||
// // [Syntax] "babel-plugin-transform-syntax-import-meta",
|
||||
// // ES2019
|
||||
// "babel-plugin-transform-optional-catch-binding",
|
||||
"babel-plugin-transform-optional-catch-binding",
|
||||
// "babel-plugin-transform-json-strings",
|
||||
// // ES2018
|
||||
// "babel-plugin-transform-async-generator-functions",
|
||||
|
|
|
|||
Loading…
Reference in a new issue