Repository: eslint/eslint
File: lib/rules/no-invalid-regexp.js (JavaScript)

Code before:
             * `regexpp` checks the combination of `u` and `v` flags when parsing `Pattern` according to `ecma262`,
             * but this rule may check only the flag when the pattern is unidentifiable, so check it here.
             * https://tc39.es/ecma262/multipage/text-processing.html#sec-parsepattern
             */
            if (flags.includes("u") && flags.includes("v")) {
                return "Regex 'u' and 'v' flags cannot be used together";
            }
            return null;
        }

        return {
            "CallExpression, NewExpression"(node) {
                if (node.callee.type !== "Identifier" || node.callee.name !== "RegExp") {
                    return;
                }

                const flags = getFlags(node);
                let flagsToCheck = flags;

                if (flags && allowedFlags && allowedFlags.length > 0) {
                    allowedFlags.forEach(flag => {
                        flagsToCheck = flagsToCheck.replace(flag, "");
                    });
                }

                let message = validateRegExpFlags(flagsToCheck);

                if (message) {
                    report(node, message);
                    return;
                }

                if (!isString(node.arguments[0])) {
                    return;
                }

                const pattern = node.arguments[0].value;

                message = (

                    // If flags are unknown, report the regex only if its pattern is invalid both with and without the "u" flag
                    flags === null
                        ? (
                            validateRegExpPattern(pattern, { unicode: true, unicodeSets: false }) &&
                            validateRegExpPattern(pattern, { unicode: false, unicodeSets: true }) &&
                            validateRegExpPattern(pattern, { unicode: false, unicodeSets: false })
                        )
                        : validateRegExpPattern(pattern, { unicode: flags.includes("u"), unicodeSets: flags.includes("v") })
                );

                if (message) {

Review comment (bug):
Maybe we should pass both the original and the filtered flags to the validation function:

```suggestion
                let message = validateRegExpFlags(flags, flagsToCheck);
```

In `validateRegExpFlags()` we could then validate the `flagsToCheck`, but if the validation fails, we could include all the original flags in the error message.

```js
        function validateRegExpFlags(flags, flagsToCheck) {
            if (!flagsToCheck) {
                return null;
            }
            try {
                validator.validateFlags(flagsToCheck);
            } catch {
                return `Invalid flags supplied to RegExp constructor '${flags}'`;
            }
```

This would retain the current error message in the case of predefined flags, and also remove the inconsistency when the message includes custom flags.

An additional error message for duplicated flags would be nice, but that could be added as a feature in another PR.

Code after:

            /*
             * `regexpp` checks the combination of `u` and `v` flags when parsing `Pattern` according to `ecma262`,
             * but this rule may check only the flag when the pattern is unidentifiable, so check it here.
             * https://tc39.es/ecma262/multipage/text-processing.html#sec-parsepattern
             */
            if (flags && flags.includes("u") && flags.includes("v")) {
                return "Regex 'u' and 'v' flags cannot be used together";
            }

            if (!flagsToCheck) {
                return null;
            }

            return `Invalid flags supplied to RegExp constructor '${flagsToReport.join("")}'`;
        }

        return {
            "CallExpression, NewExpression"(node) {
                if (node.callee.type !== "Identifier" || node.callee.name !== "RegExp") {
                    return;
                }

                const flags = getFlags(node);
                let flagsToCheck = flags;
                const allFlags = allowedFlags.length > 0 ? validFlags.split("").concat(allowedFlags) : validFlags.split("");

                if (flags) {
                    allFlags.forEach(flag => {
                        flagsToCheck = flagsToCheck.replace(flag, "");
                    });
                }

                let message = validateRegExpFlags(flags, flagsToCheck);

                if (message) {
                    report(node, message);
                    return;
                }

                if (!isString(node.arguments[0])) {
                    return;
                }

                const pattern = node.arguments[0].value;

                message = (

                    // If flags are unknown, report the regex only if its pattern is invalid both with and without the "u" flag
                    flags === null
                        ? (