Skip to content

Releases: rectorphp/rector

Released Rector 2.5.2

22 Jun 11:40

Choose a tag to compare

Bugfixes 🐛

  • Match class + path in unused-skip reporting — fix combined class => [paths] skips being wrongly flagged as unused (#8073)
  • Mark skip used only when rule would change the file — a class/path skip counts as "used" only if the rule would actually touch that file, killing false "used" hits (#8076)
  • Improve unused-skip resolver methods — cleaner resolution internals (#8072)
  • Track used skips as class => [paths] map — richer per-path skip tracking backing the report (#8074)

Released Rector 2.5.1

21 Jun 10:41

Choose a tag to compare

Bugfixes 🐛

  • Skip unused-skip reporting on narrowed runs - no more false "unused skip" noise when running Rector on a subset of paths (#8069)
  • Display skips only on uncached run - skip report shows on real runs, not when results come from cache (#8071)
  • RemoveAlwaysTrueIfConditionRector — avoid scanning whole new statements on dynamic variable checks; moved logic to ExprAnalyzer and bail early on defined variables (#8057)

Released Rector 2.5

20 Jun 17:05

Choose a tag to compare

New Features 🥳 🎉 🎉 🎉

This release has 3 interesting new features. Let's look at them:

[dx] Report skips that never matched (#8058)

  • What? - like PHPStan's reportUnusedIgnores, but for Rector ->withSkip(). Flags skip entries that never matched anything during the run, so you can delete stale skips.

  • Why? - skips rot. You skip a path/rule to dodge a problem, later the file moves or the rule stops firing there — the skip lingers forever,
    silently masking nothing. This surfaces dead skips so config stays honest.

// rector.php
return RectorConfig::configure()
    ->withSkip([
        SimplifyUselessVariableRector::class => [
            '*/src/Legacy/*',          // still matches — fine
            '*/NonexistentUnused/*',   // matches nothing — stale
        ],
    ])
    ->reportUnusedSkips();

Run output:

 [OK] Rector is done!
  
 [WARNING] This skip is unused, it never matched any element.
           You can remove it from "->withSkip()"

 * Rector\CodeQuality\Rector\FunctionLike\SimplifyUselessVariableRector => */NonexistentUnused/*

[dx] Removing unused imports by default (#8047)

You can update your rector.php config:

 return RectorConfig::configure()
-    ->withImportNames(removeUnusedImports: true);
+    ->withImportNames();

In case it's not for you, turn it off:

 return RectorConfig::configure()
-    ->withImportNames();
+    ->withImportNames(removeUnusedImports: false);

[dx] Introducing Drupal composer-based sets (#8041), Thanks @bbrala!

If you're using Drupal Rector, you can now enable it's per-version sets via:

 return RectorConfig::configure()
+    ->withComposerBased(drupal: true);

To learn more about composer-based-sets, checkout the documentation.


New Rules 🎉

  • [php 8.4] [type-declaration] Add AddArrayAnyAllClosureParamTypeRector and NarrowArrayAnyAllNullableParamTypeRector (#8049)
  • [code-quality] Add MoveInnerFunctionToTopLevelRector (#8042)
  • [code-quality] Add NewArrayItemConcatAssignToAssignRector (#8045)
  • [code-quality] Add FixClassCaseSensitivityVarDocblockRector (#8046)
  • [polyfills] add missing polyfill to PHP 8.4 array functions (#8052)
  • [rector] Add AddParamTypeToRefactorMethodRector if missing (#8061)

Bugfixes 🐛

  • [internal] Streamline use imports management to FileNode (#8040)
  • [PostRector] Do not keep an unused import matched only by a partial docblock name's tail (#8043), Thanks @ruudk!
  • [CodeQuality] Skip native function on MoveInnerFunctionToTopLevelRector (#8044)
  • Fix --only runs caching files as unchanged, hiding pending changes from full runs (#8029), Thanks @SanderMuller!
  • [fix] Fix RemoveUnusedPrivateMethodRector for NeverType (#8050)
  • [dead-code] Fix RemoveUnusedVariableAssignRector, allow for SplFileInfo as cleanup on purpose for gc (#8054)
  • [fixes] Couple ClassPropertyAssignToConstructorPromotionRector, RemoveAlwaysTrueIfConditionRector and RemoveUnusedVariableAssignRector fixes (#8055)
  • [TypeDeclaration][DeadCode] Skip class with Doctrine static function mapping (loadMetadata) in TypedPropertyFromAssignsRector and RemoveUnusedPrivatePropertyRector (#8059)
  • [TypeDeclaration] Skip class with Doctrine static function mapping (loadMetadata) in TypedPropertyFromStrictConstructorRector (#8060)

rectorphp/rector-doctrine 🟠

  • [NodeAnalyzer] Detect Doctrine static function mapping (loadMetadata) entity in DoctrineEntityDetector (736bf61)

Released Rector 2.4.6

17 Jun 12:04

Choose a tag to compare

New Features 🥳

  • [deprecation] Add RenameDeprecatedMethodCallRector inferring rename from @deprecated docblock (#8015)
  • [sets] kick of named args set (#8013)
# rector.php
return (RectorConfig::configure())
    ->withPreparedSets(namedArgs: true);
  • Add Symfony 8 to the set provider collector (#8019), Thanks @mbabker!

Bugfixes 🐛

  • [BetterPhpDocParser] Keep import referenced by @see/@uses tag with a trailing description (#8039), Thanks @ruudk!
  • [internals] skip and finalize beforeTraverse() and afterTraverse() as never used, use refactor() instead (#7765)
  • [DeadCode] Skip (void) cast with #[NoDiscard] on target method call on RemoveDeadStmtRector (#8038)
  • Bump composer/pcre to ^3.4.0 and phpstan/phpstan to ^2.2.2 (#8037)
  • [CodeQuality] Handle crash on custom exception not autoloaded on ThrowWithPreviousExceptionRector (#8036)
  • refactor: extract AutoloadFileParameterResolver from bin, add tests (#8035), Thanks @SanderMuller!
  • Fix cached results surviving a change of --autoload-file (#8034), Thanks @SanderMuller!
  • [CodingStyle] Remove AstResolver usage on ArrowFunctionAndClosureFirstClassCallableGuard (#8031)
  • [DeadCode] Remove AstResolver on RemoveParentCallWithoutParentRector (#8032)
  • [DeadCode] Skip with use of func_num_args() on RemoveNullArgOnNullDefaultParamRector (#8030)
  • [Php70] Skip rewriting to $this on static method or static closure on StaticCallOnNonStaticToInstanceCallRector (#8026)
  • [ci] add compat test (#8025)
  • Fix ReplaceArgumentDefaultValueRector generating invalid self:: constant in unrelated classes (#8023)
  • Fix RemoveDeadIfBlockRector dropping else block when merging empty if with elseif (#8022)
  • Fix RemoveParentCallWithoutParentRector removing valid call when ancestor hierarchy is unresolvable (#8018)
  • split of RemoveNullNamedArgOnNullDefaultParamRector to handle only named args (#8014)
  • Add failing tests (#8012), Thanks @u01jmg3!
  • Update rector/swiss-knife version to ^2.4.1 (#8011)

rectorphp/rector-symfony 🎶

  • [Symfony81] Add new rule for deprecated validator test usages (#948), Thanks @florianhofsaessC24!
  • fix: only convert Twig extensions fully reducible to AsTwig attributes (#947)
  • [Symfony73] Sort optional parameters last in InvokableCommandInputAttributeRector (#945)
  • Add PHPStan rule requiring nested set configs to be imported in parent set config (#943)
  • [Symfony81] Add new rule for Security component (#942), Thanks @MrYamous!
  • Remove unused imports (#941), Thanks @MrYamous!
  • [Symfony81] Add new rule for Filesystem (#940), Thanks @MrYamous!

rectorphp/rector-phpunit 🟢

  • [PHPUnit12] Handle crash on property not exists on PropertyCreateMockToCreateStubRector (#681)
  • [AnnotationsToAttributes] Convert external @Depends ClassName::method to #[DependsExternal] (#679)
  • [PHPUnit12] Drop ConstraintValidatorTestCase from AllowMockObjectsWhereParentClassRector triggers (#678)

rectorphp/rector-downgrade-php ⬇️

  • Add DowngradeDomNodeChildNodesForeachRector for null $childNodes before PHP 8.0 (#379)
  • Update boundwize/structarmed version to ^0.9 (#378)
  • Fix use of existing PhpAttributeAnalyzer service on AddReturnTypeWillChangeAttributeRector (#377)
  • Remove no longer exists '--ansi' flag from swiss-knife (#376)
  • [DowngradePhp81] Add AddReturnTypeWillChangeAttributeRector (#372), Thanks @jquiaios!

Released Rector 2.4.5

26 May 21:05

Choose a tag to compare

New Features 🥳

  • feat: Add AddNameToNullArgumentRector (#8000), Thanks @calebdw!

Bugfixes 🐛

  • fix: skip StaticCallToMethodCallRector when parent declares final __construct (#8001)
  • [NodeManipulator] Use ClassReflection parent isFinalByKeyword()->yes() on ClassDependencyManipulator (#8002)
  • [BetterPhpDocParser] Don't wrap first-position @method param union in extra parens (#8003), Thanks @kyle-bisnow!
  • [ci] kick of auto issue fixer (#8004)
  • [automated] Apply Coding Standard (#8005)
  • [CodeQuality] Skip possibly undefined variable on SimplifyEmptyCheckOnEmptyArrayRector (#8006)
  • [CodingStyle] Handle namespaced function string on FunctionFirstClassCallableRector (#8007)
  • Fix compatibility on optional key on array dim fetch to be Mixed on phpstan patch 2.1.x-dev (#8008)
  • Update Mongodb constant from DoctrineSetList (#8009)
  • Bump to PHPStan ^2.1.56 (#8010)

rectorphp/rector-symfony

  • [QA] Add StructArmed to QA (#939)
  • [Symfony81] add rule for Ulid::isValid() new argument (#938), Thanks @MrYamous
  • [Symfony81] add rule for Serialiazer method change (#937), Thanks @MrYamous
  • [Symfony81] add rules for DependencyInjection namespace change (#936), Thanks @MrYamous

rectorphp/rector-doctrine

  • [QA] Add StructArmed to QA (#482)

rectorphp/rector-phpunit

  • [QA] Add StructArmed to QA (#677)
  • fix assert call type resolving (#675)
  • fix AssertIsTypeMethodCallRector crash on enum case argument (#674)

rectorphp/rector-downgrade-php

  • [QA] Add StructArmed to QA (#375)

Released Rector 2.4.4

20 May 19:32

Choose a tag to compare

New Features 🥳

  • [QA] Add StructArmed to QA (#7989)
  • feat: create rector to add names to boolean arguments (#7944), Thanks @calebdw!
  • [CodeQuality] Add missing MinPhpVersionInterface implements on AddNameToBooleanArgumentRector (#7994)
  • [injection] If parent class has dependency via promoted property, but its private, add a new one to child class deps (#7996)

Bugfixes 🐛

  • Bump structarmed to ^0.6 (#7990)
  • [Php81] Skip NullToStrictStringFuncCallArgRector for magic __get() property access resolving to ErrorType (#7992)
  • [automated] Apply Coding Standard (#7993)
  • [TypeDeclarationDocblocks] Skip overridden methods in DocblockReturnArrayFromDirectArrayInstanceRector (#7995)
  • Fix compatibility with latest phpstan patch 2.1.x-dev (#7997)
  • Temporary pin webmozart/assert to 2.3.0 to make downgrade working (#7998)
  • Bump webmozart/assert to ^2.4 (#7999)

Removed 💀

  • [DeadCode] Skip used by get_object_vars on RemoveUnusedPromotedPropertyRector (#7988)

rectorphp/rector-symfony

  • add fixture with failing parent private (#935)
  • fix ControllerMethodInjectionToConstructorRector - update call sites when params are moved to constructor (#934)

rectorphp/rector-downgrade-php

  • [DowngradePhp82] Handle nullable true on DowngradeStandaloneNullTrueFalseReturnTypeRector (#374)

Released Rector 2.4.3

12 May 11:20

Choose a tag to compare

New Features 🥳


Bugfixes 🐛

  • Fix the behavior of ClassPropertyAssignToConstructorPromotionRector when types do not match (#7972), Thanks @mspirkov!
  • Rectify (#7973)
  • Bump crate-ci/typos from 1.44.0 to 1.46.0 (#7976), Thanks @dependabot[bot]!
  • [CodeQuality] Skip union type on UseIdenticalOverEqualWithSameTypeRector (#7975)
  • [CodingStyle] Mirror comment on SplitDoubleAssignRector (#7977)
  • [phpstan] remove copuel fixed phpstan ignores (#7979)
  • trigger code analysis on main (rectorphp/rector-src@adb24d0)
  • [CodeQuality] Skip in html for ForRepeatedCountToOwnVariableRector (#7981)
  • Clean up PHPStan ignoreErrors (#7982)
  • Fix typo namespace Sourde -> Source in rules-tests/TypeDeclarationDocblocks (#7983)
  • cs (rectorphp/rector-src@7805989)
  • [Naming] Handle rename with use after anonymous class on RenameParamToMatchTypeRector (#7984)
  • [DX] Fix run on custom rector config when no rector.php (#7985)
  • Temporary pin nette/utils version to 4.1.3 (#7986)
  • Bump to nette/utils ^4.1.4 (#7987)

Removed 💀

  • [remove] Remove deprecated StmtsAwareInterface (#7978)
  • [remove] Remove deprecated FileWithoutNamespace and ScopeResolverNodeVisitorInterface (#7980)
  • remove docker-metadata files, as no longer maintained (rectorphp/rector-src@2166603)

rectorphp/rector-symfony

  • [symfony 2.4] skip no-route in GetRequestRector (#933)
  • fix(CommandHelpToAttributeRector): support concatenated string in setHelp() (#932), Thanks @androshchuk

rectorphp/rector-phpunit

  • [CodeQuality] Handle on static closure on WithCallbackIdenticalToStandaloneAssertsRector (#672)
  • ReplaceTestAnnotationWithPrefixedFunctionRector does not match @ test annotation if it is being part of string (#671), Thanks @Dukecz
  • [PHPUnit12] Skip used as next arg with MockObject Type on ExpressionCreateMockToCreateStubRector (#670)
  • [CodeQuality] Skip multiple uses variable as arg after defined on BareCreateMockAssignToDirectUseRector (#669)

rectorphp/rector-downgrade-php

  • [DowngradePhp80] Handle combine DowngradeMixedTypeDeclarationRector+DowngradeAttributeToAnnotationRector on declare(strict_types=1) inline after open php tag (#373)
  • remove FileWithoutNamespace (#371)
  • Fix phpstan notice on latest phpstan (#370)

Released Rector 2.4.2

16 Apr 13:08

Choose a tag to compare

New Features 🥳

  • Add some symfony/polyfill support (#7965), Thanks @sreichel!
  • [DeadCode] Allow remove useless @ var on aliased object on RemoveUselessVarTagRector (#7967)

Bugfixes 🐛

  • [Php81] Handle crash on normal array with variadic inside class on ArrayToFirstClassCallableRector (#7966)
  • [CodeQuality] Skip possibly undefined variable on CoalesceToTernaryRector (#7968)
  • [Php70] Allow is_null() conversion on TernaryToNullCoalescingRector with parentheses handling (#7969)
  • Bump to PHPStan ^2.1.47 (#7970)
  • Bump to PHPStan ^2.1.48 (#7971)

rectorphp/rector-symfony 🎵

  • Fix unit test due to new PHPStan release (#931)

Released Rector 2.4.1

08 Apr 09:02

Choose a tag to compare

New Features 🥳

  • [DeadCode] Add RemoveUselessTernaryRector (#7961)
  • [CodeQuality] Add CoalesceToTernaryRector (#7960)
  • Add --rules-summary option to display applied rules summary with count (#7874), Thanks @carlos-granados!
  • Add support for adding the #[Override] attribute to methods implementing interfaces (#7934), Thanks @hockdudu!
  • feat(printer): add per-node NEWLINE_ON_FLUENT_CALL attribute to BetterStandardPrinter (#7910), Thanks @MrPunyapal!
  • Show line numbers in diff output (#7875), Thanks @carlos-granados!

Bugfixes 🐛

  • [CodeQuality] Skip with HTML on CompleteMissingIfElseBracketRector (#7952)
  • [CodeQuality] Handle with assign on SimplifyIfElseToTernaryRector (#7951)
  • [CodeQuality] Skip with HTML on TernaryFalseExpressionToIfRector (#7954)
  • [automated] Apply Coding Standard (#7955)
  • Make compatible with PHPStan 2.1.x-dev for ObjectType::equals() change behaviour (#7956)
  • [AutoImport] Handle FQCN in/not in use on auto import + remove unused import as prefix = suffix (#7957)
  • perf: use hash map for installed packages (#7878), Thanks @calebdw!
  • [ChangesReporting][Alternative] Collect changed_files on --no-diffs with json output with use of JsonOutputFactory (#7821)
  • fix: OOM crash in RemoveUnusedVariableAssignRector (#7964), Thanks @calebdw!

Deprecations 💀

  • [Php81] Deprecate NewInInitializerRector as depends on context (#7913)
  • [deprecation] deprecate file, use getFile() instead (#7962)

Released Rector 2.4.0

04 Apr 08:02

Choose a tag to compare

New Features 🥳

  • chore: add SafeDeclareStrictTypesRector to code quality set (#7935), Thanks @calebdw!
  • [Caching] Add CacheMetaExtensionInterface for custom cache invalidation (#7933), Thanks @ruudk!
  • feat(php86): add min/max to clamp rector (#7942), Thanks @calebdw!

Bugfixes 🐛

  • [Php85] Do not convert to pipe on use directly of spread operator on NestedFuncCallsToPipeOperatorRector (#7938)
  • [Console] Allow short command "p" on ProcessCommand (#7931)
  • [Arguments] Skip self class const fetch inside this class target replacement on ReplaceArgumentDefaultValueRector (#7940)
  • [CodeQuality] Hnadle with negation binary op previous if on CombineIfRector (#7945)
  • [CodingStyle] Skip by reference required params on call inside on ArrowFunctionDelegatingCallToFirstClassCallableRector (#7949)

Removed 💀

  • [DeadCode] Skip pipe operator on RemoveDeadStmtRector (#7941)
  • [DeadCode] Handle crash on multi elseif on RemoveDeadIfBlockRector (#7946)
  • [DeadCode] Skip with assign to call with target has #[NoDiscard] attribute on RemoveUnusedVariableAssignRector (#7950)

rectorphp/rector-symfony 🎵

  • [CodeQuality] Handle different parameter type same name used on ControllerMethodInjectionToConstructorRector (#929)
  • [CodeQuality] Skip used by static closure use on ControllerMethodInjectionToConstructorRector (#928)
  • [Symfony61] Skip non static external class callable on MagicClosureTwigExtensionToNativeMethodsRector (#927), Thanks @wuchen90

rectorphp/rector-doctrine 🟠

  • Fix infinite loop check instanceof name check to use Name class (#481)

rectorphp/rector-phpunit 🟢

  • [PHPunit 9] Move AssertRegExpRector to phpunit 90 set with refactor to use assertMatchesRegularExpression/assertDoesNotMatchRegularExpression (#667)
  • [PHPUnit 9] Rename assertRegExp/assertNotRegExp to assertMatchesRegularExpression/assertDoesNotMatchRegularExpression on phpunit 90 set (#666)
  • Fix assert PHPStan on ConfiguredMockEntityToSetterObjectRector (#665)