Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New: function-paren-newline rule (fixes #6074) #8102

Merged
merged 4 commits into from Sep 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile.js
Expand Up @@ -937,7 +937,8 @@ target.checkLicenses = function() {

if (impermissible.length) {
impermissible.forEach(dependency => {
console.error("%s license for %s is impermissible.",
console.error(
"%s license for %s is impermissible.",
dependency.licenses,
dependency.name
);
Expand Down
1 change: 1 addition & 0 deletions conf/eslint-recommended.js
Expand Up @@ -44,6 +44,7 @@ module.exports = {
"func-name-matching": "off",
"func-names": "off",
"func-style": "off",
"function-paren-newline": "off",
"generator-star-spacing": "off",
"getter-return": "off",
"global-require": "off",
Expand Down
277 changes: 277 additions & 0 deletions docs/rules/function-paren-newline.md
@@ -0,0 +1,277 @@
# enforce consistent line breaks inside function parentheses (function-paren-newline)

Many styleguides require or disallow newlines inside of function parentheses.

## Rule Details

This rule enforces consistent line breaks inside parentheses of function parameters or arguments.

### Options

This rule has a single option, which can either be a string or an object.

* `"always"` requires line breaks inside all function parentheses.
* `"never"` disallows line breaks inside all function parentheses.
* `"multiline"` (default) requires linebreaks inside function parentheses if any of the parameters/arguments have a line break between them. Otherwise, it disallows linebreaks.
* `"consistent"` requires consistent usage of linebreaks for each pair of parentheses. It reports an error if one parenthesis in the pair has a linebreak inside it and the other parenthesis does not.
* `{ "minItems": value }` requires linebreaks inside function parentheses if the number of parameters/arguments is at least `value`. Otherwise, it disallows linebreaks.

Example configurations:

```json
{
"rules": {
"function-paren-newline": ["error", "never"]
}
}
```

```json
{
"rules": {
"function-paren-newline": ["error", { "minItems": 3 }]
}
}
```

Examples of **incorrect** code for this rule with the `"always"` option:

```js
/* eslint function-paren-newline: ["error", "always"] */

function foo(bar, baz) {}

var foo = function(bar, baz) {};

var foo = (bar, baz) => {};

foo(bar, baz);
```

Examples of **correct** code for this rule with the `"always"` option:

```js
/* eslint function-paren-newline: ["error", "always"] */

function foo(
bar,
baz
) {}

var foo = function(
bar, baz
) {};

var foo = (
bar,
baz
) => {};

foo(
bar,
baz
);
```

Examples of **incorrect** code for this rule with the `"never"` option:

```js
/* eslint function-paren-newline: ["error", "never"] */

function foo(
bar,
baz
) {}

var foo = function(
bar, baz
) {};

var foo = (
bar,
baz
) => {};

foo(
bar,
baz
);
```

Examples of **correct** code for this rule with the `"never"` option:

```js
/* eslint function-paren-newline: ["error", "never"] */

function foo(bar, baz) {}

function foo(bar,
baz) {}

var foo = function(bar, baz) {};

var foo = (bar, baz) => {};

foo(bar, baz);

foo(bar,
baz);
```

Examples of **incorrect** code for this rule with the default `"multiline"` option:

```js
/* eslint function-paren-newline: ["error", "multiline"] */

function foo(bar,
baz
) {}

var foo = function(
bar, baz
) {};

var foo = (
bar,
baz) => {};

foo(bar,
baz);

foo(
function() {
return baz;
}
);
```

Examples of **correct** code for this rule with the default `"multiline"` option:

```js
/* eslint function-paren-newline: ["error", "multiline"] */

function foo(bar, baz) {}

var foo = function(
bar,
baz
) {};

var foo = (bar, baz) => {};

foo(bar, baz, qux);

foo(
bar,
baz,
qux
);

foo(function() {
return baz;
});
```

Examples of **incorrect** code for this rule with the `"consistent"` option:

```js
/* eslint function-paren-newline: ["error", "consistent"] */

function foo(bar,
baz
) {}

var foo = function(bar,
baz
) {};

var foo = (
bar,
baz) => {};

foo(
bar,
baz);

foo(
function() {
return baz;
});
```

Examples of **correct** code for this rule with the consistent `"consistent"` option:

```js
/* eslint function-paren-newline: ["error", "consistent"] */

function foo(bar,
baz) {}

var foo = function(bar, baz) {};

var foo = (
bar,
baz
) => {};

foo(
bar, baz
);

foo(
function() {
return baz;
}
);
```

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

```js
/* eslint function-paren-newline: ["error", { "minItems": 3 }] */

function foo(
bar,
baz
) {}

function foo(bar, baz, qux) {}

var foo = function(
bar, baz
) {};

var foo = (bar,
baz) => {};

foo(bar,
baz);
```

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

```js
/* eslint function-paren-newline: ["error", { "minItems": 3 }] */

function foo(bar, baz) {}

var foo = function(
bar,
baz,
qux
) {};

var foo = (
bar, baz, qux
) => {};

foo(bar, baz);

foo(
bar, baz, qux
);
```

## When Not To Use It

If don't want to enforce consistent linebreaks inside function parentheses, do not turn on this rule.
12 changes: 8 additions & 4 deletions lib/code-path-analysis/code-path-analyzer.js
Expand Up @@ -154,7 +154,8 @@ function forwardCurrentToHead(analyzer, node) {
analyzer.emitter.emit(
"onCodePathSegmentEnd",
currentSegment,
node);
node
);
}
}
}
Expand All @@ -175,7 +176,8 @@ function forwardCurrentToHead(analyzer, node) {
analyzer.emitter.emit(
"onCodePathSegmentStart",
headSegment,
node);
node
);
}
}
}
Expand All @@ -202,7 +204,8 @@ function leaveFromCurrentSegment(analyzer, node) {
analyzer.emitter.emit(
"onCodePathSegmentEnd",
currentSegment,
node);
node
);
}
}

Expand Down Expand Up @@ -369,7 +372,8 @@ function processCodePathToEnter(analyzer, node) {
case "SwitchStatement":
state.pushSwitchContext(
node.cases.some(isCaseNode),
astUtils.getLabel(node));
astUtils.getLabel(node)
);
break;

case "TryStatement":
Expand Down
3 changes: 2 additions & 1 deletion lib/code-path-analysis/code-path-segment.js
Expand Up @@ -164,7 +164,8 @@ class CodePathSegment {
return new CodePathSegment(
id,
flattenUnusedSegments(allPrevSegments),
allPrevSegments.some(isReachable));
allPrevSegments.some(isReachable)
);
}

/**
Expand Down