|
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- /**
- * @fileoverview Rule to enforce declarations in program or function body root.
- * @author Brandon Mills
- */
-
- "use strict";
-
- //------------------------------------------------------------------------------
- // Rule Definition
- //------------------------------------------------------------------------------
-
- module.exports = {
- meta: {
- type: "problem",
-
- docs: {
- description: "disallow variable or `function` declarations in nested blocks",
- category: "Possible Errors",
- recommended: true,
- url: "https://eslint.org/docs/rules/no-inner-declarations"
- },
-
- schema: [
- {
- enum: ["functions", "both"]
- }
- ]
- },
-
- create(context) {
-
- /**
- * Find the nearest Program or Function ancestor node.
- * @returns {Object} Ancestor's type and distance from node.
- */
- function nearestBody() {
- const ancestors = context.getAncestors();
- let ancestor = ancestors.pop(),
- generation = 1;
-
- while (ancestor && ["Program", "FunctionDeclaration",
- "FunctionExpression", "ArrowFunctionExpression"
- ].indexOf(ancestor.type) < 0) {
- generation += 1;
- ancestor = ancestors.pop();
- }
-
- return {
-
- // Type of containing ancestor
- type: ancestor.type,
-
- // Separation between ancestor and node
- distance: generation
- };
- }
-
- /**
- * Ensure that a given node is at a program or function body's root.
- * @param {ASTNode} node Declaration node to check.
- * @returns {void}
- */
- function check(node) {
- const body = nearestBody(),
- valid = ((body.type === "Program" && body.distance === 1) ||
- body.distance === 2);
-
- if (!valid) {
- context.report({
- node,
- message: "Move {{type}} declaration to {{body}} root.",
- data: {
- type: (node.type === "FunctionDeclaration" ? "function" : "variable"),
- body: (body.type === "Program" ? "program" : "function body")
- }
- });
- }
- }
-
- return {
-
- FunctionDeclaration: check,
- VariableDeclaration(node) {
- if (context.options[0] === "both" && node.kind === "var") {
- check(node);
- }
- }
-
- };
-
- }
- };
|