Skip to content

Commit

Permalink
refactor(transformer/decorators): if it is a private method definitio…
Browse files Browse the repository at this point in the history
…n, transform it (#2427)
  • Loading branch information
Dunqing authored Feb 19, 2024
1 parent 60db720 commit 27b2c21
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 77 deletions.
225 changes: 151 additions & 74 deletions crates/oxc_transformer/src/proposals/decorators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,23 @@ impl<'a> Decorators<'a> {
}

pub fn get_call_with_this(&self, name: Atom) -> Statement<'a> {
self.get_call_with_arguments(
name,
self.ast.new_vec_single(Argument::Expression(self.ast.this_expression(SPAN))),
)
}

pub fn get_call_with_arguments(
&self,
name: Atom,
arguments: Vec<'a, Argument<'a>>,
) -> Statement<'a> {
self.ast.expression_statement(
SPAN,
self.ast.call_expression(
SPAN,
self.ast.identifier_reference_expression(IdentifierReference::new(SPAN, name)),
self.ast.new_vec_single(Argument::Expression(self.ast.this_expression(SPAN))),
arguments,
false,
None,
),
Expand Down Expand Up @@ -373,6 +384,7 @@ impl<'a> Decorators<'a> {
let mut is_proto = false;
let mut is_static = false;

let mut name = Atom::new_inline("");
class.body.body.iter_mut().for_each(|element| {
if !element.has_decorator() {
return;
Expand All @@ -391,10 +403,71 @@ impl<'a> Decorators<'a> {

def.decorators.iter().for_each(|decorator| {
member_decorators_vec.push(ArrayExpressionElement::Expression(
self.get_decorator_info(&def.key, flag, decorator),
self.get_decorator_info(
&def.key,
Some(self.ast.copy(&def.value)),
flag,
decorator,
),
));
});

def.decorators.clear();

if def.key.is_private_identifier() {
name = self.get_unique_name(&if def.computed {
"init_computedKey".into()
} else {
format!("call_{}", def.key.name().unwrap()).into()
});

let mut arguments = self.ast.new_vec_with_capacity(2);
arguments.push(Argument::Expression(self.ast.this_expression(SPAN)));
arguments.push(Argument::Expression(
self.ast.identifier_reference_expression(IdentifierReference::new(
SPAN,
"v".into(),
)),
));
def.value = self.ast.function(
def.value.r#type,
def.value.span,
self.ast.copy(&def.value.id),
def.value.generator,
def.value.r#async,
self.ast.copy(&def.value.this_param),
self.ast.formal_parameters(
SPAN,
FormalParameterKind::FormalParameter,
self.ast.new_vec_single(self.ast.formal_parameter(
SPAN,
self.ast.binding_pattern(
self.ast.binding_pattern_identifier(
BindingIdentifier::new(SPAN, "v".into()),
),
None,
false,
),
None,
false,
self.ast.new_vec(),
)),
None,
),
Some(self.ast.function_body(
SPAN,
self.ast.new_vec(),
self.ast.new_vec_single(
self.get_call_with_arguments(name.clone(), arguments),
),
)),
self.ast.copy(&def.value.type_parameters),
self.ast.copy(&def.value.return_type),
self.ast.copy(&def.value.modifiers),
);
} else {
return;
}
}
ClassElement::PropertyDefinition(def) => {
let flag = if def.r#static {
Expand All @@ -403,18 +476,15 @@ impl<'a> Decorators<'a> {
DecoratorFlags::Field
};

let init_name = self.get_unique_name(&if def.computed {
name = self.get_unique_name(&if def.computed {
"init_computedKey".into()
} else {
format!("init_{}", def.key.name().unwrap()).into()
});

e_elements
.push(self.get_assignment_target_maybe_default(init_name.clone()));

def.decorators.iter().for_each(|decorator| {
member_decorators_vec.push(ArrayExpressionElement::Expression(
self.get_decorator_info(&def.key, flag.bits(), decorator),
self.get_decorator_info(&def.key, None, flag.bits(), decorator),
));
});
def.decorators.clear();
Expand All @@ -431,17 +501,18 @@ impl<'a> Decorators<'a> {
SPAN,
self.ast.identifier_reference_expression(IdentifierReference::new(
SPAN,
init_name.clone(),
name.clone(),
)),
arguments,
false,
None,
));

declarations.push(self.get_variable_declarator(init_name));
}
_ => {}
_ => return,
}

e_elements.push(self.get_assignment_target_maybe_default(name.clone()));
declarations.push(self.get_variable_declarator(name.clone()));
});

if is_proto {
Expand Down Expand Up @@ -668,6 +739,7 @@ impl<'a> Decorators<'a> {
fn get_decorator_info(
&self,
key: &PropertyKey<'a>,
value: Option<Box<'a, Function<'a>>>,
flag: u8,
decorator: &Decorator<'a>,
) -> Expression<'a> {
Expand All @@ -690,9 +762,13 @@ impl<'a> Decorators<'a> {
));

if key.is_private_identifier() {
// (o) => o.#a
let mut items =
self.ast.new_vec_single(self.ast.formal_parameter(
if let Some(value) = value {
decorator_elements.push(ArrayExpressionElement::Expression(
Expression::FunctionExpression(value),
));
} else {
// o => o.#a
let mut items = self.ast.new_vec_single(self.ast.formal_parameter(
SPAN,
self.ast.binding_pattern(
self.ast.binding_pattern_identifier(BindingIdentifier::new(
Expand All @@ -706,64 +782,21 @@ impl<'a> Decorators<'a> {
false,
self.ast.new_vec(),
));
let private_field = self.ast.private_field(
SPAN,
self.ast.identifier_reference_expression(IdentifierReference::new(
SPAN,
"o".into(),
)),
PrivateIdentifier::new(SPAN, name),
false,
);
let params = self.ast.formal_parameters(
SPAN,
FormalParameterKind::ArrowFormalParameters,
self.ast.copy(&items),
None,
);
decorator_elements.push(ArrayExpressionElement::Expression(
self.ast.arrow_expression(
let private_field = self.ast.private_field(
SPAN,
true,
false,
params,
self.ast.function_body(
self.ast.identifier_reference_expression(IdentifierReference::new(
SPAN,
self.ast.new_vec(),
self.ast.new_vec_single(self.ast.expression_statement(
SPAN,
self.ast.member_expression(self.ast.copy(&private_field)),
)),
),
None,
None,
),
));

{
// (o, v) => o.#a = v
items.push(self.ast.formal_parameter(
SPAN,
self.ast.binding_pattern(
self.ast.binding_pattern_identifier(BindingIdentifier::new(
SPAN,
"v".into(),
)),
None,
false,
),
None,
"o".into(),
)),
PrivateIdentifier::new(SPAN, name),
false,
self.ast.new_vec(),
));

);
let params = self.ast.formal_parameters(
SPAN,
FormalParameterKind::ArrowFormalParameters,
items,
self.ast.copy(&items),
None,
);

decorator_elements.push(ArrayExpressionElement::Expression(
self.ast.arrow_expression(
SPAN,
Expand All @@ -775,22 +808,66 @@ impl<'a> Decorators<'a> {
self.ast.new_vec(),
self.ast.new_vec_single(self.ast.expression_statement(
SPAN,
self.ast.assignment_expression(
SPAN,
AssignmentOperator::Assign,
self.ast.simple_assignment_target_member_expression(
private_field,
),
self.ast.identifier_reference_expression(
IdentifierReference::new(SPAN, "v".into()),
),
),
self.ast.member_expression(self.ast.copy(&private_field)),
)),
),
None,
None,
),
));

{
// (o, v) => o.#a = v
items.push(self.ast.formal_parameter(
SPAN,
self.ast.binding_pattern(
self.ast.binding_pattern_identifier(BindingIdentifier::new(
SPAN,
"v".into(),
)),
None,
false,
),
None,
false,
self.ast.new_vec(),
));

let params = self.ast.formal_parameters(
SPAN,
FormalParameterKind::ArrowFormalParameters,
items,
None,
);

decorator_elements.push(ArrayExpressionElement::Expression(
self.ast.arrow_expression(
SPAN,
true,
false,
params,
self.ast.function_body(
SPAN,
self.ast.new_vec(),
self.ast.new_vec_single(self.ast.expression_statement(
SPAN,
self.ast.assignment_expression(
SPAN,
AssignmentOperator::Assign,
self.ast.simple_assignment_target_member_expression(
private_field,
),
self.ast.identifier_reference_expression(
IdentifierReference::new(SPAN, "v".into()),
),
),
)),
),
None,
None,
),
));
}
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions tasks/transform_conformance/babel.snap.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Passed: 341/1369
Passed: 342/1369

# All Passed:
* babel-plugin-transform-numeric-separator
Expand Down Expand Up @@ -911,7 +911,7 @@ Passed: 341/1369
* spread-transform/transform-to-babel-extend/input.js
* spread-transform/transform-to-object-assign/input.js

# babel-plugin-proposal-decorators (17/190)
# babel-plugin-proposal-decorators (18/190)
* 2018-09-transformation/async-generator-method/input.js
* 2018-09-transformation/class-decorators-yield-await/input.js
* 2021-12-accessors/context-name/input.js
Expand Down Expand Up @@ -1074,7 +1074,6 @@ Passed: 341/1369
* 2023-05-ordering--to-es2015/initializers-and-static-blocks/input.js
* 2023-05-setters/context-name/input.js
* 2023-05-setters/private/input.js
* 2023-05-setters/static-private/input.js
* 2023-05-setters--to-es2015/context-name/input.js
* 2023-05-setters--to-es2015/private/input.js
* 2023-05-setters--to-es2015/public/input.js
Expand Down

0 comments on commit 27b2c21

Please sign in to comment.