Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit923f61d

Browse files
fix: false positive with assignment inno-extra-parens (#16872)
* fix: false positive with assignment in `no-extra-parens`Fixes#16850* Update lib/rules/no-extra-parens.jsUpdated as suggestedCo-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>* check assignment operator---------Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
1 parent9dbe06d commit923f61d

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

‎lib/rules/no-extra-parens.js‎

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,38 @@ module.exports = {
766766
returnfalse;
767767
}
768768

769+
/**
770+
* Checks if the left-hand side of an assignment is an identifier, the operator is one of
771+
* `=`, `&&=`, `||=` or `??=` and the right-hand side is an anonymous class or function.
772+
*
773+
* As per https://tc39.es/ecma262/#sec-assignment-operators-runtime-semantics-evaluation, an
774+
* assignment involving one of the operators `=`, `&&=`, `||=` or `??=` where the right-hand
775+
* side is an anonymous class or function and the left-hand side is an *unparenthesized*
776+
* identifier has different semantics than other assignments.
777+
* Specifically, when an expression like `foo = function () {}` is evaluated, `foo.name`
778+
* will be set to the string "foo", i.e. the identifier name. The same thing does not happen
779+
* when evaluating `(foo) = function () {}`.
780+
* Since the parenthesizing of the identifier in the left-hand side is significant in this
781+
* special case, the parentheses, if present, should not be flagged as unnecessary.
782+
*@param {ASTNode} node an AssignmentExpression node.
783+
*@returns {boolean} `true` if the left-hand side of the assignment is an identifier, the
784+
* operator is one of `=`, `&&=`, `||=` or `??=` and the right-hand side is an anonymous
785+
* class or function; otherwise, `false`.
786+
*/
787+
functionisAnonymousFunctionAssignmentException({ left, operator, right}){
788+
if(left.type==="Identifier"&&["=","&&=","||=","??="].includes(operator)){
789+
constrhsType=right.type;
790+
791+
if(rhsType==="ArrowFunctionExpression"){
792+
returntrue;
793+
}
794+
if((rhsType==="FunctionExpression"||rhsType==="ClassExpression")&&!right.id){
795+
returntrue;
796+
}
797+
}
798+
returnfalse;
799+
}
800+
769801
return{
770802
ArrayExpression(node){
771803
node.elements
@@ -804,7 +836,8 @@ module.exports = {
804836
},
805837

806838
AssignmentExpression(node){
807-
if(canBeAssignmentTarget(node.left)&&hasExcessParens(node.left)){
839+
if(canBeAssignmentTarget(node.left)&&hasExcessParens(node.left)&&
840+
(!isAnonymousFunctionAssignmentException(node)||isParenthesisedTwice(node.left))){
808841
report(node.left);
809842
}
810843

‎tests/lib/rules/no-extra-parens.js‎

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,18 @@ ruleTester.run("no-extra-parens", rule, {
771771
{
772772
code:"const net = ipaddr.parseCIDR(/** @type {string} */ (cidr));",
773773
options:["all",{allowParensAfterCommentPattern:"@type"}]
774+
},
775+
776+
// https://github.com/eslint/eslint/issues/16850
777+
"(a) = function () {};",
778+
"(a) = () => {};",
779+
"(a) = class {};",
780+
"(a) ??= function () {};",
781+
"(a) &&= class extends SuperClass {};",
782+
"(a) ||= async () => {}",
783+
{
784+
code:"((a)) = function () {};",
785+
options:["functions"]
774786
}
775787
],
776788

@@ -3410,6 +3422,28 @@ ruleTester.run("no-extra-parens", rule, {
34103422
options:["all"],
34113423
parserOptions:{ecmaVersion:2020},
34123424
errors:[{messageId:"unexpected"}]
3413-
}
3425+
},
3426+
3427+
// https://github.com/eslint/eslint/issues/16850
3428+
invalid("(a) = function foo() {};","a = function foo() {};","Identifier"),
3429+
invalid("(a) = class Bar {};","a = class Bar {};","Identifier"),
3430+
invalid("(a.b) = function () {};","a.b = function () {};","MemberExpression"),
3431+
{
3432+
code:"(newClass) = [(one)] = class { static * [Symbol.iterator]() { yield 1; } };",
3433+
output:"newClass = [one] = class { static * [Symbol.iterator]() { yield 1; } };",
3434+
errors:[
3435+
{messageId:"unexpected",type:"Identifier"},
3436+
{messageId:"unexpected",type:"Identifier"}
3437+
]
3438+
},
3439+
invalid("((a)) = () => {};","(a) = () => {};","Identifier"),
3440+
invalid("(a) = (function () {})();","a = (function () {})();","Identifier"),
3441+
...["**=","*=","/=","%=","+=","-=","<<=",">>=",">>>=","&=","^=","|="].map(
3442+
operator=>invalid(
3443+
`(a)${operator} function () {};`,
3444+
`a${operator} function () {};`,
3445+
"Identifier"
3446+
)
3447+
)
34143448
]
34153449
});

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp