compound-assignment
Flags <lvalue> = <lvalue> <op> <expr> patterns that can be written with a
compound assignment operator or ++ / --.
Rationale
A self-referential assignment carries a small amount of duplication: the
target appears twice on the same line, and a reader has to confirm that the
left and right occurrences are the same identifier before they can read the
expression as “update x”. The compound form removes that duplication and
makes intent immediately obvious.
What triggers
The rule reports any assignment whose left- and right-hand sides reference the same writable location:
<target> = <target> <op> <expr>
<target> may be an identifier (x), a member access (obj.x), or an
index access (arr[i]) — and may nest, so obj.a.b and grid[row][col]
both qualify. The two occurrences must be structurally identical, and
<op> must have a compound form:
| Binary op | Compound | Special case for literal 1 |
|---|---|---|
+ | += | x++ |
- | -= | x-- |
* | *= | — |
/ | /= | — |
% | %= | — |
& | &= | — |
| | |= | — |
^ | ^= | — |
<< | <<= | — |
>> | >>= | — |
What does not trigger
The rule skips any case where the rewrite could change observable behavior or where the two sides aren’t actually the same location:
- Targets whose receiver or index isn’t side-effect-free —
arr[next()] = arr[next()] + 1would callnext()once after the rewrite instead of twice, andarr[i++] = arr[i++] + 1similarly changes how many timesigets bumped. - Commutative variants where the target appears on the right —
x = 1 + xis semanticallyx += 1, but the binary’s left operand isn’tx, so the rule leaves it alone. - Mismatched targets —
obj.x = obj2.x + 1orobj.x = obj.y + 1. - Already-compound assignments —
x += 1,x *= n, etc. - Operators without a compound form —
==,<,&&, …
Example
Before:
function f() {
x = x + 1;
x = x - 1;
x = x + 3;
x = x * n;
obj.x = obj.x + 1;
arr[i] = arr[i] * 2;
for (i = 0; i < 10; i = i + 1) {
doStuff();
}
}
After --fix:
function f() {
x++;
x--;
x += 3;
x *= n;
obj.x++;
arr[i] *= 2;
for (i = 0; i < 10; i++) {
doStuff();
}
}
Fix
The fix replaces the entire assignment expression with the compound form. The right-hand side is copied verbatim from the source, so any inline comments and whitespace inside the RHS are preserved.