Skip to content

Commit da7b5f5

Browse files
committed
fix(sort-regexp): preserve escape sequence text
1 parent 09ee12d commit da7b5f5

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

rules/sort-regexp.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { CharacterClass } from '@eslint-community/regexpp/ast'
12
import type { TSESTree } from '@typescript-eslint/types'
23

34
import { parseRegExpLiteral, visitRegExpAST } from '@eslint-community/regexpp'
@@ -44,6 +45,22 @@ type ResolvedOptions = Required<Options[0]>
4445

4546
type MessageId = 'unexpectedRegExpOrder'
4647

48+
/**
49+
* Retrieves the original source text for a character class element.
50+
*
51+
* @param parameters - Character class element metadata.
52+
* @returns Slice of the literal raw string covering the element.
53+
*/
54+
function getCharacterClassElementRawText({
55+
literalRaw,
56+
element,
57+
}: {
58+
element: CharacterClass['elements'][number]
59+
literalRaw: string
60+
}): string {
61+
return literalRaw.slice(element.start, element.end)
62+
}
63+
4764
let defaultOptions: ResolvedOptions = {
4865
fallbackSort: { type: 'unsorted' },
4966
specialCharacters: 'keep',
@@ -309,8 +326,19 @@ export default createEslintRule<Options, MessageId>({
309326
)
310327

311328
if (needsSort) {
312-
let originalRawElements = elements.map(element => element.raw)
313-
let sortedRawElements = sortedElements.map(element => element.raw)
329+
let literalRaw = literalNode.raw
330+
let originalRawElements = elements.map(element =>
331+
getCharacterClassElementRawText({
332+
literalRaw,
333+
element,
334+
}),
335+
)
336+
let sortedRawElements = sortedElements.map(element =>
337+
getCharacterClassElementRawText({
338+
literalRaw,
339+
element,
340+
}),
341+
)
314342

315343
let mismatchIndex = originalRawElements.findIndex(
316344
(raw, index) => raw !== sortedRawElements[index],

test/rules/sort-regexp.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,23 @@ describe('sort-regexp', () => {
135135
})
136136
})
137137

138+
it('keeps escape sequences intact when sorting character classes', async () => {
139+
await invalid({
140+
errors: [
141+
{
142+
messageId: 'unexpectedRegExpOrder',
143+
},
144+
],
145+
output: dedent(String.raw`
146+
const re = /[,?.()[\]{}*\\\s#^+|$-]/g;
147+
`),
148+
code: dedent(String.raw`
149+
const re = /[-[\]{}()*+?.,\\^$|#\s]/g;
150+
`),
151+
options: [options],
152+
})
153+
})
154+
138155
it('sorts character classes with ranges', async () => {
139156
await invalid({
140157
errors: [

0 commit comments

Comments
 (0)