Rector is using PHPStan to detect types of various expressions. That means every node has access to PHPStan
Scope, e.g., with types or class reflection. From code
$value = 1; we know, that
$value is type of int. But what if we change the node?
Let's say the Rector changes the code the following way:
-$value = 1; +$value = 'yes';
$value was an
int type. But after the change, the type is gone. We have an old
Scope object where
$value is still
int or even worse. If we create a new
Assign node, no
Scope is available anymore.
This becomes problematic when we rename the variable. Suddenly PHPStan has no idea about the new variable type, and everything is
mixed for it. When we use
CountOnNullRector that prevents
null fatal error, we can see Rector changed like these:
-$items = ; +$posts = ; -echo count($items); +echo is_array($posts) ? count($posts) : 0;
Which is obviously wrong.
To solve this problem, we implemented a new feature called "scope refresh" that rebuilds the scope based on the changed node. When a variable name changes, the scope will know about it and keep its type. It's a challenge as PHPStan
Scope object has few design limitations. It's an immutable object - once you enter a class, you cannot enter it again.
In the end, we made it work so that every new node will be traversed again with a new
That will allows Rector to be aware of the node type, even if nodes change:
-$items = ; +$posts = ; -echo count($items); +echo count($posts);
This is feature coming in Rector 0.13. In the meantime, don't forget to upgrade to