Skip to content

Commit

Permalink
feat(transformer/class-properties): transform super member expression…
Browse files Browse the repository at this point in the history
…s that are inside static prop initializer
  • Loading branch information
Dunqing committed Dec 12, 2024
1 parent 74bf141 commit db00404
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 20 deletions.
2 changes: 2 additions & 0 deletions crates/oxc_transformer/src/common/helper_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ pub enum Helper {
ToSetter,
ClassPrivateFieldLooseKey,
ClassPrivateFieldLooseBase,
SuperPropGet,
}

impl Helper {
Expand All @@ -181,6 +182,7 @@ impl Helper {
Self::ToSetter => "toSetter",
Self::ClassPrivateFieldLooseKey => "classPrivateFieldLooseKey",
Self::ClassPrivateFieldLooseBase => "classPrivateFieldLooseBase",
Self::SuperPropGet => "superPropGet",
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/oxc_transformer/src/es2022/class_properties/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ mod constructor;
mod private;
mod private_props;
mod static_prop_init;
mod supers;
mod utils;
use class_bindings::ClassBindings;
use private_props::PrivatePropsStack;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,14 @@ impl<'a, 'ctx, 'v> VisitMut<'a> for StaticInitializerVisitor<'a, 'ctx, 'v> {
}
}
}
// `super.prop`
Expression::StaticMemberExpression(_) => {
self.class_properties.transform_member_expresion(expr, self.ctx);

Check warning on line 205 in crates/oxc_transformer/src/es2022/class_properties/static_prop_init.rs

View workflow job for this annotation

GitHub Actions / Spell Check

"expresion" should be "expression".
}
// `super[prop]`
Expression::ComputedMemberExpression(_) => {
self.class_properties.transform_member_expresion(expr, self.ctx);

Check warning on line 209 in crates/oxc_transformer/src/es2022/class_properties/static_prop_init.rs

View workflow job for this annotation

GitHub Actions / Spell Check

"expresion" should be "expression".
}
// `object.#prop`
Expression::PrivateFieldExpression(_) => {
self.class_properties.transform_private_field_expression(expr, self.ctx);
Expand Down
76 changes: 76 additions & 0 deletions crates/oxc_transformer/src/es2022/class_properties/supers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//! ES2022: Class Properties
//! Transform of super member expressions.
use oxc_ast::ast::*;
use oxc_span::GetSpan;
use oxc_traverse::TraverseCtx;

use crate::Helper;

use super::ClassProperties;

impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
/// Transform member expression where object is a super.
///
/// - `super.prop` -> `_superPropGet(_classBinding, "prop", _classBinding)`
/// - `super[expr]` -> `_superPropGet(_classBinding, expr, _classBinding)`
//
// `#[inline]` so that compiler sees that `expr` is an `Expression::StaticMemberExpression`
// or `Expression::ComputedMemberExpression`.
#[inline]
pub fn transform_member_expresion(

Check warning on line 21 in crates/oxc_transformer/src/es2022/class_properties/supers.rs

View workflow job for this annotation

GitHub Actions / Spell Check

"expresion" should be "expression".
&mut self,
expr: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let member = expr.to_member_expression();
if matches!(member.object(), Expression::Super(_)) {
self.transform_member_expression_impl(expr, ctx);
}
}

fn transform_member_expression_impl(
&mut self,
expr: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let property = match expr {
// `super.prop` -> `"prop"`
Expression::StaticMemberExpression(member) => {
let property = &member.property;
ctx.ast.expression_string_literal(
property.span,
property.name.clone(),
Some(property.name.clone()),
)
}
// `super[expr]` -> `expr`
Expression::ComputedMemberExpression(member) => {
ctx.ast.move_expression(&mut member.expression)
}
Expression::PrivateFieldExpression(_) => {
unreachable!("`super` cannot access private fields")
}
_ => return,
};

*expr = self.create_super_prop_get(expr.span(), property, ctx);
}

// `_superPropGet(_classBinding, "prop", _classBinding)`
fn create_super_prop_get(
&mut self,
span: Span,
property: Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let class_binding = self.class_bindings.get_or_init_temp_binding(ctx);
// (_classBinding, "prop", _classBinding)
let arguments = ctx.ast.vec_from_array([
Argument::from(class_binding.create_read_expression(ctx)),
Argument::from(property),
Argument::from(class_binding.create_read_expression(ctx)),
]);
self.ctx.helper_call_expr(Helper::SuperPropGet, span, arguments, ctx)
}
}
20 changes: 11 additions & 9 deletions tasks/transform_conformance/snapshots/babel.snap.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
commit: 54a8389f

