mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(transformer): support logical-assignment-operators plugin (#4890)
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
ab1d08ccfb
commit
0d7912217a
8 changed files with 373 additions and 7 deletions
|
|
@ -0,0 +1,271 @@
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
|
use oxc_allocator::{CloneIn, Vec};
|
||||||
|
use oxc_ast::ast::*;
|
||||||
|
use oxc_semantic::{ReferenceFlag, SymbolFlags};
|
||||||
|
use oxc_span::SPAN;
|
||||||
|
use oxc_syntax::operator::{AssignmentOperator, LogicalOperator};
|
||||||
|
use oxc_traverse::TraverseCtx;
|
||||||
|
|
||||||
|
use crate::context::Ctx;
|
||||||
|
|
||||||
|
/// ES2021: Logical Assignment Operators
|
||||||
|
///
|
||||||
|
/// References:
|
||||||
|
/// * <https://babel.dev/docs/babel-plugin-transform-logical-assignment-operators>
|
||||||
|
/// * <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-logical-assignment-operators>
|
||||||
|
pub struct LogicalAssignmentOperators<'a> {
|
||||||
|
_ctx: Ctx<'a>,
|
||||||
|
var_declarations: std::vec::Vec<Vec<'a, VariableDeclarator<'a>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> LogicalAssignmentOperators<'a> {
|
||||||
|
pub fn new(ctx: Ctx<'a>) -> Self {
|
||||||
|
Self { _ctx: ctx, var_declarations: vec![] }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clone_identifier_reference(
|
||||||
|
ident: &IdentifierReference<'a>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
|
) -> IdentifierReference<'a> {
|
||||||
|
let reference = ctx.symbols().get_reference(ident.reference_id.get().unwrap());
|
||||||
|
let symbol_id = reference.symbol_id();
|
||||||
|
let flag = reference.flag();
|
||||||
|
ctx.create_reference_id(ident.span, ident.name.clone(), symbol_id, *flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maybe_generate_memoised(
|
||||||
|
&mut self,
|
||||||
|
expr: &Expression<'a>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
|
) -> Option<IdentifierReference<'a>> {
|
||||||
|
let name = match expr {
|
||||||
|
Expression::Super(_) | Expression::ThisExpression(_) => return None,
|
||||||
|
Expression::Identifier(ident) => ident.name.clone(),
|
||||||
|
Expression::StringLiteral(str) => str.value.clone(),
|
||||||
|
_ => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let symbol_id =
|
||||||
|
ctx.generate_uid_in_current_scope(name.as_str(), SymbolFlags::FunctionScopedVariable);
|
||||||
|
let symbol_name = ctx.ast.atom(ctx.symbols().get_name(symbol_id));
|
||||||
|
|
||||||
|
// var _name;
|
||||||
|
let binding_identifier = BindingIdentifier {
|
||||||
|
span: SPAN,
|
||||||
|
name: symbol_name.clone(),
|
||||||
|
symbol_id: Cell::new(Some(symbol_id)),
|
||||||
|
};
|
||||||
|
let kind = VariableDeclarationKind::Var;
|
||||||
|
let id = ctx.ast.binding_pattern_kind_from_binding_identifier(binding_identifier);
|
||||||
|
let id = ctx.ast.binding_pattern(id, None::<TSTypeAnnotation>, false);
|
||||||
|
self.var_declarations
|
||||||
|
.last_mut()
|
||||||
|
.unwrap()
|
||||||
|
.push(ctx.ast.variable_declarator(SPAN, kind, id, None, false));
|
||||||
|
|
||||||
|
// _name = name
|
||||||
|
Some(ctx.create_reference_id(SPAN, symbol_name, Some(symbol_id), ReferenceFlag::Write))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transform_statements(
|
||||||
|
&mut self,
|
||||||
|
_statements: &mut Vec<'a, Statement<'a>>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
|
) {
|
||||||
|
self.var_declarations.push(ctx.ast.vec());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transform_statements_on_exit(
|
||||||
|
&mut self,
|
||||||
|
statements: &mut Vec<'a, Statement<'a>>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
|
) {
|
||||||
|
if let Some(declarations) = self.var_declarations.pop() {
|
||||||
|
if declarations.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let variable = ctx.ast.alloc_variable_declaration(
|
||||||
|
SPAN,
|
||||||
|
VariableDeclarationKind::Var,
|
||||||
|
declarations,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
statements.insert(0, Statement::VariableDeclaration(variable));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transform_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
let Expression::AssignmentExpression(assignment_expr) = expr else { return };
|
||||||
|
|
||||||
|
// `&&=` `||=` `??=`
|
||||||
|
let operator = match assignment_expr.operator {
|
||||||
|
AssignmentOperator::LogicalAnd => LogicalOperator::And,
|
||||||
|
AssignmentOperator::LogicalOr => LogicalOperator::Or,
|
||||||
|
AssignmentOperator::LogicalNullish => LogicalOperator::Coalesce,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
// `a &&= c` -> `a && (a = c);`
|
||||||
|
// ^ ^ assign_target
|
||||||
|
// ^ left_expr
|
||||||
|
|
||||||
|
let left_expr: Expression<'a>;
|
||||||
|
let assign_target: AssignmentTarget;
|
||||||
|
|
||||||
|
// TODO: refactor this block, add tests, cover private identifier
|
||||||
|
match &mut assignment_expr.left {
|
||||||
|
AssignmentTarget::AssignmentTargetIdentifier(ident) => {
|
||||||
|
left_expr = ctx.ast.expression_from_identifier_reference(
|
||||||
|
Self::clone_identifier_reference(ident, ctx),
|
||||||
|
);
|
||||||
|
assign_target = AssignmentTarget::from(
|
||||||
|
ctx.ast.simple_assignment_target_from_identifier_reference(
|
||||||
|
Self::clone_identifier_reference(ident, ctx),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
left @ match_member_expression!(AssignmentTarget) => {
|
||||||
|
let member_expr = left.to_member_expression_mut();
|
||||||
|
let op = AssignmentOperator::Assign;
|
||||||
|
|
||||||
|
// `a.b &&= c` -> `var _a; (_a = a).b && (_a.b = c)`
|
||||||
|
match member_expr {
|
||||||
|
MemberExpression::StaticMemberExpression(static_expr) => {
|
||||||
|
if let Some(ident) = self.maybe_generate_memoised(&static_expr.object, ctx)
|
||||||
|
{
|
||||||
|
// (_o = o).a
|
||||||
|
let right = ctx.ast.move_expression(&mut static_expr.object);
|
||||||
|
let target = AssignmentTarget::from(
|
||||||
|
ctx.ast.simple_assignment_target_from_identifier_reference(
|
||||||
|
Self::clone_identifier_reference(&ident, ctx),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
let object = ctx.ast.expression_assignment(SPAN, op, target, right);
|
||||||
|
left_expr = Expression::from(ctx.ast.member_expression_static(
|
||||||
|
SPAN,
|
||||||
|
object,
|
||||||
|
static_expr.property.clone_in(ctx.ast.allocator),
|
||||||
|
false,
|
||||||
|
));
|
||||||
|
|
||||||
|
// (_o.a = 1)
|
||||||
|
let assign_expr = ctx.ast.member_expression_static(
|
||||||
|
SPAN,
|
||||||
|
ctx.ast.expression_from_identifier_reference(ident),
|
||||||
|
static_expr.property.clone_in(ctx.ast.allocator),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
assign_target = AssignmentTarget::from(
|
||||||
|
ctx.ast.simple_assignment_target_member_expression(assign_expr),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
left_expr = Expression::from(MemberExpression::StaticMemberExpression(
|
||||||
|
static_expr.clone_in(ctx.ast.allocator),
|
||||||
|
));
|
||||||
|
assign_target = AssignmentTarget::from(
|
||||||
|
ctx.ast.simple_assignment_target_member_expression(
|
||||||
|
member_expr.clone_in(ctx.ast.allocator),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// `a[b.y] &&= c;` ->
|
||||||
|
// `var _a, _b$y; (_a = a)[_b$y = b.y] && (_a[_b$y] = c);`
|
||||||
|
MemberExpression::ComputedMemberExpression(computed_expr) => {
|
||||||
|
if let Some(ident) =
|
||||||
|
self.maybe_generate_memoised(&computed_expr.object, ctx)
|
||||||
|
{
|
||||||
|
// (_o = object)
|
||||||
|
let right = ctx.ast.move_expression(&mut computed_expr.object);
|
||||||
|
let target = AssignmentTarget::from(
|
||||||
|
ctx.ast.simple_assignment_target_from_identifier_reference(
|
||||||
|
Self::clone_identifier_reference(&ident, ctx),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
let object = ctx.ast.expression_assignment(SPAN, op, target, right);
|
||||||
|
|
||||||
|
let mut expression =
|
||||||
|
ctx.ast.move_expression(&mut computed_expr.expression);
|
||||||
|
|
||||||
|
// _b = expression
|
||||||
|
let property = self.maybe_generate_memoised(&expression, ctx);
|
||||||
|
|
||||||
|
if let Some(ref property) = property {
|
||||||
|
let left = AssignmentTarget::from(
|
||||||
|
ctx.ast.simple_assignment_target_from_identifier_reference(
|
||||||
|
Self::clone_identifier_reference(property, ctx),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expression =
|
||||||
|
ctx.ast.expression_assignment(SPAN, op, left, expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
// _o[_b]
|
||||||
|
assign_target =
|
||||||
|
AssignmentTarget::from(ctx.ast.member_expression_computed(
|
||||||
|
SPAN,
|
||||||
|
ctx.ast.expression_from_identifier_reference(
|
||||||
|
Self::clone_identifier_reference(&ident, ctx),
|
||||||
|
),
|
||||||
|
property.map_or_else(
|
||||||
|
|| expression.clone_in(ctx.ast.allocator),
|
||||||
|
|ident| ctx.ast.expression_from_identifier_reference(ident),
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
));
|
||||||
|
|
||||||
|
left_expr = Expression::from(
|
||||||
|
ctx.ast.member_expression_computed(SPAN, object, expression, false),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
let property_ident =
|
||||||
|
self.maybe_generate_memoised(&computed_expr.expression, ctx);
|
||||||
|
|
||||||
|
let mut expr = computed_expr.clone_in(ctx.ast.allocator);
|
||||||
|
if let Some(property_ident) = &property_ident {
|
||||||
|
let left = AssignmentTarget::from(
|
||||||
|
ctx.ast.simple_assignment_target_from_identifier_reference(
|
||||||
|
property_ident.clone(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
let right = computed_expr.expression.clone_in(ctx.ast.allocator);
|
||||||
|
expr.expression =
|
||||||
|
ctx.ast.expression_assignment(SPAN, op, left, right);
|
||||||
|
}
|
||||||
|
left_expr =
|
||||||
|
Expression::from(MemberExpression::ComputedMemberExpression(expr));
|
||||||
|
|
||||||
|
let mut expr = computed_expr.clone_in(ctx.ast.allocator);
|
||||||
|
if let Some(property_ident) = property_ident {
|
||||||
|
expr.expression =
|
||||||
|
ctx.ast.expression_from_identifier_reference(property_ident);
|
||||||
|
}
|
||||||
|
assign_target = AssignmentTarget::from(
|
||||||
|
ctx.ast.simple_assignment_target_member_expression(
|
||||||
|
MemberExpression::ComputedMemberExpression(expr),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
MemberExpression::PrivateFieldExpression(_) => return,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// All other are TypeScript syntax.
|
||||||
|
|
||||||
|
// It is a Syntax Error if AssignmentTargetType of LeftHandSideExpression is not simple.
|
||||||
|
// So safe to return here.
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let assign_op = AssignmentOperator::Assign;
|
||||||
|
let right = ctx.ast.move_expression(&mut assignment_expr.right);
|
||||||
|
let right = ctx.ast.expression_assignment(SPAN, assign_op, assign_target, right);
|
||||||
|
|
||||||
|
let logical_expr = ctx.ast.expression_logical(SPAN, left_expr, operator, right);
|
||||||
|
|
||||||
|
*expr = logical_expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
56
crates/oxc_transformer/src/es2021/mod.rs
Normal file
56
crates/oxc_transformer/src/es2021/mod.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
mod logical_assignment_operators;
|
||||||
|
mod options;
|
||||||
|
|
||||||
|
pub use logical_assignment_operators::LogicalAssignmentOperators;
|
||||||
|
pub use options::ES2021Options;
|
||||||
|
use oxc_allocator::Vec;
|
||||||
|
use oxc_ast::ast::*;
|
||||||
|
use oxc_traverse::TraverseCtx;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::context::Ctx;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct ES2021<'a> {
|
||||||
|
ctx: Ctx<'a>,
|
||||||
|
options: ES2021Options,
|
||||||
|
|
||||||
|
// Plugins
|
||||||
|
logical_assignment_operators: LogicalAssignmentOperators<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ES2021<'a> {
|
||||||
|
pub fn new(options: ES2021Options, ctx: Ctx<'a>) -> Self {
|
||||||
|
Self {
|
||||||
|
logical_assignment_operators: LogicalAssignmentOperators::new(Rc::clone(&ctx)),
|
||||||
|
ctx,
|
||||||
|
options,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transform_statements(
|
||||||
|
&mut self,
|
||||||
|
statements: &mut Vec<'a, Statement<'a>>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
|
) {
|
||||||
|
if self.options.logical_assignment_operators {
|
||||||
|
self.logical_assignment_operators.transform_statements(statements, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transform_statements_on_exit(
|
||||||
|
&mut self,
|
||||||
|
statements: &mut Vec<'a, Statement<'a>>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
|
) {
|
||||||
|
if self.options.logical_assignment_operators {
|
||||||
|
self.logical_assignment_operators.transform_statements_on_exit(statements, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transform_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
if self.options.logical_assignment_operators {
|
||||||
|
self.logical_assignment_operators.transform_expression(expr, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
crates/oxc_transformer/src/es2021/options.rs
Normal file
16
crates/oxc_transformer/src/es2021/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 ES2021Options {
|
||||||
|
#[serde(skip)]
|
||||||
|
pub logical_assignment_operators: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ES2021Options {
|
||||||
|
#[must_use]
|
||||||
|
pub fn with_logical_assignment_operators(mut self, enable: bool) -> Self {
|
||||||
|
self.logical_assignment_operators = enable;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ mod es2015;
|
||||||
mod es2016;
|
mod es2016;
|
||||||
mod es2019;
|
mod es2019;
|
||||||
mod es2020;
|
mod es2020;
|
||||||
|
mod es2021;
|
||||||
mod react;
|
mod react;
|
||||||
mod typescript;
|
mod typescript;
|
||||||
|
|
||||||
|
|
@ -31,6 +32,7 @@ use std::{path::Path, rc::Rc};
|
||||||
use es2016::ES2016;
|
use es2016::ES2016;
|
||||||
use es2019::ES2019;
|
use es2019::ES2019;
|
||||||
use es2020::ES2020;
|
use es2020::ES2020;
|
||||||
|
use es2021::ES2021;
|
||||||
use oxc_allocator::{Allocator, Vec};
|
use oxc_allocator::{Allocator, Vec};
|
||||||
use oxc_ast::{ast::*, AstBuilder, Trivias};
|
use oxc_ast::{ast::*, AstBuilder, Trivias};
|
||||||
use oxc_diagnostics::OxcDiagnostic;
|
use oxc_diagnostics::OxcDiagnostic;
|
||||||
|
|
@ -64,6 +66,7 @@ pub struct Transformer<'a> {
|
||||||
// NOTE: all callbacks must run in order.
|
// NOTE: all callbacks must run in order.
|
||||||
x0_typescript: TypeScript<'a>,
|
x0_typescript: TypeScript<'a>,
|
||||||
x1_react: React<'a>,
|
x1_react: React<'a>,
|
||||||
|
x2_es2021: ES2021<'a>,
|
||||||
x2_es2020: ES2020<'a>,
|
x2_es2020: ES2020<'a>,
|
||||||
x2_es2019: ES2019<'a>,
|
x2_es2019: ES2019<'a>,
|
||||||
x2_es2016: ES2016<'a>,
|
x2_es2016: ES2016<'a>,
|
||||||
|
|
@ -91,6 +94,7 @@ impl<'a> Transformer<'a> {
|
||||||
ctx: Rc::clone(&ctx),
|
ctx: Rc::clone(&ctx),
|
||||||
x0_typescript: TypeScript::new(options.typescript, Rc::clone(&ctx)),
|
x0_typescript: TypeScript::new(options.typescript, Rc::clone(&ctx)),
|
||||||
x1_react: React::new(options.react, Rc::clone(&ctx)),
|
x1_react: React::new(options.react, Rc::clone(&ctx)),
|
||||||
|
x2_es2021: ES2021::new(options.es2021, Rc::clone(&ctx)),
|
||||||
x2_es2020: ES2020::new(options.es2020, Rc::clone(&ctx)),
|
x2_es2020: ES2020::new(options.es2020, Rc::clone(&ctx)),
|
||||||
x2_es2019: ES2019::new(options.es2019, Rc::clone(&ctx)),
|
x2_es2019: ES2019::new(options.es2019, Rc::clone(&ctx)),
|
||||||
x2_es2016: ES2016::new(options.es2016, Rc::clone(&ctx)),
|
x2_es2016: ES2016::new(options.es2016, Rc::clone(&ctx)),
|
||||||
|
|
@ -172,6 +176,7 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
||||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.x0_typescript.transform_expression(expr);
|
self.x0_typescript.transform_expression(expr);
|
||||||
self.x1_react.transform_expression(expr, ctx);
|
self.x1_react.transform_expression(expr, ctx);
|
||||||
|
self.x2_es2021.transform_expression(expr, ctx);
|
||||||
self.x2_es2020.transform_expression(expr, ctx);
|
self.x2_es2020.transform_expression(expr, ctx);
|
||||||
self.x2_es2016.transform_expression(expr, ctx);
|
self.x2_es2016.transform_expression(expr, ctx);
|
||||||
self.x3_es2015.transform_expression(expr);
|
self.x3_es2015.transform_expression(expr);
|
||||||
|
|
@ -260,6 +265,7 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
||||||
|
|
||||||
fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.x0_typescript.transform_statements(stmts);
|
self.x0_typescript.transform_statements(stmts);
|
||||||
|
self.x2_es2021.transform_statements(stmts, ctx);
|
||||||
self.x2_es2020.transform_statements(stmts, ctx);
|
self.x2_es2020.transform_statements(stmts, ctx);
|
||||||
self.x2_es2016.transform_statements(stmts, ctx);
|
self.x2_es2016.transform_statements(stmts, ctx);
|
||||||
self.x3_es2015.enter_statements(stmts);
|
self.x3_es2015.enter_statements(stmts);
|
||||||
|
|
@ -267,6 +273,7 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
||||||
|
|
||||||
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.x0_typescript.transform_statements_on_exit(stmts, ctx);
|
self.x0_typescript.transform_statements_on_exit(stmts, ctx);
|
||||||
|
self.x2_es2021.transform_statements_on_exit(stmts, ctx);
|
||||||
self.x2_es2020.transform_statements_on_exit(stmts, ctx);
|
self.x2_es2020.transform_statements_on_exit(stmts, ctx);
|
||||||
self.x2_es2016.transform_statements_on_exit(stmts, ctx);
|
self.x2_es2016.transform_statements_on_exit(stmts, ctx);
|
||||||
self.x3_es2015.exit_statements(stmts);
|
self.x3_es2015.exit_statements(stmts);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ use crate::{
|
||||||
es2016::ES2016Options,
|
es2016::ES2016Options,
|
||||||
es2019::ES2019Options,
|
es2019::ES2019Options,
|
||||||
es2020::ES2020Options,
|
es2020::ES2020Options,
|
||||||
|
es2021::ES2021Options,
|
||||||
options::babel::BabelOptions,
|
options::babel::BabelOptions,
|
||||||
react::ReactOptions,
|
react::ReactOptions,
|
||||||
typescript::TypeScriptOptions,
|
typescript::TypeScriptOptions,
|
||||||
|
|
@ -43,6 +44,8 @@ pub struct TransformOptions {
|
||||||
pub es2019: ES2019Options,
|
pub es2019: ES2019Options,
|
||||||
|
|
||||||
pub es2020: ES2020Options,
|
pub es2020: ES2020Options,
|
||||||
|
|
||||||
|
pub es2021: ES2021Options,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransformOptions {
|
impl TransformOptions {
|
||||||
|
|
@ -128,6 +131,11 @@ impl TransformOptions {
|
||||||
enable_plugin(plugin_name, options, &env_options, &targets).is_some()
|
enable_plugin(plugin_name, options, &env_options, &targets).is_some()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let es2021 = ES2021Options::default().with_logical_assignment_operators({
|
||||||
|
let plugin_name = "transform-logical-assignment-operators";
|
||||||
|
enable_plugin(plugin_name, options, &env_options, &targets).is_some()
|
||||||
|
});
|
||||||
|
|
||||||
let typescript = {
|
let typescript = {
|
||||||
let plugin_name = "transform-typescript";
|
let plugin_name = "transform-typescript";
|
||||||
from_value::<TypeScriptOptions>(get_plugin_options(plugin_name, options))
|
from_value::<TypeScriptOptions>(get_plugin_options(plugin_name, options))
|
||||||
|
|
@ -162,6 +170,7 @@ impl TransformOptions {
|
||||||
es2016,
|
es2016,
|
||||||
es2019,
|
es2019,
|
||||||
es2020,
|
es2020,
|
||||||
|
es2021,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
commit: 12619ffe
|
commit: 12619ffe
|
||||||
|
|
||||||
Passed: 462/947
|
Passed: 466/953
|
||||||
|
|
||||||
# All Passed:
|
# All Passed:
|
||||||
* babel-plugin-transform-optional-catch-binding
|
* babel-plugin-transform-optional-catch-binding
|
||||||
|
|
@ -434,6 +434,10 @@ Passed: 462/947
|
||||||
* shipped-proposals/new-class-features-chrome-94/input.js
|
* shipped-proposals/new-class-features-chrome-94/input.js
|
||||||
* shipped-proposals/new-class-features-firefox-70/input.js
|
* shipped-proposals/new-class-features-firefox-70/input.js
|
||||||
|
|
||||||
|
# babel-plugin-transform-logical-assignment-operators (4/6)
|
||||||
|
* logical-assignment/general-semantics/input.js
|
||||||
|
* logical-assignment/null-coalescing/input.js
|
||||||
|
|
||||||
# babel-plugin-transform-nullish-coalescing-operator (2/12)
|
# babel-plugin-transform-nullish-coalescing-operator (2/12)
|
||||||
* assumption-noDocumentAll/transform/input.js
|
* assumption-noDocumentAll/transform/input.js
|
||||||
* assumption-noDocumentAll/transform-in-default-destructuring/input.js
|
* assumption-noDocumentAll/transform-in-default-destructuring/input.js
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
commit: 12619ffe
|
commit: 12619ffe
|
||||||
|
|
||||||
Passed: 13/19
|
Passed: 16/23
|
||||||
|
|
||||||
# All Passed:
|
# All Passed:
|
||||||
* babel-plugin-transform-nullish-coalescing-operator
|
* babel-plugin-transform-nullish-coalescing-operator
|
||||||
|
|
@ -15,6 +15,9 @@ Passed: 13/19
|
||||||
* sanity/check-es2015-constants/exec.js
|
* sanity/check-es2015-constants/exec.js
|
||||||
* sanity/regex-dot-all/exec.js
|
* sanity/regex-dot-all/exec.js
|
||||||
|
|
||||||
|
# babel-plugin-transform-logical-assignment-operators (3/4)
|
||||||
|
* logical-assignment/null-coalescing/exec.js
|
||||||
|
|
||||||
# babel-plugin-transform-react-jsx-source (0/2)
|
# babel-plugin-transform-react-jsx-source (0/2)
|
||||||
* react-source/basic-sample/exec.js
|
* react-source/basic-sample/exec.js
|
||||||
* react-source/with-source/exec.js
|
* react-source/with-source/exec.js
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ pub(crate) const PLUGINS: &[&str] = &[
|
||||||
// "babel-plugin-transform-private-methods",
|
// "babel-plugin-transform-private-methods",
|
||||||
// "babel-plugin-transform-private-property-in-object",
|
// "babel-plugin-transform-private-property-in-object",
|
||||||
// // [Syntax] "babel-plugin-transform-syntax-top-level-await",
|
// // [Syntax] "babel-plugin-transform-syntax-top-level-await",
|
||||||
// // ES2021
|
// ES2021
|
||||||
// "babel-plugin-transform-logical-assignment-operators",
|
"babel-plugin-transform-logical-assignment-operators",
|
||||||
// "babel-plugin-transform-numeric-separator",
|
// "babel-plugin-transform-numeric-separator",
|
||||||
// // ES2020
|
// ES2020
|
||||||
// "babel-plugin-transform-export-namespace-from",
|
// "babel-plugin-transform-export-namespace-from",
|
||||||
// "babel-plugin-transform-dynamic-import",
|
// "babel-plugin-transform-dynamic-import",
|
||||||
"babel-plugin-transform-nullish-coalescing-operator",
|
"babel-plugin-transform-nullish-coalescing-operator",
|
||||||
|
|
@ -19,7 +19,7 @@ pub(crate) const PLUGINS: &[&str] = &[
|
||||||
// // [Syntax] "babel-plugin-transform-syntax-bigint",
|
// // [Syntax] "babel-plugin-transform-syntax-bigint",
|
||||||
// // [Syntax] "babel-plugin-transform-syntax-dynamic-import",
|
// // [Syntax] "babel-plugin-transform-syntax-dynamic-import",
|
||||||
// // [Syntax] "babel-plugin-transform-syntax-import-meta",
|
// // [Syntax] "babel-plugin-transform-syntax-import-meta",
|
||||||
// // ES2019
|
// ES2019
|
||||||
"babel-plugin-transform-optional-catch-binding",
|
"babel-plugin-transform-optional-catch-binding",
|
||||||
// "babel-plugin-transform-json-strings",
|
// "babel-plugin-transform-json-strings",
|
||||||
// // ES2018
|
// // ES2018
|
||||||
|
|
@ -32,7 +32,7 @@ pub(crate) const PLUGINS: &[&str] = &[
|
||||||
// "babel-plugin-transform-async-to-generator",
|
// "babel-plugin-transform-async-to-generator",
|
||||||
// ES2016
|
// ES2016
|
||||||
"babel-plugin-transform-exponentiation-operator",
|
"babel-plugin-transform-exponentiation-operator",
|
||||||
// // ES2015
|
// ES2015
|
||||||
"babel-plugin-transform-arrow-functions",
|
"babel-plugin-transform-arrow-functions",
|
||||||
// "babel-plugin-transform-function-name",
|
// "babel-plugin-transform-function-name",
|
||||||
// "babel-plugin-transform-shorthand-properties",
|
// "babel-plugin-transform-shorthand-properties",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue