Skip to content

Commit

Permalink
feat(transformer/class-properties): support for transforming `TaggedT…
Browse files Browse the repository at this point in the history
…emplateExpresssion` (#7504)

```js
"object.#prop`xyz`" -> "_classPrivateFieldGet(_prop, object).bind(object)`xyz`"
"object.obj.#prop`xyz`" -> "_classPrivateFieldGet(_prop, _object$obj = object.obj).bind(_object$obj)`xyz`"
```
  • Loading branch information
Dunqing committed Nov 27, 2024
1 parent 968863b commit 3539f56
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 125 deletions.
44 changes: 37 additions & 7 deletions crates/oxc_transformer/src/es2022/class_properties/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::mem;

use oxc_allocator::Box as ArenaBox;
use oxc_ast::ast::*;
use oxc_ast::{ast::*, NONE};
use oxc_span::SPAN;
use oxc_syntax::{
reference::{ReferenceFlags, ReferenceId},
Expand Down Expand Up @@ -829,20 +829,50 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {

/// Transform tagged template expression where tag is a private field.
///
/// "object.#prop`xyz`" -> "_classPrivateFieldGet(_prop, object).bind(object)`xyz`"
/// Instance prop:
/// * "object.#prop`xyz`"
/// -> "_classPrivateFieldGet(_prop, object).bind(object)`xyz`"
/// * "object.obj.#prop`xyz`"
/// -> "_classPrivateFieldGet(_prop, _object$obj = object.obj).bind(_object$obj)`xyz`"
///
/// Static prop:
/// * "object.#prop`xyz`"
/// -> "_assertClassBrand(Class, object, _prop)._.bind(object)`xyz`"
/// * "object.obj.#prop`xyz`"
/// -> "_assertClassBrand(Class, (_object$obj = object.obj), _prop)._.bind(_object$obj)`xyz`"
//
// `#[inline]` so that compiler sees that `expr` is an `Expression::TaggedTemplateExpression`
#[inline]
#[expect(clippy::unused_self)]
pub(super) fn transform_tagged_template_expression(
&mut self,
expr: &mut Expression<'a>,
_ctx: &mut TraverseCtx<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let Expression::TaggedTemplateExpression(_tagged_temp_expr) = expr else { unreachable!() };
let Expression::TaggedTemplateExpression(tagged_temp_expr) = expr else { unreachable!() };
let Expression::PrivateFieldExpression(field_expr) = &mut tagged_temp_expr.tag else {
return;
};
if let Some(tag) = self.transform_tagged_template_expression_impl(field_expr, ctx) {
tagged_temp_expr.tag = tag;
};
}

pub(super) fn transform_tagged_template_expression_impl(
&mut self,
field_expr: &mut PrivateFieldExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Option<Expression<'a>> {
let (callee, object) = self.transform_private_field_callee(field_expr, ctx)?;

// TODO: "object.#prop`xyz`"
// See `private/tagged-template` fixture.
// Return `<callee>.bind(object)`, to be substituted as tag of tagged template expression
let callee = Expression::from(ctx.ast.member_expression_static(
SPAN,
callee,
ctx.ast.identifier_name(SPAN, Atom::from("bind")),
false,
));
let arguments = ctx.ast.vec1(Argument::from(object));
Some(ctx.ast.expression_call(field_expr.span, callee, NONE, arguments, false))
}

/// Transform private field in assignment pattern.
Expand Down
7 changes: 2 additions & 5 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: 413/846
Passed: 414/846

# 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 (86/264)
# babel-plugin-transform-class-properties (87/264)
* assumption-constantSuper/complex-super-class/input.js
x Output mismatch

Expand Down Expand Up @@ -558,9 +558,6 @@ x Output mismatch
* private/super-expression/input.js
x Output mismatch

* private/tagged-template/input.js
x Output mismatch

* private-loose/assignment/input.js
x Output mismatch

Expand Down
Loading

0 comments on commit 3539f56

Please sign in to comment.