Permalink
Browse files

New: Added max-lines-per-function rule (fixes #9842) (#10188)

* 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 0feedfdb267e110775f0a50dd5bc801c77260ae5
@@ -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",
View
@@ -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)
View
@@ -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)
@@ -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)
View
@@ -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)
@@ -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)
View
@@ -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)
@@ -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)
@@ -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)
Oops, something went wrong.

0 comments on commit 0feedfd

Please sign in to comment.