]> git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/no-inner-declarations.js
first commit
[pve-eslint.git] / eslint / lib / rules / no-inner-declarations.js
1 /**
2 * @fileoverview Rule to enforce declarations in program or function body root.
3 * @author Brandon Mills
4 */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Rule Definition
10 //------------------------------------------------------------------------------
11
12 module.exports = {
13 meta: {
14 type: "problem",
15
16 docs: {
17 description: "disallow variable or `function` declarations in nested blocks",
18 category: "Possible Errors",
19 recommended: true,
20 url: "https://eslint.org/docs/rules/no-inner-declarations"
21 },
22
23 schema: [
24 {
25 enum: ["functions", "both"]
26 }
27 ],
28
29 messages: {
30 moveDeclToRoot: "Move {{type}} declaration to {{body}} root."
31 }
32 },
33
34 create(context) {
35
36 /**
37 * Find the nearest Program or Function ancestor node.
38 * @returns {Object} Ancestor's type and distance from node.
39 */
40 function nearestBody() {
41 const ancestors = context.getAncestors();
42 let ancestor = ancestors.pop(),
43 generation = 1;
44
45 while (ancestor && ["Program", "FunctionDeclaration",
46 "FunctionExpression", "ArrowFunctionExpression"
47 ].indexOf(ancestor.type) < 0) {
48 generation += 1;
49 ancestor = ancestors.pop();
50 }
51
52 return {
53
54 // Type of containing ancestor
55 type: ancestor.type,
56
57 // Separation between ancestor and node
58 distance: generation
59 };
60 }
61
62 /**
63 * Ensure that a given node is at a program or function body's root.
64 * @param {ASTNode} node Declaration node to check.
65 * @returns {void}
66 */
67 function check(node) {
68 const body = nearestBody(),
69 valid = ((body.type === "Program" && body.distance === 1) ||
70 body.distance === 2);
71
72 if (!valid) {
73 context.report({
74 node,
75 messageId: "moveDeclToRoot",
76 data: {
77 type: (node.type === "FunctionDeclaration" ? "function" : "variable"),
78 body: (body.type === "Program" ? "program" : "function body")
79 }
80 });
81 }
82 }
83
84 return {
85
86 FunctionDeclaration: check,
87 VariableDeclaration(node) {
88 if (context.options[0] === "both" && node.kind === "var") {
89 check(node);
90 }
91 }
92
93 };
94
95 }
96 };