Skip to content

Commit 6e86e30

Browse files
authored
feat: support comma-separated ignore comments (#1235)
1 parent 15742cb commit 6e86e30

File tree

4 files changed

+63
-38
lines changed

4 files changed

+63
-38
lines changed

.changeset/quick-cloths-double.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'eslint-plugin-svelte': minor
3+
---
4+
5+
Improve performance of ignore comment extraction and add support for comma-separated ignore codes
Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { AST } from 'svelte-eslint-parser';
22
import type { RuleContext } from '../../types.js';
33

4-
const SVELTE_IGNORE_PATTERN = /^\s*svelte-ignore/m;
4+
const SVELTE_IGNORE_PATTERN = /^\s*svelte-ignore\s+/;
55

66
/**
77
* Map of legacy code -> new code
@@ -37,29 +37,45 @@ export function getSvelteIgnoreItems(context: RuleContext): (IgnoreItem | Ignore
3737

3838
const ignoreComments: (IgnoreItem | IgnoreItemWithoutCode)[] = [];
3939
for (const comment of sourceCode.getAllComments()) {
40-
const ignores = extractSvelteIgnore(comment.value, comment.range[0] + 2, comment);
41-
if (ignores) {
42-
ignoreComments.push(...ignores);
43-
} else if (hasMissingCodeIgnore(comment.value)) {
40+
const match = SVELTE_IGNORE_PATTERN.exec(comment.value);
41+
if (!match) {
42+
continue;
43+
}
44+
const codeListStart = match.index + match[0].length;
45+
const codeList = comment.value.slice(codeListStart);
46+
if (hasMissingCodeIgnore(codeList)) {
4447
ignoreComments.push({
4548
range: comment.range,
4649
code: null,
4750
token: comment
4851
});
52+
} else {
53+
const ignores = extractSvelteIgnore(comment.range[0] + 2, comment, codeList, codeListStart);
54+
if (ignores) {
55+
ignoreComments.push(...ignores);
56+
}
4957
}
5058
}
5159
for (const token of sourceCode.ast.tokens) {
5260
if (token.type === 'HTMLComment') {
5361
const text = token.value.slice(4, -3);
54-
const ignores = extractSvelteIgnore(text, token.range[0] + 4, token);
55-
if (ignores) {
56-
ignoreComments.push(...ignores);
57-
} else if (hasMissingCodeIgnore(text)) {
62+
const match = SVELTE_IGNORE_PATTERN.exec(text);
63+
if (!match) {
64+
continue;
65+
}
66+
const codeListStart = match.index + match[0].length;
67+
const codeList = text.slice(codeListStart);
68+
if (hasMissingCodeIgnore(codeList)) {
5869
ignoreComments.push({
5970
range: token.range,
6071
code: null,
6172
token
6273
});
74+
} else {
75+
const ignores = extractSvelteIgnore(token.range[0] + 4, token, codeList, codeListStart);
76+
if (ignores) {
77+
ignoreComments.push(...ignores);
78+
}
6379
}
6480
}
6581
}
@@ -69,46 +85,42 @@ export function getSvelteIgnoreItems(context: RuleContext): (IgnoreItem | Ignore
6985

7086
/** Extract svelte-ignore rule names */
7187
function extractSvelteIgnore(
72-
text: string,
7388
startIndex: number,
74-
token: AST.Token | AST.Comment
89+
token: AST.Token | AST.Comment,
90+
codeList: string,
91+
ignoreStart: number
7592
): IgnoreItem[] | null {
76-
const m1 = SVELTE_IGNORE_PATTERN.exec(text);
77-
if (!m1) {
78-
return null;
79-
}
80-
const ignoreStart = m1.index + m1[0].length;
81-
const beforeText = text.slice(ignoreStart);
82-
if (!/^\s/.test(beforeText) || !beforeText.trim()) {
83-
return null;
84-
}
85-
let start = startIndex + ignoreStart;
86-
93+
const start = startIndex + ignoreStart;
8794
const results: IgnoreItem[] = [];
88-
for (const code of beforeText.split(/\s/)) {
89-
const end = start + code.length;
90-
const trimmed = code.trim();
91-
if (trimmed) {
95+
const separatorPattern = /\s*[\s,]\s*/g;
96+
const separators = codeList.matchAll(separatorPattern);
97+
let lastSeparatorEnd = 0;
98+
for (const separator of separators) {
99+
const code = codeList.slice(lastSeparatorEnd, separator.index);
100+
if (code) {
92101
results.push({
93-
code: trimmed,
94-
codeForV5: V5_REPLACEMENTS[trimmed] || trimmed.replace(/-/gu, '_'),
95-
range: [start, end],
102+
code,
103+
codeForV5: V5_REPLACEMENTS[code] || code.replace(/-/gu, '_'),
104+
range: [start + lastSeparatorEnd, start + separator.index],
96105
token
97106
});
98107
}
99-
start = end + 1; /* space */
108+
lastSeparatorEnd = separator.index + separator[0].length;
109+
}
110+
if (results.length === 0) {
111+
const code = codeList;
112+
results.push({
113+
code,
114+
codeForV5: V5_REPLACEMENTS[code] || code.replace(/-/gu, '_'),
115+
range: [start, start + code.length],
116+
token
117+
});
100118
}
101119

102120
return results;
103121
}
104122

105123
/** Checks whether given comment has missing code svelte-ignore */
106-
function hasMissingCodeIgnore(text: string) {
107-
const m1 = SVELTE_IGNORE_PATTERN.exec(text);
108-
if (!m1) {
109-
return false;
110-
}
111-
const ignoreStart = m1.index + m1[0].length;
112-
const beforeText = text.slice(ignoreStart);
113-
return !beforeText.trim();
124+
function hasMissingCodeIgnore(codeList: string) {
125+
return !codeList.trim();
114126
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!-- svelte-ignore a11y_label_has_associated_control, a11y_no_noninteractive_tabindex -->
2+
<div class="dropdown">
3+
<label tabindex="0">Click</label>
4+
<ul tabindex="0"></ul>
5+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"svelte": ">=5.0.0-0"
3+
}

0 commit comments

Comments
 (0)