Actualizacion maquina principal
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / no-lone-blocks.js
1 /**
2  * @fileoverview Rule to flag blocks with no reason to exist
3  * @author Brandon Mills
4  */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Rule Definition
10 //------------------------------------------------------------------------------
11
12 module.exports = {
13     meta: {
14         type: "suggestion",
15
16         docs: {
17             description: "disallow unnecessary nested blocks",
18             category: "Best Practices",
19             recommended: false,
20             url: "https://eslint.org/docs/rules/no-lone-blocks"
21         },
22
23         schema: []
24     },
25
26     create(context) {
27
28         // A stack of lone blocks to be checked for block-level bindings
29         const loneBlocks = [];
30         let ruleDef;
31
32         /**
33          * Reports a node as invalid.
34          * @param {ASTNode} node The node to be reported.
35          * @returns {void}
36          */
37         function report(node) {
38             const message = node.parent.type === "BlockStatement" ? "Nested block is redundant." : "Block is redundant.";
39
40             context.report({ node, message });
41         }
42
43         /**
44          * Checks for any ocurrence of a BlockStatement in a place where lists of statements can appear
45          * @param {ASTNode} node The node to check
46          * @returns {boolean} True if the node is a lone block.
47          */
48         function isLoneBlock(node) {
49             return node.parent.type === "BlockStatement" ||
50                 node.parent.type === "Program" ||
51
52                 // Don't report blocks in switch cases if the block is the only statement of the case.
53                 node.parent.type === "SwitchCase" && !(node.parent.consequent[0] === node && node.parent.consequent.length === 1);
54         }
55
56         /**
57          * Checks the enclosing block of the current node for block-level bindings,
58          * and "marks it" as valid if any.
59          * @returns {void}
60          */
61         function markLoneBlock() {
62             if (loneBlocks.length === 0) {
63                 return;
64             }
65
66             const block = context.getAncestors().pop();
67
68             if (loneBlocks[loneBlocks.length - 1] === block) {
69                 loneBlocks.pop();
70             }
71         }
72
73         // Default rule definition: report all lone blocks
74         ruleDef = {
75             BlockStatement(node) {
76                 if (isLoneBlock(node)) {
77                     report(node);
78                 }
79             }
80         };
81
82         // ES6: report blocks without block-level bindings, or that's only child of another block
83         if (context.parserOptions.ecmaVersion >= 6) {
84             ruleDef = {
85                 BlockStatement(node) {
86                     if (isLoneBlock(node)) {
87                         loneBlocks.push(node);
88                     }
89                 },
90                 "BlockStatement:exit"(node) {
91                     if (loneBlocks.length > 0 && loneBlocks[loneBlocks.length - 1] === node) {
92                         loneBlocks.pop();
93                         report(node);
94                     } else if (
95                         node.parent.type === "BlockStatement" &&
96                         node.parent.body.length === 1
97                     ) {
98                         report(node);
99                     }
100                 }
101             };
102
103             ruleDef.VariableDeclaration = function(node) {
104                 if (node.kind === "let" || node.kind === "const") {
105                     markLoneBlock();
106                 }
107             };
108
109             ruleDef.FunctionDeclaration = function() {
110                 if (context.getScope().isStrict) {
111                     markLoneBlock();
112                 }
113             };
114
115             ruleDef.ClassDeclaration = markLoneBlock;
116         }
117
118         return ruleDef;
119     }
120 };