UNPKG

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