Skip to content

Commit e89fb07

Browse files
committed
Don’t crash when regex is missing a capture group
1 parent dde047a commit e89fb07

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

packages/tailwindcss-language-service/src/util/classes.test.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,52 @@ let table: TestRecord[] = [
160160

161161
// Edge cases
162162
{
163-
name: 'regex matches empty string',
163+
name: 'container regex matches empty string',
164164
text: `let _ = ""`,
165165
cursor: 9,
166166
filters: [['(?<=")(\\w*)(?=")']],
167167
expected: [{ classList: '', range: [9, 9] }],
168168
},
169+
170+
{
171+
name: 'container regex matches empty string (no cursor)',
172+
text: `let _ = ""`,
173+
cursor: null,
174+
filters: [['(?<=")(\\w*)(?=")']],
175+
expected: [{ classList: '', range: [9, 9] }],
176+
},
177+
178+
{
179+
name: 'class regex matches empty string',
180+
text: `let _ = clsx("")`,
181+
cursor: 14,
182+
filters: [['clsx\\(([^)]*)\\)', '(?<=")([^"]*)(?<=")']],
183+
expected: [{ classList: '', range: [14, 14] }],
184+
},
185+
186+
{
187+
name: 'class regex matches empty string (no cursor)',
188+
text: `let _ = clsx("")`,
189+
cursor: null,
190+
filters: [['clsx\\(([^)]*)\\)', '(?<=")([^"]*)(?<=")']],
191+
expected: [{ classList: '', range: [14, 14] }, { classList: '', range: [15, 15] }],
192+
},
193+
194+
{
195+
name: 'container regex is missing a capture group',
196+
text: `let _ = ""`,
197+
cursor: null,
198+
filters: [['(?<=")\\w*(?=")']],
199+
expected: [],
200+
},
201+
202+
{
203+
name: 'class regex is missing a capture group',
204+
text: `let _ = clsx("")`,
205+
cursor: null,
206+
filters: [['clsx\\(([^)]*)\\)', '"[^"]*"']],
207+
expected: [],
208+
},
169209
]
170210

171211
test.each(table)('customClassesIn: $name', ({ text, cursor, filters, expected }) => {

packages/tailwindcss-language-service/src/util/classes.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ function *matchesIn(
3434
cursor: number | null,
3535
): Iterable<ClassMatch> {
3636
for (let containerMatch of text.matchAll(containerRegex)) {
37+
// Don't crash when there's no capture group
38+
if (containerMatch[1] === undefined) {
39+
console.warn(`Regex /${containerRegex.source}/ must have exactly one capture group`)
40+
continue
41+
}
42+
3743
const matchStart = containerMatch.indices[1][0]
3844
const matchEnd = matchStart + containerMatch[1].length
3945

@@ -54,6 +60,12 @@ function *matchesIn(
5460

5561
// Handle class matches inside the "container"
5662
for (let classMatch of containerMatch[1].matchAll(classRegex)) {
63+
// Don't crash when there's no capture group
64+
if (classMatch[1] === undefined) {
65+
console.warn(`Regex /${classRegex.source}/ must have exactly one capture group`)
66+
continue
67+
}
68+
5769
const classMatchStart = matchStart + classMatch.indices[1][0]
5870
const classMatchEnd = classMatchStart + classMatch[1].length
5971

0 commit comments

Comments
 (0)