mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
feat(transformer/decorators): insert instanceBrand function (#2480)
This commit is contained in:
parent
7f867221ca
commit
3d008abacb
3 changed files with 122 additions and 16 deletions
|
|
@ -611,6 +611,20 @@ impl<'a> AstBuilder<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn private_in_expression(
|
||||||
|
&self,
|
||||||
|
span: Span,
|
||||||
|
left: PrivateIdentifier,
|
||||||
|
right: Expression<'a>,
|
||||||
|
) -> Expression<'a> {
|
||||||
|
Expression::PrivateInExpression(self.alloc(PrivateInExpression {
|
||||||
|
span,
|
||||||
|
left,
|
||||||
|
operator: BinaryOperator::In,
|
||||||
|
right,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn private_field_expression(
|
pub fn private_field_expression(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
|
||||||
|
|
@ -29,17 +29,30 @@ pub struct Decorators<'a> {
|
||||||
bitflags! {
|
bitflags! {
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct DecoratorFlags: u8 {
|
pub struct DecoratorFlags: u8 {
|
||||||
const Field = 0;
|
// flag is 0
|
||||||
const Accessor = 1;
|
const Field = 1 << 0;
|
||||||
const Method = 2;
|
// flag is 1
|
||||||
const Getter = 3;
|
const Accessor = 1 << 1;
|
||||||
const Setter = 4;
|
// flag is 2
|
||||||
const Static = 8;
|
const Method = 1 << 2;
|
||||||
const DecoratorsHaveThis = 16;
|
// flag is 3
|
||||||
|
const Getter = 1 << 3;
|
||||||
|
// flag is 4
|
||||||
|
const Setter = 1 << 4;
|
||||||
|
// flag is 8
|
||||||
|
const Static = 1 << 5;
|
||||||
|
// flag is 16
|
||||||
|
const DecoratorsHaveThis = 1 << 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DecoratorFlags {
|
impl DecoratorFlags {
|
||||||
|
pub fn is_setter(self) -> bool {
|
||||||
|
self.contains(Self::Setter)
|
||||||
|
}
|
||||||
|
pub fn is_static(self) -> bool {
|
||||||
|
self.contains(Self::Static)
|
||||||
|
}
|
||||||
pub fn get_flag_by_kind(kind: MethodDefinitionKind) -> Self {
|
pub fn get_flag_by_kind(kind: MethodDefinitionKind) -> Self {
|
||||||
match kind {
|
match kind {
|
||||||
MethodDefinitionKind::Method => Self::Method,
|
MethodDefinitionKind::Method => Self::Method,
|
||||||
|
|
@ -48,6 +61,28 @@ impl DecoratorFlags {
|
||||||
MethodDefinitionKind::Constructor => unreachable!(),
|
MethodDefinitionKind::Constructor => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn to_value(self) -> u8 {
|
||||||
|
if self.contains(DecoratorFlags::DecoratorsHaveThis) {
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
let mut value: u8 = 0;
|
||||||
|
if self.contains(DecoratorFlags::Accessor) {
|
||||||
|
value += 1;
|
||||||
|
}
|
||||||
|
if self.contains(DecoratorFlags::Method) {
|
||||||
|
value += 2;
|
||||||
|
}
|
||||||
|
if self.contains(DecoratorFlags::Getter) {
|
||||||
|
value += 3;
|
||||||
|
}
|
||||||
|
if self.contains(DecoratorFlags::Setter) {
|
||||||
|
value += 4;
|
||||||
|
}
|
||||||
|
if self.contains(DecoratorFlags::Static) {
|
||||||
|
value += 8;
|
||||||
|
}
|
||||||
|
value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, Deserialize)]
|
#[derive(Debug, Clone, Copy, Default, Deserialize)]
|
||||||
|
|
@ -297,6 +332,8 @@ impl<'a> Decorators<'a> {
|
||||||
let mut c_elements = self.ast.new_vec();
|
let mut c_elements = self.ast.new_vec();
|
||||||
let mut e_elements = self.ast.new_vec();
|
let mut e_elements = self.ast.new_vec();
|
||||||
|
|
||||||
|
let mut private_in_expressions = self.ast.new_vec();
|
||||||
|
|
||||||
let mut init_static_name = None;
|
let mut init_static_name = None;
|
||||||
|
|
||||||
// insert member decorators
|
// insert member decorators
|
||||||
|
|
@ -393,9 +430,9 @@ impl<'a> Decorators<'a> {
|
||||||
} else {
|
} else {
|
||||||
is_proto = true;
|
is_proto = true;
|
||||||
}
|
}
|
||||||
let mut flag = DecoratorFlags::get_flag_by_kind(def.kind).bits();
|
let mut flag = DecoratorFlags::get_flag_by_kind(def.kind);
|
||||||
if def.r#static {
|
if def.r#static {
|
||||||
flag += DecoratorFlags::Static.bits();
|
flag |= DecoratorFlags::Static;
|
||||||
}
|
}
|
||||||
|
|
||||||
def.decorators.iter().for_each(|decorator| {
|
def.decorators.iter().for_each(|decorator| {
|
||||||
|
|
@ -412,6 +449,54 @@ impl<'a> Decorators<'a> {
|
||||||
def.decorators.clear();
|
def.decorators.clear();
|
||||||
|
|
||||||
if def.key.is_private_identifier() {
|
if def.key.is_private_identifier() {
|
||||||
|
{
|
||||||
|
if flag.is_setter() && !flag.is_static() {
|
||||||
|
// _ => #a in _;
|
||||||
|
private_in_expressions.push(self.ast.arrow_expression(
|
||||||
|
SPAN,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
self.ast.formal_parameters(
|
||||||
|
SPAN,
|
||||||
|
FormalParameterKind::ArrowFormalParameters,
|
||||||
|
self.ast.new_vec_single(self.ast.formal_parameter(
|
||||||
|
SPAN,
|
||||||
|
self.ast.binding_pattern(
|
||||||
|
self.ast.binding_pattern_identifier(
|
||||||
|
BindingIdentifier::new(SPAN, "_".into()),
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
self.ast.new_vec(),
|
||||||
|
)),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
self.ast.function_body(
|
||||||
|
SPAN,
|
||||||
|
self.ast.new_vec(),
|
||||||
|
self.ast.new_vec_single(self.ast.expression_statement(
|
||||||
|
SPAN,
|
||||||
|
self.ast.private_in_expression(
|
||||||
|
SPAN,
|
||||||
|
PrivateIdentifier::new(
|
||||||
|
SPAN,
|
||||||
|
def.key.private_name().unwrap(),
|
||||||
|
),
|
||||||
|
self.ast.identifier_reference_expression(
|
||||||
|
IdentifierReference::new(SPAN, "_".into()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
name = self.get_unique_name(&if def.computed {
|
name = self.get_unique_name(&if def.computed {
|
||||||
"init_computedKey".into()
|
"init_computedKey".into()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -496,7 +581,7 @@ impl<'a> Decorators<'a> {
|
||||||
|
|
||||||
def.decorators.iter().for_each(|decorator| {
|
def.decorators.iter().for_each(|decorator| {
|
||||||
member_decorators_vec.push(ArrayExpressionElement::Expression(
|
member_decorators_vec.push(ArrayExpressionElement::Expression(
|
||||||
self.get_decorator_info(&def.key, None, flag.bits(), decorator),
|
self.get_decorator_info(&def.key, None, flag, decorator),
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
def.decorators.clear();
|
def.decorators.clear();
|
||||||
|
|
@ -630,6 +715,15 @@ impl<'a> Decorators<'a> {
|
||||||
None,
|
None,
|
||||||
)));
|
)));
|
||||||
arguments.push(class_decorators_argument);
|
arguments.push(class_decorators_argument);
|
||||||
|
if !private_in_expressions.is_empty() {
|
||||||
|
// classDecsHaveThis
|
||||||
|
arguments.push(Argument::Expression(self.ast.literal_number_expression(
|
||||||
|
// TODO: use correct number instead of `0`
|
||||||
|
self.ast.number_literal(SPAN, 0f64, "0", oxc_syntax::NumberBase::Decimal),
|
||||||
|
)));
|
||||||
|
// instanceBrand
|
||||||
|
arguments.extend(private_in_expressions.into_iter().map(Argument::Expression));
|
||||||
|
}
|
||||||
|
|
||||||
let mut call_expr = self.ast.call_expression(SPAN, callee, arguments, false, None);
|
let mut call_expr = self.ast.call_expression(SPAN, callee, arguments, false, None);
|
||||||
|
|
||||||
|
|
@ -754,7 +848,7 @@ impl<'a> Decorators<'a> {
|
||||||
&self,
|
&self,
|
||||||
key: &PropertyKey<'a>,
|
key: &PropertyKey<'a>,
|
||||||
value: Option<Box<'a, Function<'a>>>,
|
value: Option<Box<'a, Function<'a>>>,
|
||||||
flag: u8,
|
flag: DecoratorFlags,
|
||||||
decorator: &Decorator<'a>,
|
decorator: &Decorator<'a>,
|
||||||
) -> Expression<'a> {
|
) -> Expression<'a> {
|
||||||
let name = key.name();
|
let name = key.name();
|
||||||
|
|
@ -766,7 +860,7 @@ impl<'a> Decorators<'a> {
|
||||||
self.ast.literal_number_expression(NumericLiteral::new(
|
self.ast.literal_number_expression(NumericLiteral::new(
|
||||||
SPAN,
|
SPAN,
|
||||||
0f64,
|
0f64,
|
||||||
self.ast.new_str(flag.to_string().as_str()),
|
self.ast.new_str(flag.to_value().to_string().as_str()),
|
||||||
oxc_syntax::NumberBase::Decimal,
|
oxc_syntax::NumberBase::Decimal,
|
||||||
)),
|
)),
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
Passed: 344/1369
|
Passed: 346/1369
|
||||||
|
|
||||||
# All Passed:
|
# All Passed:
|
||||||
* babel-plugin-transform-numeric-separator
|
* babel-plugin-transform-numeric-separator
|
||||||
|
|
@ -911,7 +911,7 @@ Passed: 344/1369
|
||||||
* spread-transform/transform-to-babel-extend/input.js
|
* spread-transform/transform-to-babel-extend/input.js
|
||||||
* spread-transform/transform-to-object-assign/input.js
|
* spread-transform/transform-to-object-assign/input.js
|
||||||
|
|
||||||
# babel-plugin-proposal-decorators (20/190)
|
# babel-plugin-proposal-decorators (22/190)
|
||||||
* 2018-09-transformation/async-generator-method/input.js
|
* 2018-09-transformation/async-generator-method/input.js
|
||||||
* 2018-09-transformation/class-decorators-yield-await/input.js
|
* 2018-09-transformation/class-decorators-yield-await/input.js
|
||||||
* 2021-12-accessors/context-name/input.js
|
* 2021-12-accessors/context-name/input.js
|
||||||
|
|
@ -1033,7 +1033,6 @@ Passed: 344/1369
|
||||||
* 2023-05-getters--to-es2015/public/input.js
|
* 2023-05-getters--to-es2015/public/input.js
|
||||||
* 2023-05-getters--to-es2015/static-private/input.js
|
* 2023-05-getters--to-es2015/static-private/input.js
|
||||||
* 2023-05-getters--to-es2015/static-public/input.js
|
* 2023-05-getters--to-es2015/static-public/input.js
|
||||||
* 2023-05-getters-and-setters/private/input.js
|
|
||||||
* 2023-05-getters-and-setters--to-es2015/private/input.js
|
* 2023-05-getters-and-setters--to-es2015/private/input.js
|
||||||
* 2023-05-getters-and-setters--to-es2015/public/input.js
|
* 2023-05-getters-and-setters--to-es2015/public/input.js
|
||||||
* 2023-05-getters-and-setters--to-es2015/static-private/input.js
|
* 2023-05-getters-and-setters--to-es2015/static-private/input.js
|
||||||
|
|
@ -1071,7 +1070,6 @@ Passed: 344/1369
|
||||||
* 2023-05-ordering/initializers-and-static-blocks/input.js
|
* 2023-05-ordering/initializers-and-static-blocks/input.js
|
||||||
* 2023-05-ordering--to-es2015/initializers-and-static-blocks/input.js
|
* 2023-05-ordering--to-es2015/initializers-and-static-blocks/input.js
|
||||||
* 2023-05-setters/context-name/input.js
|
* 2023-05-setters/context-name/input.js
|
||||||
* 2023-05-setters/private/input.js
|
|
||||||
* 2023-05-setters--to-es2015/context-name/input.js
|
* 2023-05-setters--to-es2015/context-name/input.js
|
||||||
* 2023-05-setters--to-es2015/private/input.js
|
* 2023-05-setters--to-es2015/private/input.js
|
||||||
* 2023-05-setters--to-es2015/public/input.js
|
* 2023-05-setters--to-es2015/public/input.js
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue