Skip to content

Commit dadd6fe

Browse files
authored
fix: resolve computed_prop_# collision (#8418)
Fixes #8417 The issue is that unpack_destructuring in each blocks, await blocks, and @const tags were making computed_props independently. This causes computed_props_# to conflict when each blocks were used with @const tags, or await blocks and @const tags, or consecutive @const tags together. Therefore, one solution is to use component.get_unique_name to, well, make unique names and never get conflicts.
1 parent 95c4655 commit dadd6fe

File tree

5 files changed

+115
-21
lines changed

5 files changed

+115
-21
lines changed

src/compiler/compile/nodes/shared/Context.ts

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export type Context = DestructuredVariable | ComputedProperty;
1111

1212
interface ComputedProperty {
1313
type: 'ComputedProperty';
14-
property_name: string;
14+
property_name: Identifier;
1515
key: Expression | PrivateIdentifier;
1616
}
1717

@@ -30,8 +30,7 @@ export function unpack_destructuring({
3030
default_modifier = (node) => node,
3131
scope,
3232
component,
33-
context_rest_properties,
34-
number_of_computed_props = { n: 0 }
33+
context_rest_properties
3534
}: {
3635
contexts: Context[];
3736
node: Node;
@@ -40,10 +39,6 @@ export function unpack_destructuring({
4039
scope: TemplateScope;
4140
component: Component;
4241
context_rest_properties: Map<string, Node>;
43-
// we want to pass this by reference, as a sort of global variable, because
44-
// if we pass this by value, we could get computed_property_# variable collisions
45-
// when we deal with nested object destructuring
46-
number_of_computed_props?: { n: number };
4742
}) {
4843
if (!node) return;
4944

@@ -72,8 +67,7 @@ export function unpack_destructuring({
7267
default_modifier,
7368
scope,
7469
component,
75-
context_rest_properties,
76-
number_of_computed_props
70+
context_rest_properties
7771
});
7872
context_rest_properties.set((element.argument as Identifier).name, element);
7973
} else if (element && element.type === 'AssignmentPattern') {
@@ -93,8 +87,7 @@ export function unpack_destructuring({
9387
)}` as Node,
9488
scope,
9589
component,
96-
context_rest_properties,
97-
number_of_computed_props
90+
context_rest_properties
9891
});
9992
} else {
10093
unpack_destructuring({
@@ -104,8 +97,7 @@ export function unpack_destructuring({
10497
default_modifier,
10598
scope,
10699
component,
107-
context_rest_properties,
108-
number_of_computed_props
100+
context_rest_properties
109101
});
110102
}
111103
});
@@ -124,8 +116,7 @@ export function unpack_destructuring({
124116
default_modifier,
125117
scope,
126118
component,
127-
context_rest_properties,
128-
number_of_computed_props
119+
context_rest_properties
129120
});
130121
context_rest_properties.set((property.argument as Identifier).name, property);
131122
} else if (property.type === 'Property') {
@@ -136,8 +127,7 @@ export function unpack_destructuring({
136127

137128
if (property.computed) {
138129
// e.g { [computedProperty]: ... }
139-
const property_name = `computed_property_${number_of_computed_props.n}`;
140-
number_of_computed_props.n += 1;
130+
const property_name = component.get_unique_name('computed_property');
141131

142132
contexts.push({
143133
type: 'ComputedProperty',
@@ -178,8 +168,7 @@ export function unpack_destructuring({
178168
)}` as Node,
179169
scope,
180170
component,
181-
context_rest_properties,
182-
number_of_computed_props
171+
context_rest_properties
183172
});
184173
} else {
185174
// e.g. { property } or { property: newName }
@@ -190,8 +179,7 @@ export function unpack_destructuring({
190179
default_modifier,
191180
scope,
192181
component,
193-
context_rest_properties,
194-
number_of_computed_props
182+
context_rest_properties
195183
});
196184
}
197185
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export default {
2+
html: `
3+
<p>4, 12, 60</p>
4+
`,
5+
6+
async test({ component, target, assert }) {
7+
component.permutation = [2, 3, 1];
8+
await (component.promise1 = Promise.resolve({length: 1, width: 2, height: 3}));
9+
try {
10+
await (component.promise2 = Promise.reject({length: 97, width: 98, height: 99}));
11+
} catch (e) {
12+
// nothing
13+
}
14+
15+
assert.htmlEqual(target.innerHTML, `
16+
<p>2, 11, 2</p>
17+
<p>9506, 28811, 98</p>
18+
`);
19+
}
20+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<script>
2+
export let promise1 = {length: 5, width: 3, height: 4};
3+
export let promise2 = {length: 12, width: 5, height: 13};
4+
export let permutation = [1, 2, 3];
5+
6+
function calculate(length, width, height) {
7+
return {
8+
'1-Dimensions': [length, width, height],
9+
'2-Dimensions': [length * width, width * height, length * height],
10+
'3-Dimensions': [length * width * height, length + width + height, length * width + width * height + length * height]
11+
};
12+
}
13+
14+
const th = 'th';
15+
</script>
16+
17+
{#await promise1 then { length, width, height }}
18+
{@const { [0]: a, [1]: b, [2]: c } = permutation}
19+
{@const { [`${a}-Dimensions`]: { [c - 1]: first }, [`${b}-Dimensions`]: { [b - 1]: second }, [`${c}-Dimensions`]: { [a - 1]: third } } = calculate(length, width, height) }
20+
<p>{first}, {second}, {third}</p>
21+
{/await}
22+
23+
{#await promise2 catch { [`leng${th}`]: l, [`wid${th}`]: w, height: h }}
24+
{@const [a, b, c] = permutation}
25+
{@const { [`${a}-Dimensions`]: { [c - 1]: first }, [`${b}-Dimensions`]: { [b - 1]: second }, [`${c}-Dimensions`]: { [a - 1]: third } } = calculate(l, w, h) }
26+
<p>{first}, {second}, {third}</p>
27+
{/await}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export default {
2+
html: `
3+
<button>6, 12, 8, 24</button>
4+
<button>45, 35, 63, 315</button>
5+
<button>60, 48, 80, 480</button>
6+
`,
7+
8+
async test({ component, target, assert }) {
9+
component.boxes = [{ length: 10, width: 20, height: 30 }];
10+
11+
assert.htmlEqual(target.innerHTML,
12+
'<button>200, 600, 300, 6000</button>'
13+
);
14+
}
15+
};
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script>
2+
export let boxes = [
3+
{length: 2, width: 3, height: 4},
4+
{length: 9, width: 5, height: 7},
5+
{length: 10, width: 6, height: 8}
6+
];
7+
8+
function calculate(length, width, height) {
9+
return {
10+
twoDimensions: {
11+
bottomArea: length * width,
12+
sideArea1: width * height,
13+
sideArea2: length * height
14+
},
15+
threeDimensions: {
16+
volume: length * width * height
17+
}
18+
};
19+
}
20+
21+
export let dimension = 'Dimensions';
22+
function changeDimension() {
23+
dimension = 'DIMENSIONS';
24+
}
25+
26+
let area = 'Area';
27+
let th = 'th';
28+
</script>
29+
30+
{#each boxes as { [`leng${th}`]: length, [`wid${th}`]: width, height }}
31+
{@const {
32+
[`two${dimension}`]: areas,
33+
[`three${dimension}`]: {
34+
volume
35+
}
36+
} = calculate(length, width, height)}
37+
{@const {
38+
i = 1,
39+
[`bottom${area}`]: bottom,
40+
[`side${area}${i++}`]: sideone,
41+
[`side${area}${i++}`]: sidetwo
42+
} = areas}
43+
<button on:click={changeDimension}>{bottom}, {sideone}, {sidetwo}, {volume}</button>
44+
{/each}

0 commit comments

Comments
 (0)