From 983cb28158f5655babb50d3f3b4786de1465def6 Mon Sep 17 00:00:00 2001 From: Dunqing Date: Wed, 25 Dec 2024 00:34:43 +0800 Subject: [PATCH] feat(transformer/class-properties): transform private methods --- .../src/common/helper_loader.rs | 2 + .../src/es2022/class_properties/class.rs | 72 +++- .../es2022/class_properties/class_bindings.rs | 6 +- .../src/es2022/class_properties/mod.rs | 2 + .../es2022/class_properties/private_method.rs | 73 ++++ .../snapshots/babel.snap.md | 7 +- .../snapshots/babel_exec.snap.md | 375 +++++++++++++++++- .../snapshots/oxc.snap.md | 7 +- .../snapshots/oxc_exec.snap.md | 6 +- 9 files changed, 504 insertions(+), 46 deletions(-) create mode 100644 crates/oxc_transformer/src/es2022/class_properties/private_method.rs diff --git a/crates/oxc_transformer/src/common/helper_loader.rs b/crates/oxc_transformer/src/common/helper_loader.rs index eb8218e21e67f..1468bc7435934 100644 --- a/crates/oxc_transformer/src/common/helper_loader.rs +++ b/crates/oxc_transformer/src/common/helper_loader.rs @@ -152,6 +152,7 @@ pub enum Helper { ToPropertyKey, DefineProperty, ClassPrivateFieldInitSpec, + ClassPrivateMethodInitSpec, ClassPrivateFieldGet2, ClassPrivateFieldSet2, AssertClassBrand, @@ -177,6 +178,7 @@ impl Helper { Self::ToPropertyKey => "toPropertyKey", Self::DefineProperty => "defineProperty", Self::ClassPrivateFieldInitSpec => "classPrivateFieldInitSpec", + Self::ClassPrivateMethodInitSpec => "classPrivateMethodInitSpec", Self::ClassPrivateFieldGet2 => "classPrivateFieldGet2", Self::ClassPrivateFieldSet2 => "classPrivateFieldSet2", Self::AssertClassBrand => "assertClassBrand", diff --git a/crates/oxc_transformer/src/es2022/class_properties/class.rs b/crates/oxc_transformer/src/es2022/class_properties/class.rs index d6ac7c6ea2dce..3229ee45de76f 100644 --- a/crates/oxc_transformer/src/es2022/class_properties/class.rs +++ b/crates/oxc_transformer/src/es2022/class_properties/class.rs @@ -77,6 +77,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { // Check if class has any properties or statick blocks, and locate constructor (if class has one) let mut instance_prop_count = 0; let mut has_static_prop = false; + let mut has_private_method = false; let mut has_static_block = false; // TODO: Store `FxIndexMap`s in a pool and re-use them let mut private_props = FxIndexMap::default(); @@ -117,10 +118,21 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { constructor = Some(method); } } else if let PropertyKey::PrivateIdentifier(ident) = &method.key { - let dummy_binding = BoundIdentifier::new(Atom::empty(), SymbolId::new(0)); + has_private_method = true; + let name = match method.kind { + MethodDefinitionKind::Method => ident.name.as_str(), + MethodDefinitionKind::Get => &format!("get_{}", ident.name), + MethodDefinitionKind::Set => &format!("set_{}", ident.name), + MethodDefinitionKind::Constructor => unreachable!(), + }; + let binding = ctx.generate_uid( + name, + ctx.current_block_scope_id(), + SymbolFlags::FunctionScopedVariable, + ); private_props.insert( ident.name.clone(), - PrivateProp::new(dummy_binding, method.r#static, true, false), + PrivateProp::new(binding, method.r#static, true, false), ); } } @@ -142,7 +154,8 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { } // Exit if nothing to transform - if instance_prop_count == 0 && !has_static_prop && !has_static_block { + if instance_prop_count == 0 && !has_static_prop && !has_static_block && !has_private_method + { self.classes_stack.push(ClassDetails { is_declaration, is_transform_required: false, @@ -180,10 +193,22 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { None }; + let class_brand_binding = if has_private_method { + let name = class_name_binding.as_ref().map_or_else(|| "Class", |binding| &binding.name); + let name = &format!("_{name}_brand"); + Some(ctx.generate_uid( + name, + ctx.current_hoist_scope_id(), + SymbolFlags::FunctionScopedVariable, + )) + } else { + None + }; let static_private_fields_use_temp = !is_declaration; let class_bindings = ClassBindings::new( class_name_binding, class_temp_binding, + class_brand_binding, outer_hoist_scope_id, static_private_fields_use_temp, need_temp_var, @@ -198,7 +223,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { }); // Exit if no instance properties (public or private) - if instance_prop_count == 0 { + if instance_prop_count == 0 && !has_private_method { return; } @@ -249,7 +274,14 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { // `class C { [foo()] = 123; }` -> `class C { [_foo = foo()]; }` // Those assignments will be moved to before class in exit phase of the transform. // -> `_foo = foo(); class C {}` - let mut instance_inits = Vec::with_capacity(instance_prop_count); + let mut instance_inits = + Vec::with_capacity(instance_prop_count + usize::from(has_private_method)); + + // `_classPrivateMethodInitSpec(this, _C_brand);` + if has_private_method { + instance_inits.push(self.create_class_private_method_init_spec(ctx)); + } + let mut constructor = None; for element in body.body.iter_mut() { #[expect(clippy::match_same_arms)] @@ -419,16 +451,23 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { } else { // TODO: Only call `insert_many_before` if some private *instance* props let mut weakmap_symbol_id = None; + let has_method = false; self.ctx.statement_injector.insert_many_before( &stmt_address, private_props.values().filter_map(|prop| { - if prop.is_static || prop.is_method || prop.is_accessor { + if prop.is_static || has_method || prop.is_accessor { return None; } - - // `var _prop = new WeakMap();` - let value = create_new_weakmap(&mut weakmap_symbol_id, ctx); - Some(create_variable_declaration(&prop.binding, value, ctx)) + if prop.is_method { + // `var _C_brand = new WeakSet();` + let binding = class_details.bindings.brand.as_ref().unwrap(); + let value = create_new_weakset(ctx); + Some(create_variable_declaration(binding, value, ctx)) + } else { + // `var _prop = new WeakMap();` + let value = create_new_weakmap(&mut weakmap_symbol_id, ctx); + Some(create_variable_declaration(&prop.binding, value, ctx)) + } }), ); } @@ -623,8 +662,9 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { /// /// * Transform static properties and insert after class. /// * Transform static blocks and insert after class. + /// * Transform private methods and insert after class. /// * Extract computed key assignments and insert them before class. - /// * Remove all properties and static blocks from class body. + /// * Remove all properties, private methods and static blocks from class body. fn transform_class_elements(&mut self, class: &mut Class<'a>, ctx: &mut TraverseCtx<'a>) { class.body.body.retain_mut(|element| { match element { @@ -644,6 +684,9 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { } ClassElement::MethodDefinition(method) => { self.substitute_temp_var_for_method_computed_key(method, ctx); + if self.convert_private_method(method, ctx) { + return false; + } } ClassElement::AccessorProperty(_) | ClassElement::TSIndexSignature(_) => { // TODO: Need to handle these? @@ -743,3 +786,10 @@ fn create_new_weakmap<'a>( let ident = ctx.create_ident_expr(SPAN, Atom::from("WeakMap"), symbol_id, ReferenceFlags::Read); ctx.ast.expression_new(SPAN, ident, ctx.ast.vec(), NONE) } + +/// Create `new WeakSet()` expression. +fn create_new_weakset<'a>(ctx: &mut TraverseCtx<'a>) -> Expression<'a> { + let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "WeakSet"); + let ident = ctx.create_ident_expr(SPAN, Atom::from("WeakSet"), symbol_id, ReferenceFlags::Read); + ctx.ast.expression_new(SPAN, ident, ctx.ast.vec(), NONE) +} diff --git a/crates/oxc_transformer/src/es2022/class_properties/class_bindings.rs b/crates/oxc_transformer/src/es2022/class_properties/class_bindings.rs index b5bf61be74493..e0de0b01f82ea 100644 --- a/crates/oxc_transformer/src/es2022/class_properties/class_bindings.rs +++ b/crates/oxc_transformer/src/es2022/class_properties/class_bindings.rs @@ -44,6 +44,8 @@ pub(super) struct ClassBindings<'a> { /// Temp var for class. /// e.g. `_Class` in `_Class = class {}, _Class.x = 1, _Class` pub temp: Option>, + /// Temp var for WeakSet. + pub brand: Option>, /// `ScopeId` of hoist scope outside class (which temp `var` binding would be created in) pub outer_hoist_scope_id: ScopeId, /// `true` if should use temp binding for references to class in transpiled static private fields, @@ -58,6 +60,7 @@ impl<'a> ClassBindings<'a> { pub fn new( name_binding: Option>, temp_binding: Option>, + brand_binding: Option>, outer_scope_id: ScopeId, static_private_fields_use_temp: bool, temp_var_is_created: bool, @@ -65,6 +68,7 @@ impl<'a> ClassBindings<'a> { Self { name: name_binding, temp: temp_binding, + brand: brand_binding, outer_hoist_scope_id: outer_scope_id, static_private_fields_use_temp, temp_var_is_created, @@ -75,7 +79,7 @@ impl<'a> ClassBindings<'a> { /// /// Used when class needs no transform, and for dummy entry at top of `ClassesStack`. pub fn dummy() -> Self { - Self::new(None, None, ScopeId::new(0), false, false) + Self::new(None, None, None, ScopeId::new(0), false, false) } /// Get `SymbolId` of name binding. diff --git a/crates/oxc_transformer/src/es2022/class_properties/mod.rs b/crates/oxc_transformer/src/es2022/class_properties/mod.rs index 13149dd4603d7..748338cd2c88c 100644 --- a/crates/oxc_transformer/src/es2022/class_properties/mod.rs +++ b/crates/oxc_transformer/src/es2022/class_properties/mod.rs @@ -183,6 +183,7 @@ //! * `static_block_and_prop_init.rs`: Transform of static property initializers and static blocks. //! * `computed_key.rs`: Transform of property/method computed keys. //! * `private_field.rs`: Transform of private fields (`this.#prop`). +//! * `private_method.rs`: Transform of private methods (`this.#method()`). //! * `super.rs`: Transform `super` expressions. //! * `class_details.rs`: Structures containing details of classes and private properties. //! * `class_bindings.rs`: Structure containing bindings for class name and temp var. @@ -214,6 +215,7 @@ mod computed_key; mod constructor; mod instance_prop_init; mod private_field; +mod private_method; mod prop_decl; mod static_block_and_prop_init; mod supers; diff --git a/crates/oxc_transformer/src/es2022/class_properties/private_method.rs b/crates/oxc_transformer/src/es2022/class_properties/private_method.rs new file mode 100644 index 0000000000000..4d3a2f005e5c0 --- /dev/null +++ b/crates/oxc_transformer/src/es2022/class_properties/private_method.rs @@ -0,0 +1,73 @@ +//! ES2022: Class Properties +//! Transform of private method uses e.g. `this.#method()`. + +use oxc_ast::ast::{Argument, Expression, FunctionType, MethodDefinition, PropertyKey, Statement}; +use oxc_semantic::ScopeFlags; +use oxc_span::SPAN; +use oxc_traverse::TraverseCtx; + +use crate::Helper; + +use super::ClassProperties; + +impl<'a, 'ctx> ClassProperties<'a, 'ctx> { + /// Convert method definition where the key is a private identifier and + /// insert it after the class. + /// + /// ```js + /// class C { + /// #method() {} + /// set #prop(value) {} + /// get #prop() {return 0} + /// } + /// ``` + /// + /// -> + /// + /// ```js + /// class C {} + /// function _method() {} + /// function _set_prop(value) {} + /// function _get_prop() {return 0} + /// ``` + /// + /// Returns `true` if the method was converted. + pub(super) fn convert_private_method( + &mut self, + method: &mut MethodDefinition<'a>, + ctx: &mut TraverseCtx<'a>, + ) -> bool { + let PropertyKey::PrivateIdentifier(ident) = &method.key else { + return false; + }; + + let mut function = ctx.ast.move_function(&mut method.value); + + let temp_binding = self.classes_stack.find_private_prop(ident).prop_binding; + function.id = Some(temp_binding.create_binding_identifier(ctx)); + function.r#type = FunctionType::FunctionDeclaration; + + let scope_id = function.scope_id(); + let new_parent_id = ctx.current_block_scope_id(); + ctx.scopes_mut().change_parent_id(scope_id, Some(new_parent_id)); + *ctx.scopes_mut().get_flags_mut(scope_id) -= ScopeFlags::StrictMode; + + let function = ctx.ast.alloc(function); + self.insert_after_stmts.push(Statement::FunctionDeclaration(function)); + + true + } + + // `_classPrivateMethodInitSpec(this, brand)` + pub(super) fn create_class_private_method_init_spec( + &self, + ctx: &mut TraverseCtx<'a>, + ) -> Expression<'a> { + let brand = self.classes_stack.last().bindings.brand.as_ref().unwrap(); + let arguments = ctx.ast.vec_from_array([ + Argument::from(ctx.ast.expression_this(SPAN)), + Argument::from(brand.create_read_expression(ctx)), + ]); + self.ctx.helper_call_expr(Helper::ClassPrivateMethodInitSpec, SPAN, arguments, ctx) + } +} diff --git a/tasks/transform_conformance/snapshots/babel.snap.md b/tasks/transform_conformance/snapshots/babel.snap.md index be050ea09fa6f..4ba2cd443c1e0 100644 --- a/tasks/transform_conformance/snapshots/babel.snap.md +++ b/tasks/transform_conformance/snapshots/babel.snap.md @@ -1,6 +1,6 @@ commit: 54a8389f -Passed: 622/1095 +Passed: 623/1095 # All Passed: * babel-plugin-transform-logical-assignment-operators @@ -462,7 +462,7 @@ x Output mismatch x Output mismatch -# babel-plugin-transform-private-methods (7/148) +# babel-plugin-transform-private-methods (8/148) * accessors/arguments/input.js x Output mismatch @@ -592,9 +592,6 @@ x Output mismatch * private-method/generator/input.js x Output mismatch -* private-method/preserve-comments/input.js -x Output mismatch - * private-method/read-only/input.js x Output mismatch diff --git a/tasks/transform_conformance/snapshots/babel_exec.snap.md b/tasks/transform_conformance/snapshots/babel_exec.snap.md index 942123f65080e..1c60618169299 100644 --- a/tasks/transform_conformance/snapshots/babel_exec.snap.md +++ b/tasks/transform_conformance/snapshots/babel_exec.snap.md @@ -2,7 +2,7 @@ commit: 54a8389f node: v22.12.0 -Passed: 330 of 362 (91.16%) +Passed: 215 of 362 (59.39%) Failures: @@ -52,6 +52,9 @@ TypeError: Cannot read properties of undefined (reading 'bind') at Foo.test (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-private-loose-parenthesized-optional-member-call-with-transform-exec.test.js:20:59) at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-private-loose-parenthesized-optional-member-call-with-transform-exec.test.js:78:12 +./fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-private-static-self-method-exec.test.js +Private field '#bar' must be declared in an enclosing class + ./fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-private-static-shadow-exec.test.js TypeError: e.has is not a function at _assertClassBrand (./node_modules/.pnpm/@babel+runtime@7.26.0/node_modules/@babel/runtime/helpers/assertClassBrand.js:2:44) @@ -59,6 +62,9 @@ TypeError: e.has is not a function at Function.method (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-private-static-shadow-exec.test.js:12:11) at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-private-static-shadow-exec.test.js:16:14 +./fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-private-tagged-template-exec.test.js +Private field '#tag' must be declared in an enclosing class + ./fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-public-computed-toPrimitive-exec.test.js AssertionError: expected [Function] to throw error including '@@toPrimitive must return a primitive…' but got 'Cannot convert object to primitive va…' at Proxy. (./node_modules/.pnpm/@vitest+expect@2.1.2/node_modules/@vitest/expect/dist/index.js:1438:21) @@ -112,40 +118,365 @@ TypeError: Cannot read properties of undefined (reading 'x') at Foo.test (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-optional-chaining-test-fixtures-general-parenthesized-expression-member-call-loose-exec.test.js:25:63) at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-optional-chaining-test-fixtures-general-parenthesized-expression-member-call-loose-exec.test.js:68:12 +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-arguments-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-basic-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-class-binding-exec.test.js +Private field '#getA' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-get-only-setter-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-helper-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-loose-basic-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-loose-class-binding-exec.test.js +Private field '#getA' must be declared in an enclosing class + ./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-loose-get-only-setter-exec.test.js -TypeError: '#privateFieldValue' was defined without a getter - at new Cl (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-loose-get-only-setter-exec.test.js:16:16) - at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-loose-get-only-setter-exec.test.js:19:13 +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-loose-helper-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-loose-reassignment-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-loose-set-only-getter-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-loose-updates-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsProperties-basic-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsProperties-class-binding-exec.test.js +Private field '#getA' must be declared in an enclosing class ./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsProperties-get-only-setter-exec.test.js -TypeError: '#privateFieldValue' was defined without a getter - at new Cl (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsProperties-get-only-setter-exec.test.js:16:16) - at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsProperties-get-only-setter-exec.test.js:19:13 +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsProperties-helper-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsProperties-set-only-getter-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsProperties-updates-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsSymbols-basic-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsSymbols-class-binding-exec.test.js +Private field '#getA' must be declared in an enclosing class ./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsSymbols-get-only-setter-exec.test.js -TypeError: '#privateFieldValue' was defined without a getter - at new Cl (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsSymbols-get-only-setter-exec.test.js:13:16) - at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsSymbols-get-only-setter-exec.test.js:16:13 +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsSymbols-helper-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsSymbols-set-only-getter-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-privateFieldsAsSymbols-updates-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-reassignment-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-set-only-getter-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-tagged-template-exec.test.js +Private field '#tag' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-updates-bigint-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-accessors-updates-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-assignment-exec.test.js +Private field '#privateMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-before-fields-exec.test.js +Private field '#method' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-class-binding-exec.test.js +Private field '#getA' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-context-exec.test.js +Private field '#getStatus' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-exfiltrated-exec.test.js +Private field '#privateMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-generator-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-loose-assignment-exec.test.js +Private field '#privateMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-loose-before-fields-exec.test.js +Private field '#method' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-loose-class-binding-exec.test.js +Private field '#getA' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-loose-context-exec.test.js +Private field '#getStatus' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-loose-exfiltrated-exec.test.js +Private field '#privateMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-loose-generator-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-loose-reassignment-exec.test.js +Private field '#privateMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-loose-super-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsProperties-assignment-exec.test.js +Private field '#privateMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsProperties-before-fields-exec.test.js +Private field '#method' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsProperties-class-binding-exec.test.js +Private field '#getA' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsProperties-context-exec.test.js +Private field '#getStatus' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsProperties-exfiltrated-exec.test.js +Private field '#privateMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsProperties-generator-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsProperties-super-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsSymbols-assignment-exec.test.js +Private field '#privateMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsSymbols-before-fields-exec.test.js +Private field '#method' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsSymbols-class-binding-exec.test.js +Private field '#getA' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsSymbols-context-exec.test.js +Private field '#getStatus' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsSymbols-exfiltrated-exec.test.js +Private field '#privateMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsSymbols-generator-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-privateFieldsAsSymbols-super-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-read-only-exec.test.js +Private field '#method' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-reassignment-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-scopable-exec.test.js +Private field '#privateMethodA' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-super-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-method-tagged-template-exec.test.js +Private field '#tag' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-basic-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-class-check-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-exfiltrated-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-generator-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-loose-basic-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-loose-class-check-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-loose-exfiltrated-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-loose-generator-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-loose-reassignment-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-loose-scopable-exec.test.js +Private field '#privateMethodA' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-loose-super-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-loose-this-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsProperties-basic-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsProperties-class-check-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsProperties-exfiltrated-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsProperties-generator-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsProperties-reassignment-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsProperties-scopable-exec.test.js +Private field '#privateMethodA' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsProperties-super-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsProperties-this-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsSymbols-basic-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsSymbols-class-check-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsSymbols-exfiltrated-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsSymbols-generator-exec.test.js +Private field '#foo' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsSymbols-reassignment-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsSymbols-scopable-exec.test.js +Private field '#privateMethodA' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsSymbols-super-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-privateFieldsAsSymbols-this-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-read-only-exec.test.js +Private field '#method' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-reassignment-exec.test.js +Private field '#privateStaticMethod' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-scopable-exec.test.js +Private field '#privateMethodA' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-super-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-tagged-template-exec.test.js +Private field '#tag' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-private-static-method-this-exec.test.js +Invalid access to super + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-access-in-static-field-initializer-exec.test.js +Private field '#p' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-basic-exec.test.js +Private field '#privateStaticFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-destructure-set-exec.test.js +Private field '#p' must be declared in an enclosing class ./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-get-only-setter-exec.test.js -TypeError: '#privateStaticFieldValue' was defined without a getter - at Function.getPrivateStaticFieldValue (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-get-only-setter-exec.test.js:9:14) - at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-get-only-setter-exec.test.js:13:12 +Private field '#privateStaticFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-loose-access-in-static-field-initializer-exec.test.js +Private field '#p' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-loose-basic-exec.test.js +Private field '#privateStaticFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-loose-destructure-set-exec.test.js +Private field '#p' must be declared in an enclosing class ./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-loose-get-only-setter-exec.test.js -TypeError: '#privateStaticFieldValue' was defined without a getter - at Function.getPrivateStaticFieldValue (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-loose-get-only-setter-exec.test.js:12:14) - at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-loose-get-only-setter-exec.test.js:19:12 +Private field '#privateStaticFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-loose-set-only-getter-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-loose-updates-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsProperties-access-in-static-field-initializer-exec.test.js +Private field '#p' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsProperties-basic-exec.test.js +Private field '#privateStaticFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsProperties-destructure-set-exec.test.js +Private field '#p' must be declared in an enclosing class ./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsProperties-get-only-setter-exec.test.js -TypeError: '#privateStaticFieldValue' was defined without a getter - at Function.getPrivateStaticFieldValue (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsProperties-get-only-setter-exec.test.js:12:14) - at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsProperties-get-only-setter-exec.test.js:19:12 +Private field '#privateStaticFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsProperties-set-only-getter-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsProperties-updates-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsSymbols-access-in-static-field-initializer-exec.test.js +Private field '#p' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsSymbols-basic-exec.test.js +Private field '#privateStaticFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsSymbols-destructure-set-exec.test.js +Private field '#p' must be declared in an enclosing class ./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsSymbols-get-only-setter-exec.test.js -TypeError: '#privateStaticFieldValue' was defined without a getter - at Function.getPrivateStaticFieldValue (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsSymbols-get-only-setter-exec.test.js:9:14) - at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsSymbols-get-only-setter-exec.test.js:13:12 +Private field '#privateStaticFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsSymbols-set-only-getter-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-privateFieldsAsSymbols-updates-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-set-only-getter-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class + +./fixtures/babel/babel-plugin-transform-private-methods-test-fixtures-static-accessors-updates-exec.test.js +Private field '#privateFieldValue' must be declared in an enclosing class ./fixtures/babel/babel-preset-env-test-fixtures-plugins-integration-issue-15170-exec.test.js AssertionError: expected [Function] to not throw an error but 'ReferenceError: x is not defined' was thrown diff --git a/tasks/transform_conformance/snapshots/oxc.snap.md b/tasks/transform_conformance/snapshots/oxc.snap.md index 3e6f26612a974..db0f93fbcc0e6 100644 --- a/tasks/transform_conformance/snapshots/oxc.snap.md +++ b/tasks/transform_conformance/snapshots/oxc.snap.md @@ -1,6 +1,6 @@ commit: 54a8389f -Passed: 120/138 +Passed: 119/138 # All Passed: * babel-plugin-transform-class-static-block @@ -16,7 +16,10 @@ Passed: 120/138 * regexp -# babel-plugin-transform-class-properties (20/26) +# babel-plugin-transform-class-properties (19/26) +* private-field-resolve-to-method/input.js +x Output mismatch + * private-field-resolve-to-method-in-computed-key/input.js x Output mismatch diff --git a/tasks/transform_conformance/snapshots/oxc_exec.snap.md b/tasks/transform_conformance/snapshots/oxc_exec.snap.md index a6550f153a0d7..f2c7e0b449cf4 100644 --- a/tasks/transform_conformance/snapshots/oxc_exec.snap.md +++ b/tasks/transform_conformance/snapshots/oxc_exec.snap.md @@ -7,11 +7,7 @@ Passed: 3 of 5 (60.00%) Failures: ./fixtures/oxc/babel-plugin-transform-class-properties-test-fixtures-private-field-resolve-to-method-in-computed-key-exec.test.js -AssertionError: expected [Function] to throw an error - at Proxy. (./node_modules/.pnpm/@vitest+expect@2.1.2/node_modules/@vitest/expect/dist/index.js:1438:21) - at Proxy. (./node_modules/.pnpm/@vitest+expect@2.1.2/node_modules/@vitest/expect/dist/index.js:923:17) - at Proxy.methodWrapper (./node_modules/.pnpm/chai@5.1.2/node_modules/chai/chai.js:1610:25) - at ./tasks/transform_conformance/fixtures/oxc/babel-plugin-transform-class-properties-test-fixtures-private-field-resolve-to-method-in-computed-key-exec.test.js:84:33 +Private field '#shadowed' must be declared in an enclosing class ./fixtures/oxc/babel-plugin-transform-class-properties-test-fixtures-static-super-tagged-template-exec.test.js AssertionError: expected undefined to be [Function C] // Object.is equality