.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / no-lonely-if.js
1 /**
2  * @fileoverview Rule to disallow if as the only statement in an else block
3  * @author Brandon Mills
4  */
5 "use strict";
6
7 //------------------------------------------------------------------------------
8 // Rule Definition
9 //------------------------------------------------------------------------------
10
11 module.exports = {
12     meta: {
13         type: "suggestion",
14
15         docs: {
16             description: "disallow `if` statements as the only statement in `else` blocks",
17             category: "Stylistic Issues",
18             recommended: false,
19             url: "https://eslint.org/docs/rules/no-lonely-if"
20         },
21
22         schema: [],
23         fixable: "code",
24
25         messages: {
26             unexpectedLonelyIf: "Unexpected if as the only statement in an else block."
27         }
28     },
29
30     create(context) {
31         const sourceCode = context.getSourceCode();
32
33         return {
34             IfStatement(node) {
35                 const ancestors = context.getAncestors(),
36                     parent = ancestors.pop(),
37                     grandparent = ancestors.pop();
38
39                 if (parent && parent.type === "BlockStatement" &&
40                         parent.body.length === 1 && grandparent &&
41                         grandparent.type === "IfStatement" &&
42                         parent === grandparent.alternate) {
43                     context.report({
44                         node,
45                         messageId: "unexpectedLonelyIf",
46                         fix(fixer) {
47                             const openingElseCurly = sourceCode.getFirstToken(parent);
48                             const closingElseCurly = sourceCode.getLastToken(parent);
49                             const elseKeyword = sourceCode.getTokenBefore(openingElseCurly);
50                             const tokenAfterElseBlock = sourceCode.getTokenAfter(closingElseCurly);
51                             const lastIfToken = sourceCode.getLastToken(node.consequent);
52                             const sourceText = sourceCode.getText();
53
54                             if (sourceText.slice(openingElseCurly.range[1],
55                                 node.range[0]).trim() || sourceText.slice(node.range[1], closingElseCurly.range[0]).trim()) {
56
57                                 // Don't fix if there are any non-whitespace characters interfering (e.g. comments)
58                                 return null;
59                             }
60
61                             if (
62                                 node.consequent.type !== "BlockStatement" && lastIfToken.value !== ";" && tokenAfterElseBlock &&
63                                 (
64                                     node.consequent.loc.end.line === tokenAfterElseBlock.loc.start.line ||
65                                     /^[([/+`-]/u.test(tokenAfterElseBlock.value) ||
66                                     lastIfToken.value === "++" ||
67                                     lastIfToken.value === "--"
68                                 )
69                             ) {
70
71                                 /*
72                                  * If the `if` statement has no block, and is not followed by a semicolon, make sure that fixing
73                                  * the issue would not change semantics due to ASI. If this would happen, don't do a fix.
74                                  */
75                                 return null;
76                             }
77
78                             return fixer.replaceTextRange(
79                                 [openingElseCurly.range[0], closingElseCurly.range[1]],
80                                 (elseKeyword.range[1] === openingElseCurly.range[0] ? " " : "") + sourceCode.getText(node)
81                             );
82                         }
83                     });
84                 }
85             }
86         };
87
88     }
89 };