1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- /**
- * @fileoverview Rule to disallow if as the only statement in an else block
- * @author Brandon Mills
- */
- "use strict";
- //------------------------------------------------------------------------------
- // Rule Definition
- //------------------------------------------------------------------------------
- module.exports = {
- meta: {
- type: "suggestion",
- docs: {
- description: "disallow `if` statements as the only statement in `else` blocks",
- category: "Stylistic Issues",
- recommended: false,
- url: "https://eslint.org/docs/rules/no-lonely-if"
- },
- schema: [],
- fixable: "code",
- messages: {
- unexpectedLonelyIf: "Unexpected if as the only statement in an else block."
- }
- },
- create(context) {
- const sourceCode = context.getSourceCode();
- return {
- IfStatement(node) {
- const ancestors = context.getAncestors(),
- parent = ancestors.pop(),
- grandparent = ancestors.pop();
- if (parent && parent.type === "BlockStatement" &&
- parent.body.length === 1 && grandparent &&
- grandparent.type === "IfStatement" &&
- parent === grandparent.alternate) {
- context.report({
- node,
- messageId: "unexpectedLonelyIf",
- fix(fixer) {
- const openingElseCurly = sourceCode.getFirstToken(parent);
- const closingElseCurly = sourceCode.getLastToken(parent);
- const elseKeyword = sourceCode.getTokenBefore(openingElseCurly);
- const tokenAfterElseBlock = sourceCode.getTokenAfter(closingElseCurly);
- const lastIfToken = sourceCode.getLastToken(node.consequent);
- const sourceText = sourceCode.getText();
- if (sourceText.slice(openingElseCurly.range[1],
- node.range[0]).trim() || sourceText.slice(node.range[1], closingElseCurly.range[0]).trim()) {
- // Don't fix if there are any non-whitespace characters interfering (e.g. comments)
- return null;
- }
- if (
- node.consequent.type !== "BlockStatement" && lastIfToken.value !== ";" && tokenAfterElseBlock &&
- (
- node.consequent.loc.end.line === tokenAfterElseBlock.loc.start.line ||
- /^[([/+`-]/u.test(tokenAfterElseBlock.value) ||
- lastIfToken.value === "++" ||
- lastIfToken.value === "--"
- )
- ) {
- /*
- * If the `if` statement has no block, and is not followed by a semicolon, make sure that fixing
- * the issue would not change semantics due to ASI. If this would happen, don't do a fix.
- */
- return null;
- }
- return fixer.replaceTextRange(
- [openingElseCurly.range[0], closingElseCurly.range[1]],
- (elseKeyword.range[1] === openingElseCurly.range[0] ? " " : "") + sourceCode.getText(node)
- );
- }
- });
- }
- }
- };
- }
- };
|