UNPKG

1.99 kBJavaScriptView Raw
1const {docsUrl} = require('../utilities');
2
3const defaultMaximumStatements = 1;
4
5module.exports = {
6 meta: {
7 docs: {
8 description:
9 'Prefer early returns over full-body conditional wrapping in function declarations.',
10 category: 'Best Practices',
11 recommended: false,
12 uri: docsUrl('prefer-early-return'),
13 },
14 schema: [
15 {
16 type: 'object',
17 properties: {
18 maximumStatements: {
19 type: 'integer',
20 },
21 },
22 additionalProperties: false,
23 },
24 ],
25 },
26
27 create(context) {
28 const options = context.options[0] || {
29 maximumStatements: defaultMaximumStatements,
30 };
31 const maxStatements = options.maximumStatements;
32
33 function isLonelyIfStatement(statement) {
34 return statement.type === 'IfStatement' && statement.alternate == null;
35 }
36
37 function isOffendingConsequent(consequent) {
38 return (
39 (consequent.type === 'ExpressionStatement' && maxStatements === 0) ||
40 (consequent.type === 'BlockStatement' &&
41 consequent.body.length > maxStatements)
42 );
43 }
44
45 function isOffendingIfStatement(statement) {
46 return (
47 isLonelyIfStatement(statement) &&
48 isOffendingConsequent(statement.consequent)
49 );
50 }
51
52 function hasSimplifiableConditionalBody(functionBody) {
53 const body = functionBody.body;
54 return (
55 functionBody.type === 'BlockStatement' &&
56 body.length === 1 &&
57 isOffendingIfStatement(body[0])
58 );
59 }
60
61 function checkFunctionBody(functionNode) {
62 const body = functionNode.body;
63
64 if (hasSimplifiableConditionalBody(body)) {
65 context.report(
66 body,
67 'Prefer an early return to a conditionally-wrapped function body',
68 );
69 }
70 }
71
72 return {
73 FunctionDeclaration: checkFunctionBody,
74 FunctionExpression: checkFunctionBody,
75 ArrowFunctionExpression: checkFunctionBody,
76 };
77 },
78};