• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * @fileoverview Rule to flag the use of empty character classes in regular expressions
3 * @author Ian Christian Myers
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Helpers
10//------------------------------------------------------------------------------
11
12/*
13 * plain-English description of the following regexp:
14 * 0. `^` fix the match at the beginning of the string
15 * 1. `\/`: the `/` that begins the regexp
16 * 2. `([^\\[]|\\.|\[([^\\\]]|\\.)+\])*`: regexp contents; 0 or more of the following
17 * 2.0. `[^\\[]`: any character that's not a `\` or a `[` (anything but escape sequences and character classes)
18 * 2.1. `\\.`: an escape sequence
19 * 2.2. `\[([^\\\]]|\\.)+\]`: a character class that isn't empty
20 * 3. `\/` the `/` that ends the regexp
21 * 4. `[gimuy]*`: optional regexp flags
22 * 5. `$`: fix the match at the end of the string
23 */
24const regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+\])*\/[gimuys]*$/u;
25
26//------------------------------------------------------------------------------
27// Rule Definition
28//------------------------------------------------------------------------------
29
30module.exports = {
31    meta: {
32        type: "problem",
33
34        docs: {
35            description: "disallow empty character classes in regular expressions",
36            category: "Possible Errors",
37            recommended: true,
38            url: "https://eslint.org/docs/rules/no-empty-character-class"
39        },
40
41        schema: [],
42
43        messages: {
44            unexpected: "Empty class."
45        }
46    },
47
48    create(context) {
49        const sourceCode = context.getSourceCode();
50
51        return {
52
53            Literal(node) {
54                const token = sourceCode.getFirstToken(node);
55
56                if (token.type === "RegularExpression" && !regex.test(token.value)) {
57                    context.report({ node, messageId: "unexpected" });
58                }
59            }
60
61        };
62
63    }
64};
65