Skip to content

Commit

Permalink
Fix: prefer-named-capture-group incorrect locations (fixes #12233)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdjermanovic committed Sep 8, 2019
1 parent e10eeba commit 11ab0be
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 9 deletions.
36 changes: 27 additions & 9 deletions lib/rules/prefer-named-capture-group.js
Expand Up @@ -50,16 +50,16 @@ module.exports = {
/**
* Function to check regular expression.
*
* @param {string} regex The regular expression to be check.
* @param {string} pattern The regular expression pattern to be check.
* @param {ASTNode} node AST node which contains regular expression.
* @param {boolean} uFlag Flag indicates whether unicode mode is enabled or not.
* @returns {void}
*/
function checkRegex(regex, node, uFlag) {
function checkRegex(pattern, node, uFlag) {
let ast;

try {
ast = parser.parsePattern(regex, 0, regex.length, uFlag);
ast = parser.parsePattern(pattern, 0, pattern.length, uFlag);
} catch (_) {

// ignore regex syntax errors
Expand All @@ -69,12 +69,22 @@ module.exports = {
regexpp.visitRegExpAST(ast, {
onCapturingGroupEnter(group) {
if (!group.name) {
const locNode = node.type === "Literal" ? node : node.arguments[0];
let locNode, rawPattern, loc;

if (node.type === "Literal") {
locNode = node;
rawPattern = locNode.raw.slice(1, locNode.raw.lastIndexOf("/"));
} else {
locNode = node.arguments[0];
if (locNode.type === "Literal" && typeof locNode.value === "string") {
rawPattern = locNode.raw.slice(1, -1);
} else if (locNode.type === "TemplateLiteral" && locNode.expressions.length === 0 && locNode.quasis.length === 1) {
rawPattern = locNode.quasis[0].value.raw;
}
}

context.report({
node,
messageId: "required",
loc: {
if (pattern === rawPattern && locNode.loc.start.line === locNode.loc.end.line) {
loc = {
start: {
line: locNode.loc.start.line,
column: locNode.loc.start.column + group.start + 1
Expand All @@ -83,7 +93,15 @@ module.exports = {
line: locNode.loc.start.line,
column: locNode.loc.start.column + group.end + 1
}
},
};
} else {
loc = locNode.loc;
}

context.report({
node,
messageId: "required",
loc,
data: {
group: group.raw
}
Expand Down
125 changes: 125 additions & 0 deletions tests/lib/rules/prefer-named-capture-group.js
Expand Up @@ -70,6 +70,17 @@ ruleTester.run("prefer-named-capture-group", rule, {
endColumn: 19
}]
},
{
code: "new RegExp(`a(bc)d`)",
errors: [{
messageId: "required",
type: "NewExpression",
data: { group: "(bc)" },
line: 1,
column: 14,
endColumn: 18
}]
},
{
code: "/([0-9]{4})-(\\w{5})/",
errors: [
Expand All @@ -90,6 +101,120 @@ ruleTester.run("prefer-named-capture-group", rule, {
endColumn: 20
}
]
},

// For computed, multiline and strings with escape sequences, report the whole arguments[0] location.
{
code: "new RegExp('(' + 'a)')",
errors: [{
messageId: "required",
type: "NewExpression",
data: { group: "(a)" },
line: 1,
column: 12,
endColumn: 22
}]
},
{
code: "new RegExp('a(bc)d' + 'e')",
errors: [{
messageId: "required",
type: "NewExpression",
data: { group: "(bc)" },
line: 1,
column: 12,
endColumn: 26
}]
},
{
code: "RegExp('(a)'+'')",
errors: [{
messageId: "required",
type: "CallExpression",
data: { group: "(a)" },
line: 1,
column: 8,
endColumn: 16
}]
},
{
code: "RegExp( '' + '(ab)')",
errors: [{
messageId: "required",
type: "CallExpression",
data: { group: "(ab)" },
line: 1,
column: 9,
endColumn: 20
}]
},
{
code: "new RegExp(`(ab)${''}`)",
errors: [{
messageId: "required",
type: "NewExpression",
data: { group: "(ab)" },
line: 1,
column: 12,
endColumn: 23
}]
},
{
code: "new RegExp(`(a)\n`)",
errors: [{
messageId: "required",
type: "NewExpression",
data: { group: "(a)" },
line: 1,
column: 12,
endLine: 2,
endColumn: 2
}]
},
{
code: "RegExp(`a(b\nc)d`)",
errors: [{
messageId: "required",
type: "CallExpression",
data: { group: "(b\nc)" },
line: 1,
column: 8,
endLine: 2,
endColumn: 5
}]
},
{
code: "new RegExp('a(b)\\'')",
errors: [{
messageId: "required",
type: "NewExpression",
data: { group: "(b)" },
line: 1,
column: 12,
endColumn: 20
}]
},
{
code: "RegExp('(a)\\\\d')",
errors: [{
messageId: "required",
type: "CallExpression",
data: { group: "(a)" },
line: 1,
column: 8,
endColumn: 16
}]
},
{
code: "RegExp(`\\a(b)`)",
errors: [{
messageId: "required",
type: "CallExpression",
data: { group: "(b)" },
line: 1,
column: 8,
endColumn: 15
}]
}
]
});

0 comments on commit 11ab0be

Please sign in to comment.