diff --git a/crates/oxc_ast/src/ast_builder_impl.rs b/crates/oxc_ast/src/ast_builder_impl.rs index 10aafab345c5e7..a02c7ccb7b46f2 100644 --- a/crates/oxc_ast/src/ast_builder_impl.rs +++ b/crates/oxc_ast/src/ast_builder_impl.rs @@ -195,6 +195,14 @@ impl<'a> AstBuilder<'a> { mem::replace(element, empty_element) } + /// Move a class element out by replacing it with an empty + /// [StaticBlock](ClassElement::StaticBlock). + // TODO: Delete this method if not using it. + pub fn move_class_element(self, element: &mut ClassElement<'a>) -> ClassElement<'a> { + let empty_element = self.class_element_static_block(Span::default(), self.vec()); + mem::replace(element, empty_element) + } + /// Take the contents of a arena-allocated [`Vec`], leaving an empty vec in /// its place. This is akin to [`std::mem::take`]. #[inline] diff --git a/crates/oxc_transformer/src/common/helper_loader.rs b/crates/oxc_transformer/src/common/helper_loader.rs index 418b32c3f851b0..bc899cbddb6903 100644 --- a/crates/oxc_transformer/src/common/helper_loader.rs +++ b/crates/oxc_transformer/src/common/helper_loader.rs @@ -139,6 +139,7 @@ fn default_as_module_name() -> Cow<'static, str> { pub enum Helper { AsyncToGenerator, ObjectSpread2, + DefineProperty, } impl Helper { @@ -146,6 +147,7 @@ impl Helper { match self { Self::AsyncToGenerator => "asyncToGenerator", Self::ObjectSpread2 => "objectSpread2", + Self::DefineProperty => "defineProperty", } } } diff --git a/crates/oxc_transformer/src/es2022/class_properties.rs b/crates/oxc_transformer/src/es2022/class_properties.rs new file mode 100644 index 00000000000000..43bd7a3f64b20a --- /dev/null +++ b/crates/oxc_transformer/src/es2022/class_properties.rs @@ -0,0 +1,276 @@ +//! ES2022: Class Properties +//! +//! This plugin transforms class properties to initializers inside class constructor. +//! +//! > This plugin is included in `preset-env`, in ES2022 +//! +//! ## Example +//! +//! Input: +//! ```js +//! class C { +//! foo = 123; +//! #bar = 456; +//! } +//! +//! let x = 123; +//! class D extends S { +//! foo = x; +//! constructor(x) { +//! if (x) { +//! let s = super(x); +//! } else { +//! super(x); +//! } +//! } +//! } +//! ``` +//! +//! Output: +//! ```js +//! var _bar = /*#__PURE__*/ new WeakMap(); +//! class C { +//! constructor() { +//! babelHelpers.defineProperty(this, "foo", 123); +//! babelHelpers.classPrivateFieldInitSpec(this, _bar, 456); +//! } +//! } +//! +//! let x = 123; +//! class D extends S { +//! constructor(_x) { +//! if (_x) { +//! let s = (super(_x), babelHelpers.defineProperty(this, "foo", x)); +//! } else { +//! super(_x); +//! babelHelpers.defineProperty(this, "foo", x); +//! } +//! } +//! } +//! ``` +//! +//! ## Implementation +//! +//! Implementation based on [@babel/plugin-transform-class-properties](https://babel.dev/docs/babel-plugin-transform-class-properties). +//! +//! ## References: +//! * Babel plugin implementation: +//! * +//! * +//! * +//! * Class properties TC39 proposal: + +use serde::Deserialize; + +use oxc_ast::{ast::*, AstBuilder, NONE}; +use oxc_span::SPAN; +use oxc_syntax::scope::ScopeFlags; +use oxc_traverse::{Ancestor, Traverse, TraverseCtx}; + +use crate::{common::helper_loader::Helper, TransformCtx}; + +#[derive(Debug, Default, Clone, Copy, Deserialize)] +#[serde(default, rename_all = "camelCase")] +pub struct ClassPropertiesOptions { + #[serde(alias = "loose")] + pub(crate) set_public_class_fields: bool, +} + +pub struct ClassProperties<'a, 'ctx> { + #[expect(dead_code)] + options: ClassPropertiesOptions, + ctx: &'ctx TransformCtx<'a>, +} + +impl<'a, 'ctx> ClassProperties<'a, 'ctx> { + pub fn new(options: ClassPropertiesOptions, ctx: &'ctx TransformCtx<'a>) -> Self { + Self { options, ctx } + } +} + +impl<'a, 'ctx> Traverse<'a> for ClassProperties<'a, 'ctx> { + fn enter_class_body(&mut self, body: &mut ClassBody<'a>, ctx: &mut TraverseCtx<'a>) { + // Check if class has any properties and get index and `ScopeId` of constructor (if class has one) + let mut instance_prop_count = 0; + let mut static_props_count = 0; + let mut constructor = None; + for (index, element) in body.body.iter().enumerate() { + match element { + ClassElement::PropertyDefinition(prop) => { + if !prop.decorators.is_empty() + || prop.r#type == PropertyDefinitionType::TSAbstractPropertyDefinition + { + // TODO: Raise error + return; + } + + if prop.r#static { + static_props_count += 1; + } else { + instance_prop_count += 1; + } + } + ClassElement::MethodDefinition(method) => { + if method.kind == MethodDefinitionKind::Constructor { + if method.value.body.is_none() { + // Constructor has no body. TODO: Don't bail out here. + return; + } + + // Record index constructor has after properties before it are removed + let index = index - static_props_count - instance_prop_count; + constructor = Some((index, method.value.scope_id.get().unwrap())); + } + } + _ => {} + }; + } + + if instance_prop_count == 0 && static_props_count == 0 { + return; + } + + // Extract properties from class body + let mut instance_inits = Vec::with_capacity(instance_prop_count); + // let mut static_props = Vec::with_capacity(static_props_count); + body.body.retain_mut(|element| { + let ClassElement::PropertyDefinition(prop) = element else { return true }; + + #[expect(clippy::redundant_else)] + if prop.r#static { + // TODO + return false; + } else { + // TODO: Handle `loose` option + let key = match &prop.key { + PropertyKey::StaticIdentifier(ident) => { + ctx.ast.expression_string_literal(ident.span, ident.name.clone()) + } + _ => { + // TODO: Handle private properties + // TODO: Handle computed property key + ctx.ast.expression_string_literal(SPAN, Atom::from("oops")) + } + }; + let value = match &mut prop.value { + Some(value) => ctx.ast.move_expression(value), + None => ctx.ast.void_0(SPAN), + }; + let args = ctx.ast.vec_from_iter( + [ctx.ast.expression_this(SPAN), key, value].into_iter().map(Argument::from), + ); + // TODO: Should this have span of the original `PropertyDefinition`? + let expr = self.ctx.helper_call_expr(Helper::DefineProperty, args, ctx); + instance_inits.push(expr); + } + + false + }); + + // Insert instance initializers into constructor + if !instance_inits.is_empty() { + // TODO: Re-parent any scopes within initializers. + let has_super_class = match ctx.parent() { + Ancestor::ClassBody(class) => class.super_class().is_some(), + _ => unreachable!(), + }; + + if let Some((constructor_index, _)) = constructor { + // Existing constructor - amend it + Self::insert_inits_into_constructor(body, instance_inits, constructor_index, ctx); + } else { + // No constructor - create one + Self::insert_constructor(body, instance_inits, has_super_class, ctx); + } + } + + // TODO: Static properties + } +} + +impl<'a, 'ctx> ClassProperties<'a, 'ctx> { + fn insert_inits_into_constructor( + body: &mut ClassBody<'a>, + inits: Vec>, + constructor_index: usize, + ctx: &mut TraverseCtx<'a>, + ) { + // TODO: Insert after `super()` if class has super-class. + // TODO: Insert as expression sequence if `super()` is used in an expression. + // TODO: Handle where vars used in property init clash with vars in top scope of constructor. + let element = body.body.get_mut(constructor_index).unwrap(); + let ClassElement::MethodDefinition(method) = element else { unreachable!() }; + let func_body = method.value.body.as_mut().unwrap(); + func_body + .statements + .splice(0..0, inits.into_iter().map(|expr| ctx.ast.statement_expression(SPAN, expr))); + } + + fn insert_constructor( + body: &mut ClassBody<'a>, + inits: Vec>, + has_super_class: bool, + ctx: &mut TraverseCtx<'a>, + ) { + let inits_count = inits.len(); + // TODO: Should these have the span of the original `PropertyDefinition`s? + let init_stmts = inits.into_iter().map(|expr| ctx.ast.statement_expression(SPAN, expr)); + + // Add `super();` statement if class has a super class + let stmts = if has_super_class { + let mut stmts = ctx.ast.vec_with_capacity(inits_count + 1); + stmts.push(Self::create_super_call_stmt(ctx.ast)); + stmts.extend(init_stmts); + stmts + } else { + ctx.ast.vec_from_iter(init_stmts) + }; + + let scope_id = ctx.create_child_scope_of_current(ScopeFlags::Function); + + let ctor = ClassElement::MethodDefinition(ctx.ast.alloc_method_definition( + MethodDefinitionType::MethodDefinition, + SPAN, + ctx.ast.vec(), + PropertyKey::StaticIdentifier( + ctx.ast.alloc_identifier_name(SPAN, Atom::from("constructor")), + ), + ctx.ast.alloc_function_with_scope_id( + FunctionType::FunctionExpression, + SPAN, + None, + false, + false, + false, + NONE, + NONE, + ctx.ast.alloc_formal_parameters( + SPAN, + FormalParameterKind::FormalParameter, + ctx.ast.vec(), + NONE, + ), + NONE, + Some(ctx.ast.alloc_function_body(SPAN, ctx.ast.vec(), stmts)), + scope_id, + ), + MethodDefinitionKind::Constructor, + false, + false, + false, + false, + None, + )); + + // TODO(improve-on-babel): Could push constructor onto end of elements, instead of inserting as first + body.body.insert(0, ctor); + } + + /// `super();` + fn create_super_call_stmt(ast: AstBuilder<'a>) -> Statement<'a> { + ast.statement_expression( + SPAN, + ast.expression_call(SPAN, ast.expression_super(SPAN), NONE, ast.vec(), false), + ) + } +} diff --git a/crates/oxc_transformer/src/es2022/mod.rs b/crates/oxc_transformer/src/es2022/mod.rs index d2feb9f35c7cdb..c0ad06a5fb0838 100644 --- a/crates/oxc_transformer/src/es2022/mod.rs +++ b/crates/oxc_transformer/src/es2022/mod.rs @@ -1,29 +1,44 @@ use oxc_ast::ast::*; use oxc_traverse::{Traverse, TraverseCtx}; +use crate::TransformCtx; + +mod class_properties; mod class_static_block; mod options; +use class_properties::ClassProperties; +pub use class_properties::ClassPropertiesOptions; use class_static_block::ClassStaticBlock; pub use options::ES2022Options; -pub struct ES2022 { +pub struct ES2022<'a, 'ctx> { options: ES2022Options, // Plugins class_static_block: ClassStaticBlock, + class_properties: Option>, } -impl ES2022 { - pub fn new(options: ES2022Options) -> Self { - Self { options, class_static_block: ClassStaticBlock::new() } +impl<'a, 'ctx> ES2022<'a, 'ctx> { + pub fn new(options: ES2022Options, ctx: &'ctx TransformCtx<'a>) -> Self { + Self { + options, + class_static_block: ClassStaticBlock::new(), + class_properties: options + .class_properties + .map(|options| ClassProperties::new(options, ctx)), + } } } -impl<'a> Traverse<'a> for ES2022 { +impl<'a, 'ctx> Traverse<'a> for ES2022<'a, 'ctx> { fn enter_class_body(&mut self, body: &mut ClassBody<'a>, ctx: &mut TraverseCtx<'a>) { if self.options.class_static_block { self.class_static_block.enter_class_body(body, ctx); } + if let Some(class_properties) = &mut self.class_properties { + class_properties.enter_class_body(body, ctx); + } } } diff --git a/crates/oxc_transformer/src/es2022/options.rs b/crates/oxc_transformer/src/es2022/options.rs index 0cd79e5fd099d3..98f1901999ba97 100644 --- a/crates/oxc_transformer/src/es2022/options.rs +++ b/crates/oxc_transformer/src/es2022/options.rs @@ -1,8 +1,11 @@ use serde::Deserialize; -#[derive(Debug, Default, Clone, Deserialize)] +use super::ClassPropertiesOptions; + +#[derive(Debug, Default, Clone, Copy, Deserialize)] #[serde(default, rename_all = "camelCase", deny_unknown_fields)] pub struct ES2022Options { #[serde(skip)] pub class_static_block: bool, + pub class_properties: Option, } diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index 1f945142a9759d..2e28cf5fc351bf 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -97,7 +97,7 @@ impl<'a> Transformer<'a> { .is_typescript() .then(|| TypeScript::new(&self.options.typescript, &self.ctx)), x1_jsx: Jsx::new(self.options.jsx, ast_builder, &self.ctx), - x2_es2022: ES2022::new(self.options.es2022), + x2_es2022: ES2022::new(self.options.es2022, &self.ctx), x2_es2021: ES2021::new(self.options.es2021, &self.ctx), x2_es2020: ES2020::new(self.options.es2020, &self.ctx), x2_es2019: ES2019::new(self.options.es2019), @@ -118,7 +118,7 @@ struct TransformerImpl<'a, 'ctx> { // NOTE: all callbacks must run in order. x0_typescript: Option>, x1_jsx: Jsx<'a, 'ctx>, - x2_es2022: ES2022, + x2_es2022: ES2022<'a, 'ctx>, x2_es2021: ES2021<'a, 'ctx>, x2_es2020: ES2020<'a, 'ctx>, x2_es2019: ES2019, diff --git a/crates/oxc_transformer/src/options/transformer.rs b/crates/oxc_transformer/src/options/transformer.rs index 70f614c49f1061..e4cc267b9e8457 100644 --- a/crates/oxc_transformer/src/options/transformer.rs +++ b/crates/oxc_transformer/src/options/transformer.rs @@ -15,7 +15,7 @@ use crate::{ es2019::ES2019Options, es2020::ES2020Options, es2021::ES2021Options, - es2022::ES2022Options, + es2022::{ClassPropertiesOptions, ES2022Options}, jsx::JsxOptions, options::babel::BabelOptions, regexp::RegExpOptions, @@ -102,7 +102,10 @@ impl TransformOptions { es2019: ES2019Options { optional_catch_binding: true }, es2020: ES2020Options { nullish_coalescing_operator: true }, es2021: ES2021Options { logical_assignment_operators: true }, - es2022: ES2022Options { class_static_block: true }, + es2022: ES2022Options { + class_static_block: true, + class_properties: Some(ClassPropertiesOptions::default()), + }, helper_loader: HelperLoaderOptions { mode: HelperLoaderMode::Runtime, ..Default::default() @@ -194,6 +197,12 @@ impl TryFrom<&EnvOptions> for TransformOptions { targets, bugfixes, ), + class_properties: can_enable_plugin( + "transform-class-properties", + targets, + bugfixes, + ) + .then(Default::default), }, ..Default::default() }) @@ -372,6 +381,14 @@ impl TryFrom<&BabelOptions> for TransformOptions { bugfixes, ) .is_some(), + class_properties: { + let plugin_name = "transform-class-properties"; + get_enabled_plugin_options(plugin_name, options, targets, bugfixes).map(|options| { + serde_json::from_value::(options) + .inspect_err(|err| report_error(plugin_name, err, false, &mut errors)) + .unwrap_or_default() + }) + }, }; if !errors.is_empty() { diff --git a/tasks/transform_conformance/snapshots/babel.snap.md b/tasks/transform_conformance/snapshots/babel.snap.md index c0e172b9e43cef..284ee32b758775 100644 --- a/tasks/transform_conformance/snapshots/babel.snap.md +++ b/tasks/transform_conformance/snapshots/babel.snap.md @@ -1,6 +1,6 @@ commit: d20b314c -Passed: 361/1058 +Passed: 366/1162 # All Passed: * babel-plugin-transform-class-static-block @@ -1427,6 +1427,307 @@ x Output mismatch x Output mismatch +# babel-plugin-transform-class-properties (4/103) +* assumption-constantSuper/complex-super-class/input.js +x Output mismatch + +* assumption-constantSuper/instance-field/input.js +x Output mismatch + +* assumption-constantSuper/static-field/input.js +x Output mismatch + +* assumption-noDocumentAll/optional-chain-before-member-call/input.js +x Output mismatch + +* assumption-noDocumentAll/optional-chain-cast-to-boolean/input.js +x Output mismatch + +* assumption-noUninitializedPrivateFieldAccess/static-private/input.js +x Output mismatch + +* assumption-setPublicClassFields/computed/input.js +x Output mismatch + +* assumption-setPublicClassFields/constructor-collision/input.js +x Output mismatch + +* assumption-setPublicClassFields/derived/input.js +x Output mismatch + +* assumption-setPublicClassFields/foobar/input.js +x Output mismatch + +* assumption-setPublicClassFields/instance/input.js +x Output mismatch + +* assumption-setPublicClassFields/instance-computed/input.js +x Output mismatch + +* assumption-setPublicClassFields/instance-undefined/input.js +x Output mismatch + +* assumption-setPublicClassFields/length-name-use-define/input.js +x Output mismatch + +* assumption-setPublicClassFields/non-block-arrow-func/input.mjs +x Output mismatch + +* assumption-setPublicClassFields/regression-T2983/input.mjs +x Output mismatch + +* assumption-setPublicClassFields/regression-T6719/input.js +x Output mismatch + +* assumption-setPublicClassFields/regression-T7364/input.mjs +x Output mismatch + +* assumption-setPublicClassFields/static/input.js +x Output mismatch + +* assumption-setPublicClassFields/static-class-binding/input.js +x Output mismatch + +* assumption-setPublicClassFields/static-export/input.mjs +x Output mismatch + +* assumption-setPublicClassFields/static-infer-name/input.js +x Output mismatch + +* assumption-setPublicClassFields/static-super/input.js +x Output mismatch + +* assumption-setPublicClassFields/static-super-loose/input.js +x Output mismatch + +* assumption-setPublicClassFields/static-this/input.js +x Output mismatch + +* assumption-setPublicClassFields/static-undefined/input.js +x Output mismatch + +* assumption-setPublicClassFields/super-call/input.js +x Output mismatch + +* assumption-setPublicClassFields/super-expression/input.js +x Output mismatch + +* assumption-setPublicClassFields/super-statement/input.js +x Output mismatch + +* assumption-setPublicClassFields/super-with-collision/input.js +x Output mismatch + +* class-name-tdz/general/input.js +x Output mismatch + +* class-name-tdz/static-loose/input.js +x Output mismatch + +* compile-to-class/constructor-collision-ignores-types/input.js +Unresolved references mismatch: +after transform: ["T", "babelHelpers"] +rebuilt : ["babelHelpers"] + +* compile-to-class/constructor-collision-ignores-types-loose/input.js +x Output mismatch + +* compile-to-class/preserve-comments/input.js +x Output mismatch + +* private/class-shadow-builtins/input.mjs +x Output mismatch + +* private/logical-assignment/input.js +x Output mismatch + +* private/native-classes/input.js +x Output mismatch + +* private/non-block-arrow-func/input.mjs +x Output mismatch + +* private/optional-chain-before-member-call/input.js +x Output mismatch + +* private/optional-chain-before-property/input.js +x Output mismatch + +* private/optional-chain-cast-to-boolean/input.js +x Output mismatch + +* private/optional-chain-delete-property/input.js +x Output mismatch + +* private/optional-chain-in-function-param/input.js +x Output mismatch + +* private/optional-chain-member-optional-call/input.js +x Output mismatch + +* private/optional-chain-member-optional-call-spread-arguments/input.js +x Output mismatch + +* private/optional-chain-optional-member-call/input.js +x Output mismatch + +* private/optional-chain-optional-property/input.js +x Output mismatch + +* private/parenthesized-optional-member-call/input.js +x Output mismatch + +* private/reevaluated/input.js +x Output mismatch + +* private/regression-T2983/input.mjs +x Output mismatch + +* private/regression-T6719/input.js +x Output mismatch + +* private/regression-T7364/input.mjs +x Output mismatch + +* private/static/input.js +x Output mismatch + +* private/static-export/input.mjs +x Output mismatch + +* private/static-infer-name/input.js +x Output mismatch + +* private/static-inherited/input.js +x Output mismatch + +* private/static-self-field/input.js +x Output mismatch + +* private/static-shadow/input.js +x Output mismatch + +* private/static-undefined/input.js +x Output mismatch + +* private-loose/class-shadow-builtins/input.mjs +x Output mismatch + +* private-loose/logical-assignment/input.js +x Output mismatch + +* private-loose/native-classes/input.js +x Output mismatch + +* private-loose/non-block-arrow-func/input.mjs +x Output mismatch + +* private-loose/optional-chain-before-member-call/input.js +x Output mismatch + +* private-loose/optional-chain-before-property/input.js +x Output mismatch + +* private-loose/optional-chain-cast-to-boolean/input.js +x Output mismatch + +* private-loose/optional-chain-delete-property/input.js +x Output mismatch + +* private-loose/optional-chain-in-function-param/input.js +x Output mismatch + +* private-loose/optional-chain-member-optional-call/input.js +x Output mismatch + +* private-loose/optional-chain-member-optional-call-spread-arguments/input.js +x Output mismatch + +* private-loose/optional-chain-optional-member-call/input.js +x Output mismatch + +* private-loose/optional-chain-optional-property/input.js +x Output mismatch + +* private-loose/parenthesized-optional-member-call/input.js +x Output mismatch + +* private-loose/reevaluated/input.js +x Output mismatch + +* private-loose/static/input.js +x Output mismatch + +* private-loose/static-export/input.mjs +x Output mismatch + +* private-loose/static-infer-name/input.js +x Output mismatch + +* private-loose/static-inherited/input.js +x Output mismatch + +* private-loose/static-shadow/input.js +x Output mismatch + +* private-loose/static-undefined/input.js +x Output mismatch + +* public/class-shadow-builtins/input.mjs +x Output mismatch + +* public/derived-super-in-default-params/input.js +x Output mismatch + +* public/derived-super-in-default-params-complex/input.js +x Output mismatch + +* public/derived-super-in-default-params-in-arrow/input.js +x Output mismatch + +* public/foobar/input.js +x Output mismatch + +* public/native-classes/input.js +x Output mismatch + +* public/regression-T7364/input.mjs +x Output mismatch + +* public-loose/class-shadow-builtins/input.mjs +x Output mismatch + +* public-loose/regression-T7364/input.mjs +x Output mismatch + +* regression/15098/input.js +x Output mismatch + +* regression/6153/input.js +x Output mismatch + +* regression/6154/input.js +x Output mismatch + +* regression/7371/input.js +x Output mismatch + +* regression/7951/input.mjs +x Output mismatch + +* regression/8110/input.js +x Output mismatch + +* regression/8882/input.js +x Output mismatch + +* regression/T7364/input.mjs +x Output mismatch + +* regression/multiple-super-in-termary/input.js +x Output mismatch + + # babel-plugin-transform-nullish-coalescing-operator (5/12) * assumption-noDocumentAll/transform/input.js x Output mismatch @@ -1720,7 +2021,7 @@ rebuilt : ScopeId(1): [] x Output mismatch -# babel-plugin-transform-typescript (39/152) +# babel-plugin-transform-typescript (40/153) * cast/as-expression/input.ts Unresolved references mismatch: after transform: ["T", "x"] diff --git a/tasks/transform_conformance/snapshots/babel_exec.snap.md b/tasks/transform_conformance/snapshots/babel_exec.snap.md index 05fa232b701193..2f55671d2ee66b 100644 --- a/tasks/transform_conformance/snapshots/babel_exec.snap.md +++ b/tasks/transform_conformance/snapshots/babel_exec.snap.md @@ -1,6 +1,6 @@ commit: d20b314c -Passed: 45/73 +Passed: 45/120 # All Passed: * babel-plugin-transform-class-static-block @@ -24,6 +24,149 @@ exec failed exec failed +# babel-plugin-transform-class-properties (0/47) +* assumption-noDocumentAll/optional-chain-before-member-call/exec.js +exec failed + +* assumption-noDocumentAll/optional-chain-cast-to-boolean/exec.js +exec failed + +* assumption-noUninitializedPrivateFieldAccess/static-private/exec.js +exec failed + +* assumption-setPublicClassFields/computed-initialization-order/exec.js +exec failed + +* assumption-setPublicClassFields/instance-computed/exec.js +exec failed + +* assumption-setPublicClassFields/static/exec.js +exec failed + +* assumption-setPublicClassFields/static-class-binding/exec.js +exec failed + +* assumption-setPublicClassFields/static-infer-name/exec.js +exec failed + +* assumption-setPublicClassFields/static-super/exec.js +exec failed + +* assumption-setPublicClassFields/static-this/exec.js +exec failed + +* assumption-setPublicClassFields/static-undefined/exec.js +exec failed + +* class-name-tdz/general/exec.js +exec failed + +* class-name-tdz/static-loose/exec.js +exec failed + +* private/native-classes/exec.js +exec failed + +* private/optional-chain-before-member-call/exec.js +exec failed + +* private/optional-chain-before-property/exec.js +exec failed + +* private/optional-chain-cast-to-boolean/exec.js +exec failed + +* private/optional-chain-delete-property/exec.js +exec failed + +* private/optional-chain-in-function-param/exec.js +exec failed + +* private/optional-chain-member-optional-call/exec.js +exec failed + +* private/optional-chain-member-optional-call-spread-arguments/exec.js +exec failed + +* private/optional-chain-optional-member-call/exec.js +exec failed + +* private/optional-chain-optional-property/exec.js +exec failed + +* private/parenthesized-optional-member-call/exec.js +exec failed + +* private/reevaluated/exec.js +exec failed + +* private/static-inherited/exec.js +exec failed + +* private/static-self-field/exec.js +exec failed + +* private/static-shadow/exec.js +exec failed + +* private/static-undefined/exec.js +exec failed + +* private-loose/optional-chain-before-member-call/exec.js +exec failed + +* private-loose/optional-chain-before-property/exec.js +exec failed + +* private-loose/optional-chain-cast-to-boolean/exec.js +exec failed + +* private-loose/optional-chain-delete-property/exec.js +exec failed + +* private-loose/optional-chain-in-function-param/exec.js +exec failed + +* private-loose/optional-chain-member-optional-call/exec.js +exec failed + +* private-loose/optional-chain-member-optional-call-spread-arguments/exec.js +exec failed + +* private-loose/optional-chain-optional-member-call/exec.js +exec failed + +* private-loose/optional-chain-optional-property/exec.js +exec failed + +* private-loose/parenthesized-optional-member-call/exec.js +exec failed + +* private-loose/static/exec.js +exec failed + +* private-loose/static-inherited/exec.js +exec failed + +* private-loose/static-shadow/exec.js +exec failed + +* private-loose/static-undefined/exec.js +exec failed + +* public/native-classes/exec.js +exec failed + +* regression/15098/exec.js +exec failed + +* regression/7371/exec.js +exec failed + +* regression/8882/exec.js +exec failed + + # babel-plugin-transform-object-rest-spread (15/31) * assumption-objectRestNoSymbols/rest-ignore-symbols/exec.js exec failed diff --git a/tasks/transform_conformance/src/constants.rs b/tasks/transform_conformance/src/constants.rs index 3455c0160e922c..7dc38fff3ae6cf 100644 --- a/tasks/transform_conformance/src/constants.rs +++ b/tasks/transform_conformance/src/constants.rs @@ -3,7 +3,7 @@ pub(crate) const PLUGINS: &[&str] = &[ // // ES2024 // "babel-plugin-transform-unicode-sets-regex", // // ES2022 - // "babel-plugin-transform-class-properties", + "babel-plugin-transform-class-properties", "babel-plugin-transform-class-static-block", // "babel-plugin-transform-private-methods", // "babel-plugin-transform-private-property-in-object", @@ -63,7 +63,6 @@ pub(crate) const PLUGINS: &[&str] = &[ pub(crate) const PLUGINS_NOT_SUPPORTED_YET: &[&str] = &[ "proposal-decorators", - "transform-class-properties", "transform-classes", "transform-destructuring", "transform-modules-commonjs",