2 * @fileoverview Rule to enforce declarations in program or function body root.
3 * @author Brandon Mills
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
17 description: "disallow variable or `function` declarations in nested blocks",
18 category: "Possible Errors",
20 url: "https://eslint.org/docs/rules/no-inner-declarations"
25 enum: ["functions", "both"]
33 * Find the nearest Program or Function ancestor node.
34 * @returns {Object} Ancestor's type and distance from node.
36 function nearestBody() {
37 const ancestors = context.getAncestors();
38 let ancestor = ancestors.pop(),
41 while (ancestor && ["Program", "FunctionDeclaration",
42 "FunctionExpression", "ArrowFunctionExpression"
43 ].indexOf(ancestor.type) < 0) {
45 ancestor = ancestors.pop();
50 // Type of containing ancestor
53 // Separation between ancestor and node
59 * Ensure that a given node is at a program or function body's root.
60 * @param {ASTNode} node Declaration node to check.
63 function check(node) {
64 const body = nearestBody(),
65 valid = ((body.type === "Program" && body.distance === 1) ||
71 message: "Move {{type}} declaration to {{body}} root.",
73 type: (node.type === "FunctionDeclaration" ? "function" : "variable"),
74 body: (body.type === "Program" ? "program" : "function body")
82 FunctionDeclaration: check,
83 VariableDeclaration(node) {
84 if (context.options[0] === "both" && node.kind === "var") {