fix(transformer): exponentiation transform: fix temp var names (#6318)

Make naming of temp vars follow Babel. It wasn't apparent that our version of this transform was behaving differently from Babel because the Babel plugin has very few tests. The added tests replicate Babel's output.
This commit is contained in:
overlookmotel 2024-10-06 23:08:10 +00:00
parent c0e2fef0af
commit 3a4bcc77fc
7 changed files with 358 additions and 11 deletions

View file

@ -19,7 +19,11 @@ extend-exclude = [
"tasks/coverage/babel",
"tasks/coverage/test262",
"tasks/coverage/typescript",
"tasks/coverage/snapshots",
"tasks/prettier_conformance/prettier",
"tasks/prettier_conformance/snapshots",
"tasks/transform_conformance/tests/**/output.js",
"tasks/transform_conformance/snapshots",
]
[default]

View file

@ -37,7 +37,7 @@ use oxc_ast::{ast::*, NONE};
use oxc_semantic::{ReferenceFlags, SymbolFlags};
use oxc_span::SPAN;
use oxc_syntax::operator::{AssignmentOperator, BinaryOperator};
use oxc_traverse::{Traverse, TraverseCtx};
use oxc_traverse::{ast_operations::get_var_name_from_node, Traverse, TraverseCtx};
use crate::TransformCtx;
@ -151,7 +151,8 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
let reference = ctx.ast.expression_from_identifier_reference(
ctx.create_unbound_reference_id(SPAN, ident.name.clone(), ReferenceFlags::Read),
);
self.add_new_reference(reference, &mut nodes, ctx)
let name = ident.name.as_str();
self.add_new_reference(reference, name, &mut nodes, ctx)
};
let reference = ctx.ast.move_assignment_target(assign_target);
@ -228,6 +229,7 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
let mut obj = ctx.ast.move_expression(obj);
// If the object reference that we need to save is locally declared, evaluating it multiple times
// will not trigger getters or setters. `super` cannot be directly assigned, so use it directly too.
// TODO(improve-on-babel): We could also skip creating a temp var for `this.x **= 2`.
let needs_temp_var = match &obj {
Expression::Super(_) => false,
Expression::Identifier(ident) => {
@ -236,7 +238,8 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
_ => true,
};
if needs_temp_var {
obj = self.add_new_reference(obj, nodes, ctx);
let name = get_var_name_from_node(&obj);
obj = self.add_new_reference(obj, &name, nodes, ctx);
}
let computed = member_expr.is_computed();
@ -311,7 +314,8 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
if expr.is_literal() {
return expr;
}
self.add_new_reference(expr, nodes, ctx)
let name = get_var_name_from_node(&expr);
self.add_new_reference(expr, &name, nodes, ctx)
}
MemberExpression::StaticMemberExpression(expr) => {
ctx.ast.expression_string_literal(SPAN, expr.property.name.clone())
@ -324,14 +328,10 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
fn add_new_reference(
&mut self,
expr: Expression<'a>,
name: &str,
nodes: &mut Vec<'a, Expression<'a>>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let name = match expr {
Expression::Identifier(ref ident) => ident.name.clone().as_str(),
_ => "ref",
};
let binding = ctx.generate_uid_in_current_scope(name, SymbolFlags::FunctionScopedVariable);
// var _name;

View file

@ -1,17 +1,154 @@
commit: 3bcfee23
Passed: 57/66
Passed: 57/68
# All Passed:
* babel-plugin-transform-nullish-coalescing-operator
* babel-plugin-transform-optional-catch-binding
* babel-plugin-transform-exponentiation-operator
* babel-plugin-transform-arrow-functions
* babel-preset-typescript
* babel-plugin-transform-react-jsx-source
* regexp
# babel-plugin-transform-exponentiation-operator (2/4)
* assign-to-identifier/input.js
Reference flags mismatch for "x":
after transform: ReferenceId(6): ReferenceFlags(Write)
rebuilt : ReferenceId(2): ReferenceFlags(Read)
Reference flags mismatch for "_y":
after transform: ReferenceId(9): ReferenceFlags(Write)
rebuilt : ReferenceId(3): ReferenceFlags(Read | Write)
Reference flags mismatch for "_z":
after transform: ReferenceId(13): ReferenceFlags(Write)
rebuilt : ReferenceId(8): ReferenceFlags(Read | Write)
Reference flags mismatch for "_q":
after transform: ReferenceId(17): ReferenceFlags(Write)
rebuilt : ReferenceId(14): ReferenceFlags(Read | Write)
* assign-to-member-expression/input.js
Reference flags mismatch for "_obj$foo$bar":
after transform: ReferenceId(42): ReferenceFlags(Write)
rebuilt : ReferenceId(6): ReferenceFlags(Read | Write)
Reference flags mismatch for "_boundPropName":
after transform: ReferenceId(46): ReferenceFlags(Write)
rebuilt : ReferenceId(11): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundPropName":
after transform: ReferenceId(51): ReferenceFlags(Write)
rebuilt : ReferenceId(18): ReferenceFlags(Read | Write)
Reference flags mismatch for "_obj$foo2$bar":
after transform: ReferenceId(56): ReferenceFlags(Write)
rebuilt : ReferenceId(25): ReferenceFlags(Read | Write)
Reference flags mismatch for "_boundPropName2":
after transform: ReferenceId(58): ReferenceFlags(Write)
rebuilt : ReferenceId(27): ReferenceFlags(Read | Write)
Reference flags mismatch for "_obj$foo3$bar":
after transform: ReferenceId(63): ReferenceFlags(Write)
rebuilt : ReferenceId(34): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundPropName2":
after transform: ReferenceId(65): ReferenceFlags(Write)
rebuilt : ReferenceId(36): ReferenceFlags(Read | Write)
Reference flags mismatch for "_boundPropObj$foo$bar":
after transform: ReferenceId(70): ReferenceFlags(Write)
rebuilt : ReferenceId(43): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundPropObj$foo$b":
after transform: ReferenceId(75): ReferenceFlags(Write)
rebuilt : ReferenceId(50): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundObj":
after transform: ReferenceId(80): ReferenceFlags(Write)
rebuilt : ReferenceId(57): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundObj2":
after transform: ReferenceId(84): ReferenceFlags(Write)
rebuilt : ReferenceId(62): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundObj$foo$bar":
after transform: ReferenceId(88): ReferenceFlags(Write)
rebuilt : ReferenceId(67): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundObj3":
after transform: ReferenceId(92): ReferenceFlags(Write)
rebuilt : ReferenceId(72): ReferenceFlags(Read | Write)
Reference flags mismatch for "_boundPropName3":
after transform: ReferenceId(94): ReferenceFlags(Write)
rebuilt : ReferenceId(74): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundObj4":
after transform: ReferenceId(99): ReferenceFlags(Write)
rebuilt : ReferenceId(81): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundPropName3":
after transform: ReferenceId(101): ReferenceFlags(Write)
rebuilt : ReferenceId(83): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundObj$foo2$bar":
after transform: ReferenceId(106): ReferenceFlags(Write)
rebuilt : ReferenceId(90): ReferenceFlags(Read | Write)
Reference flags mismatch for "_boundPropName4":
after transform: ReferenceId(108): ReferenceFlags(Write)
rebuilt : ReferenceId(92): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundObj$foo3$bar":
after transform: ReferenceId(113): ReferenceFlags(Write)
rebuilt : ReferenceId(99): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundPropName4":
after transform: ReferenceId(115): ReferenceFlags(Write)
rebuilt : ReferenceId(101): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundObj5":
after transform: ReferenceId(120): ReferenceFlags(Write)
rebuilt : ReferenceId(108): ReferenceFlags(Read | Write)
Reference flags mismatch for "_boundPropObj2$foo$ba":
after transform: ReferenceId(122): ReferenceFlags(Write)
rebuilt : ReferenceId(110): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundObj6":
after transform: ReferenceId(127): ReferenceFlags(Write)
rebuilt : ReferenceId(117): ReferenceFlags(Read | Write)
Reference flags mismatch for "_unboundPropObj2$foo$":
after transform: ReferenceId(129): ReferenceFlags(Write)
rebuilt : ReferenceId(119): ReferenceFlags(Read | Write)
Reference flags mismatch for "_fn":
after transform: ReferenceId(134): ReferenceFlags(Write)
rebuilt : ReferenceId(126): ReferenceFlags(Read | Write)
Reference flags mismatch for "_fn$foo$bar":
after transform: ReferenceId(138): ReferenceFlags(Write)
rebuilt : ReferenceId(131): ReferenceFlags(Read | Write)
Reference flags mismatch for "_fn$prop":
after transform: ReferenceId(142): ReferenceFlags(Write)
rebuilt : ReferenceId(136): ReferenceFlags(Read | Write)
Reference flags mismatch for "_fn2":
after transform: ReferenceId(144): ReferenceFlags(Write)
rebuilt : ReferenceId(138): ReferenceFlags(Read | Write)
Reference flags mismatch for "_fn$prop2":
after transform: ReferenceId(149): ReferenceFlags(Write)
rebuilt : ReferenceId(145): ReferenceFlags(Read | Write)
Reference flags mismatch for "_ref":
after transform: ReferenceId(151): ReferenceFlags(Write)
rebuilt : ReferenceId(147): ReferenceFlags(Read | Write)
Reference flags mismatch for "_this":
after transform: ReferenceId(156): ReferenceFlags(Write)
rebuilt : ReferenceId(154): ReferenceFlags(Read | Write)
Reference flags mismatch for "_this$foo$bar":
after transform: ReferenceId(160): ReferenceFlags(Write)
rebuilt : ReferenceId(158): ReferenceFlags(Read | Write)
Reference flags mismatch for "_this2":
after transform: ReferenceId(164): ReferenceFlags(Write)
rebuilt : ReferenceId(162): ReferenceFlags(Read | Write)
Reference flags mismatch for "_this3":
after transform: ReferenceId(168): ReferenceFlags(Write)
rebuilt : ReferenceId(166): ReferenceFlags(Read | Write)
Reference flags mismatch for "_fn4$foo$bar$qux":
after transform: ReferenceId(170): ReferenceFlags(Write)
rebuilt : ReferenceId(167): ReferenceFlags(Read | Write)
Reference flags mismatch for "_this4":
after transform: ReferenceId(175): ReferenceFlags(Write)
rebuilt : ReferenceId(174): ReferenceFlags(Read | Write)
Reference flags mismatch for "_this$foo$bar2":
after transform: ReferenceId(179): ReferenceFlags(Write)
rebuilt : ReferenceId(178): ReferenceFlags(Read | Write)
Reference flags mismatch for "_this5":
after transform: ReferenceId(183): ReferenceFlags(Write)
rebuilt : ReferenceId(182): ReferenceFlags(Read | Write)
Reference flags mismatch for "_this6":
after transform: ReferenceId(187): ReferenceFlags(Write)
rebuilt : ReferenceId(186): ReferenceFlags(Read | Write)
Reference flags mismatch for "_fn4$foo$bar$qux2":
after transform: ReferenceId(189): ReferenceFlags(Write)
rebuilt : ReferenceId(187): ReferenceFlags(Read | Write)
# babel-plugin-transform-typescript (1/8)
* class-property-definition/input.ts
Unresolved references mismatch:

View file

@ -0,0 +1,5 @@
let x, fn;
x **= 2;
y **= 3;
z **= fn();
q **= unboundFn();

View file

@ -0,0 +1,6 @@
var _y, _z, _q;
let x, fn;
x = Math.pow(x, 2);
_y = y, y = Math.pow(_y, 3);
_z = z, z = Math.pow(_z, fn());
_q = q, q = Math.pow(_q, unboundFn());

View file

@ -0,0 +1,54 @@
// Bound root of member expression
let obj;
obj.prop **= 2;
obj['prop blah'] **= 3;
obj.foo.bar.qux **= 4;
let boundPropName;
obj[boundPropName] **= 5;
obj[unboundPropName] **= 6;
let boundPropName2;
obj.foo2.bar2[boundPropName2] **= 7;
obj.foo3.bar3[unboundPropName2] **= 8;
let boundPropObj;
obj[boundPropObj.foo.bar.qux] **= 9;
obj[unboundPropObj.foo.bar.qux] **= 10;
// Unbound root of member expression
unboundObj.prop **= 11;
unboundObj['prop blah'] **= 12;
unboundObj.foo.bar.qux **= 13;
let boundPropName3;
unboundObj[boundPropName3] **= 14;
unboundObj[unboundPropName3] **= 15;
let boundPropName4;
unboundObj.foo2.bar2[boundPropName4] **= 16;
unboundObj.foo3.bar3[unboundPropName4] **= 17;
let boundPropObj2;
unboundObj[boundPropObj2.foo.bar.qux] **= 18;
unboundObj[unboundPropObj2.foo.bar.qux] **= 19;
// Other expressions
let fn, fn2;
fn().prop **= 20;
fn().foo().bar().qux **= 21;
fn().prop[fn2()] **= 22;
fn().prop[fn3().foo().bar().qux() + ' junk'] **= 23;
// `this`
this.prop **= 24;
this.foo.bar.qux **= 25;
this['prop blah'] **= 26;
this[fn4().foo.bar.qux()] **= 27;
function outer() {
this.prop **= 28;
this.foo.bar.qux **= 29;
this['prop blah'] **= 30;
this[fn4().foo.bar.qux()] **= 31;
}

View file

@ -0,0 +1,141 @@
var _obj$foo$bar,
_boundPropName,
_unboundPropName,
_obj$foo2$bar,
_boundPropName2,
_obj$foo3$bar,
_unboundPropName2,
_boundPropObj$foo$bar,
_unboundPropObj$foo$b,
_unboundObj,
_unboundObj2,
_unboundObj$foo$bar,
_unboundObj3,
_boundPropName3,
_unboundObj4,
_unboundPropName3,
_unboundObj$foo2$bar,
_boundPropName4,
_unboundObj$foo3$bar,
_unboundPropName4,
_unboundObj5,
_boundPropObj2$foo$ba,
_unboundObj6,
_unboundPropObj2$foo$,
_fn,
_fn$foo$bar,
_fn$prop,
_fn2,
_fn$prop2,
_ref,
_this,
_this$foo$bar,
_this2,
_this3,
_fn4$foo$bar$qux;
// Bound root of member expression
let obj;
obj["prop"] = Math.pow(obj["prop"], 2);
obj["prop blah"] = Math.pow(obj["prop blah"], 3);
(_obj$foo$bar = obj.foo.bar),
(_obj$foo$bar["qux"] = Math.pow(_obj$foo$bar["qux"], 4));
let boundPropName;
(_boundPropName = boundPropName),
(obj[_boundPropName] = Math.pow(obj[_boundPropName], 5));
(_unboundPropName = unboundPropName),
(obj[_unboundPropName] = Math.pow(obj[_unboundPropName], 6));
let boundPropName2;
(_obj$foo2$bar = obj.foo2.bar2),
(_boundPropName2 = boundPropName2),
(_obj$foo2$bar[_boundPropName2] = Math.pow(
_obj$foo2$bar[_boundPropName2],
7
));
(_obj$foo3$bar = obj.foo3.bar3),
(_unboundPropName2 = unboundPropName2),
(_obj$foo3$bar[_unboundPropName2] = Math.pow(
_obj$foo3$bar[_unboundPropName2],
8
));
let boundPropObj;
(_boundPropObj$foo$bar = boundPropObj.foo.bar.qux),
(obj[_boundPropObj$foo$bar] = Math.pow(obj[_boundPropObj$foo$bar], 9));
(_unboundPropObj$foo$b = unboundPropObj.foo.bar.qux),
(obj[_unboundPropObj$foo$b] = Math.pow(obj[_unboundPropObj$foo$b], 10));
// Unbound root of member expression
(_unboundObj = unboundObj),
(_unboundObj["prop"] = Math.pow(_unboundObj["prop"], 11));
(_unboundObj2 = unboundObj),
(_unboundObj2["prop blah"] = Math.pow(_unboundObj2["prop blah"], 12));
(_unboundObj$foo$bar = unboundObj.foo.bar),
(_unboundObj$foo$bar["qux"] = Math.pow(_unboundObj$foo$bar["qux"], 13));
let boundPropName3;
(_unboundObj3 = unboundObj),
(_boundPropName3 = boundPropName3),
(_unboundObj3[_boundPropName3] = Math.pow(_unboundObj3[_boundPropName3], 14));
(_unboundObj4 = unboundObj),
(_unboundPropName3 = unboundPropName3),
(_unboundObj4[_unboundPropName3] = Math.pow(
_unboundObj4[_unboundPropName3],
15
));
let boundPropName4;
(_unboundObj$foo2$bar = unboundObj.foo2.bar2),
(_boundPropName4 = boundPropName4),
(_unboundObj$foo2$bar[_boundPropName4] = Math.pow(
_unboundObj$foo2$bar[_boundPropName4],
16
));
(_unboundObj$foo3$bar = unboundObj.foo3.bar3),
(_unboundPropName4 = unboundPropName4),
(_unboundObj$foo3$bar[_unboundPropName4] = Math.pow(
_unboundObj$foo3$bar[_unboundPropName4],
17
));
let boundPropObj2;
(_unboundObj5 = unboundObj),
(_boundPropObj2$foo$ba = boundPropObj2.foo.bar.qux),
(_unboundObj5[_boundPropObj2$foo$ba] = Math.pow(
_unboundObj5[_boundPropObj2$foo$ba],
18
));
(_unboundObj6 = unboundObj),
(_unboundPropObj2$foo$ = unboundPropObj2.foo.bar.qux),
(_unboundObj6[_unboundPropObj2$foo$] = Math.pow(
_unboundObj6[_unboundPropObj2$foo$],
19
));
// Other expressions
let fn, fn2;
(_fn = fn()), (_fn["prop"] = Math.pow(_fn["prop"], 20));
(_fn$foo$bar = fn().foo().bar()),
(_fn$foo$bar["qux"] = Math.pow(_fn$foo$bar["qux"], 21));
(_fn$prop = fn().prop),
(_fn2 = fn2()),
(_fn$prop[_fn2] = Math.pow(_fn$prop[_fn2], 22));
(_fn$prop2 = fn().prop),
(_ref = fn3().foo().bar().qux() + " junk"),
(_fn$prop2[_ref] = Math.pow(_fn$prop2[_ref], 23));
// `this`
(_this = this), (_this["prop"] = Math.pow(_this["prop"], 24));
(_this$foo$bar = this.foo.bar),
(_this$foo$bar["qux"] = Math.pow(_this$foo$bar["qux"], 25));
(_this2 = this), (_this2["prop blah"] = Math.pow(_this2["prop blah"], 26));
(_this3 = this),
(_fn4$foo$bar$qux = fn4().foo.bar.qux()),
(_this3[_fn4$foo$bar$qux] = Math.pow(_this3[_fn4$foo$bar$qux], 27));
function outer() {
var _this4, _this$foo$bar2, _this5, _this6, _fn4$foo$bar$qux2;
(_this4 = this), (_this4["prop"] = Math.pow(_this4["prop"], 28));
(_this$foo$bar2 = this.foo.bar),
(_this$foo$bar2["qux"] = Math.pow(_this$foo$bar2["qux"], 29));
(_this5 = this), (_this5["prop blah"] = Math.pow(_this5["prop blah"], 30));
(_this6 = this),
(_fn4$foo$bar$qux2 = fn4().foo.bar.qux()),
(_this6[_fn4$foo$bar$qux2] = Math.pow(_this6[_fn4$foo$bar$qux2], 31));
}