2 * @fileoverview Rule to enforce declarations in program or function body root.
3 * @author Brandon Mills
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 const astUtils
= require("./utils/ast-utils");
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
18 const validParent
= new Set(["Program", "StaticBlock", "ExportNamedDeclaration", "ExportDefaultDeclaration"]);
19 const validBlockStatementParent
= new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]);
22 * Finds the nearest enclosing context where this rule allows declarations and returns its description.
23 * @param {ASTNode} node Node to search from.
24 * @returns {string} Description. One of "program", "function body", "class static block body".
26 function getAllowedBodyDescription(node
) {
27 let { parent
} = node
;
31 if (parent
.type
=== "StaticBlock") {
32 return "class static block body";
35 if (astUtils
.isFunction(parent
)) {
36 return "function body";
39 ({ parent
} = parent
);
45 /** @type {import('../shared/types').Rule} */
51 description
: "disallow variable or `function` declarations in nested blocks",
53 url
: "https://eslint.org/docs/rules/no-inner-declarations"
58 enum: ["functions", "both"]
63 moveDeclToRoot
: "Move {{type}} declaration to {{body}} root."
70 * Ensure that a given node is at a program or function body's root.
71 * @param {ASTNode} node Declaration node to check.
74 function check(node
) {
75 const parent
= node
.parent
;
78 parent
.type
=== "BlockStatement" && validBlockStatementParent
.has(parent
.parent
.type
)
83 if (validParent
.has(parent
.type
)) {
89 messageId
: "moveDeclToRoot",
91 type
: (node
.type
=== "FunctionDeclaration" ? "function" : "variable"),
92 body
: getAllowedBodyDescription(node
)
100 FunctionDeclaration
: check
,
101 VariableDeclaration(node
) {
102 if (context
.options
[0] === "both" && node
.kind
=== "var") {