diff --git a/lib/rules/invalid-regex-rule.js b/lib/rules/invalid-regex-rule.js index 540ec8b..a5450e2 100644 --- a/lib/rules/invalid-regex-rule.js +++ b/lib/rules/invalid-regex-rule.js @@ -28,8 +28,9 @@ function foundStartLocation(source, foundAt) { * @param {{ regex: RegExp, id: string | undefined, message: string | undefined }} pattern Information of the pattern to be use to inspect. * @param {*} replace Replacement function * @param {Function} report Report function + * @param {*[]} [suggestions] Array of suggestion functions. */ -function checkRegex(source, pattern, replace, report) { +function checkRegex(source, pattern, replace, report, suggestions = []) { /** * @param {string} source Text to be checked. * @param {RegExp} regex Regular Expression use to check. @@ -53,7 +54,11 @@ function checkRegex(source, pattern, replace, report) { report({ loc: { start: foundStartLocation(source, matchDetail.matchStart) }, message, - fix: replace(0, matchDetail) + fix: replace(0, matchDetail), + suggest: suggestions.map(s => ({ + desc: s.message, + fix: s.replacement(0, matchDetail), + })), }) } } @@ -106,14 +111,27 @@ function createReplacement(replacement) { } function checkPatterns(fileName, source, patterns, report) { - patterns.forEach(pattern => shouldCheck(pattern.files, fileName) && - checkRegex(source, pattern, createReplacement(pattern.details.replacement), report)) + patterns.forEach(pattern => { + if (!shouldCheck(pattern.files, fileName)) { + return + } + + const replacement = createReplacement(pattern.details.replacement) + let suggestions = pattern.details.suggestions || [] + suggestions = suggestions.map((d) => ({ + message: d.message, + replacement: createReplacement(d.replacement) + })) + + checkRegex(source, pattern, replacement, report, suggestions) + }) } module.exports = { meta: { type: 'suggestion', fixable: 'code', + hasSuggestions: true, docs: { description: 'Invalid regular expressions to be reported', category: 'Stylistic Issues', @@ -168,15 +186,53 @@ module.exports = { maxProperties: 1 }] }, - message: { - title: 'Invalid message', - description: 'Message to be shown when Invalid pattern is found', - type: 'string', - minLength: 3 + suggestions: { + type: 'array', + description: 'Array of suggestions to be used when the pattern is found', + title: 'Suggestions', + items: { + type: 'object', + description: 'Suggestion to be used when the pattern is found', + properties: { + message: { + title: 'Suggestion message', + description: 'Message to be shown when the suggestion is applied', + type: 'string', + minLength: 3 + }, + replacement: { + oneOf: [{ + title: 'Replacement', + description: 'Replacement for invalid pattern', + type: 'string' + }, { + title: 'Detailed replacement', + description: 'Detailed replacements for invalid patterns', + type: 'object', + properties: { + function: { + title: 'Replacement function', + description: 'Function used to replace the found pattern. It receives the found text and must return the replacement text', + type: 'string', + minLength: 1 + } + }, + minProperties: 1, + maxProperties: 1 + }] + } + }, + }, + message: { + title: 'Invalid message', + description: 'Message to be shown when Invalid pattern is found', + type: 'string', + minLength: 3 + }, + files: FILES_FIELD_DEFINITION }, - files: FILES_FIELD_DEFINITION - }, - required: ['regex'] + required: ['regex'] + } }] }, minItems: 1