From f4313c5d9549b047f00b36645e2e30b92d68217c Mon Sep 17 00:00:00 2001 From: overlookmotel Date: Wed, 18 Dec 2024 22:56:20 +0000 Subject: [PATCH] Correct `classes_stack` when nothing to transform --- .../src/es2022/class_properties/class.rs | 37 ++++++++++++++----- .../es2022/class_properties/class_details.rs | 2 + 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/crates/oxc_transformer/src/es2022/class_properties/class.rs b/crates/oxc_transformer/src/es2022/class_properties/class.rs index bdb6c70f5ce073..6397b77e48a94f 100644 --- a/crates/oxc_transformer/src/es2022/class_properties/class.rs +++ b/crates/oxc_transformer/src/es2022/class_properties/class.rs @@ -105,12 +105,6 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { } } - // Exit if nothing to transform - if instance_prop_count == 0 && !has_static_prop && !has_static_block { - self.classes_stack.push(ClassDetails::default()); - return; - } - // Determine if is a class declaration let is_declaration = match ctx.ancestor(1) { Ancestor::ExportDefaultDeclarationDeclaration(_) @@ -118,6 +112,17 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { grandparent => grandparent.is_via_statement(), }; + // Exit if nothing to transform + if instance_prop_count == 0 && !has_static_prop && !has_static_block { + self.classes_stack.push(ClassDetails { + is_declaration, + transform_required: false, + private_props: None, + bindings: ClassBindings::default(), + }); + return; + } + // Initialize class binding vars. // Static prop in class expression or anonymous `export default class {}` always require // temp var for class. Static prop in class declaration doesn't. @@ -152,6 +157,7 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { // Add entry to `classes_stack` self.classes_stack.push(ClassDetails { is_declaration, + transform_required: true, private_props: if private_props.is_empty() { None } else { Some(private_props) }, bindings: class_bindings, }); @@ -267,6 +273,13 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { return; } + // TODO: Refactor + if !class_details.transform_required { + debug_assert!(class_details.bindings.temp.is_none()); + self.classes_stack.pop(); + return; + } + // TODO: Comment explaining why class_details.bindings.static_private_fields_use_temp = true; @@ -367,6 +380,13 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { return; } + let class_details = self.current_class(); + if !class_details.transform_required { + debug_assert!(class_details.bindings.temp.is_none()); + self.classes_stack.pop(); + return; + } + // Transform static properties, remove static and instance properties, and move computed keys // to before class self.transform_class_on_exit_impl(class, ctx); @@ -393,9 +413,8 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> { expr_count += private_props.len(); } - if expr_count == 0 { - return; - } + // TODO: Why is this assertion failing sometimes? + // debug_assert!(expr_count > 0); expr_count += 1 + usize::from(class_details.bindings.temp.is_some()); diff --git a/crates/oxc_transformer/src/es2022/class_properties/class_details.rs b/crates/oxc_transformer/src/es2022/class_properties/class_details.rs index e77f85f0312771..91dc6c764fd854 100644 --- a/crates/oxc_transformer/src/es2022/class_properties/class_details.rs +++ b/crates/oxc_transformer/src/es2022/class_properties/class_details.rs @@ -12,6 +12,8 @@ use super::{ClassBindings, ClassProperties, FxIndexMap}; pub(super) struct ClassDetails<'a> { /// `true` for class declaration, `false` for class expression pub is_declaration: bool, + /// `true` if class requires no transformation + pub transform_required: bool, /// Private properties. /// Mapping private prop name to binding for temp var. /// This is then used as lookup when transforming e.g. `this.#x`.