fix: possible name clash in hoisted functions (#11237)

* fix: possible name clash in hoisted functions

* chore: add test
pull/11233/merge
Paolo Ricciuti 3 months ago committed by GitHub
parent cca67bba51
commit eac4218402
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: possible name clash in hoisted functions

@ -455,18 +455,28 @@ export const function_visitor = (node, context) => {
function get_hoistable_params(node, context) {
const scope = context.state.scope;
/** @type {import('estree').Pattern[]} */
/** @type {import('estree').Identifier[]} */
const params = [];
let added_props = false;
/**
* we only want to push if it's not already present to avoid name clashing
* @param {import('estree').Identifier} id
*/
function safe_push(id) {
if (!params.find((param) => param.name === id.name)) {
params.push(id);
}
}
for (const [reference] of scope.references) {
const binding = scope.get(reference);
if (binding !== null && !scope.declarations.has(reference) && binding.initial !== node) {
if (binding.kind === 'store_sub') {
// We need both the subscription for getting the value and the store for updating
params.push(b.id(binding.node.name.slice(1)));
params.push(b.id(binding.node.name));
safe_push(b.id(binding.node.name.slice(1)));
safe_push(b.id(binding.node.name));
} else if (
// If it's a destructured derived binding, then we can extract the derived signal reference and use that.
binding.expression !== null &&
@ -477,7 +487,7 @@ function get_hoistable_params(node, context) {
binding.expression.object.callee.name === '$.get' &&
binding.expression.object.arguments[0].type === 'Identifier'
) {
params.push(b.id(binding.expression.object.arguments[0].name));
safe_push(b.id(binding.expression.object.arguments[0].name));
} else if (
// If we are referencing a simple $$props value, then we need to reference the object property instead
(binding.kind === 'prop' || binding.kind === 'bindable_prop') &&
@ -488,11 +498,11 @@ function get_hoistable_params(node, context) {
// Handle $$props.something use-cases
if (!added_props) {
added_props = true;
params.push(b.id('$$props'));
safe_push(b.id('$$props'));
}
} else {
// create a copy to remove start/end tags which would mess up source maps
params.push(b.id(binding.node.name));
safe_push(b.id(binding.node.name));
}
}
}

@ -0,0 +1,9 @@
import { test } from '../../test';
export default test({
compileOptions: {
dev: true
},
recover: true,
mode: ['client']
});

@ -0,0 +1,11 @@
<script lang="ts">
import { writable } from 'svelte/store';
const store = writable(0);
async function logStore() {
console.log($store)
store.set(100);
}
</script>
<button onclick={logStore}>Click me</button>
Loading…
Cancel
Save