@masknet/eslint-plugin
Version:
eslint plugin for masknet
63 lines • 2.35 kB
JavaScript
import { isFunctionLike } from '../node.js';
import { createRule } from '../rule.js';
import { wrap } from '../utils.js';
export default createRule({
name: 'prefer-early-return',
meta: {
type: 'problem',
fixable: 'code',
docs: {
description: 'Prefer early returns over full-body conditional wrapping in function declarations',
recommended: 'stylistic',
},
schema: [
{
type: 'object',
properties: { maximumStatements: { type: 'integer', minimum: 0 } },
additionalProperties: false,
},
],
messages: {
prefer: 'Prefer an early return to a conditionally-wrapped function body',
},
},
resolveOptions(options) {
return options?.maximumStatements ?? 1;
},
create(context, maximumStatements) {
function handle({ body, parent }) {
if (!isFunctionLike(parent))
return;
// cspell:words simplifiable
const simplifiable = body.length === 1 && isOffending(body[0], maximumStatements);
if (!simplifiable)
return;
const fix = makeFixer(context, body[0]);
context.report({ node: body[0], messageId: 'prefer', fix });
}
return {
BlockStatement: handle,
};
},
});
function makeFixer(context, parent) {
return function* (fixer) {
if (parent.type !== 'IfStatement')
return;
const { test, consequent } = parent;
yield fixer.insertTextBefore(test, '!(');
yield fixer.insertTextAfter(test, ')');
yield fixer.replaceText(consequent, 'return;');
const modified = wrap(context.sourceCode.getText(consequent), (input) => consequent.type === 'BlockStatement' ? input.slice(1, -1) : input);
yield fixer.insertTextAfter(parent, modified);
};
}
function isOffending(node, maximumStatements) {
if (!(node.type === 'IfStatement' && node.alternate === null)) {
return false;
}
const { consequent } = node;
return ((consequent.type === 'ExpressionStatement' && maximumStatements === 0) ||
(consequent.type === 'BlockStatement' && consequent.body.length > maximumStatements));
}
//# sourceMappingURL=prefer-early-return.js.map