mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
refactor(transformer): combine ObjectRestSpread into a single file (#7002)
This commit is contained in:
parent
e5ecbb9bf1
commit
d9edef6ae1
5 changed files with 31 additions and 128 deletions
|
|
@ -1,6 +1,6 @@
|
|||
//! ES2018 object spread transformation.
|
||||
//!
|
||||
//! This plugin transforms object spread properties (`{ ...x }`) to a series of `_objectSpread` calls.
|
||||
//! This plugin transforms rest properties for object destructuring assignment and spread properties for object literals.
|
||||
//!
|
||||
//! > This plugin is included in `preset-env`, in ES2018
|
||||
//!
|
||||
|
|
@ -26,6 +26,8 @@
|
|||
//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-object-rest-spread>
|
||||
//! * Object rest/spread TC39 proposal: <https://github.com/tc39/proposal-object-rest-spread>
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use oxc_ast::{ast::*, NONE};
|
||||
use oxc_semantic::{ReferenceFlags, SymbolId};
|
||||
use oxc_span::SPAN;
|
||||
|
|
@ -33,20 +35,38 @@ use oxc_traverse::{Traverse, TraverseCtx};
|
|||
|
||||
use crate::{common::helper_loader::Helper, TransformCtx};
|
||||
|
||||
use super::ObjectRestSpreadOptions;
|
||||
#[derive(Debug, Default, Clone, Copy, Deserialize)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct ObjectRestSpreadOptions {
|
||||
#[serde(alias = "loose")]
|
||||
pub(crate) set_spread_properties: bool,
|
||||
|
||||
pub struct ObjectSpread<'a, 'ctx> {
|
||||
options: ObjectRestSpreadOptions,
|
||||
ctx: &'ctx TransformCtx<'a>,
|
||||
pub(crate) use_built_ins: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'ctx> ObjectSpread<'a, 'ctx> {
|
||||
pub struct ObjectRestSpread<'a, 'ctx> {
|
||||
ctx: &'ctx TransformCtx<'a>,
|
||||
options: ObjectRestSpreadOptions,
|
||||
}
|
||||
|
||||
impl<'a, 'ctx> ObjectRestSpread<'a, 'ctx> {
|
||||
pub fn new(options: ObjectRestSpreadOptions, ctx: &'ctx TransformCtx<'a>) -> Self {
|
||||
Self { options, ctx }
|
||||
Self { ctx, options }
|
||||
}
|
||||
}
|
||||
impl<'a, 'ctx> Traverse<'a> for ObjectSpread<'a, 'ctx> {
|
||||
|
||||
impl<'a, 'ctx> Traverse<'a> for ObjectRestSpread<'a, 'ctx> {
|
||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.transform_object_expression(expr, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'ctx> ObjectRestSpread<'a, 'ctx> {
|
||||
fn transform_object_expression(
|
||||
&mut self,
|
||||
expr: &mut Expression<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
let Expression::ObjectExpression(obj_expr) = expr else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -97,9 +117,7 @@ impl<'a, 'ctx> Traverse<'a> for ObjectSpread<'a, 'ctx> {
|
|||
*expr = ctx.ast.expression_call(SPAN, callee, NONE, arguments, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'ctx> ObjectSpread<'a, 'ctx> {
|
||||
#[expect(clippy::option_option)]
|
||||
fn get_object_symbol_id(&self, ctx: &mut TraverseCtx<'a>) -> Option<Option<SymbolId>> {
|
||||
if self.options.set_spread_properties {
|
||||
|
|
@ -118,7 +136,7 @@ impl<'a, 'ctx> ObjectSpread<'a, 'ctx> {
|
|||
if let Some(object_id) = object_id {
|
||||
Self::object_assign(object_id, ctx)
|
||||
} else {
|
||||
self.babel_external_helper(ctx)
|
||||
self.ctx.helper_load(Helper::ObjectSpread2, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,11 +145,6 @@ impl<'a, 'ctx> ObjectSpread<'a, 'ctx> {
|
|||
ctx.create_reference_id(SPAN, Atom::from("Object"), symbol_id, ReferenceFlags::Read);
|
||||
let object = ctx.ast.expression_from_identifier_reference(ident);
|
||||
let property = ctx.ast.identifier_name(SPAN, Atom::from("assign"));
|
||||
|
||||
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false))
|
||||
}
|
||||
|
||||
fn babel_external_helper(&self, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
|
||||
self.ctx.helper_load(Helper::ObjectSpread2, ctx)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
//! ES2018 object spread transformation.
|
||||
//!
|
||||
//! This plugin transforms rest properties for object destructuring assignment and spread properties for object literals.
|
||||
//!
|
||||
//! > This plugin is included in `preset-env`, in ES2018
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! Input:
|
||||
//! ```js
|
||||
//! var x = { a: 1, b: 2 };
|
||||
//! var y = { ...x, c: 3 };
|
||||
//! ```
|
||||
//!
|
||||
//! Output:
|
||||
//! ```js
|
||||
//! var x = { a: 1, b: 2 };
|
||||
//! var y = _objectSpread({}, x, { c: 3 });
|
||||
//! ```
|
||||
//!
|
||||
//! ## Implementation
|
||||
//!
|
||||
//! Implementation based on [@babel/plugin-transform-object-rest-spread](https://babeljs.io/docs/babel-plugin-transform-object-rest-spread).
|
||||
//!
|
||||
//! ## References:
|
||||
//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-object-rest-spread>
|
||||
//! * Object rest/spread TC39 proposal: <https://github.com/tc39/proposal-object-rest-spread>
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_traverse::{Traverse, TraverseCtx};
|
||||
|
||||
use crate::TransformCtx;
|
||||
|
||||
mod object_rest;
|
||||
mod object_spread;
|
||||
use object_rest::ObjectRest;
|
||||
use object_spread::ObjectSpread;
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, Deserialize)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
pub struct ObjectRestSpreadOptions {
|
||||
#[serde(alias = "loose")]
|
||||
pub(crate) set_spread_properties: bool,
|
||||
pub(crate) use_built_ins: bool,
|
||||
}
|
||||
|
||||
pub struct ObjectRestSpread<'a, 'ctx> {
|
||||
#[allow(dead_code)]
|
||||
options: ObjectRestSpreadOptions,
|
||||
|
||||
// Plugins
|
||||
object_spread: ObjectSpread<'a, 'ctx>,
|
||||
#[allow(dead_code)]
|
||||
object_rest: ObjectRest,
|
||||
}
|
||||
|
||||
impl<'a, 'ctx> ObjectRestSpread<'a, 'ctx> {
|
||||
pub fn new(options: ObjectRestSpreadOptions, ctx: &'ctx TransformCtx<'a>) -> Self {
|
||||
Self {
|
||||
object_spread: ObjectSpread::new(options, ctx),
|
||||
object_rest: ObjectRest::new(options),
|
||||
options,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'ctx> Traverse<'a> for ObjectRestSpread<'a, 'ctx> {
|
||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.object_spread.enter_expression(expr, ctx);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
//! ES2018 object spread transformation.
|
||||
//!
|
||||
//! PLACEHOLDER ONLY. NOT IMPLEMENTED YET. TODO.
|
||||
//!
|
||||
//! > This plugin is included in `preset-env`, in ES2018
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! Input:
|
||||
//! ```js
|
||||
//! var { a, ...b } = x;
|
||||
//! ```
|
||||
//!
|
||||
//! Output:
|
||||
//! ```js
|
||||
//! // TBD
|
||||
//! ```
|
||||
//!
|
||||
//! ## Implementation
|
||||
//!
|
||||
//! Implementation based on [@babel/plugin-transform-object-rest-spread](https://babeljs.io/docs/babel-plugin-transform-object-rest-spread).
|
||||
//!
|
||||
//! ## References:
|
||||
//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-object-rest-spread>
|
||||
//! * Object rest/spread TC39 proposal: <https://github.com/tc39/proposal-object-rest-spread>
|
||||
|
||||
use super::ObjectRestSpreadOptions;
|
||||
|
||||
pub struct ObjectRest {
|
||||
_options: ObjectRestSpreadOptions,
|
||||
}
|
||||
|
||||
impl ObjectRest {
|
||||
pub fn new(options: ObjectRestSpreadOptions) -> Self {
|
||||
Self { _options: options }
|
||||
}
|
||||
}
|
||||
|
|
@ -94,11 +94,11 @@ impl TransformOptions {
|
|||
arrow_function: None,
|
||||
},
|
||||
es2016: ES2016Options { exponentiation_operator: true },
|
||||
es2018: ES2018Options { object_rest_spread: Some(ObjectRestSpreadOptions::default()) },
|
||||
es2017: ES2017Options {
|
||||
// Turned off because it is not ready.
|
||||
async_to_generator: false,
|
||||
},
|
||||
es2018: ES2018Options { object_rest_spread: Some(ObjectRestSpreadOptions::default()) },
|
||||
es2019: ES2019Options { optional_catch_binding: true },
|
||||
es2020: ES2020Options { nullish_coalescing_operator: true },
|
||||
es2021: ES2021Options { logical_assignment_operators: true },
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ use crate::TraverseCtx;
|
|||
/// * `BoundIdentifier` is `Clone` (unlike `BindingIdentifier`).
|
||||
/// * `BoundIdentifier` re-uses the same `Atom` for all `BindingIdentifier` / `IdentifierReference`s
|
||||
/// created from it.
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BoundIdentifier<'a> {
|
||||
pub name: Atom<'a>,
|
||||
pub symbol_id: SymbolId,
|
||||
|
|
|
|||
Loading…
Reference in a new issue