From 6e86e30cd766181dce5849ae739eedd2adfd8d8e Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Wed, 21 May 2025 10:25:56 +0100 Subject: [PATCH 1/5] feat: support comma-separated ignore comments (#1235) --- .changeset/quick-cloths-double.md | 5 ++ .../svelte-compile-warns/ignore-comment.ts | 88 +++++++++++-------- ...svelte-ignore-comma-separated-input.svelte | 5 ++ ...e-ignore-comma-separated-requirements.json | 3 + 4 files changed, 63 insertions(+), 38 deletions(-) create mode 100644 .changeset/quick-cloths-double.md create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-svelte-ignore/valid/svelte-ignore-comma-separated-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-svelte-ignore/valid/svelte-ignore-comma-separated-requirements.json diff --git a/.changeset/quick-cloths-double.md b/.changeset/quick-cloths-double.md new file mode 100644 index 000000000..bcbde127c --- /dev/null +++ b/.changeset/quick-cloths-double.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-svelte': minor +--- + +Improve performance of ignore comment extraction and add support for comma-separated ignore codes diff --git a/packages/eslint-plugin-svelte/src/shared/svelte-compile-warns/ignore-comment.ts b/packages/eslint-plugin-svelte/src/shared/svelte-compile-warns/ignore-comment.ts index 2655c789e..77cf5a0c4 100644 --- a/packages/eslint-plugin-svelte/src/shared/svelte-compile-warns/ignore-comment.ts +++ b/packages/eslint-plugin-svelte/src/shared/svelte-compile-warns/ignore-comment.ts @@ -1,7 +1,7 @@ import type { AST } from 'svelte-eslint-parser'; import type { RuleContext } from '../../types.js'; -const SVELTE_IGNORE_PATTERN = /^\s*svelte-ignore/m; +const SVELTE_IGNORE_PATTERN = /^\s*svelte-ignore\s+/; /** * Map of legacy code -> new code @@ -37,29 +37,45 @@ export function getSvelteIgnoreItems(context: RuleContext): (IgnoreItem | Ignore const ignoreComments: (IgnoreItem | IgnoreItemWithoutCode)[] = []; for (const comment of sourceCode.getAllComments()) { - const ignores = extractSvelteIgnore(comment.value, comment.range[0] + 2, comment); - if (ignores) { - ignoreComments.push(...ignores); - } else if (hasMissingCodeIgnore(comment.value)) { + const match = SVELTE_IGNORE_PATTERN.exec(comment.value); + if (!match) { + continue; + } + const codeListStart = match.index + match[0].length; + const codeList = comment.value.slice(codeListStart); + if (hasMissingCodeIgnore(codeList)) { ignoreComments.push({ range: comment.range, code: null, token: comment }); + } else { + const ignores = extractSvelteIgnore(comment.range[0] + 2, comment, codeList, codeListStart); + if (ignores) { + ignoreComments.push(...ignores); + } } } for (const token of sourceCode.ast.tokens) { if (token.type === 'HTMLComment') { const text = token.value.slice(4, -3); - const ignores = extractSvelteIgnore(text, token.range[0] + 4, token); - if (ignores) { - ignoreComments.push(...ignores); - } else if (hasMissingCodeIgnore(text)) { + const match = SVELTE_IGNORE_PATTERN.exec(text); + if (!match) { + continue; + } + const codeListStart = match.index + match[0].length; + const codeList = text.slice(codeListStart); + if (hasMissingCodeIgnore(codeList)) { ignoreComments.push({ range: token.range, code: null, token }); + } else { + const ignores = extractSvelteIgnore(token.range[0] + 4, token, codeList, codeListStart); + if (ignores) { + ignoreComments.push(...ignores); + } } } } @@ -69,46 +85,42 @@ export function getSvelteIgnoreItems(context: RuleContext): (IgnoreItem | Ignore /** Extract svelte-ignore rule names */ function extractSvelteIgnore( - text: string, startIndex: number, - token: AST.Token | AST.Comment + token: AST.Token | AST.Comment, + codeList: string, + ignoreStart: number ): IgnoreItem[] | null { - const m1 = SVELTE_IGNORE_PATTERN.exec(text); - if (!m1) { - return null; - } - const ignoreStart = m1.index + m1[0].length; - const beforeText = text.slice(ignoreStart); - if (!/^\s/.test(beforeText) || !beforeText.trim()) { - return null; - } - let start = startIndex + ignoreStart; - + const start = startIndex + ignoreStart; const results: IgnoreItem[] = []; - for (const code of beforeText.split(/\s/)) { - const end = start + code.length; - const trimmed = code.trim(); - if (trimmed) { + const separatorPattern = /\s*[\s,]\s*/g; + const separators = codeList.matchAll(separatorPattern); + let lastSeparatorEnd = 0; + for (const separator of separators) { + const code = codeList.slice(lastSeparatorEnd, separator.index); + if (code) { results.push({ - code: trimmed, - codeForV5: V5_REPLACEMENTS[trimmed] || trimmed.replace(/-/gu, '_'), - range: [start, end], + code, + codeForV5: V5_REPLACEMENTS[code] || code.replace(/-/gu, '_'), + range: [start + lastSeparatorEnd, start + separator.index], token }); } - start = end + 1; /* space */ + lastSeparatorEnd = separator.index + separator[0].length; + } + if (results.length === 0) { + const code = codeList; + results.push({ + code, + codeForV5: V5_REPLACEMENTS[code] || code.replace(/-/gu, '_'), + range: [start, start + code.length], + token + }); } return results; } /** Checks whether given comment has missing code svelte-ignore */ -function hasMissingCodeIgnore(text: string) { - const m1 = SVELTE_IGNORE_PATTERN.exec(text); - if (!m1) { - return false; - } - const ignoreStart = m1.index + m1[0].length; - const beforeText = text.slice(ignoreStart); - return !beforeText.trim(); +function hasMissingCodeIgnore(codeList: string) { + return !codeList.trim(); } diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-svelte-ignore/valid/svelte-ignore-comma-separated-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-svelte-ignore/valid/svelte-ignore-comma-separated-input.svelte new file mode 100644 index 000000000..7e2559f55 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-svelte-ignore/valid/svelte-ignore-comma-separated-input.svelte @@ -0,0 +1,5 @@ + + diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-svelte-ignore/valid/svelte-ignore-comma-separated-requirements.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-svelte-ignore/valid/svelte-ignore-comma-separated-requirements.json new file mode 100644 index 000000000..0192b1098 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-svelte-ignore/valid/svelte-ignore-comma-separated-requirements.json @@ -0,0 +1,3 @@ +{ + "svelte": ">=5.0.0-0" +} From a0f5c172131200be0b9689d0001a73e88ef822eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 May 2025 18:33:57 +0900 Subject: [PATCH 2/5] chore: release eslint-plugin-svelte (#1236) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/quick-cloths-double.md | 5 ----- packages/eslint-plugin-svelte/CHANGELOG.md | 6 ++++++ packages/eslint-plugin-svelte/package.json | 2 +- packages/eslint-plugin-svelte/src/meta.ts | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 .changeset/quick-cloths-double.md diff --git a/.changeset/quick-cloths-double.md b/.changeset/quick-cloths-double.md deleted file mode 100644 index bcbde127c..000000000 --- a/.changeset/quick-cloths-double.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-svelte': minor ---- - -Improve performance of ignore comment extraction and add support for comma-separated ignore codes diff --git a/packages/eslint-plugin-svelte/CHANGELOG.md b/packages/eslint-plugin-svelte/CHANGELOG.md index 3c911aac5..5e27f2038 100644 --- a/packages/eslint-plugin-svelte/CHANGELOG.md +++ b/packages/eslint-plugin-svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # eslint-plugin-svelte +## 3.9.0 + +### Minor Changes + +- [#1235](https://github.com/sveltejs/eslint-plugin-svelte/pull/1235) [`6e86e30`](https://github.com/sveltejs/eslint-plugin-svelte/commit/6e86e30cd766181dce5849ae739eedd2adfd8d8e) Thanks [@43081j](https://github.com/43081j)! - Improve performance of ignore comment extraction and add support for comma-separated ignore codes + ## 3.8.2 ### Patch Changes diff --git a/packages/eslint-plugin-svelte/package.json b/packages/eslint-plugin-svelte/package.json index 520bd8468..a65f5e31d 100644 --- a/packages/eslint-plugin-svelte/package.json +++ b/packages/eslint-plugin-svelte/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-svelte", - "version": "3.8.2", + "version": "3.9.0", "description": "ESLint plugin for Svelte using AST", "repository": "git+https://github.com/sveltejs/eslint-plugin-svelte.git", "homepage": "https://sveltejs.github.io/eslint-plugin-svelte", diff --git a/packages/eslint-plugin-svelte/src/meta.ts b/packages/eslint-plugin-svelte/src/meta.ts index 9984d3ca6..a4c93e9c9 100644 --- a/packages/eslint-plugin-svelte/src/meta.ts +++ b/packages/eslint-plugin-svelte/src/meta.ts @@ -2,4 +2,4 @@ // This file has been automatically generated, // in order to update its content execute "pnpm run update" export const name = 'eslint-plugin-svelte' as const; -export const version = '3.8.2' as const; +export const version = '3.9.0' as const; From d8e0724019053a99e4a5b393221ae6d8d8cdc66b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 31 May 2025 02:14:52 +0000 Subject: [PATCH 3/5] chore(deps): update dependency eslint to ~9.28.0 (#1237) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cd3fdec23..36bd2fad9 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@typescript-eslint/parser": "^8.16.0", "c8": "^10.1.2", "env-cmd": "^10.1.0", - "eslint": "~9.27.0", + "eslint": "~9.28.0", "eslint-config-prettier": "^10.0.0", "eslint-formatter-friendly": "^7.0.0", "eslint-plugin-eslint-plugin": "^6.3.2", From a3d42245fbb6a6663a1b3c6a4e211dce2b6dfbbb Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Mon, 2 Jun 2025 08:10:35 +0900 Subject: [PATCH 4/5] fix(prefer-const): Use `additionalProperties` instead of `ignoreReadonly` to match the ESLint core rule option name (#1239) --- .changeset/good-carrots-notice.md | 5 +++++ docs/rules/prefer-const.md | 10 +++++----- packages/eslint-plugin-svelte/src/rule-types.ts | 1 + .../eslint-plugin-svelte/src/rules/prefer-const.ts | 3 ++- .../rules/prefer-const/valid/1238/_config.json | 8 ++++++++ .../rules/prefer-const/valid/1238/input.svelte | 1 + 6 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 .changeset/good-carrots-notice.md create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/1238/_config.json create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/1238/input.svelte diff --git a/.changeset/good-carrots-notice.md b/.changeset/good-carrots-notice.md new file mode 100644 index 000000000..6a7f03087 --- /dev/null +++ b/.changeset/good-carrots-notice.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-svelte': patch +--- + +fix(prefer-const): Use `additionalProperties` instead of `ignoreReadonly` to match the ESLint core rule option name. diff --git a/docs/rules/prefer-const.md b/docs/rules/prefer-const.md index 8029ea881..f158d47b6 100644 --- a/docs/rules/prefer-const.md +++ b/docs/rules/prefer-const.md @@ -46,7 +46,7 @@ This rule reports the same as the base ESLint `prefer-const` rule, except that i "error", { "destructuring": "any", - "ignoreReadonly": true, + "additionalProperties": false, "excludedRunes": ["$props", "$derived"] } ] @@ -54,14 +54,14 @@ This rule reports the same as the base ESLint `prefer-const` rule, except that i ``` - `destructuring`: The kind of the way to address variables in destructuring. There are 2 values: - - `any` (default): if any variables in destructuring should be const, this rule warns for those variables. - - `all`: if all variables in destructuring should be const, this rule warns the variables. Otherwise, ignores them. -- `ignoreReadonly`: If `true`, this rule will ignore variables that are read between the declaration and the _first_ assignment. + - `any` (default) - If any variables in destructuring should be const, this rule warns for those variables. + - `all`: If all variables in destructuring should be const, this rule warns the variables. Otherwise, ignores them. +- `ignoreReadBeforeAssign`: This is an option to avoid conflicting with `no-use-before-define` rule (without "nofunc" option). If `true` is specified, this rule will ignore variables that are read between the declaration and the first assignment. Default is `false`. - `excludedRunes`: An array of rune names that should be ignored. Even if a rune is declared with `let`, it will still be ignored. ## :books: Further Reading -- See [ESLint `prefer-const` rule](https://eslint.org/docs/latest/rules/prefer-const) for more information about the base rule. +- See [ESLint prefer-const rule](https://eslint.org/docs/latest/rules/prefer-const) for more information about the base rule. ## :rocket: Version diff --git a/packages/eslint-plugin-svelte/src/rule-types.ts b/packages/eslint-plugin-svelte/src/rule-types.ts index 2fd9c7db2..81657270d 100644 --- a/packages/eslint-plugin-svelte/src/rule-types.ts +++ b/packages/eslint-plugin-svelte/src/rule-types.ts @@ -573,6 +573,7 @@ type SveltePreferConst = []|[{ destructuring?: ("any" | "all") ignoreReadBeforeAssign?: boolean excludedRunes?: string[] + [k: string]: unknown | undefined }] // ----- svelte/require-event-prefix ----- type SvelteRequireEventPrefix = []|[{ diff --git a/packages/eslint-plugin-svelte/src/rules/prefer-const.ts b/packages/eslint-plugin-svelte/src/rules/prefer-const.ts index 842bbc924..e28765baa 100644 --- a/packages/eslint-plugin-svelte/src/rules/prefer-const.ts +++ b/packages/eslint-plugin-svelte/src/rules/prefer-const.ts @@ -68,7 +68,8 @@ export default createRule('prefer-const', { } } }, - additionalProperties: false + // Allow ESLint core rule properties in case new options are added in the future. + additionalProperties: true } ] }, diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/1238/_config.json b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/1238/_config.json new file mode 100644 index 000000000..88200a87e --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/1238/_config.json @@ -0,0 +1,8 @@ +{ + "options": [ + { + "destructuring": "all", + "additionalProperties": true + } + ] +} diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/1238/input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/1238/input.svelte new file mode 100644 index 000000000..190a18037 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/prefer-const/valid/1238/input.svelte @@ -0,0 +1 @@ +123 From 6320a20efb0dc8eed8d97b3538a53d96b9257f68 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 2 Jun 2025 08:12:54 +0900 Subject: [PATCH 5/5] chore: release eslint-plugin-svelte (#1240) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/good-carrots-notice.md | 5 ----- packages/eslint-plugin-svelte/CHANGELOG.md | 6 ++++++ packages/eslint-plugin-svelte/package.json | 2 +- packages/eslint-plugin-svelte/src/meta.ts | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 .changeset/good-carrots-notice.md diff --git a/.changeset/good-carrots-notice.md b/.changeset/good-carrots-notice.md deleted file mode 100644 index 6a7f03087..000000000 --- a/.changeset/good-carrots-notice.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-svelte': patch ---- - -fix(prefer-const): Use `additionalProperties` instead of `ignoreReadonly` to match the ESLint core rule option name. diff --git a/packages/eslint-plugin-svelte/CHANGELOG.md b/packages/eslint-plugin-svelte/CHANGELOG.md index 5e27f2038..0b0f3dee0 100644 --- a/packages/eslint-plugin-svelte/CHANGELOG.md +++ b/packages/eslint-plugin-svelte/CHANGELOG.md @@ -1,5 +1,11 @@ # eslint-plugin-svelte +## 3.9.1 + +### Patch Changes + +- [#1239](https://github.com/sveltejs/eslint-plugin-svelte/pull/1239) [`a3d4224`](https://github.com/sveltejs/eslint-plugin-svelte/commit/a3d42245fbb6a6663a1b3c6a4e211dce2b6dfbbb) Thanks [@baseballyama](https://github.com/baseballyama)! - fix(prefer-const): Use `additionalProperties` instead of `ignoreReadonly` to match the ESLint core rule option name. + ## 3.9.0 ### Minor Changes diff --git a/packages/eslint-plugin-svelte/package.json b/packages/eslint-plugin-svelte/package.json index a65f5e31d..ffce141a8 100644 --- a/packages/eslint-plugin-svelte/package.json +++ b/packages/eslint-plugin-svelte/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-svelte", - "version": "3.9.0", + "version": "3.9.1", "description": "ESLint plugin for Svelte using AST", "repository": "git+https://github.com/sveltejs/eslint-plugin-svelte.git", "homepage": "https://sveltejs.github.io/eslint-plugin-svelte", diff --git a/packages/eslint-plugin-svelte/src/meta.ts b/packages/eslint-plugin-svelte/src/meta.ts index a4c93e9c9..1ea9551ba 100644 --- a/packages/eslint-plugin-svelte/src/meta.ts +++ b/packages/eslint-plugin-svelte/src/meta.ts @@ -2,4 +2,4 @@ // This file has been automatically generated, // in order to update its content execute "pnpm run update" export const name = 'eslint-plugin-svelte' as const; -export const version = '3.9.0' as const; +export const version = '3.9.1' as const;