Skip to content

Commit f65ca58

Browse files
VincentLangletphpstan-bot
authored andcommitted
Report error when $this is re-assigned
- Added $this reassignment check to InvalidAssignVarRule - Handles direct assignment ($this = ...), compound assignment ($this .= ...), and destructuring ([$this] = ...) - Error is reported in all contexts (instance methods, static methods, functions) - New regression test in tests/PHPStan/Rules/Operators/data/bug-3585.php Closes phpstan/phpstan#3585
1 parent a3fb8e9 commit f65ca58

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

src/Rules/Operators/InvalidAssignVarRule.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,38 @@ public function processNode(Node $node, Scope $scope): array
6666
];
6767
}
6868

69+
if ($this->containsThisVariable($node->var)) {
70+
return [
71+
RuleErrorBuilder::message('Cannot re-assign $this.')
72+
->identifier('assign.this')
73+
->nonIgnorable()
74+
->build(),
75+
];
76+
}
77+
6978
return [];
7079
}
7180

81+
private function containsThisVariable(Expr $expr): bool
82+
{
83+
if ($expr instanceof Expr\Variable && $expr->name === 'this') {
84+
return true;
85+
}
86+
87+
if ($expr instanceof Expr\List_) {
88+
foreach ($expr->items as $item) {
89+
if ($item === null) {
90+
continue;
91+
}
92+
if ($this->containsThisVariable($item->value)) {
93+
return true;
94+
}
95+
}
96+
}
97+
98+
return false;
99+
}
100+
72101
private function containsNonAssignableExpression(Expr $expr): bool
73102
{
74103
if ($expr instanceof Expr\Variable) {

tests/PHPStan/Rules/Operators/InvalidAssignVarRuleTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,36 @@ protected function getRule(): Rule
1717
return new InvalidAssignVarRule(new NullsafeCheck());
1818
}
1919

20+
public function testBug3585(): void
21+
{
22+
$this->analyse([__DIR__ . '/data/bug-3585.php'], [
23+
[
24+
'Cannot re-assign $this.',
25+
9,
26+
],
27+
[
28+
'Cannot re-assign $this.',
29+
10,
30+
],
31+
[
32+
'Cannot re-assign $this.',
33+
11,
34+
],
35+
[
36+
'Cannot re-assign $this.',
37+
12,
38+
],
39+
[
40+
'Cannot re-assign $this.',
41+
17,
42+
],
43+
[
44+
'Cannot re-assign $this.',
45+
23,
46+
],
47+
]);
48+
}
49+
2050
public function testRule(): void
2151
{
2252
$this->analyse([__DIR__ . '/data/invalid-assign-var.php'], [
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug3585;
4+
5+
class Foo
6+
{
7+
public function doFoo(): void
8+
{
9+
$this = 1;
10+
$this = new self();
11+
$this .= 'foo';
12+
[$this] = [1];
13+
}
14+
15+
public static function doBar(): void
16+
{
17+
$this = 1; // allowed in static context? Actually no, PHP still forbids it
18+
}
19+
}
20+
21+
function baz(): void
22+
{
23+
$this = 1; // PHP forbids this too
24+
}

0 commit comments

Comments
 (0)