Repository: eslint/eslint (js)

Issue:
func-names causes visual clutter inside editors
The func-names rule flags the entire function instead of just the declaration, causing visual clutter in editors such as VSCode.

**What rule do you want to change?**
`func-names`

**Does this change cause the rule to produce more or fewer warnings?**
No

**How will the change be implemented? (New option, new default behavior, etc.)?**
Either new option, or change current behaviour.

**Please provide some example code that this change will affect:**

<!-- Put your code examples here -->
```js
const x = function () {
  return 100;
}
```

**What does the rule currently do for this code?**
Highlights the entire function declaration as a warning.

**What will the rule do after it's changed?**
Highlight only `function () `.

**Are you willing to submit a pull request to implement this change?**
Maybe

Pull request:
Update: report location of func-names (fixes #12022)
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[x] Changes an existing rule 

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**
Fixes #12022 

**Is there anything you'd like reviewers to focus on?**




Patch:
diff --git a/lib/rules/func-names.js b/lib/rules/func-names.js
index 01beb9e2e..ff3a1f4b5 100644
--- a/lib/rules/func-names.js
+++ b/lib/rules/func-names.js
@@ -69,6 +69,8 @@ module.exports = {
 
     create(context) {
 
+        const sourceCode = context.getSourceCode();
+
         /**
          * Returns the config option for the given node.
          * @param {ASTNode} node - A node to get the config for.
@@ -130,6 +132,7 @@ module.exports = {
             context.report({
                 node,
                 messageId: "unnamed",
+                loc: astUtils.getFunctionHeadLoc(node, sourceCode),
                 data: { name: astUtils.getFunctionNameWithKind(node) }
             });
         }
@@ -143,6 +146,7 @@ module.exports = {
             context.report({
                 node,
                 messageId: "named",
+                loc: astUtils.getFunctionHeadLoc(node, sourceCode),
                 data: { name: astUtils.getFunctionNameWithKind(node) }
             });
         }


Test patch:
diff --git a/tests/lib/rules/func-names.js b/tests/lib/rules/func-names.js
index 3fcfc50a3..1976d565c 100644
--- a/tests/lib/rules/func-names.js
+++ b/tests/lib/rules/func-names.js
@@ -17,7 +17,6 @@ const rule = require("../../../lib/rules/func-names"),
 //------------------------------------------------------------------------------
 
 const ruleTester = new RuleTester();
-const unnamedError = { messageId: "unnamed", type: "FunctionExpression" };
 
 ruleTester.run("func-names", rule, {
     valid: [
@@ -254,73 +253,166 @@ ruleTester.run("func-names", rule, {
     invalid: [
         {
             code: "Foo.prototype.bar = function() {};",
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 21,
+                endColumn: 29
+            }]
         },
         {
             code: "(function(){}())",
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 2,
+                endColumn: 10
+            }]
         },
         {
             code: "f(function(){})",
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 3,
+                endColumn: 11
+            }]
         },
         {
             code: "var a = new Date(function() {});",
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 18,
+                endColumn: 26
+            }]
         },
         {
             code: "var test = function(d, e, f) {};",
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 12,
+                endColumn: 20
+            }]
         },
         {
             code: "new function() {}",
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 5,
+                endColumn: 13
+            }]
         },
         {
             code: "Foo.prototype.bar = function() {};",
             options: ["as-needed"],
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 21,
+                endColumn: 29
+            }]
         },
         {
             code: "(function(){}())",
             options: ["as-needed"],
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 2,
+                endColumn: 10
+            }]
         },
         {
             code: "f(function(){})",
             options: ["as-needed"],
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 3,
+                endColumn: 11
+            }]
         },
         {
             code: "var a = new Date(function() {});",
             options: ["as-needed"],
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 18,
+                endColumn: 26
+            }]
         },
         {
             code: "new function() {}",
             options: ["as-needed"],
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 5,
+                endColumn: 13
+            }]
         },
         {
             code: "var {foo} = function(){};",
             options: ["as-needed"],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 13,
+                endColumn: 21
+            }]
         },
         {
             code: "var x = function foo() {};",
             options: ["never"],
-            errors: [{ messageId: "named", data: { name: "function 'foo'" }, type: "FunctionExpression" }]
+            errors: [{
+                messageId: "named",
+                data: { name: "function 'foo'" },
+                type: "FunctionExpression",
+                line: 1,
+                column: 9,
+                endColumn: 21
+            }]
         },
         {
             code: "Foo.prototype.bar = function foo() {};",
             options: ["never"],
-            errors: [{ messageId: "named", data: { name: "function 'foo'" }, type: "FunctionExpression" }]
+            errors: [{
+                messageId: "named",
+                data: { name: "function 'foo'" },
+                type: "FunctionExpression",
+                line: 1,
+                column: 21,
+                endColumn: 33
+            }]
         },
         {
             code: "({foo: function foo() {}})",
             options: ["never"],
-            errors: [{ messageId: "named", data: { name: "method 'foo'" }, type: "FunctionExpression" }]
+            errors: [{
+                messageId: "named",
+                data: { name: "method 'foo'" },
+                type: "FunctionExpression",
+                line: 1,
+                column: 3,
+                endColumn: 20
+            }]
         },
 
         // generators
@@ -328,121 +420,241 @@ ruleTester.run("func-names", rule, {
             code: "var foo = bar(function *() {});",
             options: ["always"],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 25
+            }]
         },
         {
             code: "var foo = function*() {};",
             options: ["always"],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 11,
+                endColumn: 20
+            }]
         },
         {
             code: "(function*() {}())",
             options: ["always"],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 2,
+                endColumn: 11
+            }]
         },
         {
             code: "var foo = bar(function *() {});",
             options: ["always", { generators: "always" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 25
+            }]
         },
         {
             code: "var foo = function*() {};",
             options: ["always", { generators: "always" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 11,
+                endColumn: 20
+            }]
         },
         {
             code: "(function*() {}())",
             options: ["always", { generators: "always" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 2,
+                endColumn: 11
+            }]
         },
         {
             code: "var foo = bar(function *() {});",
             options: ["always", { generators: "as-needed" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 25
+            }]
         },
         {
             code: "(function*() {}())",
             options: ["always", { generators: "as-needed" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 2,
+                endColumn: 11
+            }]
         },
         {
             code: "var foo = bar(function *() {});",
             options: ["as-needed"],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 25
+            }]
         },
         {
             code: "(function*() {}())",
             options: ["as-needed"],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 2,
+                endColumn: 11
+            }]
         },
         {
             code: "var foo = bar(function *() {});",
             options: ["as-needed", { generators: "always" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 25
+            }]
         },
         {
             code: "var foo = function*() {};",
             options: ["as-needed", { generators: "always" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 11,
+                endColumn: 20
+            }]
         },
         {
             code: "(function*() {}())",
             options: ["as-needed", { generators: "always" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 2,
+                endColumn: 11
+            }]
         },
         {
             code: "var foo = bar(function *() {});",
             options: ["as-needed", { generators: "as-needed" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 25
+            }]
         },
         {
             code: "(function*() {}())",
             options: ["as-needed", { generators: "as-needed" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 2,
+                endColumn: 11
+            }]
         },
         {
             code: "var foo = bar(function *() {});",
             options: ["never", { generators: "always" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 25
+            }]
         },
         {
             code: "var foo = function*() {};",
             options: ["never", { generators: "always" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 11,
+                endColumn: 20
+            }]
         },
         {
             code: "(function*() {}())",
             options: ["never", { generators: "always" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 2,
+                endColumn: 11
+            }]
         },
         {
             code: "var foo = bar(function *() {});",
             options: ["never", { generators: "as-needed" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 25
+            }]
         },
         {
             code: "(function*() {}())",
             options: ["never", { generators: "as-needed" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [unnamedError]
+            errors: [{
+                messageId: "unnamed",
+                type: "FunctionExpression",
+                line: 1,
+                column: 2,
+                endColumn: 11
+            }]
         },
 
         {
@@ -450,26 +662,52 @@ ruleTester.run("func-names", rule, {
             options: ["never"],
             parserOptions: { ecmaVersion: 6 },
             errors: [{
-                message: "Unexpected named generator function 'baz'."
+                messageId: "named",
+                data: { name: "generator function 'baz'" },
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 28
             }]
         },
         {
             code: "var foo = bar(function *baz() {});",
             options: ["never", { generators: "never" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ messageId: "named", data: { name: "generator function 'baz'" }, type: "FunctionExpression" }]
+            errors: [{
+                messageId: "named",
+                data: { name: "generator function 'baz'" },
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 28
+            }]
         },
         {
             code: "var foo = bar(function *baz() {});",
             options: ["always", { generators: "never" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ messageId: "named", data: { name: "generator function 'baz'" }, type: "FunctionExpression" }]
+            errors: [{
+                messageId: "named",
+                data: { name: "generator function 'baz'" },
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 28
+            }]
         },
         {
             code: "var foo = bar(function *baz() {});",
             options: ["as-needed", { generators: "never" }],
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ messageId: "named", data: { name: "generator function 'baz'" }, type: "FunctionExpression" }]
+            errors: [{
+                messageId: "named",
+                data: { name: "generator function 'baz'" },
+                type: "FunctionExpression",
+                line: 1,
+                column: 15,
+                endColumn: 28
+            }]
         }
     ]
 });