Skip to content

Commit b3baa15

Browse files
Added prefer-named-backreference rule (#140)
1 parent 4120db6 commit b3baa15

File tree

6 files changed

+118
-0
lines changed

6 files changed

+118
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ The rules with the following star :star: are included in the `plugin:regexp/reco
118118
| [regexp/prefer-character-class](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-character-class.html) | enforce using character class | :wrench: |
119119
| [regexp/prefer-d](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-d.html) | enforce using `\d` | :star::wrench: |
120120
| [regexp/prefer-escape-replacement-dollar-char](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-escape-replacement-dollar-char.html) | enforces escape of replacement `$` character (`$$`). | |
121+
| [regexp/prefer-named-backreference](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-named-backreference.html) | enforce using named backreferences | :wrench: |
121122
| [regexp/prefer-plus-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-plus-quantifier.html) | enforce using `+` quantifier | :star::wrench: |
122123
| [regexp/prefer-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-quantifier.html) | enforce using quantifier | :wrench: |
123124
| [regexp/prefer-question-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-question-quantifier.html) | enforce using `?` quantifier | :star::wrench: |

docs/rules/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ The rules with the following star :star: are included in the `plugin:regexp/reco
4646
| [regexp/prefer-character-class](./prefer-character-class.md) | enforce using character class | :wrench: |
4747
| [regexp/prefer-d](./prefer-d.md) | enforce using `\d` | :star::wrench: |
4848
| [regexp/prefer-escape-replacement-dollar-char](./prefer-escape-replacement-dollar-char.md) | enforces escape of replacement `$` character (`$$`). | |
49+
| [regexp/prefer-named-backreference](./prefer-named-backreference.md) | enforce using named backreferences | :wrench: |
4950
| [regexp/prefer-plus-quantifier](./prefer-plus-quantifier.md) | enforce using `+` quantifier | :star::wrench: |
5051
| [regexp/prefer-quantifier](./prefer-quantifier.md) | enforce using quantifier | :wrench: |
5152
| [regexp/prefer-question-quantifier](./prefer-question-quantifier.md) | enforce using `?` quantifier | :star::wrench: |
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
pageClass: "rule-details"
3+
sidebarDepth: 0
4+
title: "regexp/prefer-named-backreference"
5+
description: "enforce using named backreferences"
6+
---
7+
# regexp/prefer-named-backreference
8+
9+
> enforce using named backreferences
10+
11+
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge>
12+
- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
13+
14+
## :book: Rule Details
15+
16+
This rule reports and fixes backreferences that do not use the name of their referenced capturing group.
17+
18+
<eslint-code-block fix>
19+
20+
```js
21+
/* eslint regexp/prefer-named-backreference: "error" */
22+
23+
/* ✓ GOOD */
24+
var foo = /(a)\1/
25+
var foo = /(?<foo>a)\k<foo>/
26+
27+
/* ✗ BAD */
28+
var foo = /(?<foo>a)\1/
29+
```
30+
31+
</eslint-code-block>
32+
33+
## :wrench: Options
34+
35+
Nothing.
36+
37+
## :mag: Implementation
38+
39+
- [Rule source](https://github.com/ota-meshi/eslint-plugin-regexp/blob/master/lib/rules/prefer-named-backreference.ts)
40+
- [Test source](https://github.com/ota-meshi/eslint-plugin-regexp/blob/master/tests/lib/rules/prefer-named-backreference.ts)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import type { Expression } from "estree"
2+
import type { RegExpVisitor } from "regexpp/visitor"
3+
import {
4+
createRule,
5+
defineRegexpVisitor,
6+
fixReplaceNode,
7+
getRegexpLocation,
8+
} from "../utils"
9+
10+
export default createRule("prefer-named-backreference", {
11+
meta: {
12+
docs: {
13+
description: "enforce using named backreferences",
14+
recommended: false,
15+
},
16+
fixable: "code",
17+
schema: [],
18+
messages: {
19+
unexpected: "Unexpected unnamed backreference.",
20+
},
21+
type: "suggestion", // "problem",
22+
},
23+
create(context) {
24+
const sourceCode = context.getSourceCode()
25+
26+
/**
27+
* Create visitor
28+
* @param node
29+
*/
30+
function createVisitor(node: Expression): RegExpVisitor.Handlers {
31+
return {
32+
onBackreferenceEnter(bNode) {
33+
if (bNode.resolved.name && !bNode.raw.startsWith("\\k<")) {
34+
context.report({
35+
node,
36+
loc: getRegexpLocation(sourceCode, node, bNode),
37+
messageId: "unexpected",
38+
fix: fixReplaceNode(
39+
sourceCode,
40+
node,
41+
bNode,
42+
() => `\\k<${bNode.resolved.name}>`,
43+
),
44+
})
45+
}
46+
},
47+
}
48+
}
49+
50+
return defineRegexpVisitor(context, {
51+
createVisitor,
52+
})
53+
},
54+
})

lib/utils/rules.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import orderInCharacterClass from "../rules/order-in-character-class"
3434
import preferCharacterClass from "../rules/prefer-character-class"
3535
import preferD from "../rules/prefer-d"
3636
import preferEscapeReplacementDollarChar from "../rules/prefer-escape-replacement-dollar-char"
37+
import preferNamedBackreference from "../rules/prefer-named-backreference"
3738
import preferPlusQuantifier from "../rules/prefer-plus-quantifier"
3839
import preferQuantifier from "../rules/prefer-quantifier"
3940
import preferQuestionQuantifier from "../rules/prefer-question-quantifier"
@@ -81,6 +82,7 @@ export const rules = [
8182
preferCharacterClass,
8283
preferD,
8384
preferEscapeReplacementDollarChar,
85+
preferNamedBackreference,
8486
preferPlusQuantifier,
8587
preferQuantifier,
8688
preferQuestionQuantifier,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { RuleTester } from "eslint"
2+
import rule from "../../../lib/rules/prefer-named-backreference"
3+
4+
const tester = new RuleTester({
5+
parserOptions: {
6+
ecmaVersion: 2020,
7+
sourceType: "module",
8+
},
9+
})
10+
11+
tester.run("prefer-named-backreference", rule as any, {
12+
valid: [`/(a)\\1/`, `/(?<foo>a)\\k<foo>/`, `/(a)\\1 (?<foo>a)\\k<foo>/`],
13+
invalid: [
14+
{
15+
code: `/(?<foo>a)\\1/`,
16+
output: `/(?<foo>a)\\k<foo>/`,
17+
errors: [{ messageId: "unexpected" }],
18+
},
19+
],
20+
})

0 commit comments

Comments
 (0)