]> git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/init-declarations.js
d994bbc1ea0590ea54d780dc14e8d84425c262c2
[pve-eslint.git] / eslint / lib / rules / init-declarations.js
1 /**
2 * @fileoverview A rule to control the style of variable initializations.
3 * @author Colin Ihrig
4 */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Helpers
10 //------------------------------------------------------------------------------
11
12 /**
13 * Checks whether or not a given node is a for loop.
14 * @param {ASTNode} block A node to check.
15 * @returns {boolean} `true` when the node is a for loop.
16 */
17 function isForLoop(block) {
18 return block.type === "ForInStatement" ||
19 block.type === "ForOfStatement" ||
20 block.type === "ForStatement";
21 }
22
23 /**
24 * Checks whether or not a given declarator node has its initializer.
25 * @param {ASTNode} node A declarator node to check.
26 * @returns {boolean} `true` when the node has its initializer.
27 */
28 function isInitialized(node) {
29 const declaration = node.parent;
30 const block = declaration.parent;
31
32 if (isForLoop(block)) {
33 if (block.type === "ForStatement") {
34 return block.init === declaration;
35 }
36 return block.left === declaration;
37 }
38 return Boolean(node.init);
39 }
40
41 //------------------------------------------------------------------------------
42 // Rule Definition
43 //------------------------------------------------------------------------------
44
45 module.exports = {
46 meta: {
47 type: "suggestion",
48
49 docs: {
50 description: "require or disallow initialization in variable declarations",
51 recommended: false,
52 url: "https://eslint.org/docs/rules/init-declarations"
53 },
54
55 schema: {
56 anyOf: [
57 {
58 type: "array",
59 items: [
60 {
61 enum: ["always"]
62 }
63 ],
64 minItems: 0,
65 maxItems: 1
66 },
67 {
68 type: "array",
69 items: [
70 {
71 enum: ["never"]
72 },
73 {
74 type: "object",
75 properties: {
76 ignoreForLoopInit: {
77 type: "boolean"
78 }
79 },
80 additionalProperties: false
81 }
82 ],
83 minItems: 0,
84 maxItems: 2
85 }
86 ]
87 },
88 messages: {
89 initialized: "Variable '{{idName}}' should be initialized on declaration.",
90 notInitialized: "Variable '{{idName}}' should not be initialized on declaration."
91 }
92 },
93
94 create(context) {
95
96 const MODE_ALWAYS = "always",
97 MODE_NEVER = "never";
98
99 const mode = context.options[0] || MODE_ALWAYS;
100 const params = context.options[1] || {};
101
102 //--------------------------------------------------------------------------
103 // Public API
104 //--------------------------------------------------------------------------
105
106 return {
107 "VariableDeclaration:exit"(node) {
108
109 const kind = node.kind,
110 declarations = node.declarations;
111
112 for (let i = 0; i < declarations.length; ++i) {
113 const declaration = declarations[i],
114 id = declaration.id,
115 initialized = isInitialized(declaration),
116 isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent);
117 let messageId = "";
118
119 if (mode === MODE_ALWAYS && !initialized) {
120 messageId = "initialized";
121 } else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) {
122 messageId = "notInitialized";
123 }
124
125 if (id.type === "Identifier" && messageId) {
126 context.report({
127 node: declaration,
128 messageId,
129 data: {
130 idName: id.name
131 }
132 });
133 }
134 }
135 }
136 };
137 }
138 };