From 6f7c2223947a55d8bf714daa331fe483ac54e1e1 Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Sun, 2 Aug 2020 01:38:53 +0900 Subject: [PATCH 01/19] #12579 add allowFunctionParams option --- lib/rules/no-underscore-dangle.js | 32 ++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/rules/no-underscore-dangle.js b/lib/rules/no-underscore-dangle.js index cac594e1004..0e8219a21be 100644 --- a/lib/rules/no-underscore-dangle.js +++ b/lib/rules/no-underscore-dangle.js @@ -45,6 +45,10 @@ module.exports = { enforceInMethodNames: { type: "boolean", default: false + }, + allowFunctionParams: { + type: "boolean", + default: false } }, additionalProperties: false @@ -64,6 +68,7 @@ module.exports = { const allowAfterSuper = typeof options.allowAfterSuper !== "undefined" ? options.allowAfterSuper : false; const allowAfterThisConstructor = typeof options.allowAfterThisConstructor !== "undefined" ? options.allowAfterThisConstructor : false; const enforceInMethodNames = typeof options.enforceInMethodNames !== "undefined" ? options.enforceInMethodNames : false; + const allowFunctionParams = typeof options.allowFunctionParams !== "undefined" ? options.allowFunctionParams : false; //------------------------------------------------------------------------- // Helpers @@ -125,6 +130,28 @@ module.exports = { node.object.object.type === "ThisExpression"; } + /** + * Check if a node is a function parameter + * @param {ASTNode} node node to evaluate + * @returns {boolean} true if it is a function parameter + * @private + */ + function checkParameter(node) { + if (!allowFunctionParams && node.params) { + const identifier = node.params.name; + + if (typeof identifier !== "undefined" && identifier.indexOf("_") === 0) { + context.report({ + node, + messageId: "unexpectedUnderscore", + data: { + identifier + } + }); + } + } + } + /** * Check if function has a underscore at the end * @param {ASTNode} node node to evaluate @@ -145,6 +172,7 @@ module.exports = { }); } } + checkParameter(node); } /** @@ -225,7 +253,9 @@ module.exports = { VariableDeclarator: checkForTrailingUnderscoreInVariableExpression, MemberExpression: checkForTrailingUnderscoreInMemberExpression, MethodDefinition: checkForTrailingUnderscoreInMethod, - Property: checkForTrailingUnderscoreInMethod + Property: checkForTrailingUnderscoreInMethod, + FunctionExpression: checkParameter, + ArrowFunctionExpression: checkParameter }; } From ad72c3fbb77fb33e934e735338f22bc898f3e5af Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Sun, 2 Aug 2020 14:15:59 +0900 Subject: [PATCH 02/19] #12579 edit doc & function name --- lib/rules/no-underscore-dangle.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/rules/no-underscore-dangle.js b/lib/rules/no-underscore-dangle.js index 0e8219a21be..86a5ca90c98 100644 --- a/lib/rules/no-underscore-dangle.js +++ b/lib/rules/no-underscore-dangle.js @@ -131,12 +131,12 @@ module.exports = { } /** - * Check if a node is a function parameter + * Check if function parameter has a underscore at the beginning. * @param {ASTNode} node node to evaluate - * @returns {boolean} true if it is a function parameter + * @returns {boolean} true if function parameter name has a underscore at the beginning. * @private */ - function checkParameter(node) { + function checkForFollowingUnderscoreInFunctionParameter(node) { if (!allowFunctionParams && node.params) { const identifier = node.params.name; @@ -172,7 +172,7 @@ module.exports = { }); } } - checkParameter(node); + checkForFollowingUnderscoreInFunctionParameter(node); } /** @@ -254,8 +254,8 @@ module.exports = { MemberExpression: checkForTrailingUnderscoreInMemberExpression, MethodDefinition: checkForTrailingUnderscoreInMethod, Property: checkForTrailingUnderscoreInMethod, - FunctionExpression: checkParameter, - ArrowFunctionExpression: checkParameter + FunctionExpression: checkForFollowingUnderscoreInFunctionParameter, + ArrowFunctionExpression: checkForFollowingUnderscoreInFunctionParameter }; } From 0951da623fa54869961bd3f903bf1712cdd038cb Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Sun, 2 Aug 2020 15:28:40 +0900 Subject: [PATCH 03/19] #12579 add test case --- tests/lib/rules/no-underscore-dangle.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index 4baef3e82da..3029c4da539 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -26,6 +26,7 @@ ruleTester.run("no-underscore-dangle", rule, { "console.log(__filename); console.log(__dirname);", "var _ = require('underscore');", "var a = b._;", + "function foo(bar) {}", { code: "export default function() {}", parserOptions: { ecmaVersion: 6, sourceType: "module" } }, { code: "var _foo = 1", options: [{ allow: ["_foo"] }] }, { code: "var __proto__ = 1;", options: [{ allow: ["__proto__"] }] }, @@ -40,7 +41,12 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const o = { _onClick() { } }", options: [{ allow: ["_onClick"], enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 } }, { code: "const o = { _foo: 'bar' }", parserOptions: { ecmaVersion: 6 } }, { code: "const o = { foo_: 'bar' }", parserOptions: { ecmaVersion: 6 } }, - { code: "this.constructor._bar", options: [{ allowAfterThisConstructor: true }] } + { code: "this.constructor._bar", options: [{ allowAfterThisConstructor: true }] }, + { code: "const foo = { onClick(bar) { } }", parserOptions: { ecmaVersion: 6 } }, + { code: "const foo = (bar) => {}", parserOptions: { ecmaVersion: 6 } }, + { code: "function foo(_bar) {}", options: [{ allowFunctionParams: true }] }, + { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, + { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } } ], invalid: [ { code: "var _foo = 1", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_foo" }, type: "VariableDeclarator" }] }, @@ -56,7 +62,12 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "class foo { onClick_() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "onClick_" }, type: "MethodDefinition" }] }, { code: "const o = { _onClick() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_onClick" }, type: "Property" }] }, { code: "const o = { onClick_() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "onClick_" }, type: "Property" }] }, - { code: "this.constructor._bar", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "MemberExpression" }] }, - { code: "foo.constructor._bar", options: [{ allowAfterThisConstructor: true }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "MemberExpression" }] } + { code: "this.constructor._bar", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "MemberExpression" }] } + + /* + * { code: "function foo(_bar) {}", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] }, + * { code: "function foo(_bar) {}", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] }, + * { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] } + */ ] }); From a5d73708da754105a33ba6abd85ae1f03c159343 Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Sun, 2 Aug 2020 15:29:29 +0900 Subject: [PATCH 04/19] #12579 add allowFunctionParam rule in docs --- docs/rules/no-underscore-dangle.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/docs/rules/no-underscore-dangle.md b/docs/rules/no-underscore-dangle.md index ebe7fd7b6d0..447ba72c028 100644 --- a/docs/rules/no-underscore-dangle.md +++ b/docs/rules/no-underscore-dangle.md @@ -29,7 +29,7 @@ Examples of **correct** code for this rule: ```js /*eslint no-underscore-dangle: "error"*/ -var _ = require('underscore'); +var _ = require("underscore"); var obj = _.contains(items, item); obj.__proto__ = {}; var file = __filename; @@ -39,11 +39,12 @@ var file = __filename; This rule has an object option: -* `"allow"` allows specified identifiers to have dangling underscores -* `"allowAfterThis": false` (default) disallows dangling underscores in members of the `this` object -* `"allowAfterSuper": false` (default) disallows dangling underscores in members of the `super` object -* `"allowAfterThisConstructor": false` (default) disallows dangling underscores in members of the `this.constructor` object -* `"enforceInMethodNames": false` (default) allows dangling underscores in method names +- `"allow"` allows specified identifiers to have dangling underscores +- `"allowAfterThis": false` (default) disallows dangling underscores in members of the `this` object +- `"allowAfterSuper": false` (default) disallows dangling underscores in members of the `super` object +- `"allowAfterThisConstructor": false` (default) disallows dangling underscores in members of the `this.constructor` object +- `"enforceInMethodNames": false` (default) allows dangling underscores in method names +- `"allowFunctionParams": false` (default) disallows dangling underscores in first letter of function parameter name ### allow @@ -113,6 +114,20 @@ const o = { }; ``` +### allowFunctionParams + +Examples of **correct** code for this rule with the `{ "allowFunctionParams": true }` option: + +```js +/*eslint no-underscore-dangle: ["error", { "allowFunctionParams": true }]*/ + +function foo (_bar) {} + +const foo = function onClick (_bar) {} + +const foo = (_bar) {}; +``` + ## When Not To Use It If you want to allow dangling underscores in identifiers, then you can safely turn this rule off. From 1d12aea3dd9a9f91d8b4e79c112e68c4f2773f18 Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Sun, 2 Aug 2020 20:13:18 +0900 Subject: [PATCH 05/19] #12579 Update : test case when option is false --- tests/lib/rules/no-underscore-dangle.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index 3029c4da539..55ed1114cd1 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -46,7 +46,10 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const foo = (bar) => {}", parserOptions: { ecmaVersion: 6 } }, { code: "function foo(_bar) {}", options: [{ allowFunctionParams: true }] }, { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, - { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } } + { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, + { code: "function foo(bar) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, + { code: "const foo = { onClick(bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, + { code: "const foo = (bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } } ], invalid: [ { code: "var _foo = 1", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_foo" }, type: "VariableDeclarator" }] }, From 5109bf0c0d1f1ecaaf4e874457f2431f16052ec5 Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Sun, 2 Aug 2020 20:22:47 +0900 Subject: [PATCH 06/19] Return to origin code --- docs/rules/no-underscore-dangle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-underscore-dangle.md b/docs/rules/no-underscore-dangle.md index 447ba72c028..043f2490300 100644 --- a/docs/rules/no-underscore-dangle.md +++ b/docs/rules/no-underscore-dangle.md @@ -29,7 +29,7 @@ Examples of **correct** code for this rule: ```js /*eslint no-underscore-dangle: "error"*/ -var _ = require("underscore"); +var _ = require('underscore'); var obj = _.contains(items, item); obj.__proto__ = {}; var file = __filename; From 03689ba2557f8cf6438d9317545ed7bf3afa8cd5 Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Sun, 2 Aug 2020 20:38:40 +0900 Subject: [PATCH 07/19] Remove comments --- tests/lib/rules/no-underscore-dangle.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index 55ed1114cd1..22da37637d6 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -65,12 +65,8 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "class foo { onClick_() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "onClick_" }, type: "MethodDefinition" }] }, { code: "const o = { _onClick() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_onClick" }, type: "Property" }] }, { code: "const o = { onClick_() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "onClick_" }, type: "Property" }] }, - { code: "this.constructor._bar", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "MemberExpression" }] } - - /* - * { code: "function foo(_bar) {}", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] }, - * { code: "function foo(_bar) {}", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] }, - * { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] } - */ + { code: "this.constructor._bar", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "MemberExpression" }] }, + { code: "function foo(_bar) {}", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] }, + { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] } ] }); From b1ef8db00aea58f99403a7061859790ad2a2b044 Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Sun, 2 Aug 2020 21:18:20 +0900 Subject: [PATCH 08/19] Edit what was reviewed --- docs/rules/no-underscore-dangle.md | 2 +- lib/rules/no-underscore-dangle.js | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/rules/no-underscore-dangle.md b/docs/rules/no-underscore-dangle.md index 043f2490300..7568550b508 100644 --- a/docs/rules/no-underscore-dangle.md +++ b/docs/rules/no-underscore-dangle.md @@ -125,7 +125,7 @@ function foo (_bar) {} const foo = function onClick (_bar) {} -const foo = (_bar) {}; +const foo = (_bar) => {}; ``` ## When Not To Use It diff --git a/lib/rules/no-underscore-dangle.js b/lib/rules/no-underscore-dangle.js index 86a5ca90c98..66b0d56c931 100644 --- a/lib/rules/no-underscore-dangle.js +++ b/lib/rules/no-underscore-dangle.js @@ -137,18 +137,20 @@ module.exports = { * @private */ function checkForFollowingUnderscoreInFunctionParameter(node) { - if (!allowFunctionParams && node.params) { - const identifier = node.params.name; + if (!allowFunctionParams) { + node.params.forEach(param => { + const identifier = param.name; - if (typeof identifier !== "undefined" && identifier.indexOf("_") === 0) { - context.report({ - node, - messageId: "unexpectedUnderscore", - data: { - identifier - } - }); - } + if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier)) { + context.report({ + node, + messageId: "unexpectedUnderscore", + data: { + identifier + } + }); + } + }); } } From 170329356a7d916a42c6ae37163306a166b2f104 Mon Sep 17 00:00:00 2001 From: "sunghyun.cho" Date: Mon, 3 Aug 2020 11:10:34 +0900 Subject: [PATCH 09/19] Update: Destructuring param test --- tests/lib/rules/no-underscore-dangle.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index 22da37637d6..7b468b4a35e 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -49,7 +49,9 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, { code: "function foo(bar) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, { code: "const foo = { onClick(bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, - { code: "const foo = (bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } } + { code: "const foo = (bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, + { code: "function foo({ _bar }) {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, + { code: "function foo([ _bar ]) {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } } ], invalid: [ { code: "var _foo = 1", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_foo" }, type: "VariableDeclarator" }] }, From 4f1b8cf503e611f13a0eac50a289a84b65a7dafd Mon Sep 17 00:00:00 2001 From: "sunghyun.cho" Date: Mon, 3 Aug 2020 16:20:11 +0900 Subject: [PATCH 10/19] Update: invalid test case --- tests/lib/rules/no-underscore-dangle.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index 7b468b4a35e..6003cc06e41 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -69,6 +69,10 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const o = { onClick_() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "onClick_" }, type: "Property" }] }, { code: "this.constructor._bar", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "MemberExpression" }] }, { code: "function foo(_bar) {}", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] }, - { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] } + { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] }, + { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionExpression" }] }, + { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "ArrowFunctionExpression" }] }, + { code: "const foo = { onClick(_bar) { } }", parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionExpression" }] }, + { code: "const foo = (_bar) => {}", parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "ArrowFunctionExpression" }] } ] }); From fbdc7fdc74f598ecb62e5e30a65ba86c862c09e3 Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Mon, 3 Aug 2020 23:59:29 +0900 Subject: [PATCH 11/19] Change initial state to true --- docs/rules/no-underscore-dangle.md | 2 +- lib/rules/no-underscore-dangle.js | 4 ++-- tests/lib/rules/no-underscore-dangle.js | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/rules/no-underscore-dangle.md b/docs/rules/no-underscore-dangle.md index 7568550b508..b79a4dd2996 100644 --- a/docs/rules/no-underscore-dangle.md +++ b/docs/rules/no-underscore-dangle.md @@ -44,7 +44,7 @@ This rule has an object option: - `"allowAfterSuper": false` (default) disallows dangling underscores in members of the `super` object - `"allowAfterThisConstructor": false` (default) disallows dangling underscores in members of the `this.constructor` object - `"enforceInMethodNames": false` (default) allows dangling underscores in method names -- `"allowFunctionParams": false` (default) disallows dangling underscores in first letter of function parameter name +- `"allowFunctionParams": true` (default) disallows dangling underscores in first letter of function parameter name ### allow diff --git a/lib/rules/no-underscore-dangle.js b/lib/rules/no-underscore-dangle.js index 66b0d56c931..1be1efe1918 100644 --- a/lib/rules/no-underscore-dangle.js +++ b/lib/rules/no-underscore-dangle.js @@ -48,7 +48,7 @@ module.exports = { }, allowFunctionParams: { type: "boolean", - default: false + default: true } }, additionalProperties: false @@ -68,7 +68,7 @@ module.exports = { const allowAfterSuper = typeof options.allowAfterSuper !== "undefined" ? options.allowAfterSuper : false; const allowAfterThisConstructor = typeof options.allowAfterThisConstructor !== "undefined" ? options.allowAfterThisConstructor : false; const enforceInMethodNames = typeof options.enforceInMethodNames !== "undefined" ? options.enforceInMethodNames : false; - const allowFunctionParams = typeof options.allowFunctionParams !== "undefined" ? options.allowFunctionParams : false; + const allowFunctionParams = typeof options.allowFunctionParams !== "undefined" ? options.allowFunctionParams : true; //------------------------------------------------------------------------- // Helpers diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index 6003cc06e41..f7aca891b9d 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -26,7 +26,9 @@ ruleTester.run("no-underscore-dangle", rule, { "console.log(__filename); console.log(__dirname);", "var _ = require('underscore');", "var a = b._;", - "function foo(bar) {}", + "function foo(_bar) {}", + { code: "const foo = { onClick(_bar) { } }", parserOptions: { ecmaVersion: 6 } }, + { code: "const foo = (_bar) => {}", parserOptions: { ecmaVersion: 6 } }, { code: "export default function() {}", parserOptions: { ecmaVersion: 6, sourceType: "module" } }, { code: "var _foo = 1", options: [{ allow: ["_foo"] }] }, { code: "var __proto__ = 1;", options: [{ allow: ["__proto__"] }] }, @@ -68,11 +70,8 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const o = { _onClick() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_onClick" }, type: "Property" }] }, { code: "const o = { onClick_() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "onClick_" }, type: "Property" }] }, { code: "this.constructor._bar", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "MemberExpression" }] }, - { code: "function foo(_bar) {}", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] }, { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] }, { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionExpression" }] }, - { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "ArrowFunctionExpression" }] }, - { code: "const foo = { onClick(_bar) { } }", parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionExpression" }] }, - { code: "const foo = (_bar) => {}", parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "ArrowFunctionExpression" }] } + { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "ArrowFunctionExpression" }] } ] }); From 64911e99a6988750b0b331d6e376f2b317d6a508 Mon Sep 17 00:00:00 2001 From: "sunghyun.cho" Date: Tue, 4 Aug 2020 13:38:33 +0900 Subject: [PATCH 12/19] #12579 Update: Edit what was reviewed --- docs/rules/no-underscore-dangle.md | 9 +++-- lib/rules/no-underscore-dangle.js | 54 +++++++++++++++--------------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/docs/rules/no-underscore-dangle.md b/docs/rules/no-underscore-dangle.md index 7568550b508..e00007282b8 100644 --- a/docs/rules/no-underscore-dangle.md +++ b/docs/rules/no-underscore-dangle.md @@ -33,6 +33,9 @@ var _ = require('underscore'); var obj = _.contains(items, item); obj.__proto__ = {}; var file = __filename; +function foo(_bar) {}; +const foo = { onClick(_bar) {} }; +const foo = (_bar) => {}; ``` ## Options @@ -44,7 +47,7 @@ This rule has an object option: - `"allowAfterSuper": false` (default) disallows dangling underscores in members of the `super` object - `"allowAfterThisConstructor": false` (default) disallows dangling underscores in members of the `this.constructor` object - `"enforceInMethodNames": false` (default) allows dangling underscores in method names -- `"allowFunctionParams": false` (default) disallows dangling underscores in first letter of function parameter name +- `"allowFunctionParams": false` (default) disallows dangling underscores in function parameter names ### allow @@ -116,10 +119,10 @@ const o = { ### allowFunctionParams -Examples of **correct** code for this rule with the `{ "allowFunctionParams": true }` option: +Examples of **incorrect** code for this rule with the `{ "allowFunctionParams": false }` option: ```js -/*eslint no-underscore-dangle: ["error", { "allowFunctionParams": true }]*/ +/*eslint no-underscore-dangle: ["error", { "allowFunctionParams": false }]*/ function foo (_bar) {} diff --git a/lib/rules/no-underscore-dangle.js b/lib/rules/no-underscore-dangle.js index 66b0d56c931..7e53c202576 100644 --- a/lib/rules/no-underscore-dangle.js +++ b/lib/rules/no-underscore-dangle.js @@ -1,5 +1,5 @@ /** - * @fileoverview Rule to flag trailing underscores in variable declarations. + * @fileoverview Rule to flag dangling underscores in variable declarations. * @author Matt DuVall */ @@ -85,12 +85,12 @@ module.exports = { } /** - * Check if identifier has a underscore at the end + * Check if identifier has a dangling underscore * @param {string} identifier name of the node * @returns {boolean} true if its is present * @private */ - function hasTrailingUnderscore(identifier) { + function hasDanglingUnderscore(identifier) { const len = identifier.length; return identifier !== "_" && (identifier[0] === "_" || identifier[len - 1] === "_"); @@ -131,17 +131,17 @@ module.exports = { } /** - * Check if function parameter has a underscore at the beginning. + * Check if function parameter has a dangling underscore. * @param {ASTNode} node node to evaluate - * @returns {boolean} true if function parameter name has a underscore at the beginning. + * @returns {boolean} true if function parameter name has a dangling underscore. * @private */ - function checkForFollowingUnderscoreInFunctionParameter(node) { + function checkForDanglingUnderscoreInFunctionParameter(node) { if (!allowFunctionParams) { node.params.forEach(param => { const identifier = param.name; - if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier)) { + if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier)) { context.report({ node, messageId: "unexpectedUnderscore", @@ -155,16 +155,16 @@ module.exports = { } /** - * Check if function has a underscore at the end + * Check if function has a dangling underscore * @param {ASTNode} node node to evaluate * @returns {void} * @private */ - function checkForTrailingUnderscoreInFunctionDeclaration(node) { + function checkForDanglingUnderscoreInFunction(node) { if (node.id) { const identifier = node.id.name; - if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && !isAllowed(identifier)) { + if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { context.report({ node, messageId: "unexpectedUnderscore", @@ -174,19 +174,19 @@ module.exports = { }); } } - checkForFollowingUnderscoreInFunctionParameter(node); + checkForDanglingUnderscoreInFunctionParameter(node); } /** - * Check if variable expression has a underscore at the end + * Check if variable expression has a dangling underscore * @param {ASTNode} node node to evaluate * @returns {void} * @private */ - function checkForTrailingUnderscoreInVariableExpression(node) { + function checkForDanglingUnderscoreInVariableExpression(node) { const identifier = node.id.name; - if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && + if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isSpecialCaseIdentifierInVariableExpression(identifier) && !isAllowed(identifier)) { context.report({ node, @@ -199,18 +199,18 @@ module.exports = { } /** - * Check if member expression has a underscore at the end + * Check if member expression has a dangling underscore * @param {ASTNode} node node to evaluate * @returns {void} * @private */ - function checkForTrailingUnderscoreInMemberExpression(node) { + function checkForDanglingUnderscoreInMemberExpression(node) { const identifier = node.property.name, isMemberOfThis = node.object.type === "ThisExpression", isMemberOfSuper = node.object.type === "Super", isMemberOfThisConstructor = isThisConstructorReference(node); - if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && + if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !(isMemberOfThis && allowAfterThis) && !(isMemberOfSuper && allowAfterSuper) && !(isMemberOfThisConstructor && allowAfterThisConstructor) && @@ -226,16 +226,16 @@ module.exports = { } /** - * Check if method declaration or method property has a underscore at the end + * Check if method declaration or method property has a dangling underscore * @param {ASTNode} node node to evaluate * @returns {void} * @private */ - function checkForTrailingUnderscoreInMethod(node) { + function checkForDanglingUnderscoreInMethod(node) { const identifier = node.key.name; const isMethod = node.type === "MethodDefinition" || node.type === "Property" && node.method; - if (typeof identifier !== "undefined" && enforceInMethodNames && isMethod && hasTrailingUnderscore(identifier) && !isAllowed(identifier)) { + if (typeof identifier !== "undefined" && enforceInMethodNames && isMethod && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { context.report({ node, messageId: "unexpectedUnderscore", @@ -251,13 +251,13 @@ module.exports = { //-------------------------------------------------------------------------- return { - FunctionDeclaration: checkForTrailingUnderscoreInFunctionDeclaration, - VariableDeclarator: checkForTrailingUnderscoreInVariableExpression, - MemberExpression: checkForTrailingUnderscoreInMemberExpression, - MethodDefinition: checkForTrailingUnderscoreInMethod, - Property: checkForTrailingUnderscoreInMethod, - FunctionExpression: checkForFollowingUnderscoreInFunctionParameter, - ArrowFunctionExpression: checkForFollowingUnderscoreInFunctionParameter + FunctionDeclaration: checkForDanglingUnderscoreInFunction, + VariableDeclarator: checkForDanglingUnderscoreInVariableExpression, + MemberExpression: checkForDanglingUnderscoreInMemberExpression, + MethodDefinition: checkForDanglingUnderscoreInMethod, + Property: checkForDanglingUnderscoreInMethod, + FunctionExpression: checkForDanglingUnderscoreInFunction, + ArrowFunctionExpression: checkForDanglingUnderscoreInFunction }; } From c50c6d592a8430fc6307d40f11ea3545bb7325d9 Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Tue, 4 Aug 2020 21:25:10 +0900 Subject: [PATCH 13/19] #12579 Fix a typo --- docs/rules/no-underscore-dangle.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/rules/no-underscore-dangle.md b/docs/rules/no-underscore-dangle.md index ef5925b0d3f..b98c6cf44ab 100644 --- a/docs/rules/no-underscore-dangle.md +++ b/docs/rules/no-underscore-dangle.md @@ -42,12 +42,12 @@ const foo = (_bar) => {}; This rule has an object option: -- `"allow"` allows specified identifiers to have dangling underscores -- `"allowAfterThis": false` (default) disallows dangling underscores in members of the `this` object -- `"allowAfterSuper": false` (default) disallows dangling underscores in members of the `super` object -- `"allowAfterThisConstructor": false` (default) disallows dangling underscores in members of the `this.constructor` object -- `"enforceInMethodNames": false` (default) allows dangling underscores in method names -- `"allowFunctionParams": true` (default) disallows dangling underscores in function parameter names parameter name +- `"allow"` allows specified identifiers to have dangling underscores +- `"allowAfterThis": false` (default) disallows dangling underscores in members of the `this` object +- `"allowAfterSuper": false` (default) disallows dangling underscores in members of the `super` object +- `"allowAfterThisConstructor": false` (default) disallows dangling underscores in members of the `this.constructor` object +- `"enforceInMethodNames": false` (default) allows dangling underscores in method names +- `"allowFunctionParams": true` (default) allows dangling underscores in function parameter names ### allow From 7e9cceafd77b2464f3c186ed484bebc8decd4dc9 Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Tue, 4 Aug 2020 21:26:42 +0900 Subject: [PATCH 14/19] #12579 Update : allow option --- lib/rules/no-underscore-dangle.js | 2 +- tests/lib/rules/no-underscore-dangle.js | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/rules/no-underscore-dangle.js b/lib/rules/no-underscore-dangle.js index 4408258aaa6..b7947128857 100644 --- a/lib/rules/no-underscore-dangle.js +++ b/lib/rules/no-underscore-dangle.js @@ -141,7 +141,7 @@ module.exports = { node.params.forEach(param => { const identifier = param.name; - if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier)) { + if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { context.report({ node, messageId: "unexpectedUnderscore", diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index f7aca891b9d..9a072e6a49d 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -53,7 +53,10 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const foo = { onClick(bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, { code: "const foo = (bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, { code: "function foo({ _bar }) {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, - { code: "function foo([ _bar ]) {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } } + { code: "function foo([ _bar ]) {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, + { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false, allow: ["_bar"] }] }, + { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: false, allow: ["_bar"] }], parserOptions: { ecmaVersion: 6 } }, + { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false, allow: ["_bar"] }], parserOptions: { ecmaVersion: 6 } } ], invalid: [ { code: "var _foo = 1", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_foo" }, type: "VariableDeclarator" }] }, From 850c80f4f89f5dee613b0958f37359972ebe52a8 Mon Sep 17 00:00:00 2001 From: "sunghyun.cho" Date: Fri, 7 Aug 2020 14:20:21 +0900 Subject: [PATCH 15/19] #12579 Update: Edit what was reviewed --- lib/rules/no-underscore-dangle.js | 12 ++++++------ tests/lib/rules/no-underscore-dangle.js | 19 ++++++++++++++----- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/lib/rules/no-underscore-dangle.js b/lib/rules/no-underscore-dangle.js index b7947128857..4f335f4ea2c 100644 --- a/lib/rules/no-underscore-dangle.js +++ b/lib/rules/no-underscore-dangle.js @@ -132,18 +132,18 @@ module.exports = { /** * Check if function parameter has a dangling underscore. - * @param {ASTNode} node node to evaluate - * @returns {boolean} true if function parameter name has a dangling underscore. + * @param {ASTNode} node function node to evaluate + * @returns {void} * @private */ - function checkForDanglingUnderscoreInFunctionParameter(node) { + function checkForDanglingUnderscoreInFunctionParameters(node) { if (!allowFunctionParams) { node.params.forEach(param => { const identifier = param.name; if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { context.report({ - node, + node: param, messageId: "unexpectedUnderscore", data: { identifier @@ -161,7 +161,7 @@ module.exports = { * @private */ function checkForDanglingUnderscoreInFunction(node) { - if (node.id) { + if (node.type === "FunctionDeclaration" && node.id) { const identifier = node.id.name; if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { @@ -174,7 +174,7 @@ module.exports = { }); } } - checkForDanglingUnderscoreInFunctionParameter(node); + checkForDanglingUnderscoreInFunctionParameters(node); } /** diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index 9a072e6a49d..1d00fd2b6d8 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -27,8 +27,11 @@ ruleTester.run("no-underscore-dangle", rule, { "var _ = require('underscore');", "var a = b._;", "function foo(_bar) {}", + { code: "function foo( _bar = 0) {}", parserOptions: { ecmaVersion: 6 } }, { code: "const foo = { onClick(_bar) { } }", parserOptions: { ecmaVersion: 6 } }, + { code: "const foo = { onClick(_bar = 0) { } }", parserOptions: { ecmaVersion: 6 } }, { code: "const foo = (_bar) => {}", parserOptions: { ecmaVersion: 6 } }, + { code: "const foo = (_bar = 0) => {}", parserOptions: { ecmaVersion: 6 } }, { code: "export default function() {}", parserOptions: { ecmaVersion: 6, sourceType: "module" } }, { code: "var _foo = 1", options: [{ allow: ["_foo"] }] }, { code: "var __proto__ = 1;", options: [{ allow: ["__proto__"] }] }, @@ -47,13 +50,12 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const foo = { onClick(bar) { } }", parserOptions: { ecmaVersion: 6 } }, { code: "const foo = (bar) => {}", parserOptions: { ecmaVersion: 6 } }, { code: "function foo(_bar) {}", options: [{ allowFunctionParams: true }] }, + { code: "function foo( _bar = 0) {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, { code: "function foo(bar) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, { code: "const foo = { onClick(bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, { code: "const foo = (bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, - { code: "function foo({ _bar }) {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, - { code: "function foo([ _bar ]) {}", options: [{ allowFunctionParams: true }], parserOptions: { ecmaVersion: 6 } }, { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false, allow: ["_bar"] }] }, { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: false, allow: ["_bar"] }], parserOptions: { ecmaVersion: 6 } }, { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false, allow: ["_bar"] }], parserOptions: { ecmaVersion: 6 } } @@ -73,8 +75,15 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const o = { _onClick() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_onClick" }, type: "Property" }] }, { code: "const o = { onClick_() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "onClick_" }, type: "Property" }] }, { code: "this.constructor._bar", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "MemberExpression" }] }, - { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionDeclaration" }] }, - { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "FunctionExpression" }] }, - { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "ArrowFunctionExpression" }] } + { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, + { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, + { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] } + + /* + * { code: "function foo(_bar = 0) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, + * { code: "const foo = { onClick(_bar = 0) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, + * { code: "const foo = (_bar = 0) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] } + */ + ] }); From 7423641b91f20d0be89957b29f1cbe965de02141 Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Sun, 9 Aug 2020 17:07:43 +0900 Subject: [PATCH 16/19] #12579 Update : check type of param --- lib/rules/no-underscore-dangle.js | 33 ++++++++++++++++++------- tests/lib/rules/no-underscore-dangle.js | 17 +++++++------ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/lib/rules/no-underscore-dangle.js b/lib/rules/no-underscore-dangle.js index 4f335f4ea2c..bce4ccc5703 100644 --- a/lib/rules/no-underscore-dangle.js +++ b/lib/rules/no-underscore-dangle.js @@ -139,16 +139,31 @@ module.exports = { function checkForDanglingUnderscoreInFunctionParameters(node) { if (!allowFunctionParams) { node.params.forEach(param => { - const identifier = param.name; + let identifier = ""; + const { type } = param; - if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { - context.report({ - node: param, - messageId: "unexpectedUnderscore", - data: { - identifier - } - }); + if (type === "RestElement" && param.argument !== "undefined") { + if (param.argument.name !== "undefined") { + identifier = param.argument.name; + } + } else if (type === "AssignmentPattern" && param.left !== "undefined") { + if (param.left.name !== "undefined") { + identifier = param.left.name; + } + } else if (type === "Identifier" && param.name !== "undefined") { + identifier = param.name; + } + + if (identifier !== "") { + if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { + context.report({ + node: param, + messageId: "unexpectedUnderscore", + data: { + identifier + } + }); + } } }); } diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index 1d00fd2b6d8..07cb4941248 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -32,6 +32,9 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const foo = { onClick(_bar = 0) { } }", parserOptions: { ecmaVersion: 6 } }, { code: "const foo = (_bar) => {}", parserOptions: { ecmaVersion: 6 } }, { code: "const foo = (_bar = 0) => {}", parserOptions: { ecmaVersion: 6 } }, + { code: "function foo( ..._bar) {}", parserOptions: { ecmaVersion: 6 } }, + { code: "const foo = (..._bar) => {}", parserOptions: { ecmaVersion: 6 } }, + { code: "const foo = { onClick(..._bar) { } }", parserOptions: { ecmaVersion: 6 } }, { code: "export default function() {}", parserOptions: { ecmaVersion: 6, sourceType: "module" } }, { code: "var _foo = 1", options: [{ allow: ["_foo"] }] }, { code: "var __proto__ = 1;", options: [{ allow: ["__proto__"] }] }, @@ -77,13 +80,13 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "this.constructor._bar", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "MemberExpression" }] }, { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, - { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] } - - /* - * { code: "function foo(_bar = 0) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, - * { code: "const foo = { onClick(_bar = 0) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, - * { code: "const foo = (_bar = 0) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] } - */ + { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, + { code: "function foo(_bar = 0) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "AssignmentPattern" }] }, + { code: "const foo = { onClick(_bar = 0) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "AssignmentPattern" }] }, + { code: "const foo = (_bar = 0) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "AssignmentPattern" }] }, + { code: "function foo(..._bar) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "RestElement" }] }, + { code: "const foo = { onClick(..._bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "RestElement" }] }, + { code: "const foo = (..._bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "RestElement" }] } ] }); From 7667054b2dee731459e77014a873a1d0d8a8e187 Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Mon, 10 Aug 2020 01:20:35 +0900 Subject: [PATCH 17/19] #12579 Simplify the code --- lib/rules/no-underscore-dangle.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/lib/rules/no-underscore-dangle.js b/lib/rules/no-underscore-dangle.js index bce4ccc5703..87d2336fa4a 100644 --- a/lib/rules/no-underscore-dangle.js +++ b/lib/rules/no-underscore-dangle.js @@ -139,23 +139,21 @@ module.exports = { function checkForDanglingUnderscoreInFunctionParameters(node) { if (!allowFunctionParams) { node.params.forEach(param => { - let identifier = ""; const { type } = param; + let nodeToCheck; - if (type === "RestElement" && param.argument !== "undefined") { - if (param.argument.name !== "undefined") { - identifier = param.argument.name; - } - } else if (type === "AssignmentPattern" && param.left !== "undefined") { - if (param.left.name !== "undefined") { - identifier = param.left.name; - } - } else if (type === "Identifier" && param.name !== "undefined") { - identifier = param.name; + if (type === "RestElement") { + nodeToCheck = param.argument; + } else if (type === "AssignmentPattern") { + nodeToCheck = param.left; + } else { + nodeToCheck = param; } - if (identifier !== "") { - if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { + if (nodeToCheck.type === "Identifier") { + const identifier = nodeToCheck.name; + + if (hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { context.report({ node: param, messageId: "unexpectedUnderscore", From 1da841850dc04b533156e42ef8d7cb20ccf38bae Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Thu, 13 Aug 2020 23:49:14 +0900 Subject: [PATCH 18/19] Update : test case --- docs/rules/no-underscore-dangle.md | 6 ++++++ tests/lib/rules/no-underscore-dangle.js | 13 ++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/rules/no-underscore-dangle.md b/docs/rules/no-underscore-dangle.md index b98c6cf44ab..e887ab921a9 100644 --- a/docs/rules/no-underscore-dangle.md +++ b/docs/rules/no-underscore-dangle.md @@ -125,10 +125,16 @@ Examples of **incorrect** code for this rule with the `{ "allowFunctionParams": /*eslint no-underscore-dangle: ["error", { "allowFunctionParams": false }]*/ function foo (_bar) {} +function foo (_bar = 0) {} +function foo (..._bar) {} const foo = function onClick (_bar) {} +const foo = function onClick (_bar = 0) {} +const foo = function onClick (..._bar) {} const foo = (_bar) => {}; +const foo = (_bar = 0) => {}; +const foo = (...bar) => {}; ``` ## When Not To Use It diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index 07cb4941248..89f20835de2 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -27,6 +27,9 @@ ruleTester.run("no-underscore-dangle", rule, { "var _ = require('underscore');", "var a = b._;", "function foo(_bar) {}", + "function foo(bar_) {}", + "(function _foo() {})", + { code: "function foo(_bar) {}", options: [{}] }, { code: "function foo( _bar = 0) {}", parserOptions: { ecmaVersion: 6 } }, { code: "const foo = { onClick(_bar) { } }", parserOptions: { ecmaVersion: 6 } }, { code: "const foo = { onClick(_bar = 0) { } }", parserOptions: { ecmaVersion: 6 } }, @@ -61,7 +64,12 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const foo = (bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false, allow: ["_bar"] }] }, { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: false, allow: ["_bar"] }], parserOptions: { ecmaVersion: 6 } }, - { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false, allow: ["_bar"] }], parserOptions: { ecmaVersion: 6 } } + { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false, allow: ["_bar"] }], parserOptions: { ecmaVersion: 6 } }, + { code: "function foo([_bar]) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, + { code: "function foo([_bar] = []) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, + { code: "function foo( { _bar }) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, + { code: "function foo( { _bar = 0 } = {}) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 } }, + { code: "function foo(...[_bar]) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 2016 } } ], invalid: [ { code: "var _foo = 1", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_foo" }, type: "VariableDeclarator" }] }, @@ -79,6 +87,8 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const o = { onClick_() { } }", options: [{ enforceInMethodNames: true }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "onClick_" }, type: "Property" }] }, { code: "this.constructor._bar", errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "MemberExpression" }] }, { code: "function foo(_bar) {}", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, + { code: "(function foo(_bar) {})", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, + { code: "function foo(bar, _foo) {}", options: [{ allowFunctionParams: false }], errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_foo" }, type: "Identifier" }] }, { code: "const foo = { onClick(_bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, { code: "const foo = (_bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "Identifier" }] }, { code: "function foo(_bar = 0) {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "AssignmentPattern" }] }, @@ -88,5 +98,6 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "const foo = { onClick(..._bar) { } }", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "RestElement" }] }, { code: "const foo = (..._bar) => {}", options: [{ allowFunctionParams: false }], parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "unexpectedUnderscore", data: { identifier: "_bar" }, type: "RestElement" }] } + ] }); From 39f89e2895aff1193db965b65f099bb0e6d5adad Mon Sep 17 00:00:00 2001 From: sunghyunjo Date: Fri, 14 Aug 2020 00:14:22 +0900 Subject: [PATCH 19/19] Fix : ...bar -> ..._bar --- docs/rules/no-underscore-dangle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-underscore-dangle.md b/docs/rules/no-underscore-dangle.md index e887ab921a9..ded42815d2a 100644 --- a/docs/rules/no-underscore-dangle.md +++ b/docs/rules/no-underscore-dangle.md @@ -134,7 +134,7 @@ const foo = function onClick (..._bar) {} const foo = (_bar) => {}; const foo = (_bar = 0) => {}; -const foo = (...bar) => {}; +const foo = (..._bar) => {}; ``` ## When Not To Use It