New Features 🥳
withTypeGuardedClasses()
Are you an open-source project or package used by others? Do you want to make type changes, but keep BC?
Guard the listed classes and their non-final descendants against method signature changes - e.g. adding a return type or a param type — that would break child classes (#8135)
return RectorConfig::configure()
->withTypeGuardedClasses([SomeContract::class]);New Rules 🎉
NegatedAndsToPositiveOrsRector
(CodeQuality) — simplify a negated "and" to "or" via de Morgan (#8082)
$a = 5;
$b = 10;
-$result = !($a > 20 && $b <= 50);
+$result = $a <= 20 || $b > 50;ExplicitAttributeNamedArgsRector
(CodeQuality) — positional attribute args → named args (#8079), Thanks @DaveLiddament!
-#[SomeAttribute(SomeClass::class, null, ['home'])]
+#[SomeAttribute(value: SomeClass::class, only: null, except: ['home'])]
class SomeClass
{
}SwitchTrueToMatchRector
(CodeQuality) — switch (true) of returning cases → match (true), replaces deprecated SwitchTrueToIfRector (#8113)
- switch (true) {
- case $value === 0:
- return 'no';
- case $value === 1:
- return 'yes';
- default:
- return 'maybe';
- }
+ return match (true) {
+ $value === 0 => 'no',
+ $value === 1 => 'yes',
+ default => 'maybe',
+ };RemoveDuplicatedReturnSelfDocblockRector
(DeadCode) — drop @return duplicating native self/static (#8087)
final class SomeClass
{
- /**
- * @return $this
- */
public function some(): self
{
return $this;
}
}RemoveMixedDocblockOverruledByNativeTypeRector
(DeadCode) — drop @param mixed / @return mixed overruled by native type (#8089)
- /**
- * @param mixed $value
- * @return mixed
- */
public function run(int $value): string
{
}RemoveUselessUnionReturnDocblockRector
(DeadCode) — drop @return union broader than a specific native type (#8126)
- /**
- * @return bool|mixed|string
- */
public function run(): false|string
{
}ClosureReturnTypeFromAssertInstanceOfRector
(TypeDeclaration) — add closure return type narrowed by assertInstanceOf() (#8115)
- $callback = function (object $object) {
+ $callback = function (object $object): SomeType {
$this->assertInstanceOf(SomeType::class, $object);
return $object;
};TypedPropertyFromContainerGetSetUpRector
(TypeDeclaration) — type property from @var when assigned via container get() in setUp() (#8120)
- /**
- * @var SomeService
- */
- private $someService;
+ private SomeService $someService;
protected function setUp(): void
{
$this->someService = static::getContainer()->get(SomeService::class);
}TypedPropertyFromGetRepositorySetUpRector
(TypeDeclaration) — same, for getRepository() assignment in setUp() (#8124)
- /**
- * @var SomeEntityRepository
- */
- private $someEntityRepository;
+ private SomeEntityRepository $someEntityRepository;
protected function setUp(): void
{
$this->someEntityRepository = $this->em->getRepository(SomeEntity::class);
}NarrowBoolDocblockReturnTypeRector
(TypeDeclaration) — narrow @return bool to false/true per native type (#8127)
/**
- * @return bool|string[]
+ * @return false|string[]
*/
public function run(): false|arrayNarrowArrayCollectionUnionReturnDocblockRector
(TypeDeclarationDocblocks) — Type[]|ArrayCollection → generic ArrayCollection<int, Type> (#8136)
/**
- * @return LeadEventLog[]|ArrayCollection
+ * @return ArrayCollection<int, LeadEventLog>
*/
public function getSuccessful(): ArrayCollectionAddClosureParamTypeFromVariableCallRector
(TypeDeclaration) — add closure param type from how the closure variable is called (#8142)
-$printItem = function ($item) {
+$printItem = function (Item $item) {
echo $item->name;
};
$printItem(new Item());rectorphp/rector-symfony 🎵
EventSubscriberMethodReturnVoidRector
(CodeQuality) — subscribed event methods must return void (event is by-reference) (#949)
- public function onEvent(Event $event): Event
+ public function onEvent(Event $event): void
{
- return $event->setSomething('value');
+ $event->setSomething('value');
}rectorphp/rector-phpunit 🟢
PHPUnit 12 cluster — typing createMock() / createStub() properties as intersections after the MockObject → Stub split.
ChangeMockObjectReturnUnionToIntersectionRector
(CodeQuality) — MockObject @return union → intersection (#703)
/**
- * @return Event|\PHPUnit\Framework\MockObject\MockObject
+ * @return Event&\PHPUnit\Framework\MockObject\MockObject
*/
private function createEvent(): \PHPUnit\Framework\MockObject\MockObjectAddIntersectionVarToMockObjectPropertyRector
(CodeQuality) — add MockObject intersection @var to a native MockObject property (#697)
+ /**
+ * @var \PHPUnit\Framework\MockObject\MockObject&\SomeService
+ */
private \PHPUnit\Framework\MockObject\MockObject $someServiceMock;AddStubIntersectionVarToStubPropertyRector
(CodeQuality) — add Stub intersection @var to a native Stub property (#700)
+ /**
+ * @var \PHPUnit\Framework\MockObject\Stub&\SomeService
+ */
private \PHPUnit\Framework\MockObject\Stub $someServiceStub;MockObjectVarToStubRector
(PHPUnit120) — on a property retyped to Stub, update @var from MockObject to Stub (#689)
/**
- * @var FieldModel|MockObject
+ * @var FieldModel|\PHPUnit\Framework\MockObject\Stub
*/
private \PHPUnit\Framework\MockObject\Stub $leadFieldModel;BareVarToStubIntersectionRector
(PHPUnit120) — add &Stub to a bare single-class @var of a Stub property (#690)
/**
- * @var FormBuilderInterface
+ * @var FormBuilderInterface&Stub
*/
private \PHPUnit\Framework\MockObject\Stub $formBuilder;PreferTestsWithCamelCaseRector
(CodeQuality) — rename PHPUnit test methods to camelCase (#668), Thanks @Xammie!
- public function test_something()
+ public function testSomething()
{
}PreferTestsWithSnakeCaseRector
(CodeQuality) — rename PHPUnit test methods to snake_case, the opposite convention (#668), Thanks @Xammie!
- public function testSomething()
+ public function test_something()
{
}Bugfixes 🐛
--only/--only-suffixruns now cache under a rule-scoped key (#8075), Thanks @SanderMuller!- Fix double clear-cache (#8096)
ParamTypeByMethodCallTypeRectorsplit into Object / Scalar / Array rules (#8134)
Deprecations & Removals 💀
Migrate away - these will be removed in a future release:
SwitchTrueToIfRector→ use newSwitchTrueToMatchRector(#8109)StrictStringParamConcatRector— too many false positives (#8090)StaticClosureRector+StaticArrowFunctionRector(#8092)StaticCallOnNonStaticToInstanceCallRector— risky change (#8093)EnumCaseToPascalCaseRector— risky change (#8095)JoinStringConcatRector(#8107)RemoveTypedPropertyNonMockDocblockRector— no real value (#8119)- Removed: long-deprecated rules (5+ months old) (#8094)
rectorphp/rector-symfony
rectorphp/rector-phpunit
BehatPHPUnitAssertToWebmozartRector— too narrow (#686)