[fix] better context checks for identifiers in const tags (#7222)

Fixes #7423
Fixes #7431
Fixes #7206
Fixes #7431
Fixes #7221

Co-authored-by: tanhauhau <lhtan93@gmail.com>
pull/7439/head
Yuichiro Yamashita 2 years ago committed by GitHub
parent f6fd8e1ec8
commit eca1a652fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -254,11 +254,17 @@ export default class Expression {
const declaration = b`const ${id} = ${node}`;
if (owner.type === 'ConstTag') {
let child_scope = scope;
walk(node, {
enter(node: Node) {
if (node.type === 'Identifier') {
enter(node: Node, parent: any) {
if (map.has(node)) child_scope = map.get(node);
if (node.type === 'Identifier' && is_reference(node, parent)) {
if (child_scope.has(node.name)) return;
this.replace(block.renderer.reference(node, ctx));
}
},
leave(node: Node) {
if (map.has(node)) child_scope = child_scope.parent;
}
});
} else if (dependencies.size === 0 && contextual_dependencies.size === 0) {

@ -0,0 +1,29 @@
export default {
html: `
<p>0</p>
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
`,
async test({ component, target, assert }) {
assert.htmlEqual(
target.innerHTML,
`
<p>0</p>
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
`
);
component.nums = [1, 2, 3];
assert.htmlEqual(
target.innerHTML,
`
<p>0</p>
<p>bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1</p>
<p>bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2</p>
<p>bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3</p>
`
);
}
};

@ -0,0 +1,26 @@
<script>
export let nums = [1, 2];
let foos = [
{
nums: [1, 2, 3],
},
{
nums: [0, 2, 4],
},
{
nums: [-100, 0, 100],
},
];
let foo = 0;
</script>
<p>{foo}</p>
{#each nums as num, index}
{@const bar = nums.map((num) => {
const func = (foos, num) => {
return [...foos.map((foo) => foo), num];
}
return func(foos[index].nums, num);
})}
<p>bar: {bar}, num: {num}</p>
{/each}

@ -0,0 +1,29 @@
export default {
html: `
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
`,
async test({ component, target, assert }) {
assert.htmlEqual(
target.innerHTML,
`
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
`
);
component.nums = [1, 2, 3, 4];
assert.htmlEqual(
target.innerHTML,
`
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 1</p>
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 2</p>
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 3</p>
<p>bar: 1,2,3,0,2,4,-100,0,100, num: 4</p>
`
);
}
};

@ -0,0 +1,19 @@
<script>
export let nums = [1, 2, 3];
let foos = [
{
nums: [1, 2, 3],
},
{
nums: [0, 2, 4],
},
{
nums: [-100, 0, 100],
},
];
</script>
{#each nums as num}
{@const bar = foos.map((foos) => foos.nums)}
<p>bar: {bar}, num: {num}</p>
{/each}

@ -0,0 +1,32 @@
export default {
html: `
<p>foo: dummy-foo, num: dummy-num</p>
<p>bar: 1,2,3,2,, num: 1</p>
<p>bar: 1,2,3,2,, num: 2</p>
<p>bar: 1,2,3,2,, num: 3</p>
`,
async test({ component, target, assert }) {
assert.htmlEqual(
target.innerHTML,
`
<p>foo: dummy-foo, num: dummy-num</p>
<p>bar: 1,2,3,2,, num: 1</p>
<p>bar: 1,2,3,2,, num: 2</p>
<p>bar: 1,2,3,2,, num: 3</p>
`
);
component.nums = [1, 2, 3, 4];
assert.htmlEqual(
target.innerHTML,
`
<p>foo: dummy-foo, num: dummy-num</p>
<p>bar: 1,2,3,2,4,, num: 1</p>
<p>bar: 1,2,3,2,4,, num: 2</p>
<p>bar: 1,2,3,2,4,, num: 3</p>
<p>bar: 1,2,3,2,4,, num: 4</p>
`
);
}
};

@ -0,0 +1,33 @@
<script>
export let nums = [1, 2, 3];
let foos = [
{
nums: [1, 2, 3],
},
{
nums: [0, 2, 4],
},
{
nums: [-100, 0, 100],
},
];
let default_nums = [-1];
let foo = "dummy-foo";
let num = "dummy-num";
</script>
<p>foo: {foo}, num: {num}</p>
{#each nums as num}
{@const bar = foos.map((foo) =>
foo.nums.filter((num) => {
if (Object.keys($$slots).length) {
return false;
} else if (Object.keys(foo).length) {
return nums.includes(num) || default_nums.includes(num);
} else {
return false;
}
}) || num
)}
<p>bar: {bar}, num: {num}</p>
{/each}

@ -0,0 +1,29 @@
export default {
html: `
<p>0</p>
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
`,
async test({ component, target, assert }) {
assert.htmlEqual(
target.innerHTML,
`
<p>0</p>
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
`
);
component.nums = [1, 2, 3];
assert.htmlEqual(
target.innerHTML,
`
<p>0</p>
<p>bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1</p>
<p>bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2</p>
<p>bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3</p>
`
);
}
};

@ -0,0 +1,25 @@
<script>
export let nums = [1, 2];
let foos = [
{
nums: [1, 2, 3],
},
{
nums: [0, 2, 4],
},
{
nums: [-100, 0, 100],
},
];
let foo = 0;
</script>
<p>{foo}</p>
{#each nums as num, index}
{@const bar = nums.map((num) => {
return (function (foos, num) {
return [...foos.map((foo) => foo), num];
})(foos[index].nums, num);
})}
<p>bar: {bar}, num: {num}</p>
{/each}

@ -0,0 +1,29 @@
export default {
html: `
<p>0</p>
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
`,
async test({ component, target, assert }) {
assert.htmlEqual(
target.innerHTML,
`
<p>0</p>
<p>bar: 1,2,3,1,1,2,3,2, num: 1</p>
<p>bar: 0,2,4,1,0,2,4,2, num: 2</p>
`
);
component.nums = [1, 2, 3];
assert.htmlEqual(
target.innerHTML,
`
<p>0</p>
<p>bar: 1,2,3,1,1,2,3,2,1,2,3,3, num: 1</p>
<p>bar: 0,2,4,1,0,2,4,2,0,2,4,3, num: 2</p>
<p>bar: -100,0,100,1,-100,0,100,2,-100,0,100,3, num: 3</p>
`
);
}
};

@ -0,0 +1,26 @@
<script>
export let nums = [1, 2];
let foos = [
{
nums: [1, 2, 3],
},
{
nums: [0, 2, 4],
},
{
nums: [-100, 0, 100],
},
];
let foo = 0;
</script>
<p>{foo}</p>
{#each nums as num, index}
{@const bar = nums.map((num) => {
function func(foos, num) {
return [...foos.map((foo) => foo), num];
}
return func(foos[index].nums, num);
})}
<p>bar: {bar}, num: {num}</p>
{/each}

@ -0,0 +1,37 @@
export default {
html: `
<p>1</p>
<p>3,6,9</p>
<p>2</p>
<p>3,6,9</p>
<p>3</p>
<p>3,6,9</p>
`,
test({ component, target, assert }) {
component.baz = 5;
assert.htmlEqual(
target.innerHTML,
`
<p>1</p>
<p>5,10,15</p>
<p>2</p>
<p>5,10,15</p>
<p>3</p>
<p>5,10,15</p>
`
);
component.array = [3, 4, 5];
assert.htmlEqual(
target.innerHTML,
`
<p>3</p>
<p>15,20,25</p>
<p>4</p>
<p>15,20,25</p>
<p>5</p>
<p>15,20,25</p>
`
);
}
};

@ -0,0 +1,15 @@
<script>
export let array = [1, 2, 3];
export let baz = 3;
const foo = (item) => item;
</script>
{#each array as item}
<p>{foo(item)}</p>
{@const bar = array.map((item) => {
const bar = baz;
const foo = (item) => item * bar;
return foo(item);
})}
<p>{bar}</p>
{/each}
Loading…
Cancel
Save