Skip to content

Commit eca1a65

Browse files
[fix] better context checks for identifiers in const tags (#7222)
Fixes #7423 Fixes #7431 Fixes #7206 Fixes #7431 Fixes #7221 Co-authored-by: tanhauhau <[email protected]>
1 parent f6fd8e1 commit eca1a65

File tree

13 files changed

+337
-2
lines changed

13 files changed

+337
-2
lines changed

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

+8-2
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,17 @@ export default class Expression {
254254
const declaration = b`const ${id} = ${node}`;
255255

256256
if (owner.type === 'ConstTag') {
257+
let child_scope = scope;
257258
walk(node, {
258-
enter(node: Node) {
259-
if (node.type === 'Identifier') {
259+
enter(node: Node, parent: any) {
260+
if (map.has(node)) child_scope = map.get(node);
261+
if (node.type === 'Identifier' && is_reference(node, parent)) {
262+
if (child_scope.has(node.name)) return;
260263
this.replace(block.renderer.reference(node, ctx));
261264
}
265+
},
266+
leave(node: Node) {
267+
if (map.has(node)) child_scope = child_scope.parent;
262268
}
263269
});
264270
} else if (dependencies.size === 0 && contextual_dependencies.size === 0) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export default {
2+
html: `
3+
<p>0</p>
4+
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
5+
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
6+
`,
7+
async test({ component, target, assert }) {
8+
assert.htmlEqual(
9+
target.innerHTML,
10+
`
11+
<p>0</p>
12+
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
13+
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
14+
`
15+
);
16+
17+
component.nums = [1, 2, 3];
18+
19+
assert.htmlEqual(
20+
target.innerHTML,
21+
`
22+
<p>0</p>
23+
<p>bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1</p>
24+
<p>bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2</p>
25+
<p>bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3</p>
26+
`
27+
);
28+
}
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script>
2+
export let nums = [1, 2];
3+
let foos = [
4+
{
5+
nums: [1, 2, 3],
6+
},
7+
{
8+
nums: [0, 2, 4],
9+
},
10+
{
11+
nums: [-100, 0, 100],
12+
},
13+
];
14+
let foo = 0;
15+
</script>
16+
17+
<p>{foo}</p>
18+
{#each nums as num, index}
19+
{@const bar = nums.map((num) => {
20+
const func = (foos, num) => {
21+
return [...foos.map((foo) => foo), num];
22+
}
23+
return func(foos[index].nums, num);
24+
})}
25+
<p>bar: {bar}, num: {num}</p>
26+
{/each}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export default {
2+
html: `
3+
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
4+
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
5+
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
6+
`,
7+
async test({ component, target, assert }) {
8+
assert.htmlEqual(
9+
target.innerHTML,
10+
`
11+
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
12+
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
13+
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
14+
`
15+
);
16+
17+
component.nums = [1, 2, 3, 4];
18+
19+
assert.htmlEqual(
20+
target.innerHTML,
21+
`
22+
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
23+
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
24+
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
25+
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 4</p>
26+
`
27+
);
28+
}
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<script>
2+
export let nums = [1, 2, 3];
3+
let foos = [
4+
{
5+
nums: [1, 2, 3],
6+
},
7+
{
8+
nums: [0, 2, 4],
9+
},
10+
{
11+
nums: [-100, 0, 100],
12+
},
13+
];
14+
</script>
15+
16+
{#each nums as num}
17+
{@const bar = foos.map((foos) => foos.nums)}
18+
<p>bar: {bar}, num: {num}</p>
19+
{/each}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export default {
2+
html: `
3+
<p>foo: dummy-foo, num: dummy-num</p>
4+
<p>bar: 1,2,3,2,, num: 1</p>
5+
<p>bar: 1,2,3,2,, num: 2</p>
6+
<p>bar: 1,2,3,2,, num: 3</p>
7+
`,
8+
async test({ component, target, assert }) {
9+
assert.htmlEqual(
10+
target.innerHTML,
11+
`
12+
<p>foo: dummy-foo, num: dummy-num</p>
13+
<p>bar: 1,2,3,2,, num: 1</p>
14+
<p>bar: 1,2,3,2,, num: 2</p>
15+
<p>bar: 1,2,3,2,, num: 3</p>
16+
`
17+
);
18+
19+
component.nums = [1, 2, 3, 4];
20+
21+
assert.htmlEqual(
22+
target.innerHTML,
23+
`
24+
<p>foo: dummy-foo, num: dummy-num</p>
25+
<p>bar: 1,2,3,2,4,, num: 1</p>
26+
<p>bar: 1,2,3,2,4,, num: 2</p>
27+
<p>bar: 1,2,3,2,4,, num: 3</p>
28+
<p>bar: 1,2,3,2,4,, num: 4</p>
29+
`
30+
);
31+
}
32+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<script>
2+
export let nums = [1, 2, 3];
3+
let foos = [
4+
{
5+
nums: [1, 2, 3],
6+
},
7+
{
8+
nums: [0, 2, 4],
9+
},
10+
{
11+
nums: [-100, 0, 100],
12+
},
13+
];
14+
let default_nums = [-1];
15+
let foo = "dummy-foo";
16+
let num = "dummy-num";
17+
</script>
18+
19+
<p>foo: {foo}, num: {num}</p>
20+
{#each nums as num}
21+
{@const bar = foos.map((foo) =>
22+
foo.nums.filter((num) => {
23+
if (Object.keys($$slots).length) {
24+
return false;
25+
} else if (Object.keys(foo).length) {
26+
return nums.includes(num) || default_nums.includes(num);
27+
} else {
28+
return false;
29+
}
30+
}) || num
31+
)}
32+
<p>bar: {bar}, num: {num}</p>
33+
{/each}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export default {
2+
html: `
3+
<p>0</p>
4+
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
5+
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
6+
`,
7+
async test({ component, target, assert }) {
8+
assert.htmlEqual(
9+
target.innerHTML,
10+
`
11+
<p>0</p>
12+
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
13+
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
14+
`
15+
);
16+
17+
component.nums = [1, 2, 3];
18+
19+
assert.htmlEqual(
20+
target.innerHTML,
21+
`
22+
<p>0</p>
23+
<p>bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1</p>
24+
<p>bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2</p>
25+
<p>bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3</p>
26+
`
27+
);
28+
}
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<script>
2+
export let nums = [1, 2];
3+
let foos = [
4+
{
5+
nums: [1, 2, 3],
6+
},
7+
{
8+
nums: [0, 2, 4],
9+
},
10+
{
11+
nums: [-100, 0, 100],
12+
},
13+
];
14+
let foo = 0;
15+
</script>
16+
17+
<p>{foo}</p>
18+
{#each nums as num, index}
19+
{@const bar = nums.map((num) => {
20+
return (function (foos, num) {
21+
return [...foos.map((foo) => foo), num];
22+
})(foos[index].nums, num);
23+
})}
24+
<p>bar: {bar}, num: {num}</p>
25+
{/each}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export default {
2+
html: `
3+
<p>0</p>
4+
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
5+
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
6+
`,
7+
async test({ component, target, assert }) {
8+
assert.htmlEqual(
9+
target.innerHTML,
10+
`
11+
<p>0</p>
12+
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
13+
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
14+
`
15+
);
16+
17+
component.nums = [1, 2, 3];
18+
19+
assert.htmlEqual(
20+
target.innerHTML,
21+
`
22+
<p>0</p>
23+
<p>bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1</p>
24+
<p>bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2</p>
25+
<p>bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3</p>
26+
`
27+
);
28+
}
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script>
2+
export let nums = [1, 2];
3+
let foos = [
4+
{
5+
nums: [1, 2, 3],
6+
},
7+
{
8+
nums: [0, 2, 4],
9+
},
10+
{
11+
nums: [-100, 0, 100],
12+
},
13+
];
14+
let foo = 0;
15+
</script>
16+
17+
<p>{foo}</p>
18+
{#each nums as num, index}
19+
{@const bar = nums.map((num) => {
20+
function func(foos, num) {
21+
return [...foos.map((foo) => foo), num];
22+
}
23+
return func(foos[index].nums, num);
24+
})}
25+
<p>bar: {bar}, num: {num}</p>
26+
{/each}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
export default {
2+
html: `
3+
<p>1</p>
4+
<p>3,6,9</p>
5+
<p>2</p>
6+
<p>3,6,9</p>
7+
<p>3</p>
8+
<p>3,6,9</p>
9+
`,
10+
test({ component, target, assert }) {
11+
component.baz = 5;
12+
assert.htmlEqual(
13+
target.innerHTML,
14+
`
15+
<p>1</p>
16+
<p>5,10,15</p>
17+
<p>2</p>
18+
<p>5,10,15</p>
19+
<p>3</p>
20+
<p>5,10,15</p>
21+
`
22+
);
23+
24+
component.array = [3, 4, 5];
25+
assert.htmlEqual(
26+
target.innerHTML,
27+
`
28+
<p>3</p>
29+
<p>15,20,25</p>
30+
<p>4</p>
31+
<p>15,20,25</p>
32+
<p>5</p>
33+
<p>15,20,25</p>
34+
`
35+
);
36+
}
37+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script>
2+
export let array = [1, 2, 3];
3+
export let baz = 3;
4+
const foo = (item) => item;
5+
</script>
6+
7+
{#each array as item}
8+
<p>{foo(item)}</p>
9+
{@const bar = array.map((item) => {
10+
const bar = baz;
11+
const foo = (item) => item * bar;
12+
return foo(item);
13+
})}
14+
<p>{bar}</p>
15+
{/each}

0 commit comments

Comments
 (0)