]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/no-self-assign.js
2 * @fileoverview Rule to disallow assignments where both sides are exactly the same
3 * @author Toru Nagashima
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 const astUtils
= require("./utils/ast-utils");
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
18 const SPACES
= /\s+/gu;
21 * Traverses 2 Pattern nodes in parallel, then reports self-assignments.
22 * @param {ASTNode|null} left A left node to traverse. This is a Pattern or
24 * @param {ASTNode|null} right A right node to traverse. This is a Pattern or
26 * @param {boolean} props The flag to check member expressions as well.
27 * @param {Function} report A callback function to report.
30 function eachSelfAssignment(left
, right
, props
, report
) {
31 if (!left
|| !right
) {
35 left
.type
=== "Identifier" &&
36 right
.type
=== "Identifier" &&
37 left
.name
=== right
.name
41 left
.type
=== "ArrayPattern" &&
42 right
.type
=== "ArrayExpression"
44 const end
= Math
.min(left
.elements
.length
, right
.elements
.length
);
46 for (let i
= 0; i
< end
; ++i
) {
47 const leftElement
= left
.elements
[i
];
48 const rightElement
= right
.elements
[i
];
50 // Avoid cases such as [...a] = [...a, 1]
53 leftElement
.type
=== "RestElement" &&
54 i
< right
.elements
.length
- 1
59 eachSelfAssignment(leftElement
, rightElement
, props
, report
);
61 // After a spread element, those indices are unknown.
62 if (rightElement
&& rightElement
.type
=== "SpreadElement") {
67 left
.type
=== "RestElement" &&
68 right
.type
=== "SpreadElement"
70 eachSelfAssignment(left
.argument
, right
.argument
, props
, report
);
72 left
.type
=== "ObjectPattern" &&
73 right
.type
=== "ObjectExpression" &&
74 right
.properties
.length
>= 1
78 * Gets the index of the last spread property.
79 * It's possible to overwrite properties followed by it.
83 for (let i
= right
.properties
.length
- 1; i
>= 0; --i
) {
84 const propType
= right
.properties
[i
].type
;
86 if (propType
=== "SpreadElement" || propType
=== "ExperimentalSpreadProperty") {
92 for (let i
= 0; i
< left
.properties
.length
; ++i
) {
93 for (let j
= startJ
; j
< right
.properties
.length
; ++j
) {
103 left
.type
=== "Property" &&
104 right
.type
=== "Property" &&
105 right
.kind
=== "init" &&
108 const leftName
= astUtils
.getStaticPropertyName(left
);
110 if (leftName
!== null && leftName
=== astUtils
.getStaticPropertyName(right
)) {
111 eachSelfAssignment(left
.value
, right
.value
, props
, report
);
115 astUtils
.skipChainExpression(left
).type
=== "MemberExpression" &&
116 astUtils
.skipChainExpression(right
).type
=== "MemberExpression" &&
117 astUtils
.isSameReference(left
, right
)
123 //------------------------------------------------------------------------------
125 //------------------------------------------------------------------------------
127 /** @type {import('../shared/types').Rule} */
133 description
: "Disallow assignments where both sides are exactly the same",
135 url
: "https://eslint.org/docs/latest/rules/no-self-assign"
147 additionalProperties
: false
152 selfAssignment
: "'{{name}}' is assigned to itself."
157 const sourceCode
= context
.sourceCode
;
158 const [{ props
= true } = {}] = context
.options
;
161 * Reports a given node as self assignments.
162 * @param {ASTNode} node A node to report. This is an Identifier node.
165 function report(node
) {
168 messageId
: "selfAssignment",
170 name
: sourceCode
.getText(node
).replace(SPACES
, "")
176 AssignmentExpression(node
) {
177 if (["=", "&&=", "||=", "??="].includes(node
.operator
)) {
178 eachSelfAssignment(node
.left
, node
.right
, props
, report
);