Blame view

node_modules/eslint/lib/rules/init-declarations.js 3.59 KB
c39994410   Ryan Glover   wip converting to...
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
115
116
117
118
119
120
  /**
   * @fileoverview A rule to control the style of variable initializations.
   * @author Colin Ihrig
   * @copyright 2015 Colin Ihrig. All rights reserved.
   */
  
  "use strict";
  
  //------------------------------------------------------------------------------
  // Helpers
  //------------------------------------------------------------------------------
  
  /**
   * Checks whether or not a given node is a for loop.
   * @param {ASTNode} block - A node to check.
   * @returns {boolean} `true` when the node is a for loop.
   */
  function isForLoop(block) {
      return block.type === "ForInStatement" ||
      block.type === "ForOfStatement" ||
      block.type === "ForStatement";
  }
  
  /**
   * Checks whether or not a given declarator node has its initializer.
   * @param {ASTNode} node - A declarator node to check.
   * @returns {boolean} `true` when the node has its initializer.
   */
  function isInitialized(node) {
      var declaration = node.parent;
      var block = declaration.parent;
  
      if (isForLoop(block)) {
          if (block.type === "ForStatement") {
              return block.init === declaration;
          }
          return block.left === declaration;
      }
      return Boolean(node.init);
  }
  
  //------------------------------------------------------------------------------
  // Rule Definition
  //------------------------------------------------------------------------------
  
  module.exports = function(context) {
  
      var MODE_ALWAYS = "always",
          MODE_NEVER = "never";
  
      var mode = context.options[0] || MODE_ALWAYS;
      var params = context.options[1] || {};
      //--------------------------------------------------------------------------
      // Public API
      //--------------------------------------------------------------------------
  
      return {
          "VariableDeclaration:exit": function(node) {
  
              var kind = node.kind,
                  declarations = node.declarations;
  
              for (var i = 0; i < declarations.length; ++i) {
                  var declaration = declarations[i],
                      id = declaration.id,
                      initialized = isInitialized(declaration),
                      isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent);
                  if (id.type !== "Identifier") {
                      continue;
                  }
  
                  if (mode === MODE_ALWAYS && !initialized) {
                      context.report(declaration, "Variable '" + id.name + "' should be initialized on declaration.");
                  } else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) {
                      context.report(declaration, "Variable '" + id.name + "' should not be initialized on declaration.");
                  }
              }
          }
      };
  };
  
  module.exports.schema = {
      "anyOf": [
          {
              "type": "array",
              "items": [
                  {
                      "enum": [0, 1, 2]
                  },
                  {
                      "enum": ["always"]
                  }
              ],
              "minItems": 1,
              "maxItems": 2
          },
          {
              "type": "array",
              "items": [
                  {
                      "enum": [0, 1, 2]
                  },
                  {
                      "enum": ["never"]
                  },
                  {
                      "type": "object",
                      "properties": {
                          "ignoreForLoopInit": {
                              "type": "boolean"
                          }
                      },
                      "additionalProperties": false
                  }
              ],
              "minItems": 1,
              "maxItems": 3
          }
      ]
  };