Skip to content

Commit

Permalink
optimize: don't memoise non-root right when there is only one destruc…
Browse files Browse the repository at this point in the history
…turing in the left
  • Loading branch information
JLHwung committed Mar 29, 2022
1 parent 4eb651d commit 1274a18
Show file tree
Hide file tree
Showing 20 changed files with 69 additions and 68 deletions.
33 changes: 19 additions & 14 deletions packages/babel-plugin-proposal-destructuring-private/src/index.ts
Expand Up @@ -125,6 +125,7 @@ export default declare(function ({
declarator.init,
scope,
/* isAssignment */ false,
/* shouldPreserveCompletion */ false,
name => state.addHelper(name),
objectRestNoSymbols,
/* useBuiltIns */ true,
Expand All @@ -140,38 +141,42 @@ export default declare(function ({
const { node, scope, parent } = path;
if (!hasPrivateKeys(node.left)) return;
const assignments = [];
const shouldPreserveCompletion =
(!isExpressionStatement(parent) && !isSequenceExpression(parent)) ||
path.isCompletionRecord();
for (const { left, right } of transformPrivateKeyDestructuring(
// @ts-expect-error The left of an assignment expression must not be a RestElement
node.left,
node.right,
scope,
/* isAssignment */ true,
shouldPreserveCompletion,
name => state.addHelper(name),
objectRestNoSymbols,
/* useBuiltIns */ true,
)) {
assignments.push(assignmentExpression("=", left, right));
}
// preserve completion record
if (
(!isExpressionStatement(parent) && !isSequenceExpression(parent)) ||
path.isCompletionRecord()
) {
const { left } = assignments[0];
if (scope.isStatic(node.right)) {
if (shouldPreserveCompletion) {
const { left, right } = assignments[0];
// If node.right is right and left is an identifier, then the left is an effectively-constant memoised id
if (isIdentifier(left) && right === node.right) {
if (
!isIdentifier(assignments[assignments.length - 1].right, {
name: left.name,
})
) {
// If the last assignment does not end with left, then we push `left` as the completion value
assignments.push(cloneNode(left));
}
// do nothing as `left` is already at the end of assignments
} else {
const tempId = scope.generateDeclaredUidIdentifier("m");
assignments.unshift(
assignmentExpression("=", tempId, cloneNode(node.right)),
);
assignments.push(cloneNode(tempId));
} else if (
!isIdentifier(assignments[assignments.length - 1].right, {
name: left.name,
})
) {
// If node.right is non-static and then the left is an effectively-constant memoised id
// If the last assignment does not end with left, that we can safely reuse `left` as the completion value
assignments.push(cloneNode(left));
}
}

Expand Down
13 changes: 12 additions & 1 deletion packages/babel-plugin-proposal-destructuring-private/src/util.ts
Expand Up @@ -281,6 +281,8 @@ function rightWillBeReferencedOnce(left: LHS) {
case "Identifier":
case "ArrayPattern":
return true;
case "ObjectPattern":
return left.properties.length === 1;
default:
return false;
}
Expand All @@ -302,11 +304,13 @@ export function* transformPrivateKeyDestructuring(
right: t.Expression,
scope: Scope,
isAssignment: boolean,
shouldPreserveCompletion: boolean,
addHelper: File["addHelper"],
objectRestNoSymbols: boolean,
useBuiltIns: boolean,
): Generator<Transformed, void, void> {
const stack: Item[] = [];
const rootRight = right;
// The stack holds patterns that we don't known whether they contain private key
stack.push({
left,
Expand Down Expand Up @@ -353,7 +357,14 @@ export function* transformPrivateKeyDestructuring(
(index = indexPath.shift()) !== undefined ||
left.type === "AssignmentPattern"
) {
if (!rightWillBeReferencedOnce(left) && !scope.isStatic(right)) {
const isRightSafeToReuse =
// If we should preserve completion and the right is the rootRight, then the
// right is NOT safe to reuse because we will insert a new memoising statement
// in the AssignmentExpression visitor, which causes right to be referenced more
// than once
!(shouldPreserveCompletion && right === rootRight) &&
(rightWillBeReferencedOnce(left) || scope.isStatic(right));
if (!isRightSafeToReuse) {
const tempId = scope.generateUidIdentifier("m");
if (isAssignment) {
scope.push({ id: cloneNode(tempId) });
Expand Down
Expand Up @@ -9,10 +9,10 @@ var _x = {
};

(() => {
var _p, _m, _m2;
var _p, _m;

var x, z;
[..._p] = [C], _m = _p[0], _m2 = babelHelpers.classStaticPrivateFieldSpecGet(_m, C, _x), x = _m2 === void 0 ? 1 : _m2, z = babelHelpers.objectWithoutProperties(_p, _excluded);
[..._p] = [C], _m = babelHelpers.classStaticPrivateFieldSpecGet(_p[0], C, _x), x = _m === void 0 ? 1 : _m, z = babelHelpers.objectWithoutProperties(_p, _excluded);
result = {
x,
z
Expand Down
Expand Up @@ -19,8 +19,8 @@ var _z = {
babelHelpers.defineProperty(C, "self", C);

(() => {
var _p, _p2, _p3, _m, _p4, _m2, _m3;
var _p, _p2, _p3, _p4, _m;

let x, y, z;
[_p, _p2,, _p3] = [C, C], _m = _p === void 0 ? C.self : _p, x = babelHelpers.classStaticPrivateFieldSpecGet(_m, C, _x), [, _p4] = babelHelpers.classStaticPrivateFieldSpecGet(_p2, C, _y), _m2 = _p4 === void 0 ? C.self : _p4, _m3 = babelHelpers.classStaticPrivateFieldSpecGet(_m2, C, _z), y = _m3 === void 0 ? babelHelpers.classStaticPrivateMethodGet(C, C, _self).call(C) : _m3, z = _p3 === void 0 ? babelHelpers.classStaticPrivateFieldSpecGet(y, C, _y) : _p3;
[_p, _p2,, _p3] = [C, C], x = babelHelpers.classStaticPrivateFieldSpecGet(_p === void 0 ? C.self : _p, C, _x), [, _p4] = babelHelpers.classStaticPrivateFieldSpecGet(_p2, C, _y), _m = babelHelpers.classStaticPrivateFieldSpecGet(_p4 === void 0 ? C.self : _p4, C, _z), y = _m === void 0 ? babelHelpers.classStaticPrivateMethodGet(C, C, _self).call(C) : _m, z = _p3 === void 0 ? babelHelpers.classStaticPrivateFieldSpecGet(y, C, _y) : _p3;
})();
Expand Up @@ -5,7 +5,7 @@ let a;
class C {
static m(r = (_m2 = C, ({
a
} = babelHelpers.classStaticPrivateFieldSpecGet(C, C, _x)), _m2)) {}
} = babelHelpers.classStaticPrivateFieldSpecGet(_m2, C, _x)), _m2)) {}

}

Expand All @@ -24,7 +24,7 @@ var _x = {

(function f(r = (_m = C, ({
b
} = babelHelpers.classStaticPrivateFieldSpecGet(C, C, _x)), _m)) {})();
} = babelHelpers.classStaticPrivateFieldSpecGet(_m, C, _x)), _m)) {})();
})();

C.m();
Expand Up @@ -4,10 +4,10 @@ let result;
class C {
static #x;
static {
var _p, _m, _m2;
var _p, _m;

var x, z;
[..._p] = [C], _m = _p[0], _m2 = _m.#x, x = _m2 === void 0 ? 1 : _m2, z = babelHelpers.objectWithoutProperties(_p, _excluded);
[..._p] = [C], _m = _p[0].#x, x = _m === void 0 ? 1 : _m, z = babelHelpers.objectWithoutProperties(_p, _excluded);
result = {
x,
z
Expand Down
Expand Up @@ -9,9 +9,9 @@ class C {
}

static {
var _p, _p2, _p3, _m, _p4, _m2, _m3;
var _p, _p2, _p3, _p4, _m;

let x, y, z;
[_p, _p2,, _p3] = [this, this], _m = _p === void 0 ? C.self : _p, x = _m.#x, [, _p4] = _p2.#y, _m2 = _p4 === void 0 ? C.self : _p4, _m3 = _m2.#z, y = _m3 === void 0 ? C.#self() : _m3, z = _p3 === void 0 ? y.#y : _p3;
[_p, _p2,, _p3] = [this, this], x = (_p === void 0 ? C.self : _p).#x, [, _p4] = _p2.#y, _m = (_p4 === void 0 ? C.self : _p4).#z, y = _m === void 0 ? C.#self() : _m, z = _p3 === void 0 ? y.#y : _p3;
}
}
Expand Up @@ -14,13 +14,13 @@ class C {

(function f(r = (_m = C, ({
b
} = C.#x), _m)) {})();
} = _m.#x), _m)) {})();

}

static m(r = (_m2 = C, ({
a
} = C.#x), _m2)) {}
} = _m2.#x), _m2)) {}

}

Expand Down
Expand Up @@ -8,7 +8,7 @@ var _x = {
(() => {
let x, y;

for (_m = (_m2 = C, y = babelHelpers.classStaticPrivateFieldSpecGet(C, C, _x), _m2), x = babelHelpers.classStaticPrivateFieldSpecGet(_m, C, _x), _m;;) {
for (_m = (_m2 = C, y = babelHelpers.classStaticPrivateFieldSpecGet(_m2, C, _x), _m2), x = babelHelpers.classStaticPrivateFieldSpecGet(_m, C, _x), _m;;) {
var _m, _m2;

break;
Expand Down
Expand Up @@ -11,7 +11,7 @@ class C {
}

(() => {
for (_m = C, x = babelHelpers.classPrivateFieldGet(C, _x), _m;;) {
for (_m = C, x = babelHelpers.classPrivateFieldGet(_m, _x), _m;;) {
var _m;

break;
Expand Down
Expand Up @@ -8,8 +8,8 @@ var _x = {
(() => {
let y;

for (let _m = (_m2 = C, y = babelHelpers.classStaticPrivateFieldSpecGet(C, C, _x), _m2), x = babelHelpers.classStaticPrivateFieldSpecGet(_m, C, _x);;) {
var _m2;
for (let x = babelHelpers.classStaticPrivateFieldSpecGet((_m = C, y = babelHelpers.classStaticPrivateFieldSpecGet(_m, C, _x), _m), C, _x);;) {
var _m;

break;
}
Expand Down
Expand Up @@ -3,7 +3,7 @@ class C {
static {
let x, y;

for (_m = (_m2 = C, y = C.#x, _m2), x = _m.#x, _m;;) {
for (_m = (_m2 = C, y = _m2.#x, _m2), x = _m.#x, _m;;) {
var _m, _m2;

break;
Expand Down
@@ -1,7 +1,7 @@
class C {
#x;
static {
for (_m = this, x = this.#x, _m;;) {
for (_m = this, x = _m.#x, _m;;) {
var _m;

break;
Expand Down
Expand Up @@ -3,8 +3,8 @@ class C {
static {
let y;

for (let _m = (_m2 = C, y = C.#x, _m2), x = _m.#x;;) {
var _m2;
for (let x = (_m = C, y = _m.#x, _m).#x;;) {
var _m;

break;
}
Expand Down
Expand Up @@ -10,9 +10,8 @@ var _x = {

(() => {
var [..._p] = [C],
_m = _p[0],
_m2 = babelHelpers.classStaticPrivateFieldSpecGet(_m, C, _x),
x = _m2 === void 0 ? 1 : _m2,
_m = babelHelpers.classStaticPrivateFieldSpecGet(_p[0], C, _x),
x = _m === void 0 ? 1 : _m,
z = babelHelpers.objectWithoutProperties(_p, _excluded);

result = {
Expand Down
Expand Up @@ -20,11 +20,9 @@ babelHelpers.defineProperty(C, "self", C);

(() => {
var [_p, _p2,, _p3] = [C, C],
_m = _p === void 0 ? C.self : _p,
x = babelHelpers.classStaticPrivateFieldSpecGet(_m, C, _x),
x = babelHelpers.classStaticPrivateFieldSpecGet(_p === void 0 ? C.self : _p, C, _x),
[, _p4] = babelHelpers.classStaticPrivateFieldSpecGet(_p2, C, _y),
_m2 = _p4 === void 0 ? C.self : _p4,
_m3 = babelHelpers.classStaticPrivateFieldSpecGet(_m2, C, _z),
y = _m3 === void 0 ? babelHelpers.classStaticPrivateMethodGet(C, C, _self).call(C) : _m3,
_m = babelHelpers.classStaticPrivateFieldSpecGet(_p4 === void 0 ? C.self : _p4, C, _z),
y = _m === void 0 ? babelHelpers.classStaticPrivateMethodGet(C, C, _self).call(C) : _m,
z = _p3 === void 0 ? babelHelpers.classStaticPrivateFieldSpecGet(y, C, _y) : _p3;
})();
Expand Up @@ -2,13 +2,9 @@ class C {
static #x;
static {
var _m = [C, C, C, C],
_m2 = _m["0"],
w = _m2.#x,
_m3 = _m[1],
x = _m3.#x,
_m4 = _m[2n],
y = _m4.#x,
_m5 = _m[3m],
z = _m5.#x;
w = _m["0"].#x,
x = _m[1].#x,
y = _m[2n].#x,
z = _m[3m].#x;
}
}
Expand Up @@ -5,9 +5,8 @@ class C {
static #x;
static {
var [..._p] = [C],
_m = _p[0],
_m2 = _m.#x,
x = _m2 === void 0 ? 1 : _m2,
_m = _p[0].#x,
x = _m === void 0 ? 1 : _m,
z = babelHelpers.objectWithoutProperties(_p, _excluded);
result = {
x,
Expand Down
Expand Up @@ -10,13 +10,10 @@ class C {

static {
var [_p, _p2,, _p3] = [this, this],
_m = _p === void 0 ? C.self : _p,
x = _m.#x,
x = (_p === void 0 ? C.self : _p).#x,
[, _p4] = _p2.#y,
_m2 = _p4 === void 0 ? C.self : _p4,
_m3 = _m2.#z,
y = _m3 === void 0 ? C.#self() : _m3,
_m = (_p4 === void 0 ? C.self : _p4).#z,
y = _m === void 0 ? C.#self() : _m,
z = _p3 === void 0 ? y.#y : _p3;

}
}
Expand Up @@ -2,13 +2,9 @@ class C {
static #x;
static {
var _m = [C, C, C, C],
_m2 = _m["0"],
w = _m2.#x,
_m3 = _m[1],
x = _m3.#x,
_m4 = _m[2n],
y = _m4.#x,
_m5 = _m[3m],
z = _m5.#x;
w = _m["0"].#x,
x = _m[1].#x,
y = _m[2n].#x,
z = _m[3m].#x;
}
}

0 comments on commit 1274a18

Please sign in to comment.