Skip to content

Commit 6c68455

Browse files
authored
Fix more variable deconflicting issues (#5728)
* Ensure we also include declared variables if they are included for a key or default side effect * Always include full array patterns
1 parent aaf38b7 commit 6c68455

File tree

15 files changed

+88
-9
lines changed

15 files changed

+88
-9
lines changed

src/ast/nodes/ArrayPattern.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,21 @@ export default class ArrayPattern extends NodeBase implements DeclarationPattern
8787
let included = false;
8888
const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
8989
for (const element of this.elements) {
90-
included =
91-
element?.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
90+
if (element) {
91+
element.included ||= included;
92+
included =
93+
element.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
94+
}
95+
}
96+
if (included) {
97+
// This is necessary so that if any pattern element is included, all are
98+
// included for proper deconflicting
99+
for (const element of this.elements) {
100+
if (element && !element.included) {
101+
element.included = true;
102+
element.includeDestructuredIfNecessary(context, includedPatternPath, init);
103+
}
104+
}
92105
}
93106
return (this.included ||= included);
94107
}

src/ast/nodes/AssignmentPattern.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ export default class AssignmentPattern extends NodeBase implements DeclarationPa
7070
this.included;
7171
if ((included ||= this.right.shouldBeIncluded(context))) {
7272
this.right.includePath(UNKNOWN_PATH, context, false);
73+
if (!this.left.included) {
74+
this.left.included = true;
75+
// Unfortunately, we need to include the left side again now, so that
76+
// any declared variables are properly included.
77+
this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init);
78+
}
7379
}
7480
return (this.included = included);
7581
}

src/ast/nodes/Property.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,18 @@ export default class Property extends MethodBase implements DeclarationPatternNo
7777
destructuredInitPath: ObjectPath,
7878
init: ExpressionEntity
7979
): boolean {
80+
const path = this.getPathInProperty(destructuredInitPath);
8081
let included =
81-
(this.value as PatternNode).includeDestructuredIfNecessary(
82-
context,
83-
this.getPathInProperty(destructuredInitPath),
84-
init
85-
) || this.included;
86-
included ||= this.key.hasEffects(createHasEffectsContext());
87-
if (included) {
82+
(this.value as PatternNode).includeDestructuredIfNecessary(context, path, init) ||
83+
this.included;
84+
if ((included ||= this.key.hasEffects(createHasEffectsContext()))) {
8885
this.key.includePath(EMPTY_PATH, context, false);
86+
if (!this.value.included) {
87+
this.value.included = true;
88+
// Unfortunately, we need to include the value again now, so that any
89+
// declared variables are properly included.
90+
(this.value as PatternNode).includeDestructuredIfNecessary(context, path, init);
91+
}
8992
}
9093
return (this.included = included);
9194
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = defineTest({
2+
description: 'makes sure to deconflict all variables in an array pattern if included'
3+
});
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const Foo = { ok: true };
2+
export { Foo as default };
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import bar from './dep.js';
2+
3+
const [Foo, Bar] = [1, 2];
4+
5+
assert.deepStrictEqual(bar, { ok: true });
6+
assert.deepStrictEqual(Bar, 2);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = defineTest({
2+
description:
3+
'makes sure to deconflict variables that are destructured for side effects in their array pattern default values only'
4+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const Foo = { ok: true };
2+
export { Foo as default };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import bar from './dep.js';
2+
let mutated = false;
3+
const [
4+
Foo = (() => {
5+
mutated = true;
6+
})()
7+
] = [];
8+
assert.ok(mutated);
9+
assert.deepStrictEqual(bar, { ok: true });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = defineTest({
2+
description:
3+
'makes sure to deconflict variables that are destructured for side effects in their default values only'
4+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const Foo = { ok: true };
2+
export { Foo as default };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import bar from './dep.js';
2+
let mutated = false;
3+
const {
4+
Foo = (() => {
5+
mutated = true;
6+
})()
7+
} = {};
8+
assert.ok(mutated);
9+
assert.deepStrictEqual(bar, { ok: true });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = defineTest({
2+
description:
3+
'makes sure to deconflict variables that are destructured for side effects in their key only'
4+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const Foo = { ok: true };
2+
export { Foo as default };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import bar from './dep.js';
2+
let mutated = false;
3+
const {
4+
[(() => {
5+
mutated = true;
6+
return 'Foo';
7+
})()]: Foo
8+
} = { Foo: true };
9+
assert.ok(mutated);
10+
assert.deepStrictEqual(bar, { ok: true });

0 commit comments

Comments
 (0)