diff --git a/crates/oxc_transformer/src/common/arrow_function_converter.rs b/crates/oxc_transformer/src/common/arrow_function_converter.rs index aeb7d4736d5159..c9b31fa62dbdf3 100644 --- a/crates/oxc_transformer/src/common/arrow_function_converter.rs +++ b/crates/oxc_transformer/src/common/arrow_function_converter.rs @@ -87,7 +87,10 @@ //! The Implementation based on //! -use rustc_hash::{FxHashMap, FxHashSet}; +use std::hash::BuildHasherDefault; + +use indexmap::IndexMap; +use rustc_hash::{FxHashSet, FxHasher}; use oxc_allocator::{Box as ArenaBox, String as ArenaString, Vec as ArenaVec}; use oxc_ast::{ast::*, NONE}; @@ -102,6 +105,8 @@ use oxc_traverse::{Ancestor, BoundIdentifier, Traverse, TraverseCtx}; use crate::EnvOptions; +type FxIndexMap = IndexMap>; + /// Mode for arrow function conversion #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ArrowFunctionConverterMode { @@ -129,7 +134,9 @@ pub struct ArrowFunctionConverter<'a> { this_var_stack: SparseStack>, arguments_var_stack: SparseStack>, renamed_arguments_symbol_ids: FxHashSet, - super_methods: Option, SuperMethodInfo<'a>>>, + // TODO(improve-on-babel): `FxHashMap` would suffice here. Iteration order is not important. + // Only using `FxIndexMap` for predictable iteration order to match Babel's output. + super_methods: Option, SuperMethodInfo<'a>>>, } impl<'a> ArrowFunctionConverter<'a> { @@ -187,7 +194,7 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> { self.arguments_var_stack.push(None); if self.is_async_only() && func.r#async && Self::is_class_method_like_ancestor(ctx.parent()) { - self.super_methods = Some(FxHashMap::default()); + self.super_methods = Some(FxIndexMap::default()); } } @@ -1163,7 +1170,7 @@ impl<'a> ArrowFunctionConverter<'a> { let is_class_method_like = Self::is_class_method_like_ancestor(ctx.parent()); let declarations_count = usize::from(arguments.is_some()) + if is_class_method_like { - self.super_methods.as_ref().map_or(0, FxHashMap::len) + self.super_methods.as_ref().map_or(0, FxIndexMap::len) } else { 0 } @@ -1183,7 +1190,7 @@ impl<'a> ArrowFunctionConverter<'a> { // `_superprop_getSomething = () => super.getSomething;` if is_class_method_like { if let Some(super_methods) = self.super_methods.as_mut() { - declarations.extend(super_methods.drain().map(|(_, super_method)| { + declarations.extend(super_methods.drain(..).map(|(_, super_method)| { Self::generate_super_method(target_scope_id, super_method, ctx) })); } diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/super/assign/output.js b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/super/assign/output.js index 1e69ce6904e0db..e00541768cb612 100644 --- a/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/super/assign/output.js +++ b/tasks/transform_conformance/tests/babel-plugin-transform-async-to-generator/test/fixtures/super/assign/output.js @@ -1,15 +1,15 @@ const Obj = { value: 0, method() { - var _superprop_getObject = () => super.object, - _superprop_set = (_prop, _value) => super[_prop] = _value, - _superprop_setValue = _value2 => super.value = _value2; + var _superprop_setValue = (_value) => (super.value = _value), + _superprop_set = (_prop, _value2) => (super[_prop] = _value2), + _superprop_getObject = () => super.object; return babelHelpers.asyncToGenerator(function* () { _superprop_setValue(true); () => { - _superprop_set('value', true); + _superprop_set("value", true); _superprop_getObject().value = true; }; })(); } -}; \ No newline at end of file +};