Blame view

node_modules/eslint/lib/rules/no-regex-spaces.js 3.61 KB
f7563de62   Palak Handa   first commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  /**
   * @fileoverview Rule to count multiple spaces in regular expressions
   * @author Matt DuVall <http://www.mattduvall.com/>
   */
  
  "use strict";
  
  const astUtils = require("../ast-utils");
  
  //------------------------------------------------------------------------------
  // Rule Definition
  //------------------------------------------------------------------------------
  
  module.exports = {
      meta: {
          docs: {
              description: "disallow multiple spaces in regular expressions",
              category: "Possible Errors",
              recommended: true
          },
  
          schema: [],
  
          fixable: "code"
      },
  
      create(context) {
          const sourceCode = context.getSourceCode();
  
          /**
           * Validate regular expressions
           * @param {ASTNode} node node to validate
           * @param {string} value regular expression to validate
           * @param {number} valueStart The start location of the regex/string literal. It will always be the case that
           `sourceCode.getText().slice(valueStart, valueStart + value.length) === value`
           * @returns {void}
           * @private
           */
          function checkRegex(node, value, valueStart) {
              const multipleSpacesRegex = /( {2,})+?/,
                  regexResults = multipleSpacesRegex.exec(value);
  
              if (regexResults !== null) {
                  const count = regexResults[0].length;
  
                  context.report({
                      node,
                      message: "Spaces are hard to count. Use {{{count}}}.",
                      data: { count },
                      fix(fixer) {
                          return fixer.replaceTextRange(
                              [valueStart + regexResults.index, valueStart + regexResults.index + count],
                              ` {${count}}`
                          );
                      }
                  });
  
                  /*
                   * TODO: (platinumazure) Fix message to use rule message
                   * substitution when api.report is fixed in lib/eslint.js.
                   */
              }
          }
  
          /**
           * Validate regular expression literals
           * @param {ASTNode} node node to validate
           * @returns {void}
           * @private
           */
          function checkLiteral(node) {
              const token = sourceCode.getFirstToken(node),
                  nodeType = token.type,
                  nodeValue = token.value;
  
              if (nodeType === "RegularExpression") {
                  checkRegex(node, nodeValue, token.start);
              }
          }
  
          /**
           * Check if node is a string
           * @param {ASTNode} node node to evaluate
           * @returns {boolean} True if its a string
           * @private
           */
          function isString(node) {
              return node && node.type === "Literal" && typeof node.value === "string";
          }
  
          /**
           * Validate strings passed to the RegExp constructor
           * @param {ASTNode} node node to validate
           * @returns {void}
           * @private
           */
          function checkFunction(node) {
              const scope = context.getScope();
              const regExpVar = astUtils.getVariableByName(scope, "RegExp");
              const shadowed = regExpVar && regExpVar.defs.length > 0;
  
              if (node.callee.type === "Identifier" && node.callee.name === "RegExp" && isString(node.arguments[0]) && !shadowed) {
                  checkRegex(node, node.arguments[0].value, node.arguments[0].start + 1);
              }
          }
  
          return {
              Literal: checkLiteral,
              CallExpression: checkFunction,
              NewExpression: checkFunction
          };
  
      }
  };