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// Requirements 10//------------------------------------------------------------------------------ 11 12const astUtils = require("./utils/ast-utils"); 13 14//------------------------------------------------------------------------------ 15// Rule Definition 16//------------------------------------------------------------------------------ 17 18const validParent = new Set(["Program", "ExportNamedDeclaration", "ExportDefaultDeclaration"]); 19const validBlockStatementParent = new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]); 20 21module.exports = { 22 meta: { 23 type: "problem", 24 25 docs: { 26 description: "disallow variable or `function` declarations in nested blocks", 27 category: "Possible Errors", 28 recommended: true, 29 url: "https://eslint.org/docs/rules/no-inner-declarations" 30 }, 31 32 schema: [ 33 { 34 enum: ["functions", "both"] 35 } 36 ], 37 38 messages: { 39 moveDeclToRoot: "Move {{type}} declaration to {{body}} root." 40 } 41 }, 42 43 create(context) { 44 45 /** 46 * Ensure that a given node is at a program or function body's root. 47 * @param {ASTNode} node Declaration node to check. 48 * @returns {void} 49 */ 50 function check(node) { 51 const parent = node.parent; 52 53 if ( 54 parent.type === "BlockStatement" && validBlockStatementParent.has(parent.parent.type) 55 ) { 56 return; 57 } 58 59 if (validParent.has(parent.type)) { 60 return; 61 } 62 63 const upperFunction = astUtils.getUpperFunction(parent); 64 65 context.report({ 66 node, 67 messageId: "moveDeclToRoot", 68 data: { 69 type: (node.type === "FunctionDeclaration" ? "function" : "variable"), 70 body: (upperFunction === null ? "program" : "function body") 71 } 72 }); 73 } 74 75 76 return { 77 78 FunctionDeclaration: check, 79 VariableDeclaration(node) { 80 if (context.options[0] === "both" && node.kind === "var") { 81 check(node); 82 } 83 } 84 85 }; 86 87 } 88}; 89