Passed: 562/927
Passed: 564/927

# All Passed:
* babel-plugin-transform-class-static-block
Expand Down Expand Up @@ -276,7 +276,7 @@ x Output mismatch
x Output mismatch


# babel-plugin-transform-class-properties (176/264)
# babel-plugin-transform-class-properties (178/264)
* assumption-constantSuper/complex-super-class/input.js
x Output mismatch

Expand Down Expand Up @@ -341,9 +341,6 @@ rebuilt : ScopeId(9): Some(ScopeId(8))
* 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

Expand Down Expand Up @@ -645,9 +642,6 @@ rebuilt : ScopeId(9): Some(ScopeId(8))
* public/static-infer-name/input.js
x Output mismatch

* public/static-super/input.js
x Output mismatch

* public/super-with-collision/input.js
x Output mismatch

Expand Down Expand Up @@ -713,7 +707,15 @@ x Output mismatch
x Output mismatch

* regression/6154/input.js
x Output mismatch
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
Expand Down
14 changes: 3 additions & 11 deletions tasks/transform_conformance/snapshots/babel_exec.snap.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ commit: 54a8389f

node: v22.12.0

Passed: 186 of 215 (86.51%)
Passed: 189 of 215 (87.91%)

Failures:

Expand All @@ -13,9 +13,6 @@ Failures:
AssertionError: expected '_Class' to be 'Foo' // Object.is equality
at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-assumption-setPublicClassFields-static-infer-name-exec.test.js:8:19

./fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-assumption-setPublicClassFields-static-super-exec.test.js
Invalid access to super

./fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-nested-class-super-call-in-decorator-exec.test.js
AssertionError: expected undefined to be 'hello' // Object.is equality
at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-nested-class-super-call-in-decorator-exec.test.js:21:28
Expand Down Expand Up @@ -98,22 +95,17 @@ AssertionError: expected [Function] to throw error including '@@toPrimitive must
at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-public-computed-toPrimitive-exec.test.js:37:5

./fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-public-delete-super-property-exec.test.js
Invalid access to super
AssertionError: expected function to throw an error, but it didn't
at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-public-delete-super-property-exec.test.js:25:5

./fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-public-loose-static-infer-name-exec.test.js
AssertionError: expected '_Class' to be 'Foo' // Object.is equality
at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-public-loose-static-infer-name-exec.test.js:8:19

./fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-public-loose-static-super-exec.test.js
Invalid access to super

./fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-public-static-infer-name-exec.test.js
AssertionError: expected '_Class' to be 'Foo' // Object.is equality
at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-public-static-infer-name-exec.test.js:9:19

./fixtures/babel/babel-plugin-transform-class-properties-test-fixtures-public-static-super-exec.test.js
Invalid access to super

./fixtures/babel/babel-plugin-transform-optional-chaining-test-fixtures-assumption-noDocumentAll-parenthesized-expression-member-call-exec.test.js
TypeError: Cannot read properties of undefined (reading 'x')
at m (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-optional-chaining-test-fixtures-assumption-noDocumentAll-parenthesized-expression-member-call-exec.test.js:10:16)
Expand Down

0 comments on commit db00404

Please sign in to comment.