diff --git a/.changeset/ninety-rockets-battle.md b/.changeset/ninety-rockets-battle.md new file mode 100644 index 000000000000..9d70e42ad039 --- /dev/null +++ b/.changeset/ninety-rockets-battle.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: allow for more svelte-ignore to work diff --git a/packages/svelte/scripts/process-messages/templates/compile-warnings.js b/packages/svelte/scripts/process-messages/templates/compile-warnings.js index 15908fcec216..d6a0cd6a0bc6 100644 --- a/packages/svelte/scripts/process-messages/templates/compile-warnings.js +++ b/packages/svelte/scripts/process-messages/templates/compile-warnings.js @@ -1,4 +1,4 @@ -import { filename, locator, warnings, ignore_stack } from './state.js'; +import { filename, locator, warnings, ignore_stack, ignore_map } from './state.js'; /** @typedef {{ start?: number, end?: number }} NodeLike */ @@ -8,7 +8,11 @@ import { filename, locator, warnings, ignore_stack } from './state.js'; * @param {string} message */ function w(node, code, message) { - if (ignore_stack.at(-1)?.has(code)) return; + let stack = ignore_stack; + if (node) { + stack = ignore_map.get(node) ?? ignore_stack; + } + if (stack && stack.at(-1)?.has(code)) return; warnings.push({ code, diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index bda4ad424cd4..618864d4e44d 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -30,7 +30,7 @@ import { prune } from './css/css-prune.js'; import { hash } from './utils.js'; import { warn_unused } from './css/css-warn.js'; import { extract_svelte_ignore } from '../../utils/extract_svelte_ignore.js'; -import { pop_ignore, push_ignore } from '../../state.js'; +import { ignore_map, ignore_stack, pop_ignore, push_ignore } from '../../state.js'; /** * @param {import('#compiler').Script | null} script @@ -1107,6 +1107,7 @@ function is_safe_identifier(expression, scope) { /** @type {import('./types').Visitors} */ const common_visitors = { _(node, { state, next, path }) { + ignore_map.set(node, structuredClone(ignore_stack)); const parent = path.at(-1); if (parent?.type === 'Fragment' && node.type !== 'Comment' && node.type !== 'Text') { const idx = parent.nodes.indexOf(/** @type {any} */ (node)); @@ -1129,6 +1130,7 @@ const common_visitors = { if (ignores.length > 0) { push_ignore(ignores); + ignore_map.set(node, structuredClone(ignore_stack)); next(); pop_ignore(); } @@ -1148,6 +1150,7 @@ const common_visitors = { } if (ignores.length > 0) { push_ignore(ignores); + ignore_map.set(node, structuredClone(ignore_stack)); next(); pop_ignore(); } diff --git a/packages/svelte/src/compiler/state.js b/packages/svelte/src/compiler/state.js index a317f74771c3..41b4f29a170a 100644 --- a/packages/svelte/src/compiler/state.js +++ b/packages/svelte/src/compiler/state.js @@ -14,9 +14,20 @@ export let filename; export let locator = getLocator('', { offsetLine: 1 }); -/** @type {Set[]} */ +/** + * The current stack of ignored warnings + * @type {Set[]} + */ export let ignore_stack = []; +/** + * For each node the list of warnings that should be ignored for that node. + * Exists in addition to `ignore_stack` because not all warnings are emitted + * while the stack is being built. + * @type {Map[]>} + */ +export let ignore_map = new Map(); + /** * @param {string[]} ignores */ @@ -49,4 +60,5 @@ export function reset(source, options) { locator = getLocator(source, { offsetLine: 1 }); warnings = []; ignore_stack = []; + ignore_map.clear(); } diff --git a/packages/svelte/src/compiler/warnings.js b/packages/svelte/src/compiler/warnings.js index 904f20c192ff..7f40eec02b91 100644 --- a/packages/svelte/src/compiler/warnings.js +++ b/packages/svelte/src/compiler/warnings.js @@ -1,6 +1,12 @@ /* This file is generated by scripts/process-messages/index.js. Do not edit! */ -import { filename, locator, warnings, ignore_stack } from './state.js'; +import { + filename, + locator, + warnings, + ignore_stack, + ignore_map +} from './state.js'; /** @typedef {{ start?: number, end?: number }} NodeLike */ /** @@ -9,7 +15,13 @@ import { filename, locator, warnings, ignore_stack } from './state.js'; * @param {string} message */ function w(node, code, message) { - if (ignore_stack.at(-1)?.has(code)) return; + let stack = ignore_stack; + + if (node) { + stack = ignore_map.get(node) ?? ignore_stack; + } + + if (stack && stack.at(-1)?.has(code)) return; warnings.push({ code, diff --git a/packages/svelte/tests/validator/samples/svelte-ignore-export-let-unused/input.svelte b/packages/svelte/tests/validator/samples/svelte-ignore-export-let-unused/input.svelte new file mode 100644 index 000000000000..749be44f4902 --- /dev/null +++ b/packages/svelte/tests/validator/samples/svelte-ignore-export-let-unused/input.svelte @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/packages/svelte/tests/validator/samples/svelte-ignore-export-let-unused/warnings.json b/packages/svelte/tests/validator/samples/svelte-ignore-export-let-unused/warnings.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/packages/svelte/tests/validator/samples/svelte-ignore-export-let-unused/warnings.json @@ -0,0 +1 @@ +[] diff --git a/packages/svelte/tests/validator/samples/svelte-ignore-non-reactive-update/input.svelte b/packages/svelte/tests/validator/samples/svelte-ignore-non-reactive-update/input.svelte new file mode 100644 index 000000000000..43d44368e921 --- /dev/null +++ b/packages/svelte/tests/validator/samples/svelte-ignore-non-reactive-update/input.svelte @@ -0,0 +1,10 @@ + + + + +{value} \ No newline at end of file diff --git a/packages/svelte/tests/validator/samples/svelte-ignore-non-reactive-update/warnings.json b/packages/svelte/tests/validator/samples/svelte-ignore-non-reactive-update/warnings.json new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/packages/svelte/tests/validator/samples/svelte-ignore-non-reactive-update/warnings.json @@ -0,0 +1 @@ +[]