Skip to content

Commit

Permalink
Update: Add never option for func-names (fixes #6059)
Browse files Browse the repository at this point in the history
  • Loading branch information
alberto committed Jun 12, 2016
1 parent 6b08cfc commit ff4569a
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 9 deletions.
2 changes: 1 addition & 1 deletion docs/rules/README.md
Expand Up @@ -161,7 +161,7 @@ These rules relate to style guidelines, and are therefore quite subjective:
* [computed-property-spacing](computed-property-spacing.md): enforce consistent spacing inside computed property brackets (fixable)
* [consistent-this](consistent-this.md): enforce consistent naming when capturing the current execution context
* [eol-last](eol-last.md): enforce at least one newline at the end of files (fixable)
* [func-names](func-names.md): enforce named `function` expressions
* [func-names](func-names.md): require or disallow named `function` expressions
* [func-style](func-style.md): enforce the consistent use of either `function` declarations or expressions
* [id-blacklist](id-blacklist.md): disallow specified identifiers
* [id-length](id-length.md): enforce minimum and maximum identifier lengths
Expand Down
45 changes: 42 additions & 3 deletions docs/rules/func-names.md
@@ -1,4 +1,4 @@
# Require Function Expressions to have a Name (func-names)
# Require or disallow named `function` expressions (func-names)

A pattern that's becoming more common is to give function expressions names to aid in debugging. For example:

Expand All @@ -10,7 +10,17 @@ Adding the second `bar` in the above example is optional. If you leave off the

## Rule Details

Examples of **incorrect** code for this rule:
This rule can enforce or disallow the use of named function expressions.

## Options

This rule has a string option:

* `"always"` (default) requires function expressions to have a name
* `"never"` disallows named function expressions


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

```js
/*eslint func-names: "error"*/
Expand All @@ -22,7 +32,7 @@ Foo.prototype.bar = function() {};
}())
```

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

```js
/*eslint func-names: "error"*/
Expand All @@ -34,6 +44,35 @@ Foo.prototype.bar = function bar() {};
}())
```

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

```js
/*eslint func-names: "error"*/

Foo.prototype.bar = function bar() {};

(function bar() {
// ...
}())
```

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

```js
/*eslint func-names: "error"*/

Foo.prototype.bar = function() {};

(function() {
// ...
}())
```

## Further Reading

* [Functions Explained](http://markdaggett.com/blog/2013/02/15/functions-explained/)

## Compatibility

* **JSCS**: [requireAnonymousFunctions](http://jscs.info/rule/requireAnonymousFunctions)
* **JSCS**: [disallowAnonymousFunctions](http://jscs.info/rule/disallowAnonymousFunctions)
19 changes: 15 additions & 4 deletions lib/rules/func-names.js
Expand Up @@ -12,15 +12,20 @@
module.exports = {
meta: {
docs: {
description: "enforce named `function` expressions",
description: "require or disallow named `function` expressions",
category: "Stylistic Issues",
recommended: false
},

schema: []
schema: [
{
enum: ["always", "never"]
}
]
},

create: function(context) {
var never = context.options[0] === "never";

/**
* Determines whether the current FunctionExpression node is a get, set, or
Expand All @@ -44,8 +49,14 @@ module.exports = {

var name = node.id && node.id.name;

if (!name && !isObjectOrClassMethod()) {
context.report(node, "Missing function expression name.");
if (never) {
if (name) {
context.report(node, "Unexpected function expression name.");
}
} else {
if (!name && !isObjectOrClassMethod()) {
context.report(node, "Missing function expression name.");
}
}
}
};
Expand Down
55 changes: 54 additions & 1 deletion tests/lib/rules/func-names.js
Expand Up @@ -33,6 +33,44 @@ ruleTester.run("func-names", rule, {
{
code: "class A { constructor(){} foo(){} get bar(){} set baz(value){} static qux(){}}",
parserOptions: { ecmaVersion: 6 }
},
{
code: "function foo() {}",
options: ["always"]
},
{
code: "var a = function foo() {};",
options: ["always"]
},
{
code: "function foo() {}",
options: ["never"]
},
{
code: "var a = function() {};",
options: ["never"]
},
{
code: "var foo = {bar: function() {}};",
options: ["never"]
},
{
code: "$('#foo').click(function() {});",
options: ["never"]
},
{
code: "Foo.prototype.bar = function() {};",
options: ["never"]
},
{
code: "class A { constructor(){} foo(){} get bar(){} set baz(value){} static qux(){}}",
options: ["never"],
parserOptions: { ecmaVersion: 6 }
},
{
code: "({ foo() {} });",
options: ["never"],
parserOptions: { ecmaVersion: 6 }
}
],
invalid: [
Expand All @@ -41,6 +79,21 @@ ruleTester.run("func-names", rule, {
{ code: "f(function(){})", errors: [{ message: "Missing function expression name.", type: "FunctionExpression"}] },
{ code: "var a = new Date(function() {});", errors: [{ message: "Missing function expression name.", type: "FunctionExpression"}] },
{ code: "var test = function(d, e, f) {};", errors: [{ message: "Missing function expression name.", type: "FunctionExpression"}] },
{ code: "new function() {}", errors: [{ message: "Missing function expression name.", type: "FunctionExpression"}] }
{ code: "new function() {}", errors: [{ message: "Missing function expression name.", type: "FunctionExpression"}] },
{
code: "var x = function named() {};",
options: ["never"],
errors: [{ message: "Unexpected function expression name.", type: "FunctionExpression"}]
},
{
code: "Foo.prototype.bar = function named() {};",
options: ["never"],
errors: [{ message: "Unexpected function expression name.", type: "FunctionExpression"}]
},
{
code: "({foo: function named() {}})",
options: ["never"],
errors: [{ message: "Unexpected function expression name.", type: "FunctionExpression"}]
}
]
});

0 comments on commit ff4569a

Please sign in to comment.