diff --git a/rules/better-regex.js b/rules/better-regex.js index dcb6184277..d12081fc66 100644 --- a/rules/better-regex.js +++ b/rules/better-regex.js @@ -6,8 +6,10 @@ const {newExpressionSelector} = require('./selectors/index.js'); const {isStringLiteral} = require('./ast/index.js'); const MESSAGE_ID = 'better-regex'; +const MESSAGE_ID_PARSE_ERROR = 'better-regex/parse-error'; const messages = { [MESSAGE_ID]: '{{original}} can be optimized to {{optimized}}.', + [MESSAGE_ID_PARSE_ERROR]: 'Problem parsing {{original}}: {{error}}', }; const newRegExp = newExpressionSelector({name: 'RegExp', minimumArguments: 1}); @@ -39,11 +41,11 @@ const create = context => { } catch (error) { return { node, + messageId: MESSAGE_ID_PARSE_ERROR, data: { original, error: error.message, }, - message: 'Problem parsing {{original}}: {{error}}', }; } diff --git a/rules/prefer-string-replace-all.js b/rules/prefer-string-replace-all.js index 8e925bed2a..fd69042d07 100644 --- a/rules/prefer-string-replace-all.js +++ b/rules/prefer-string-replace-all.js @@ -27,11 +27,17 @@ function getPatternReplacement(node) { return; } - const tree = parseRegExp(pattern, flags, { - unicodePropertyEscape: true, - namedGroups: true, - lookbehind: true, - }); + let tree; + + try { + tree = parseRegExp(pattern, flags, { + unicodePropertyEscape: true, + namedGroups: true, + lookbehind: true, + }); + } catch { + return; + } const parts = tree.type === 'alternative' ? tree.body : [tree]; if (parts.some(part => part.type !== 'value')) { diff --git a/test/better-regex.mjs b/test/better-regex.mjs index de3ec56bc0..1c6cefc18c 100644 --- a/test/better-regex.mjs +++ b/test/better-regex.mjs @@ -323,3 +323,11 @@ test({ }, ], }); + +test.snapshot({ + valid: [], + invalid: [ + // Invalid RegExp + '/(?!a)+/g', + ], +}); diff --git a/test/prefer-string-replace-all.mjs b/test/prefer-string-replace-all.mjs index d8226d698d..e742f84c3b 100644 --- a/test/prefer-string-replace-all.mjs +++ b/test/prefer-string-replace-all.mjs @@ -103,5 +103,8 @@ test.snapshot({ 'foo.replaceAll(/a]/g, _)', 'foo.replaceAll(/\\r\\n\\u{1f600}/gu, _)', `foo.replaceAll(/a${' very'.repeat(30)} long string/g, _)`, + + // Invalid RegExp #2010 + 'foo.replace(/(?!a)+/g, "")', ], }); diff --git a/test/snapshots/better-regex.mjs.md b/test/snapshots/better-regex.mjs.md new file mode 100644 index 0000000000..ad358abe96 --- /dev/null +++ b/test/snapshots/better-regex.mjs.md @@ -0,0 +1,19 @@ +# Snapshot report for `test/better-regex.mjs` + +The actual snapshot is saved in `better-regex.mjs.snap`. + +Generated by [AVA](https://avajs.dev). + +## Invalid #1 + 1 | /(?!a)+/g + +> Error 1/1 + + `␊ + > 1 | /(?!a)+/g␊ + | ^^^^^^^^^ Problem parsing /(?!a)+/g: ␊ + ␊ + /(?!a)+/g␊ + ^␊ + Unexpected token: "+" at 1:6.␊ + ` diff --git a/test/snapshots/better-regex.mjs.snap b/test/snapshots/better-regex.mjs.snap new file mode 100644 index 0000000000..344e9979f7 Binary files /dev/null and b/test/snapshots/better-regex.mjs.snap differ diff --git a/test/snapshots/prefer-string-replace-all.mjs.md b/test/snapshots/prefer-string-replace-all.mjs.md index 56aa976f28..ead98c4bb3 100644 --- a/test/snapshots/prefer-string-replace-all.mjs.md +++ b/test/snapshots/prefer-string-replace-all.mjs.md @@ -613,3 +613,19 @@ Generated by [AVA](https://avajs.dev). > 1 | foo.replaceAll(/a very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long string/g, _)␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This pattern can be replaced with a string literal.␊ ` + +## Invalid #38 + 1 | foo.replace(/(?!a)+/g, "") + +> Output + + `␊ + 1 | foo.replaceAll(/(?!a)+/g, "")␊ + ` + +> Error 1/1 + + `␊ + > 1 | foo.replace(/(?!a)+/g, "")␊ + | ^^^^^^^ Prefer \`String#replaceAll()\` over \`String#replace()\`.␊ + ` diff --git a/test/snapshots/prefer-string-replace-all.mjs.snap b/test/snapshots/prefer-string-replace-all.mjs.snap index aa0b930b23..8e01a4e09c 100644 Binary files a/test/snapshots/prefer-string-replace-all.mjs.snap and b/test/snapshots/prefer-string-replace-all.mjs.snap differ