UNPKG

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