UNPKG

2.5 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// 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};