diff --git a/.changeset/eight-pianos-raise.md b/.changeset/eight-pianos-raise.md new file mode 100644 index 0000000000..d73c7424a9 --- /dev/null +++ b/.changeset/eight-pianos-raise.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: add backwards-compat for old warning codes in legacy mode diff --git a/packages/svelte/src/compiler/migrate/index.js b/packages/svelte/src/compiler/migrate/index.js index 6f5d2681d9..7d5ca36599 100644 --- a/packages/svelte/src/compiler/migrate/index.js +++ b/packages/svelte/src/compiler/migrate/index.js @@ -7,6 +7,7 @@ import { get_rune } from '../phases/scope.js'; import { reset } from '../state.js'; import { extract_identifiers } from '../utils/ast.js'; import { regex_is_valid_identifier } from '../phases/patterns.js'; +import { migrate_svelte_ignore } from '../utils/extract_svelte_ignore.js'; /** * Does a best-effort migration of Svelte code towards using runes, event attributes and render tags. @@ -174,6 +175,21 @@ export function migrate(source) { /** @type {import('zimmerframe').Visitors} */ const instance_script = { + _(node, { state, next }) { + // @ts-expect-error + const comments = node.leadingComments; + if (comments) { + for (const comment of comments) { + if (comment.type === 'Line') { + const migrated = migrate_svelte_ignore(comment.value); + if (migrated !== comment.value) { + state.str.overwrite(comment.start + '//'.length, comment.end, migrated); + } + } + } + } + next(); + }, Identifier(node, { state }) { handle_identifier(node, state); }, @@ -474,6 +490,12 @@ const template = { } else { state.str.update(node.start, node.end, `{@render ${name}?.(${slot_props})}`); } + }, + Comment(node, { state }) { + const migrated = migrate_svelte_ignore(node.data); + if (migrated !== node.data) { + state.str.overwrite(node.start + ''.length, migrated); + } } }; diff --git a/packages/svelte/src/compiler/utils/extract_svelte_ignore.js b/packages/svelte/src/compiler/utils/extract_svelte_ignore.js index d68a9515fc..1f5d29db7d 100644 --- a/packages/svelte/src/compiler/utils/extract_svelte_ignore.js +++ b/packages/svelte/src/compiler/utils/extract_svelte_ignore.js @@ -3,9 +3,16 @@ import * as w from '../warnings.js'; const regex_svelte_ignore = /^\s*svelte-ignore\s/; -/** @type {Record} */ +/** @type {Record} Map of legacy code -> new code */ const replacements = { - 'non-top-level-reactive-declaration': 'reactive_declaration_invalid_placement' + 'non-top-level-reactive-declaration': 'reactive_declaration_invalid_placement', + 'module-script-reactive-declaration': 'reactive_declaration_module_script', + 'empty-block': 'block_empty', + 'avoid-is': 'attribute_avoid_is', + 'invalid-html-attribute': 'attribute_invalid_property_name', + 'a11y-structure': 'a11y_figcaption_parent', + 'illegal-attribute-character': 'attribute_illegal_colon', + 'invalid-rest-eachblock-binding': 'bind_invalid_each_rest' }; /** @@ -56,3 +63,21 @@ export function extract_svelte_ignore(offset, text, runes) { return ignores; } + +/** + * Replaces legacy svelte-ignore codes with new codes. + * @param {string} text + * @returns {string} + */ +export function migrate_svelte_ignore(text) { + const match = regex_svelte_ignore.exec(text); + if (!match) return text; + + const length = match[0].length; + return ( + text.substring(0, length) + + text + .substring(length) + .replace(/\w+-\w+(-\w+)*/g, (code) => replacements[code] ?? code.replace(/-/g, '_')) + ); +} diff --git a/packages/svelte/tests/migrate/samples/svelte-ignore/input.svelte b/packages/svelte/tests/migrate/samples/svelte-ignore/input.svelte new file mode 100644 index 0000000000..fa734942f9 --- /dev/null +++ b/packages/svelte/tests/migrate/samples/svelte-ignore/input.svelte @@ -0,0 +1,9 @@ + + + +
\ No newline at end of file diff --git a/packages/svelte/tests/migrate/samples/svelte-ignore/output.svelte b/packages/svelte/tests/migrate/samples/svelte-ignore/output.svelte new file mode 100644 index 0000000000..fa305cefb1 --- /dev/null +++ b/packages/svelte/tests/migrate/samples/svelte-ignore/output.svelte @@ -0,0 +1,9 @@ + + + +
\ No newline at end of file