Rector is helping with PHP upgrades and framework migrations. It also helps to rise the type coverage of your project.
Rector completes the type declarations for parameters, returns, and properties, with one Rector rule per each case. The only problem was, these rules use PHPStan type inference that relies on docblocks, and it could complete strict types that are not true. You burn once, and then you ignore these rules forever.
Our goal is to make Rector reliable, so it does not guess and does not require your attention on every change. Instead, it must work without flaws and be 100 % reliable.
That's why we slowly refactored away from these rules, split them into dozens of small ones that work only with strictly known types.
Next release brings huge improvement in type inferring 💪
— Rector (@rectorphp) December 3, 2022
We moved many rules from unreliable docblocks
to 100 % sure type declarations ↓
Every project will get the most type coverage they can with guaranteed safety 😎https://t.co/kAuyIbaK48 pic.twitter.com/xQlyxf6vTz
Before, Rector would make this change:
class SomeProject
{
- private $name;
+ private string $name;
/**
* @param string $name
*/
public function __construct($name)
{
$this->name = $name;
}
}
Then we create the Project
based on the API call:
$projectName = $this->apiCaller->getProjectName(123);
$project = new Project($projectName);
and get a crash as pass a null
to the Project
constructor. We don't want that.
From Rector 0.15, we removed the ParamTypeDeclarationRector
, ReturnTypeDeclarationRector
, and PropertyTypeDeclarationRector
and their array alternatives, so this will not happen.
Now, Rector takes into account only strict type declarations:
class Project
{
- private $name;
+ private string $name;
public function __construct(string $name)
{
$this->name = $name;
}
}
or
class Project
{
- public function getSize()
+ public function getSize(): int
{
return strlen($this->name);
}
}
We removed the TYPE_DECLARATION_STRICT
set and moved reliable rules to the TYPE_DECLARATION
set. Now you can use a single set to handle the type declarations.
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\SetList;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->sets([
SetList::TYPE_DECLARATION,
- SetList::TYPE_DECLARATION_STRICT,
]);
};
Take a single rule from the TYPE_DECLARATION
set, one by one. Apply the rules slowly on your code base and create a pull request per rule. Soon the strict type declarations will be everywhere they can.
Start with return type declaration rules first. They're the easiest to apply and tolerated thanks to return type covariance.