Skip to content

Commit

Permalink
Fix more variable deconflicting issues (#5728)
Browse files Browse the repository at this point in the history
* Ensure we also include declared variables if they are included for a key or default side effect

* Always include full array patterns
  • Loading branch information
lukastaegert authored Nov 15, 2024
1 parent aaf38b7 commit 6c68455
Show file tree
Hide file tree
Showing 15 changed files with 88 additions and 9 deletions.
17 changes: 15 additions & 2 deletions src/ast/nodes/ArrayPattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,21 @@ export default class ArrayPattern extends NodeBase implements DeclarationPattern
let included = false;
const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
for (const element of this.elements) {
included =
element?.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
if (element) {
element.included ||= included;
included =
element.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
}
}
if (included) {
// This is necessary so that if any pattern element is included, all are
// included for proper deconflicting
for (const element of this.elements) {
if (element && !element.included) {
element.included = true;
element.includeDestructuredIfNecessary(context, includedPatternPath, init);
}
}
}
return (this.included ||= included);
}
Expand Down
6 changes: 6 additions & 0 deletions src/ast/nodes/AssignmentPattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ export default class AssignmentPattern extends NodeBase implements DeclarationPa
this.included;
if ((included ||= this.right.shouldBeIncluded(context))) {
this.right.includePath(UNKNOWN_PATH, context, false);
if (!this.left.included) {
this.left.included = true;
// Unfortunately, we need to include the left side again now, so that
// any declared variables are properly included.
this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init);
}
}
return (this.included = included);
}
Expand Down
17 changes: 10 additions & 7 deletions src/ast/nodes/Property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,18 @@ export default class Property extends MethodBase implements DeclarationPatternNo
destructuredInitPath: ObjectPath,
init: ExpressionEntity
): boolean {
const path = this.getPathInProperty(destructuredInitPath);
let included =
(this.value as PatternNode).includeDestructuredIfNecessary(
context,
this.getPathInProperty(destructuredInitPath),
init
) || this.included;
included ||= this.key.hasEffects(createHasEffectsContext());
if (included) {
(this.value as PatternNode).includeDestructuredIfNecessary(context, path, init) ||
this.included;
if ((included ||= this.key.hasEffects(createHasEffectsContext()))) {
this.key.includePath(EMPTY_PATH, context, false);
if (!this.value.included) {
this.value.included = true;
// Unfortunately, we need to include the value again now, so that any
// declared variables are properly included.
(this.value as PatternNode).includeDestructuredIfNecessary(context, path, init);
}
}
return (this.included = included);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = defineTest({
description: 'makes sure to deconflict all variables in an array pattern if included'
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const Foo = { ok: true };
export { Foo as default };
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import bar from './dep.js';

const [Foo, Bar] = [1, 2];

assert.deepStrictEqual(bar, { ok: true });
assert.deepStrictEqual(Bar, 2);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = defineTest({
description:
'makes sure to deconflict variables that are destructured for side effects in their array pattern default values only'
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const Foo = { ok: true };
export { Foo as default };
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import bar from './dep.js';
let mutated = false;
const [
Foo = (() => {
mutated = true;
})()
] = [];
assert.ok(mutated);
assert.deepStrictEqual(bar, { ok: true });
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = defineTest({
description:
'makes sure to deconflict variables that are destructured for side effects in their default values only'
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const Foo = { ok: true };
export { Foo as default };
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import bar from './dep.js';
let mutated = false;
const {
Foo = (() => {
mutated = true;
})()
} = {};
assert.ok(mutated);
assert.deepStrictEqual(bar, { ok: true });
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = defineTest({
description:
'makes sure to deconflict variables that are destructured for side effects in their key only'
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const Foo = { ok: true };
export { Foo as default };
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import bar from './dep.js';
let mutated = false;
const {
[(() => {
mutated = true;
return 'Foo';
})()]: Foo
} = { Foo: true };
assert.ok(mutated);
assert.deepStrictEqual(bar, { ok: true });

0 comments on commit 6c68455

Please sign in to comment.