Skip to content

Commit 6e07030

Browse files
Fix control-character-escape false negatives (#327)
1 parent 4b01aa5 commit 6e07030

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

lib/rules/control-character-escape.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { PatternRange } from "../utils/ast-utils/pattern-source"
12
import type { RegExpVisitor } from "regexpp/visitor"
23
import type { RegExpContext } from "../utils"
34
import {
@@ -21,6 +22,26 @@ const CONTROL_CHARS = new Map<number, string>([
2122
[CP_CR, "\\r"],
2223
])
2324

25+
/**
26+
* Returns whether the regex is represented by a RegExp literal in source code
27+
* at the given range.
28+
*/
29+
function isRegExpLiteralAt(
30+
{ node, patternSource }: RegExpContext,
31+
at: PatternRange,
32+
): boolean {
33+
if (isRegexpLiteral(node)) {
34+
return true
35+
}
36+
37+
const replaceRange = patternSource.getReplaceRange(at)
38+
if (replaceRange && replaceRange.type === "RegExp") {
39+
return true
40+
}
41+
42+
return false
43+
}
44+
2445
export default createRule("control-character-escape", {
2546
meta: {
2647
docs: {
@@ -40,11 +61,11 @@ export default createRule("control-character-escape", {
4061
/**
4162
* Create visitor
4263
*/
43-
function createVisitor({
44-
node,
45-
getRegexpLocation,
46-
fixReplaceNode,
47-
}: RegExpContext): RegExpVisitor.Handlers {
64+
function createVisitor(
65+
regexpContext: RegExpContext,
66+
): RegExpVisitor.Handlers {
67+
const { node, getRegexpLocation, fixReplaceNode } = regexpContext
68+
4869
return {
4970
onCharacterEnter(cNode) {
5071
if (cNode.parent.type === "CharacterClassRange") {
@@ -62,7 +83,7 @@ export default createRule("control-character-escape", {
6283
return
6384
}
6485
if (
65-
!isRegexpLiteral(node) &&
86+
!isRegExpLiteralAt(regexpContext, cNode) &&
6687
cNode.raw === String.fromCodePoint(cNode.value)
6788
) {
6889
// we allow the direct usage of control characters in

tests/lib/rules/control-character-escape.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,5 +108,12 @@ tester.run("control-character-escape", rule as any, {
108108
"Unexpected control character escape '\\u0009' (U+0009). Use '\\t' instead.",
109109
],
110110
},
111+
{
112+
code: String.raw`RegExp("\t\r\n\0" + / /.source)`,
113+
output: String.raw`RegExp("\t\r\n\0" + /\t/.source)`,
114+
errors: [
115+
"Unexpected control character escape '\t' (U+0009). Use '\\t' instead.",
116+
],
117+
},
111118
],
112119
})

0 commit comments

Comments
 (0)