Skip to content

Commit

Permalink
Merge branch 'main' into fix-define-span
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa authored Dec 13, 2024
2 parents 3ea1491 + 65b109a commit 6149889
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 21 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
2 changes: 2 additions & 0 deletions crates/oxc_transformer/src/es2022/class_properties/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
//! * `private_props.rs`: Structures storing details of private properties.
//! * `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.
//! * `utils.rs`: Utility functions.
//!
//! ## References
Expand Down Expand Up @@ -159,6 +160,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_static_member_expression(expr, self.ctx);
}
// `super[prop]`
Expression::ComputedMemberExpression(_) => {
self.class_properties.transform_computed_member_expression(expr, self.ctx);
}
// `object.#prop`
Expression::PrivateFieldExpression(_) => {
self.class_properties.transform_private_field_expression(expr, self.ctx);
Expand Down Expand Up @@ -453,7 +461,7 @@ impl<'a, 'ctx, 'v> StaticInitializerVisitor<'a, 'ctx, 'v> {
}

impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
fn get_temp_binding(&mut self, ctx: &mut TraverseCtx<'a>) -> &BoundIdentifier<'a> {
pub(super) fn get_temp_binding(&mut self, ctx: &mut TraverseCtx<'a>) -> &BoundIdentifier<'a> {
// `PrivateProps` is the source of truth for bindings if class has private props
// because other visitors which transform private fields may create a temp binding
// and store it on `PrivateProps`
Expand Down
83 changes: 83 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,83 @@
//! ES2022: Class Properties
//! Transform of `super` expressions.
use oxc_ast::ast::*;
use oxc_traverse::TraverseCtx;

use crate::Helper;

use super::ClassProperties;

impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
/// Transform static member expression where object is `super`.
///
/// `super.prop` -> `_superPropGet(_Class, "prop", _Class)`
//
// `#[inline]` so that compiler sees that `expr` is an `Expression::StaticMemberExpression`.
#[inline]
pub(super) fn transform_static_member_expression(
&mut self,
expr: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let Expression::StaticMemberExpression(member) = expr else { unreachable!() };
if matches!(member.object, Expression::Super(_)) {
*expr = self.transform_static_member_expression_impl(member, ctx);
}
}

fn transform_static_member_expression_impl(
&mut self,
member: &mut StaticMemberExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let property = &member.property;
let property =
ctx.ast.expression_string_literal(property.span, property.name.clone(), None);
self.create_super_prop_get(member.span, property, ctx)
}

/// Transform computed member expression where object is `super`.
///
/// `super[prop]` -> `_superPropGet(_Class, prop, _Class)`
//
// `#[inline]` so that compiler sees that `expr` is an `Expression::ComputedMemberExpression`.
#[inline]
pub(super) fn transform_computed_member_expression(
&mut self,
expr: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let Expression::ComputedMemberExpression(member) = expr else { unreachable!() };
if matches!(member.object, Expression::Super(_)) {
*expr = self.transform_computed_member_expression_impl(member, ctx);
}
}

fn transform_computed_member_expression_impl(
&mut self,
member: &mut ComputedMemberExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let property = ctx.ast.move_expression(&mut member.expression);
self.create_super_prop_get(member.span, property, ctx)
}

/// `_superPropGet(_Class, prop, _Class)`
fn create_super_prop_get(
&mut self,
span: Span,
property: Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let class_binding = self.get_temp_binding(ctx);
// `(_Class, prop, _Class)`
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)),
]);
// `_superPropGet(_Class, prop, _Class)`
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 6149889

Please sign in to comment.