Repository: eslint/eslint
File: lib/rules/require-unicode-regexp.js (JavaScript)

Code before:
/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Enforce the use of `u` and `v` flag on RegExp",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/require-unicode-regexp"
        },

        hasSuggestions: true,

        messages: {
            addUFlag: "Add the 'u' flag.",
            requireUFlag: "Use the 'u' flag.",
            addVFlag: "Add the 'v' flag.",
            requireVFlag: "Use the 'v' flag."
        },

        schema: [{
            type: "object",
            properties: {
                requiredUnicodeFlag: {
                    type: "string",
                    enum: ["u", "v"]
                }
            },
            additionalProperties: false,
            description: "The required flag. If this is not specified, this rule allows both 'u' and 'v' flags."
        }]
    },

    create(context) {

        const sourceCode = context.sourceCode;

        const config = context.options[0] || {};
        const requiredUnicodeFlag = config.requiredUnicodeFlag || null;

        const isRequiredUFlagOnly = requiredUnicodeFlag === "u";
        const isRequiredVFlagOnly = requiredUnicodeFlag === "v";

        /**
         * Checks whether or not the given flags include the required flags.
         * @param {string} flags RegExp flags
         * @returns {{ shouldReportForUFlag: boolean, shouldReportForVFlag: boolean }} `true` if the given flags include the required flags.
         */
        function shouldReport(flags) {
            const includesUFlag = flags.includes("u");
            const includesVFlag = flags.includes("v");

Review comment (suggestion):
I don't think completely disallowing the `v` flag (by requiring the `u` flag) makes sense for this rule.

For example:

```js
/* eslint require-unicode-regexp: ["error", { requiredUnicodeFlag: "u" }] */

const regex = /[[a-z]--[j-n]]/v; // error: Use the 'u' flag.

```

In this regex, the `v` flag cannot be simply replaced with the `u` flag, so this rule would be basically disallowing using the new syntax in patterns.

I think, for the start, the rule should just allow regular expressions with the `v` flag, and maybe have an additional suggestion to add the `v` flag for those that have neither `u` nor `v`. Later, if there is a request, we could consider adding options to enforce a particular flag.

Code after:
/** @type {import('../shared/types').Rule} */
module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "Enforce the use of `u` or `v` flag on RegExp",
            recommended: false,
            url: "https://eslint.org/docs/latest/rules/require-unicode-regexp"
        },

        hasSuggestions: true,

        messages: {
            addUFlag: "Add the 'u' flag.",
            requireUFlag: "Use the 'u' flag."
        },

        schema: []
    },

    create(context) {

        const sourceCode = context.sourceCode;

        return {
            "Literal[regex]"(node) {
                const flags = node.regex.flags || "";

                if (!flags.includes("u") && !flags.includes("v")) {
                    context.report({
                        messageId: "requireUFlag",
                        node,
                        suggest: isValidWithUnicodeFlag(context.languageOptions.ecmaVersion, node.regex.pattern)
                            ? [
                                {
                                    fix(fixer) {
                                        return fixer.insertTextAfter(node, "u");
                                    },
                                    messageId: "addUFlag"
                                }
                            ]
                            : null
                    });
                }
            },

            Program(node) {
                const scope = sourceCode.getScope(node);
                const tracker = new ReferenceTracker(scope);
                const trackMap = {