mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
fix(transformer/class-properties): fix ScopeIds in instance prop initializers (#7823)
Code in instance property initializers moves from class body into constructor, or a `_super` function. Update parent `ScopeId`s for first level scopes in initializers.
This commit is contained in:
parent
e70deb9b48
commit
25bb6daa40
5 changed files with 86 additions and 260 deletions
|
|
@ -531,7 +531,10 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
|
|||
) {
|
||||
// Get value
|
||||
let value = match &mut prop.value {
|
||||
Some(value) => ctx.ast.move_expression(value),
|
||||
Some(value) => {
|
||||
self.transform_instance_initializer(value, ctx);
|
||||
ctx.ast.move_expression(value)
|
||||
}
|
||||
None => ctx.ast.void_0(SPAN),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
//! ES2022: Class Properties
|
||||
//! Transform of instance property initializers.
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use oxc_ast::{ast::*, visit::VisitMut};
|
||||
use oxc_syntax::scope::{ScopeFlags, ScopeId};
|
||||
use oxc_traverse::TraverseCtx;
|
||||
|
||||
use super::ClassProperties;
|
||||
|
||||
impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
|
||||
/// Transform instance property initializer.
|
||||
///
|
||||
/// Instance property initializers move from the class body into either class constructor,
|
||||
/// or a `_super` function. Change parent scope of first-level scopes in initializer to reflect this.
|
||||
pub(super) fn transform_instance_initializer(
|
||||
&mut self,
|
||||
value: &mut Expression<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
let mut updater = InstanceInitializerVisitor::new(self, ctx);
|
||||
updater.visit_expression(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Visitor to change parent scope of first-level scopes in instance property initializer.
|
||||
struct InstanceInitializerVisitor<'a, 'v> {
|
||||
/// Incremented when entering a scope, decremented when exiting it.
|
||||
/// Parent `ScopeId` should be updated when `scope_depth == 0`.
|
||||
scope_depth: u32,
|
||||
/// Parent scope
|
||||
parent_scope_id: ScopeId,
|
||||
/// `TraverseCtx` object.
|
||||
ctx: &'v mut TraverseCtx<'a>,
|
||||
}
|
||||
|
||||
impl<'a, 'v> InstanceInitializerVisitor<'a, 'v> {
|
||||
fn new(
|
||||
class_properties: &'v mut ClassProperties<'a, '_>,
|
||||
ctx: &'v mut TraverseCtx<'a>,
|
||||
) -> Self {
|
||||
let parent_scope_id = class_properties.instance_inits_scope_id;
|
||||
Self { scope_depth: 0, parent_scope_id, ctx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'v> VisitMut<'a> for InstanceInitializerVisitor<'a, 'v> {
|
||||
/// Update parent scope for first level of scopes.
|
||||
/// Convert scope to sloppy mode if `self.make_sloppy_mode == true`.
|
||||
fn enter_scope(&mut self, _flags: ScopeFlags, scope_id: &Cell<Option<ScopeId>>) {
|
||||
let scope_id = scope_id.get().unwrap();
|
||||
|
||||
// TODO: Not necessary to do this check for all scopes.
|
||||
// In JS, only `Function`, `ArrowFunctionExpression` or `Class` can be the first-level scope,
|
||||
// as all other types which have a scope are statements or `StaticBlock` which would need to be
|
||||
// inside a function or class. But some TS types with scopes could be first level via
|
||||
// e.g. `TaggedTemplateExpression::type_parameters`, which contains `TSType`.
|
||||
// Not sure if that matters though, as they'll be stripped out anyway by TS transform.
|
||||
if self.scope_depth == 0 {
|
||||
self.reparent_scope(scope_id);
|
||||
}
|
||||
self.scope_depth += 1;
|
||||
}
|
||||
|
||||
fn leave_scope(&mut self) {
|
||||
self.scope_depth -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'v> InstanceInitializerVisitor<'a, 'v> {
|
||||
/// Update parent of scope to scope above class.
|
||||
fn reparent_scope(&mut self, scope_id: ScopeId) {
|
||||
self.ctx.scopes_mut().change_parent_id(scope_id, Some(self.parent_scope_id));
|
||||
}
|
||||
}
|
||||
|
|
@ -130,6 +130,7 @@
|
|||
//! * `constructor.rs`: Insertion of property initializers into class constructor.
|
||||
//! * `private.rs`: Transform of private property usages (`this.#prop`).
|
||||
//! * `private_props.rs`: Structures storing details of private properties.
|
||||
//! * `instance_prop_init.rs`: Transform of instance property initializers.
|
||||
//! * `static_prop_init.rs`: Transform of static property initializers.
|
||||
//! * `class_bindings.rs`: Structure containing bindings for class name and temp var.
|
||||
//! * `super.rs`: Transform `super` expressions.
|
||||
|
|
@ -158,6 +159,7 @@ use crate::TransformCtx;
|
|||
mod class;
|
||||
mod class_bindings;
|
||||
mod constructor;
|
||||
mod instance_prop_init;
|
||||
mod private;
|
||||
mod private_props;
|
||||
mod static_prop_init;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
commit: 54a8389f
|
||||
|
||||
Passed: 564/927
|
||||
Passed: 578/927
|
||||
|
||||
# All Passed:
|
||||
* babel-plugin-transform-class-static-block
|
||||
|
|
@ -276,7 +276,7 @@ x Output mismatch
|
|||
x Output mismatch
|
||||
|
||||
|
||||
# babel-plugin-transform-class-properties (178/264)
|
||||
# babel-plugin-transform-class-properties (192/264)
|
||||
* assumption-constantSuper/complex-super-class/input.js
|
||||
x Output mismatch
|
||||
|
||||
|
|
@ -298,46 +298,6 @@ x Output mismatch
|
|||
* assumption-setPublicClassFields/constructor-collision/input.js
|
||||
x Output mismatch
|
||||
|
||||
* assumption-setPublicClassFields/foobar/input.js
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(3)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(2): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(3): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
|
||||
* assumption-setPublicClassFields/regression-T7364/input.mjs
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(7)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(7): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(2): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(3): [ScopeId(4), ScopeId(8)]
|
||||
rebuilt : ScopeId(4): [ScopeId(5)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(8): []
|
||||
rebuilt : ScopeId(5): [ScopeId(6)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(4): Some(ScopeId(3))
|
||||
rebuilt : ScopeId(6): Some(ScopeId(5))
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(5): [ScopeId(6), ScopeId(9)]
|
||||
rebuilt : ScopeId(7): [ScopeId(8)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(9): []
|
||||
rebuilt : ScopeId(8): [ScopeId(9)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(6): Some(ScopeId(5))
|
||||
rebuilt : ScopeId(9): Some(ScopeId(8))
|
||||
|
||||
* assumption-setPublicClassFields/static-infer-name/input.js
|
||||
x Output mismatch
|
||||
|
||||
|
|
@ -378,17 +338,6 @@ x Output mismatch
|
|||
* nested-class/super-property-in-decorator/input.js
|
||||
x Output mismatch
|
||||
|
||||
* private/call/input.js
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(3), ScopeId(4)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2), ScopeId(4)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(4): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(2): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
|
||||
* private/class-shadow-builtins/input.mjs
|
||||
x Output mismatch
|
||||
|
||||
|
|
@ -398,17 +347,6 @@ x Output mismatch
|
|||
* private/extracted-this/input.js
|
||||
x Output mismatch
|
||||
|
||||
* private/foobar/input.js
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(3)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(2): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(3): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
|
||||
* private/nested-class-computed-redeclared/input.js
|
||||
x Output mismatch
|
||||
|
||||
|
|
@ -439,52 +377,12 @@ x Output mismatch
|
|||
* private/parenthesized-optional-member-call-with-transform/input.js
|
||||
x Output mismatch
|
||||
|
||||
* private/regression-T7364/input.mjs
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(7)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(7): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(2): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(3): [ScopeId(4), ScopeId(8)]
|
||||
rebuilt : ScopeId(4): [ScopeId(5)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(8): []
|
||||
rebuilt : ScopeId(5): [ScopeId(6)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(4): Some(ScopeId(3))
|
||||
rebuilt : ScopeId(6): Some(ScopeId(5))
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(5): [ScopeId(6), ScopeId(9)]
|
||||
rebuilt : ScopeId(7): [ScopeId(8)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(9): []
|
||||
rebuilt : ScopeId(8): [ScopeId(9)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(6): Some(ScopeId(5))
|
||||
rebuilt : ScopeId(9): Some(ScopeId(8))
|
||||
|
||||
* private/static-infer-name/input.js
|
||||
x Output mismatch
|
||||
|
||||
* private/static-shadow/input.js
|
||||
x Output mismatch
|
||||
|
||||
* private-loose/call/input.js
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(3), ScopeId(4)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2), ScopeId(4)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(4): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(2): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
|
||||
* private-loose/class-shadow-builtins/input.mjs
|
||||
x Output mismatch
|
||||
|
||||
|
|
@ -494,17 +392,6 @@ x Output mismatch
|
|||
* private-loose/extracted-this/input.js
|
||||
x Output mismatch
|
||||
|
||||
* private-loose/foobar/input.js
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(3)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(2): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(3): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
|
||||
* private-loose/nested-class-computed-redeclared/input.js
|
||||
x Output mismatch
|
||||
|
||||
|
|
@ -573,17 +460,6 @@ x Output mismatch
|
|||
* private-loose/static-infer-name/input.js
|
||||
x Output mismatch
|
||||
|
||||
* public/call/input.js
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(3), ScopeId(4)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2), ScopeId(4)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(4): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(2): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
|
||||
* public/class-shadow-builtins/input.mjs
|
||||
x Output mismatch
|
||||
|
||||
|
|
@ -599,46 +475,6 @@ x Output mismatch
|
|||
* public/extracted-this/input.js
|
||||
x Output mismatch
|
||||
|
||||
* public/foobar/input.js
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(3)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(2): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(3): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
|
||||
* public/regression-T7364/input.mjs
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(7)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(7): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(2): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(3): [ScopeId(4), ScopeId(8)]
|
||||
rebuilt : ScopeId(4): [ScopeId(5)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(8): []
|
||||
rebuilt : ScopeId(5): [ScopeId(6)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(4): Some(ScopeId(3))
|
||||
rebuilt : ScopeId(6): Some(ScopeId(5))
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(5): [ScopeId(6), ScopeId(9)]
|
||||
rebuilt : ScopeId(7): [ScopeId(8)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(9): []
|
||||
rebuilt : ScopeId(8): [ScopeId(9)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(6): Some(ScopeId(5))
|
||||
rebuilt : ScopeId(9): Some(ScopeId(8))
|
||||
|
||||
* public/static-infer-name/input.js
|
||||
x Output mismatch
|
||||
|
||||
|
|
@ -654,46 +490,6 @@ x Output mismatch
|
|||
* public-loose/constructor-collision/input.js
|
||||
x Output mismatch
|
||||
|
||||
* public-loose/foobar/input.js
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(3)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(2): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(3): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
|
||||
* public-loose/regression-T7364/input.mjs
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(7)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(7): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(2): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(3): [ScopeId(4), ScopeId(8)]
|
||||
rebuilt : ScopeId(4): [ScopeId(5)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(8): []
|
||||
rebuilt : ScopeId(5): [ScopeId(6)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(4): Some(ScopeId(3))
|
||||
rebuilt : ScopeId(6): Some(ScopeId(5))
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(5): [ScopeId(6), ScopeId(9)]
|
||||
rebuilt : ScopeId(7): [ScopeId(8)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(9): []
|
||||
rebuilt : ScopeId(8): [ScopeId(9)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(6): Some(ScopeId(5))
|
||||
rebuilt : ScopeId(9): Some(ScopeId(8))
|
||||
|
||||
* public-loose/static-infer-name/input.js
|
||||
x Output mismatch
|
||||
|
||||
|
|
@ -706,17 +502,6 @@ x Output mismatch
|
|||
* regression/6153/input.js
|
||||
x Output mismatch
|
||||
|
||||
* regression/6154/input.js
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(3): [ScopeId(4), ScopeId(6)]
|
||||
rebuilt : ScopeId(3): [ScopeId(4)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(6): []
|
||||
rebuilt : ScopeId(4): [ScopeId(5)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(4): Some(ScopeId(3))
|
||||
rebuilt : ScopeId(5): Some(ScopeId(4))
|
||||
|
||||
* regression/7951/input.mjs
|
||||
x Output mismatch
|
||||
|
||||
|
|
@ -734,35 +519,6 @@ Symbol scope ID mismatch for "_bar":
|
|||
after transform: SymbolId(3): ScopeId(2)
|
||||
rebuilt : SymbolId(3): ScopeId(0)
|
||||
|
||||
* regression/T7364/input.mjs
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(7)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(7): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(2): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(3): [ScopeId(4), ScopeId(8)]
|
||||
rebuilt : ScopeId(4): [ScopeId(5)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(8): []
|
||||
rebuilt : ScopeId(5): [ScopeId(6)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(4): Some(ScopeId(3))
|
||||
rebuilt : ScopeId(6): Some(ScopeId(5))
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(5): [ScopeId(6), ScopeId(9)]
|
||||
rebuilt : ScopeId(7): [ScopeId(8)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(9): []
|
||||
rebuilt : ScopeId(8): [ScopeId(9)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(6): Some(ScopeId(5))
|
||||
rebuilt : ScopeId(9): Some(ScopeId(8))
|
||||
|
||||
|
||||
# babel-plugin-transform-nullish-coalescing-operator (5/12)
|
||||
* assumption-noDocumentAll/transform/input.js
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
commit: 54a8389f
|
||||
|
||||
Passed: 107/121
|
||||
Passed: 108/121
|
||||
|
||||
# All Passed:
|
||||
* babel-plugin-transform-class-static-block
|
||||
|
|
@ -16,18 +16,7 @@ Passed: 107/121
|
|||
* regexp
|
||||
|
||||
|
||||
# babel-plugin-transform-class-properties (8/11)
|
||||
* private-loose-tagged-template/input.js
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(1): [ScopeId(2), ScopeId(3), ScopeId(4)]
|
||||
rebuilt : ScopeId(1): [ScopeId(2), ScopeId(4)]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(4): []
|
||||
rebuilt : ScopeId(2): [ScopeId(3)]
|
||||
Scope parent mismatch:
|
||||
after transform: ScopeId(2): Some(ScopeId(1))
|
||||
rebuilt : ScopeId(3): Some(ScopeId(2))
|
||||
|
||||
# babel-plugin-transform-class-properties (9/11)
|
||||
* typescript/optional-call/input.ts
|
||||
Symbol reference IDs mismatch for "X":
|
||||
after transform: SymbolId(0): [ReferenceId(0), ReferenceId(2), ReferenceId(6), ReferenceId(11), ReferenceId(16)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue