Skip to content

Commit

Permalink
New: Added max-lines-per-function rule (fixes #9842) (#10188)
Browse files Browse the repository at this point in the history
* New: Added max-lines-per-function rule (fixes #9842)

* Docs: Added max-statements-per-line to related rules

* Docs: Added example of how max-lines-per-function differs to other complexity rules.

* Chore: Changed default to 50 LOC. Removed unnecessary hasOwnProperty calls.

* Update: "MethodDefinition" and "Property" nodes are now analysed too, so static methods and class properties are counted from the root of their statements instead of just the FunctionExpression.

Added ignoreIIFEs option

* Update: Refactor so Property and MethodDefinition are no longer required as entrypoints. Better property / method detection as per PR feedback

* Update: Changed boolean option defaults to true. Renamed ignoreComments to skipComments to keep consistent with other rules. Updated doc with new IIFEs option. Made detecting "Property" function definitions more robust as per PR feedback.

* Update: Don't confuse IIFE with callback, so check parent callee is same as functionexpression node

* Update: Fix trailing whitespace on multi line comments processing when detecting full line comments.

Updated old code comments.
ParserOptions in tests passed through to RuleTester constructor.

* Docs: Clarify that "max" option can be used instead of an object

* Docs: Clarify options

* Docs: Typo in documentation. Added comments for each test; and a couple of extra tests
  • Loading branch information
peteward44 authored and platinumazure committed Jun 23, 2018
1 parent daefbdb commit 0feedfd
Show file tree
Hide file tree
Showing 11 changed files with 854 additions and 0 deletions.
1 change: 1 addition & 0 deletions conf/eslint-recommended.js
Expand Up @@ -69,6 +69,7 @@ module.exports = {
"max-depth": "off",
"max-len": "off",
"max-lines": "off",
"max-lines-per-function": "off",
"max-nested-callbacks": "off",
"max-params": "off",
"max-statements": "off",
Expand Down
2 changes: 2 additions & 0 deletions docs/rules/complexity.md
Expand Up @@ -80,6 +80,8 @@ If you can't determine an appropriate complexity limit for your code, then it's

* [max-depth](max-depth.md)
* [max-len](max-len.md)
* [max-lines](max-lines.md)
* [max-lines-per-function](max-lines-per-function.md)
* [max-nested-callbacks](max-nested-callbacks.md)
* [max-params](max-params.md)
* [max-statements](max-statements.md)
2 changes: 2 additions & 0 deletions docs/rules/max-depth.md
Expand Up @@ -58,6 +58,8 @@ function foo() {

* [complexity](complexity.md)
* [max-len](max-len.md)
* [max-lines](max-lines.md)
* [max-lines-per-function](max-lines-per-function.md)
* [max-nested-callbacks](max-nested-callbacks.md)
* [max-params](max-params.md)
* [max-statements](max-statements.md)
191 changes: 191 additions & 0 deletions docs/rules/max-lines-per-function.md
@@ -0,0 +1,191 @@
# enforce a maximum function length (max-lines-per-function)

Some people consider large functions a code smell. Large functions tend to do a lot of things and can make it hard following what's going on. Many coding style guides dictate a limit of the number of lines that a function can comprise of. This rule can help enforce that style.

## Rule Details

This rule enforces a maximum number of lines per function, in order to aid in maintainability and reduce complexity.

## Why not use `max-statements` or other complexity measurement rules instead?

Nested long method chains like the below example are often broken onto separate lines for readability:

```
function() {
return m("div", [
m("table", {className: "table table-striped latest-data"}, [
m("tbody",
data.map(function(db) {
return m("tr", {key: db.dbname}, [
m("td", {className: "dbname"}, db.dbname),
m("td", {className: "query-count"}, [
m("span", {className: db.lastSample.countClassName}, db.lastSample.nbQueries)
])
])
})
)
])
])
}
```

* `max-statements` will only report this as 1 statement, despite being 16 lines of code.
* `complexity` will only report a complexity of 1
* `max-nested-callbacks` will only report 1
* `max-depth` will report a depth of 0

## Options

This rule has the following options that can be specified using an object:

* `"max"` (default `50`) enforces a maximum number of lines in a function.

* `"skipBlankLines": true` ignore lines made up purely of whitespace.

* `"skipComments": true` ignore lines containing just comments.

* `"IIFEs": true` include any code included in IIFEs.

Alternatively, you may specify a single integer for the `max` option:

```json
"max-lines-per-function": ["error", 20]
```

is equivalent to

```json
"max-lines-per-function": ["error", { "max": 20 }]
```

### code

Examples of **incorrect** code for this rule with a max value of `2`:

```js
/*eslint max-lines-per-function: ["error", 2]*/
function foo() {
var x = 0;
}
```

```js
/*eslint max-lines-per-function: ["error", 2]*/
function foo() {
// a comment
var x = 0;
}
```

```js
/*eslint max-lines-per-function: ["error", 2]*/
function foo() {
// a comment followed by a blank line

var x = 0;
}
```

Examples of **correct** code for this rule with a max value of `2`:

```js
/*eslint max-lines-per-function: ["error", 3]*/
function foo() {
var x = 0;
}
```

```js
/*eslint max-lines-per-function: ["error", 3]*/
function foo() {
// a comment
var x = 0;
}
```

```js
/*eslint max-lines-per-function: ["error", 3]*/
function foo() {
// a comment followed by a blank line

var x = 0;
}
```

### skipBlankLines

Examples of **incorrect** code for this rule with the `{ "skipBlankLines": true }` option:

```js
/*eslint max-lines-per-function: ["error", {"max": 2, "skipBlankLines": true}]*/
function foo() {

var x = 0;
}
```

Examples of **correct** code for this rule with the `{ "skipBlankLines": true }` option:

```js
/*eslint max-lines-per-function: ["error", {"max": 3, "skipBlankLines": true}]*/
function foo() {

var x = 0;
}
```

### skipComments

Examples of **incorrect** code for this rule with the `{ "skipComments": true }` option:

```js
/*eslint max-lines-per-function: ["error", {"max": 2, "skipComments": true}]*/
function foo() {
// a comment
var x = 0;
}
```

Examples of **correct** code for this rule with the `{ "skipComments": true }` option:

```js
/*eslint max-lines-per-function: ["error", {"max": 3, "skipComments": true}]*/
function foo() {
// a comment
var x = 0;
}
```

### IIFEs

Examples of **incorrect** code for this rule with the `{ "IIFEs": true }` option:

```js
/*eslint max-lines-per-function: ["error", {"max": 2, "IIFEs": true}]*/
(function(){
var x = 0;
}());
```

Examples of **correct** code for this rule with the `{ "IIFEs": true }` option:

```js
/*eslint max-lines-per-function: ["error", {"max": 3, "IIFEs": true}]*/
(function(){
var x = 0;
}());
```

## When Not To Use It

You can turn this rule off if you are not concerned with the number of lines in your functions.

## Related Rules

* [complexity](complexity.md)
* [max-depth](max-depth.md)
* [max-lines](max-lines.md)
* [max-nested-callbacks](max-nested-callbacks.md)
* [max-params](max-params.md)
* [max-statements](max-statements.md)
* [max-statements-per-line](max-statements-per-line.md)
1 change: 1 addition & 0 deletions docs/rules/max-lines.md
Expand Up @@ -116,6 +116,7 @@ You can turn this rule off if you are not concerned with the number of lines in

* [complexity](complexity.md)
* [max-depth](max-depth.md)
* [max-lines-per-function](max-lines-per-function.md)
* [max-nested-callbacks](max-nested-callbacks.md)
* [max-params](max-params.md)
* [max-statements](max-statements.md)
Expand Down
2 changes: 2 additions & 0 deletions docs/rules/max-nested-callbacks.md
Expand Up @@ -79,5 +79,7 @@ function handleFoo4() {
* [complexity](complexity.md)
* [max-depth](max-depth.md)
* [max-len](max-len.md)
* [max-lines](max-lines.md)
* [max-lines-per-function](max-lines-per-function.md)
* [max-params](max-params.md)
* [max-statements](max-statements.md)
2 changes: 2 additions & 0 deletions docs/rules/max-params.md
Expand Up @@ -57,5 +57,7 @@ let foo = (bar, baz, qux) => {
* [complexity](complexity.md)
* [max-depth](max-depth.md)
* [max-len](max-len.md)
* [max-lines](max-lines.md)
* [max-lines-per-function](max-lines-per-function.md)
* [max-nested-callbacks](max-nested-callbacks.md)
* [max-statements](max-statements.md)
2 changes: 2 additions & 0 deletions docs/rules/max-statements-per-line.md
Expand Up @@ -80,6 +80,8 @@ You can turn this rule off if you are not concerned with the number of statement

* [max-depth](max-depth.md)
* [max-len](max-len.md)
* [max-lines](max-lines.md)
* [max-lines-per-function](max-lines-per-function.md)
* [max-nested-callbacks](max-nested-callbacks.md)
* [max-params](max-params.md)
* [max-statements](max-statements.md)
2 changes: 2 additions & 0 deletions docs/rules/max-statements.md
Expand Up @@ -139,5 +139,7 @@ function foo() {
* [complexity](complexity.md)
* [max-depth](max-depth.md)
* [max-len](max-len.md)
* [max-lines](max-lines.md)
* [max-lines-per-function](max-lines-per-function.md)
* [max-nested-callbacks](max-nested-callbacks.md)
* [max-params](max-params.md)

0 comments on commit 0feedfd

Please sign in to comment.