-
Notifications
You must be signed in to change notification settings - Fork 54
feat: add sort-regexp rule #600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: next
Are you sure you want to change the base?
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis pull request introduces a new ESLint rule Changes
Sequence Diagram(s)sequenceDiagram
participant ESLint as ESLint Core
participant Rule as sort-regexp Rule
participant Parser as RegExp Parser
participant Sorter as Sorting Logic
ESLint->>Rule: onProgram (context)
activate Rule
Rule->>Rule: Register RegExp visitor
ESLint->>Rule: Encounter RegExp Literal
activate Rule
Rule->>Parser: Parse RegExp pattern & flags
activate Parser
Parser-->>Rule: AST (flags, alternatives, char classes)
deactivate Parser
alt Phase 1: Flag Sorting
Rule->>Sorter: Sort inline flags
activate Sorter
Sorter-->>Rule: Reordered flags + fix
deactivate Sorter
Rule->>Rule: Report if out of order
end
alt Phase 2: Content Sorting
Rule->>Sorter: Analyze alternatives/char classes
activate Sorter
Sorter->>Sorter: Apply grouping (custom/alias)
Sorter->>Sorter: Sort by strategy (alphabetical/natural/line-length)
Sorter-->>Rule: Sorted elements + mappings
deactivate Sorter
Rule->>Rule: Report mismatches with fixes
end
deactivate Rule
deactivate Rule
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes The changes span multiple files with heterogeneous purposes: configuration setup, comprehensive type definitions, substantial rule logic with multi-phase sorting and custom grouping support, and an extensive test suite. While documentation and setup files are straightforward, the core rule implementation (sort-regexp.ts) contains dense logic requiring careful review of sorting algorithms, group computation, and fix generation. The test suite is extensive and validates complex edge cases, warranting focused attention despite repetitive structure. Pre-merge checks❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request adds a new sort-regexp
rule to the ESLint Perfectionist plugin that enforces consistent ordering in regular expressions. The rule sorts three main components: regex flags, character class elements, and alternation branches within capture groups or top-level patterns.
Key Changes:
- New rule implementation that sorts regex flags, character classes, and alternation branches
- Comprehensive test suite covering alphabetical, natural, line-length, custom, and unsorted sorting modes
- Documentation and configuration updates to integrate the new rule
Reviewed Changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
rules/sort-regexp.ts | Core rule implementation with sorting logic for regex components |
rules/sort-regexp/types.ts | Type definitions and configuration options for the rule |
test/rules/sort-regexp.test.ts | Extensive test suite covering all sorting modes and edge cases |
docs/content/rules/sort-regexp.mdx | Complete documentation with usage examples and configuration options |
package.json | Added regexpp dependency for regex AST parsing |
index.ts | Exported the new rule in the plugin's rule collection |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
@@ -0,0 +1,2835 @@ | |||
/* Cspell:ignore gimsu igmus yusmig ysumgi Ωmega Δelta */ |
Copilot
AI
Oct 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'gimsu' to 'gimus'
/* Cspell:ignore gimsu igmus yusmig ysumgi Ωmega Δelta */ | |
/* Cspell:ignore gimus igmus yusmig ysumgi Ωmega Δelta */ |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤦
it('sorts character classes', async () => { | ||
let customOptions = { | ||
...options, | ||
type: 'natural', |
Copilot
AI
Oct 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type
property is redundant here since it's already defined in the options object being spread above.
type: 'natural', |
Copilot uses AI. Check for mistakes.
function codePointToString(value: number): string { | ||
return String.fromCodePoint(value) | ||
} |
Copilot
AI
Oct 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is a simple wrapper around String.fromCodePoint
. Consider using the native method directly or add JSDoc comments to explain why this abstraction is needed.
Copilot uses AI. Check for mistakes.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## next #600 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 108 110 +2
Lines 8836 9379 +543
Branches 1695 1791 +96
==========================================
+ Hits 8836 9379 +543 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (9)
rules/sort-regexp/types.ts (1)
64-75
: Prefer const and literal types for exported constantsUse const (and literal typing) to prevent accidental mutation and improve type inference.
-export let allSelectors: Selector[] = ['alias', 'pattern'] +export const allSelectors = ['alias', 'pattern'] as const -export let allModifiers: Modifier[] = [] +export const allModifiers: Modifier[] = [] -export let singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { +export const singleCustomGroupJsonSchema: Record<string, JSONSchema4> = { selector: buildCustomGroupSelectorJsonSchema(allSelectors as unknown as string[]), elementValuePattern: regexJsonSchema, elementNamePattern: regexJsonSchema, }docs/content/rules/sort-regexp.mdx (1)
267-271
: Avoid hardcoding release version until it shipsPackage.json is 4.15.1 in this PR. Don’t claim v5.0.0 yet.
-## Version - -This rule was introduced in [v5.0.0](...). +## Version + +Unreleased (will be included in the next major release). Update this section with the exact tag after publishing.test/rules/sort-regexp.test.ts (2)
1182-1206
: Add guard tests for non-commutative alternations and backrefsTo prevent unsafe fixes, add tests that must not report/fix when reordering could change behavior.
@@ describe('alphabetical', () => { @@ it('works with complex cases', async () => { @@ }) + + it.skip('does not reorder shared-prefix alternatives (behavior would change)', async () => { + await valid({ + // (ab|a) → (a|ab) would change which alternative matches + code: dedent`/(ab|a)/`, + options: [options], + }) + }) + + it.skip('does not reorder when numeric backreferences depend on group order', async () => { + await valid({ + // Reordering changes numbering of (b) vs (d), altering \2 semantics + code: dedent`/(?:c(d)|a(b))\\2/`, + options: [options], + }) + })Please un-skip once the rule detects and bails out for these cases.
2401-2468
: Character class edge cases: ensure fix preserves literal “-” and “]”Sorting must not turn literal “-” into a range or move “]” to an invalid position. Add tests to lock behavior.
@@ describe('line-length', () => { @@ it('sorts character class elements', async () => { @@ }) + + it('preserves literal hyphen placement in character classes', async () => { + await valid({ + code: dedent`/[-ab]/`, // '-' first is safe + options: [options], + }) + await valid({ + code: dedent`/[ab-]/`, // '-' last is safe + options: [options], + }) + await valid({ + code: dedent`/[a\\-b]/`, // escaped '-' is safe anywhere + options: [options], + }) + }) + + it('does not produce invalid character classes with closing bracket', async () => { + await valid({ + code: dedent`/[\\]ab]/`, // ']' escaped inside class + options: [options], + }) + })Run the suite to confirm the fixer never introduces invalid ranges or bracket placement.
rules/sort-regexp.ts (5)
243-248
: Consider skipping character-class sorting under the /v flag until set-operations are handled.ECMAScript’s /v introduces class set operations; naive reordering may change semantics. Either detect and skip when flags include 'v' or add targeted handling/tests.
Add a conservative guard:
onCharacterClassLeave(characterClass) { let { elements, negate, start, end } = characterClass + if (literalNode.regex.flags.includes('v')) { + return + } if (!isSortable(elements)) { return }Please add tests covering intersections/subtractions with /v.
376-379
: Do not enable this rule in “recommended” until unsafe cases are blocked.Given the behavior-changing edge cases above, ship as non‑recommended first. Flip to recommended after guards are in place and tests cover them.
- recommended: true, + recommended: false,
641-649
: Tighten the type guard or include lookarounds intentionally.isCapturingContext never returns true for lookarounds but its predicate type includes LookaroundAssertion. Either add lookarounds to the check or narrow the return type.
function isCapturingContext( node: Alternative['parent'], -): node is LookaroundAssertion | CapturingGroup | Pattern | Group { +): node is CapturingGroup | Pattern | Group { return ( node.type === 'CapturingGroup' || node.type === 'Group' || node.type === 'Pattern' ) }
178-242
: Single-pass visitor for minor perf/readability win.Both visitors traverse the same AST. Merge onAlternativeLeave and onCharacterClassLeave into a single visitRegExpAST call.
Also applies to: 243-348
375-386
: Meta: keep fixers, but consider “suggest only” for alternatives until safe.If you prefer not to flip recommended, make alternative reordering report-only (no fix) when ambiguity is detected; keep autofix for flags/character classes.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
,!pnpm-lock.yaml
📒 Files selected for processing (8)
docs/content/rules/sort-regexp.mdx
(1 hunks)docs/public/llms.txt
(1 hunks)index.ts
(3 hunks)package.json
(1 hunks)readme.md
(1 hunks)rules/sort-regexp.ts
(1 hunks)rules/sort-regexp/types.ts
(1 hunks)test/rules/sort-regexp.test.ts
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
rules/sort-regexp.ts (19)
types/sorting-node.ts (1)
SortingNode
(18-102)rules/sort-regexp/types.ts (5)
Options
(22-41)allSelectors
(65-65)allModifiers
(68-68)Group
(78-78)Selector
(59-59)utils/create-eslint-rule.ts (1)
createEslintRule
(32-35)utils/get-settings.ts (1)
getSettings
(91-136)utils/complete.ts (1)
complete
(30-45)utils/validate-custom-sort-configuration.ts (1)
validateCustomSortConfiguration
(25-35)utils/validate-generated-groups-configuration.ts (1)
validateGeneratedGroupsConfiguration
(74-95)utils/get-eslint-disabled-lines.ts (1)
getEslintDisabledLines
(45-97)utils/sort-nodes.ts (1)
sortNodes
(39-76)utils/create-node-index-map.ts (1)
createNodeIndexMap
(27-35)utils/pairwise.ts (1)
pairwise
(29-44)utils/sort-nodes-by-groups.ts (1)
sortNodesByGroups
(106-162)utils/report-all-errors.ts (1)
reportAllErrors
(203-325)utils/compare.ts (1)
compare
(108-142)utils/common-json-schemas.ts (3)
commonJsonSchemas
(139-140)buildCustomGroupsArrayJsonSchema
(302-351)groupsJsonSchema
(165-190)utils/report-errors.ts (1)
ORDER_ERROR
(21-22)utils/compute-group.ts (1)
computeGroup
(75-113)utils/does-custom-group-match.ts (1)
doesCustomGroupMatch
(121-141)utils/is-node-eslint-disabled.ts (1)
isNodeEslintDisabled
(27-32)
rules/sort-regexp/types.ts (2)
types/common-options.ts (4)
CustomGroupsOption
(103-134)GroupsOptions
(427-433)CommonOptions
(23-73)RegexOption
(459-459)utils/common-json-schemas.ts (2)
buildCustomGroupSelectorJsonSchema
(431-439)regexJsonSchema
(219-228)
test/rules/sort-regexp.test.ts (2)
utils/alphabet.ts (1)
Alphabet
(46-467)test/utils/validate-rule-json-schema.ts (1)
validateRuleJsonSchema
(8-19)
🪛 ESLint
test/rules/sort-regexp.test.ts
[error] 33-33: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 36-36: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 45-45: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 54-54: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 69-69: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 72-72: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 87-87: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 90-90: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 111-111: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 114-114: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 128-128: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 131-131: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 146-146: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 149-149: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 164-164: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 167-167: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 176-176: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 191-191: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 194-194: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 209-209: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 212-212: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 231-231: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 234-234: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 253-253: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 256-256: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 271-271: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 274-274: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 289-289: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 292-292: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 310-310: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 313-313: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 328-328: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 331-331: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 352-352: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 355-355: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 369-369: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 372-372: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 391-391: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 394-394: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 403-403: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 412-412: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 431-431: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 434-434: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 449-449: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 452-452: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 461-461: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 476-476: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 479-479: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 494-494: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 497-497: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 518-518: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 521-521: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 552-552: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 555-555: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 569-569: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 572-572: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 591-591: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 594-594: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 609-609: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 612-612: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 627-627: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 630-630: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 639-639: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 658-658: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 661-661: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 676-676: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 679-679: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 694-694: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 697-697: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 720-720: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 723-723: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 738-738: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 741-741: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 756-756: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 759-759: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 774-774: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 777-777: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 792-792: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 795-795: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 818-818: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 821-821: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 836-836: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 839-839: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 854-854: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 857-857: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 872-872: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 875-875: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 910-910: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 913-913: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 922-922: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 931-931: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 946-946: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 949-949: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 964-964: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 967-967: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 982-982: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 985-985: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1000-1000: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1003-1003: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1018-1018: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1021-1021: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1040-1040: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1043-1043: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1073-1073: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1076-1076: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1091-1091: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1094-1094: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1109-1109: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1112-1112: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1127-1127: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1130-1130: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1145-1145: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1148-1148: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1157-1157: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1166-1166: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1175-1175: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1198-1198: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1201-1201: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1222-1222: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1225-1225: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1234-1234: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1243-1243: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1258-1258: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1261-1261: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1276-1276: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1279-1279: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1300-1300: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1303-1303: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1317-1317: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1320-1320: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1335-1335: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1338-1338: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1353-1353: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1356-1356: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1365-1365: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1380-1380: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 1383-1383: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 1397-1397: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 1400-1400: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 1419-1419: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 1422-1422: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 1442-1442: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1445-1445: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1464-1464: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 1467-1467: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 1482-1482: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1485-1485: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1500-1500: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1503-1503: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1521-1521: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 1524-1524: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 1539-1539: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1542-1542: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1563-1563: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1566-1566: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1580-1580: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1583-1583: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1602-1602: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1605-1605: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1614-1614: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1623-1623: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1642-1642: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1645-1645: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1660-1660: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1663-1663: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1672-1672: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1687-1687: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1690-1690: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1705-1705: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1708-1708: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1729-1729: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1732-1732: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1763-1763: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1766-1766: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1784-1784: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1787-1787: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1802-1802: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1805-1805: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1820-1820: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1823-1823: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1838-1838: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1841-1841: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1850-1850: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1865-1865: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1868-1868: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1883-1883: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1886-1886: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1901-1901: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1904-1904: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1927-1927: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1930-1930: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1945-1945: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1948-1948: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1963-1963: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1966-1966: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1981-1981: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1984-1984: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 1999-1999: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2002-2002: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2021-2021: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2024-2024: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2039-2039: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2042-2042: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2057-2057: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2060-2060: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2075-2075: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2078-2078: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2113-2113: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2116-2116: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2125-2125: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2134-2134: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2149-2149: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2152-2152: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2167-2167: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2170-2170: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2185-2185: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2188-2188: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2203-2203: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2206-2206: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2221-2221: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2224-2224: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2243-2243: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2246-2246: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2276-2276: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2279-2279: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2294-2294: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2297-2297: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2312-2312: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2315-2315: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2330-2330: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2333-2333: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2348-2348: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2351-2351: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2360-2360: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2369-2369: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2378-2378: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2401-2401: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2404-2404: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2419-2419: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2429-2429: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2432-2432: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2447-2447: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2450-2450: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2465-2465: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2468-2468: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2477-2477: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2492-2492: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 2495-2495: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 2513-2513: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 2516-2516: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 2535-2535: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2538-2538: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2547-2547: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2562-2562: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2565-2565: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2580-2580: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2583-2583: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2598-2598: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2601-2601: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2616-2616: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2619-2619: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2628-2628: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2631-2631: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2647-2647: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2650-2650: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2665-2665: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2668-2668: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2683-2683: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 2686-2686: Unsafe call of a(n) error
type typed value.
(typescript/no-unsafe-call)
[error] 2704-2704: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2707-2707: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2722-2722: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2725-2725: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2744-2744: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2747-2747: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2767-2767: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2783-2783: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2786-2786: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2802-2802: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2811-2811: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
[error] 2820-2820: Unsafe use of a(n) error
type typed template tag.
(typescript/no-unsafe-call)
🔇 Additional comments (5)
package.json (1)
60-63
: Dependency addition LGTMAdding @eslint-community/regexpp as a runtime dep matches the rule’s needs. No issues.
readme.md (1)
196-196
: Rule table entry looks goodEntry formatting and link match existing rows.
docs/public/llms.txt (1)
47-47
: Docs index update LGTMConsistent with other entries.
index.ts (1)
23-50
: Rule wiring is correctImport, typing in PluginConfig, and rules map entry are consistent.
Also applies to: 97-98
rules/sort-regexp.ts (1)
1-68
: Test coverage is comprehensive for standard patterns but missing edge cases for newer regex features.The test file contains 156 test cases across 2835 lines and thoroughly covers:
- Non-capturing groups and alternations
- Character classes with ranges and special characters
- All standard flags (i, g, m, s, u, y)
- Complex nested patterns, lookahead/lookbehind assertions
However, the tests do not include:
- The
/v
flag (Unicode Sets, ES2024)- Character class intersection/subtraction operators (
&&
,-
at boundaries)- Character classes with dashes in boundary positions
The code structure (lines 1-68) is solid with proper imports and integration with shared utilities. Whether the missing edge case tests are acceptable depends on the project's scope and target environment compatibility. Verify if these features should be supported.
The rule is **safe** – it only reorders elements without changing their meaning. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docs overstate safety; add caveat and guidance
Reordering alternations is not universally safe (e.g., shared prefixes like (ab|a)
), and numeric backreferences can also change behavior if group numbering shifts after reordering.
- The rule is **safe** – it only reorders elements without changing their meaning.
+ Important: Reordering can change behavior in specific cases (e.g., alternatives that share a prefix like `(ab|a)`, or patterns whose numeric backreferences depend on the textual order of capturing groups). The rule avoids such changes when it detects risk; otherwise, prefer `type: 'unsorted'` or disable the rule locally for those patterns.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
The rule is **safe** – it only reorders elements without changing their meaning. | |
Important: Reordering can change behavior in specific cases (e.g., alternatives that share a prefix like `(ab|a)`, or patterns whose numeric backreferences depend on the textual order of capturing groups). The rule avoids such changes when it detects risk; otherwise, prefer `type: 'unsorted'` or disable the rule locally for those patterns. |
🤖 Prompt for AI Agents
In docs/content/rules/sort-regexp.mdx around lines 22-23, the claim "The rule is
**safe** – it only reorders elements without changing their meaning." overstates
safety; update the text to add a short caveat and guidance: state that
reordering alternations can change behavior for patterns with shared prefixes
(e.g., (ab|a)) and when numeric capture group indices are relied upon by
backreferences, and advise when the rule is safe to apply (alternations are
independent, use non-capturing groups (?:...) or named captures to preserve
backreference semantics) and when to avoid it; include one minimal example of a
problematic case and a recommended fix or workaround (use non-capturing groups
or reorder/escape to preserve intended match) so readers know when to
enable/disable the rule.
let eslintDisabledLines = getEslintDisabledLines({ | ||
ruleName: id, | ||
sourceCode, | ||
}) | ||
|
||
let ast = parseRegExpLiteral(literalNode.raw) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Respect eslint-disable for the literal; bail out early.
Flags/character-class paths will still report even when the rule is disabled on that line. Add an early return after computing disabled lines.
let eslintDisabledLines = getEslintDisabledLines({
ruleName: id,
sourceCode,
})
+ // Skip this literal if the rule is disabled for its line
+ if (isNodeEslintDisabled(literalNode, eslintDisabledLines)) {
+ return
+ }
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In rules/sort-regexp.ts around lines 107 to 112, after computing
eslintDisabledLines with getEslintDisabledLines({ ruleName: id, sourceCode }),
add an early return that checks whether the regexp literal node's starting line
(literalNode.loc.start.line) is disabled for this rule and bail out if so; this
prevents further processing (like parseRegExpLiteral and subsequent
flag/character-class checks) when eslint-disable covers the literal's line.
visitRegExpAST(ast, { | ||
onAlternativeLeave(alternative) { | ||
if ( | ||
!isCapturingContext(alternative.parent) || | ||
!isSortable(alternative.parent.alternatives) | ||
) { | ||
return | ||
} | ||
|
||
if (alternative !== alternative.parent.alternatives.at(-1)) { | ||
return | ||
} | ||
|
||
let nodes = alternative.parent.alternatives.map(currentAlternative => | ||
createSortingNode({ | ||
alternative: currentAlternative, | ||
eslintDisabledLines, | ||
literalNode, | ||
sourceCode, | ||
options, | ||
}), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid behavior-changing fixes when alternatives share a prefix.
Reordering (ab|a) to (a|ab) changes matches. Guard and skip reporting/fixing when any pair of alternatives is a prefix of another.
visitRegExpAST(ast, {
onAlternativeLeave(alternative) {
if (
!isCapturingContext(alternative.parent) ||
!isSortable(alternative.parent.alternatives)
) {
return
}
if (alternative !== alternative.parent.alternatives.at(-1)) {
return
}
+ // Safety: if any two alternatives share a prefix, skip to avoid behavior changes.
+ if (hasAmbiguousPrefixOrder(alternative.parent.alternatives)) {
+ return
+ }
+
let nodes = alternative.parent.alternatives.map(currentAlternative =>
createSortingNode({
alternative: currentAlternative,
eslintDisabledLines,
literalNode,
sourceCode,
options,
}),
)
Add the helper:
+function hasAmbiguousPrefixOrder(alternatives: Alternative[]): boolean {
+ for (let i = 0; i < alternatives.length; i++) {
+ for (let j = i + 1; j < alternatives.length; j++) {
+ let a = alternatives[i]!.raw
+ let b = alternatives[j]!.raw
+ if (a.startsWith(b) || b.startsWith(a)) {
+ return true
+ }
+ }
+ }
+ return false
+}
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In rules/sort-regexp.ts around lines 178-199, the current fix can change regex
behavior when one alternative is a prefix of another (e.g. (ab|a) -> (a|ab)).
Before creating sorting nodes, add a guard that scans
alternative.parent.alternatives and, if any pair of alternatives has a prefix
relationship (one's source/raw startsWith the other's source/raw or vice versa),
skip reporting/fixing by returning early; implement a small helper like
isPrefixPair(a,b) that compares the alternatives' text and use it to detect any
prefix pair and bail out.
let sortedElements = [...elements].toSorted((a, b) => { | ||
let aKey = getCharacterClassElementSortKey(a) | ||
let bKey = getCharacterClassElementSortKey(b) | ||
|
||
if ( | ||
options.type !== 'line-length' && | ||
aKey.category !== bKey.category | ||
) { | ||
let categoryDiff = aKey.category - bKey.category | ||
return options.order === 'asc' ? categoryDiff : -categoryDiff | ||
} | ||
|
||
let aNode = createCharacterClassSortingNode({ | ||
literalNode, | ||
element: a, | ||
}) | ||
let bNode = createCharacterClassSortingNode({ | ||
literalNode, | ||
element: b, | ||
}) | ||
|
||
let comparison = compare({ | ||
fallbackSortNodeValueGetter: null, | ||
nodeValueGetter: null, | ||
a: aNode, | ||
b: bNode, | ||
options, | ||
}) | ||
|
||
if (comparison !== 0) { | ||
return comparison | ||
} | ||
|
||
let rawComparison = aKey.raw.localeCompare( | ||
bKey.raw, | ||
options.locales, | ||
{ | ||
sensitivity: options.ignoreCase ? 'base' : 'variant', | ||
numeric: options.type === 'natural', | ||
}, | ||
) | ||
|
||
let rawOrderMultiplier = 1 | ||
if (options.type !== 'line-length' && options.order !== 'asc') { | ||
rawOrderMultiplier = -1 | ||
} | ||
|
||
return rawOrderMultiplier * rawComparison | ||
}) | ||
|
||
let needsSort = elements.some( | ||
(element, i) => element !== sortedElements[i], | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent accidental ranges in character classes caused by bare '-'.
Sorting can move an unescaped '-' from edges into the middle, turning it into a range. Ensure bare '-' literals are kept at the end (or skip sorting).
- let sortedElements = [...elements].toSorted((a, b) => {
+ let sortedElements = [...elements].toSorted((a, b) => {
let aKey = getCharacterClassElementSortKey(a)
let bKey = getCharacterClassElementSortKey(b)
…
return rawOrderMultiplier * rawComparison
})
+
+ // Safety: keep any bare '-' (raw === '-') at the end to avoid creating unintended ranges.
+ if (sortedElements.some(el => el.type === 'Character' && el.raw === '-')) {
+ let hyphens: typeof sortedElements = []
+ let others: typeof sortedElements = []
+ for (let el of sortedElements) {
+ if (el.type === 'Character' && el.raw === '-') hyphens.push(el)
+ else others.push(el)
+ }
+ sortedElements = [...others, ...hyphens]
+ }
🤖 Prompt for AI Agents
In rules/sort-regexp.ts around lines 254 to 306, the current sort can move an
unescaped '-' literal from an edge into the middle of a character class,
creating an accidental range; modify the comparator so that bare (unescaped) '-'
elements are forced to the end of the sortedElements (or cause the function to
skip sorting when such a move would place '-' in the middle). Concretely: detect
an element that is a literal '-' and not escaped, and give it a sort priority
that always ranks it after all other elements (taking options.order into
account), or bail out of sorting for that character class when preserving edge
'-' placement cannot be guaranteed. Ensure this change only applies to unescaped
'-' and leaves other elements’ ordering logic intact.
Description
A new rule for sorting regular expressions is added. It works with:
/(error|warning|info|debug)/
)/[zxa-f0-9A-Z]/
)/pattern/igmus
)Additional context
...
TODO:
At the moment the rule blindly reorders alternatives (e.g. (ab|a) becomes (a|ab)), which changes the behaviour of the regular expression.
We need to detect when alternatives share the same prefix and, in that case, avoid reporting an error or applying a fix.
What is the purpose of this pull request?
Before submitting the PR, please make sure you do the following