mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(transformer/object-rest-spread): using helper loader (#6449)
This commit is contained in:
parent
c0e9d7eb77
commit
41c8675f0d
5 changed files with 32 additions and 39 deletions
|
|
@ -262,7 +262,6 @@ impl<'a> HelperLoaderStore<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a helper function and return the callee expression.
|
/// Load a helper function and return the callee expression.
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn load(&self, helper_name: Atom<'a>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
|
pub fn load(&self, helper_name: Atom<'a>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
HelperLoaderMode::Runtime => self.transform_for_runtime_helper(&helper_name, ctx),
|
HelperLoaderMode::Runtime => self.transform_for_runtime_helper(&helper_name, ctx),
|
||||||
|
|
|
||||||
|
|
@ -6,25 +6,28 @@ pub use options::ES2018Options;
|
||||||
use oxc_ast::ast::*;
|
use oxc_ast::ast::*;
|
||||||
use oxc_traverse::{Traverse, TraverseCtx};
|
use oxc_traverse::{Traverse, TraverseCtx};
|
||||||
|
|
||||||
pub struct ES2018 {
|
use crate::context::TransformCtx;
|
||||||
|
|
||||||
|
pub struct ES2018<'a, 'ctx> {
|
||||||
options: ES2018Options,
|
options: ES2018Options,
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
object_rest_spread: ObjectRestSpread,
|
object_rest_spread: ObjectRestSpread<'a, 'ctx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ES2018 {
|
impl<'a, 'ctx> ES2018<'a, 'ctx> {
|
||||||
pub fn new(options: ES2018Options) -> Self {
|
pub fn new(options: ES2018Options, ctx: &'ctx TransformCtx<'a>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
object_rest_spread: ObjectRestSpread::new(
|
object_rest_spread: ObjectRestSpread::new(
|
||||||
options.object_rest_spread.unwrap_or_default(),
|
options.object_rest_spread.unwrap_or_default(),
|
||||||
|
ctx,
|
||||||
),
|
),
|
||||||
options,
|
options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Traverse<'a> for ES2018 {
|
impl<'a, 'ctx> Traverse<'a> for ES2018<'a, 'ctx> {
|
||||||
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>) {
|
||||||
if self.options.object_rest_spread.is_some() {
|
if self.options.object_rest_spread.is_some() {
|
||||||
self.object_rest_spread.enter_expression(expr, ctx);
|
self.object_rest_spread.enter_expression(expr, ctx);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ use oxc_ast::ast::*;
|
||||||
use oxc_traverse::{Traverse, TraverseCtx};
|
use oxc_traverse::{Traverse, TraverseCtx};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use crate::context::TransformCtx;
|
||||||
|
|
||||||
mod object_rest;
|
mod object_rest;
|
||||||
mod object_spread;
|
mod object_spread;
|
||||||
|
|
||||||
|
|
@ -43,27 +45,27 @@ pub struct ObjectRestSpreadOptions {
|
||||||
pub(crate) use_built_ins: bool,
|
pub(crate) use_built_ins: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ObjectRestSpread {
|
pub struct ObjectRestSpread<'a, 'ctx> {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
options: ObjectRestSpreadOptions,
|
options: ObjectRestSpreadOptions,
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
object_spread: ObjectSpread,
|
object_spread: ObjectSpread<'a, 'ctx>,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
object_rest: ObjectRest,
|
object_rest: ObjectRest,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectRestSpread {
|
impl<'a, 'ctx> ObjectRestSpread<'a, 'ctx> {
|
||||||
pub fn new(options: ObjectRestSpreadOptions) -> Self {
|
pub fn new(options: ObjectRestSpreadOptions, ctx: &'ctx TransformCtx<'a>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
object_spread: ObjectSpread::new(options),
|
object_spread: ObjectSpread::new(options, ctx),
|
||||||
object_rest: ObjectRest::new(options),
|
object_rest: ObjectRest::new(options),
|
||||||
options,
|
options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Traverse<'a> for ObjectRestSpread {
|
impl<'a, 'ctx> Traverse<'a> for ObjectRestSpread<'a, 'ctx> {
|
||||||
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.object_spread.enter_expression(expr, ctx);
|
self.object_spread.enter_expression(expr, ctx);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,18 +31,21 @@ use oxc_semantic::{ReferenceFlags, SymbolId};
|
||||||
use oxc_span::SPAN;
|
use oxc_span::SPAN;
|
||||||
use oxc_traverse::{Traverse, TraverseCtx};
|
use oxc_traverse::{Traverse, TraverseCtx};
|
||||||
|
|
||||||
|
use crate::context::TransformCtx;
|
||||||
|
|
||||||
use super::ObjectRestSpreadOptions;
|
use super::ObjectRestSpreadOptions;
|
||||||
|
|
||||||
pub struct ObjectSpread {
|
pub struct ObjectSpread<'a, 'ctx> {
|
||||||
options: ObjectRestSpreadOptions,
|
options: ObjectRestSpreadOptions,
|
||||||
|
ctx: &'ctx TransformCtx<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectSpread {
|
impl<'a, 'ctx> ObjectSpread<'a, 'ctx> {
|
||||||
pub fn new(options: ObjectRestSpreadOptions) -> Self {
|
pub fn new(options: ObjectRestSpreadOptions, ctx: &'ctx TransformCtx<'a>) -> Self {
|
||||||
Self { options }
|
Self { options, ctx }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> Traverse<'a> for ObjectSpread {
|
impl<'a, 'ctx> Traverse<'a> for ObjectSpread<'a, 'ctx> {
|
||||||
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>) {
|
||||||
let Expression::ObjectExpression(obj_expr) = expr else {
|
let Expression::ObjectExpression(obj_expr) = expr else {
|
||||||
return;
|
return;
|
||||||
|
|
@ -77,9 +80,8 @@ impl<'a> Traverse<'a> for ObjectSpread {
|
||||||
arguments.push(Argument::from(ctx.ast.move_expression(&mut spread_prop.argument)));
|
arguments.push(Argument::from(ctx.ast.move_expression(&mut spread_prop.argument)));
|
||||||
|
|
||||||
let object_id = ctx.scopes().find_binding(ctx.current_scope_id(), "Object");
|
let object_id = ctx.scopes().find_binding(ctx.current_scope_id(), "Object");
|
||||||
let babel_helpers_id = ctx.scopes().find_binding(ctx.current_scope_id(), "babelHelpers");
|
|
||||||
|
|
||||||
let callee = self.get_extend_object_callee(object_id, babel_helpers_id, ctx);
|
let callee = self.get_extend_object_callee(object_id, ctx);
|
||||||
|
|
||||||
// ({ ...x }) => _objectSpread({}, x)
|
// ({ ...x }) => _objectSpread({}, x)
|
||||||
*expr = ctx.ast.expression_call(SPAN, callee, NONE, arguments, false);
|
*expr = ctx.ast.expression_call(SPAN, callee, NONE, arguments, false);
|
||||||
|
|
@ -91,14 +93,14 @@ impl<'a> Traverse<'a> for ObjectSpread {
|
||||||
arguments.push(Argument::from(ctx.ast.move_expression(expr)));
|
arguments.push(Argument::from(ctx.ast.move_expression(expr)));
|
||||||
arguments.push(Argument::from(ctx.ast.expression_object(SPAN, obj_prop_list, None)));
|
arguments.push(Argument::from(ctx.ast.expression_object(SPAN, obj_prop_list, None)));
|
||||||
|
|
||||||
let callee = self.get_extend_object_callee(object_id, babel_helpers_id, ctx);
|
let callee = self.get_extend_object_callee(object_id, ctx);
|
||||||
|
|
||||||
*expr = ctx.ast.expression_call(SPAN, callee, NONE, arguments, false);
|
*expr = ctx.ast.expression_call(SPAN, callee, NONE, arguments, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ObjectSpread {
|
impl<'a, 'ctx> ObjectSpread<'a, 'ctx> {
|
||||||
fn object_assign(symbol_id: Option<SymbolId>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
|
fn object_assign(symbol_id: Option<SymbolId>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
|
||||||
let ident =
|
let ident =
|
||||||
ctx.create_reference_id(SPAN, Atom::from("Object"), symbol_id, ReferenceFlags::Read);
|
ctx.create_reference_id(SPAN, Atom::from("Object"), symbol_id, ReferenceFlags::Read);
|
||||||
|
|
@ -108,32 +110,19 @@ impl<'a> ObjectSpread {
|
||||||
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false))
|
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn babel_external_helper(
|
fn babel_external_helper(&self, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
|
||||||
symbol_id: Option<SymbolId>,
|
self.ctx.helper_loader.load(Atom::from("objectSpread2"), ctx)
|
||||||
ctx: &mut TraverseCtx<'a>,
|
|
||||||
) -> Expression<'a> {
|
|
||||||
let ident = ctx.create_reference_id(
|
|
||||||
SPAN,
|
|
||||||
Atom::from("babelHelpers"),
|
|
||||||
symbol_id,
|
|
||||||
ReferenceFlags::Read,
|
|
||||||
);
|
|
||||||
let object = ctx.ast.expression_from_identifier_reference(ident);
|
|
||||||
let property = ctx.ast.identifier_name(SPAN, Atom::from("objectSpread2"));
|
|
||||||
|
|
||||||
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_extend_object_callee(
|
fn get_extend_object_callee(
|
||||||
&mut self,
|
&mut self,
|
||||||
object_id: Option<SymbolId>,
|
object_id: Option<SymbolId>,
|
||||||
babel_helpers_id: Option<SymbolId>,
|
|
||||||
ctx: &mut TraverseCtx<'a>,
|
ctx: &mut TraverseCtx<'a>,
|
||||||
) -> Expression<'a> {
|
) -> Expression<'a> {
|
||||||
if self.options.set_spread_properties {
|
if self.options.set_spread_properties {
|
||||||
Self::object_assign(object_id, ctx)
|
Self::object_assign(object_id, ctx)
|
||||||
} else {
|
} else {
|
||||||
Self::babel_external_helper(babel_helpers_id, ctx)
|
self.babel_external_helper(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ impl<'a> Transformer<'a> {
|
||||||
x2_es2021: ES2021::new(self.options.es2021, &self.ctx),
|
x2_es2021: ES2021::new(self.options.es2021, &self.ctx),
|
||||||
x2_es2020: ES2020::new(self.options.es2020, &self.ctx),
|
x2_es2020: ES2020::new(self.options.es2020, &self.ctx),
|
||||||
x2_es2019: ES2019::new(self.options.es2019),
|
x2_es2019: ES2019::new(self.options.es2019),
|
||||||
x2_es2018: ES2018::new(self.options.es2018),
|
x2_es2018: ES2018::new(self.options.es2018, &self.ctx),
|
||||||
x2_es2016: ES2016::new(self.options.es2016, &self.ctx),
|
x2_es2016: ES2016::new(self.options.es2016, &self.ctx),
|
||||||
x3_es2015: ES2015::new(self.options.es2015),
|
x3_es2015: ES2015::new(self.options.es2015),
|
||||||
x4_regexp: RegExp::new(self.options.regexp, &self.ctx),
|
x4_regexp: RegExp::new(self.options.regexp, &self.ctx),
|
||||||
|
|
@ -112,7 +112,7 @@ struct TransformerImpl<'a, 'ctx> {
|
||||||
x2_es2021: ES2021<'a, 'ctx>,
|
x2_es2021: ES2021<'a, 'ctx>,
|
||||||
x2_es2020: ES2020<'a, 'ctx>,
|
x2_es2020: ES2020<'a, 'ctx>,
|
||||||
x2_es2019: ES2019,
|
x2_es2019: ES2019,
|
||||||
x2_es2018: ES2018,
|
x2_es2018: ES2018<'a, 'ctx>,
|
||||||
x2_es2016: ES2016<'a, 'ctx>,
|
x2_es2016: ES2016<'a, 'ctx>,
|
||||||
x3_es2015: ES2015<'a>,
|
x3_es2015: ES2015<'a>,
|
||||||
x4_regexp: RegExp<'a, 'ctx>,
|
x4_regexp: RegExp<'a, 'ctx>,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue