|
| 1 | +import type { CharacterClass } from '@eslint-community/regexpp/ast' |
1 | 2 | import type { TSESTree } from '@typescript-eslint/types' |
2 | 3 |
|
3 | 4 | import { parseRegExpLiteral, visitRegExpAST } from '@eslint-community/regexpp' |
@@ -44,6 +45,22 @@ type ResolvedOptions = Required<Options[0]> |
44 | 45 |
|
45 | 46 | type MessageId = 'unexpectedRegExpOrder' |
46 | 47 |
|
| 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 | + |
47 | 64 | let defaultOptions: ResolvedOptions = { |
48 | 65 | fallbackSort: { type: 'unsorted' }, |
49 | 66 | specialCharacters: 'keep', |
@@ -309,8 +326,19 @@ export default createEslintRule<Options, MessageId>({ |
309 | 326 | ) |
310 | 327 |
|
311 | 328 | 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 | + ) |
314 | 342 |
|
315 | 343 | let mismatchIndex = originalRawElements.findIndex( |
316 | 344 | (raw, index) => raw !== sortedRawElements[index], |
|
0 commit comments