From 190c5919fb2ae0327ece10302855ea01ce794e4f Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 25 Sep 2019 10:35:23 +0200 Subject: [PATCH 1/2] Fix pseudo namespace to namespace with use statement [closes #1732] --- .../PseudoNamespaceToNamespaceRector.php | 40 +++++++++---------- .../Fixture/use_statement.php.inc | 30 ++++++++++++++ .../PseudoNamespaceToNamespaceRectorTest.php | 2 + 3 files changed, 52 insertions(+), 20 deletions(-) create mode 100644 tests/Rector/Namespace_/PseudoNamespaceToNamespaceRector/Fixture/use_statement.php.inc diff --git a/src/Rector/Namespace_/PseudoNamespaceToNamespaceRector.php b/src/Rector/Namespace_/PseudoNamespaceToNamespaceRector.php index 7cb81377d8ff..e84c95cbe5af 100644 --- a/src/Rector/Namespace_/PseudoNamespaceToNamespaceRector.php +++ b/src/Rector/Namespace_/PseudoNamespaceToNamespaceRector.php @@ -2,6 +2,7 @@ namespace Rector\Rector\Namespace_; +use Nette\Utils\Strings; use PhpParser\Node; use PhpParser\Node\FunctionLike; use PhpParser\Node\Identifier; @@ -11,6 +12,7 @@ use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\Namespace_; use PhpParser\Node\Stmt\Property; +use PhpParser\Node\Stmt\Use_; use Rector\Exception\ShouldNotHappenException; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\PhpParser\Node\Manipulator\ClassManipulator; @@ -23,6 +25,12 @@ */ final class PseudoNamespaceToNamespaceRector extends AbstractRector { + /** + * @see https://regex101.com/r/chvLgs/1/ + * @var string + */ + private const SPLIT_BY_UNDERSCORE_PATTERN = '#([a-zA-Z])(_)?(_)([a-zA-Z])#'; + /** * @var string|null */ @@ -53,29 +61,20 @@ public function getDefinition(): RectorDefinition { return new RectorDefinition('Replaces defined Pseudo_Namespaces by Namespace\Ones.', [ new ConfiguredCodeSample( - '$someService = new Some_Object;', - '$someService = new Some\Object;', - [ - [ - 'Some_' => [], - ], - ] - ), - new ConfiguredCodeSample( <<<'PHP' -/** @var Some_Object $someService */ -$someService = new Some_Object; +/** @var Some_Chicken $someService */ +$someService = new Some_Chicken; $someClassToKeep = new Some_Class_To_Keep; PHP , <<<'PHP' -/** @var Some\Object $someService */ -$someService = new Some\Object; +/** @var Some\Chicken $someService */ +$someService = new Some\Chicken; $someClassToKeep = new Some_Class_To_Keep; PHP , [ - [ + '$namespacePrefixesWithExcludedClasses' => [ 'Some_' => ['Some_Class_To_Keep'], ], ] @@ -121,7 +120,7 @@ public function afterTraverse(array $nodes): array $namespaceNode = new Namespace_(new Name($this->newNamespace)); foreach ($nodes as $key => $node) { - if ($node instanceof Class_) { + if ($node instanceof Use_ || $node instanceof Class_) { $nodes = $this->classManipulator->insertBeforeAndFollowWithNewline($nodes, $namespaceNode, $key); break; @@ -156,13 +155,14 @@ private function processIdentifier(Identifier $identifier): ?Identifier return null; } - $newNameParts = explode('_', $name); - $lastNewNamePart = $newNameParts[count($newNameParts) - 1]; + /** @var string $namespaceName */ + $namespaceName = Strings::before($name, '_', -1); + + /** @var string $lastNewNamePart */ + $lastNewNamePart = Strings::after($name, '_', -1); - $namespaceParts = $newNameParts; - array_pop($namespaceParts); + $newNamespace = Strings::replace($namespaceName, self::SPLIT_BY_UNDERSCORE_PATTERN, '$1$2\\\\$4'); - $newNamespace = implode('\\', $namespaceParts); if ($this->newNamespace !== null && $this->newNamespace !== $newNamespace) { throw new ShouldNotHappenException('There cannot be 2 different namespaces in one file'); } diff --git a/tests/Rector/Namespace_/PseudoNamespaceToNamespaceRector/Fixture/use_statement.php.inc b/tests/Rector/Namespace_/PseudoNamespaceToNamespaceRector/Fixture/use_statement.php.inc new file mode 100644 index 000000000000..e834434d9a28 --- /dev/null +++ b/tests/Rector/Namespace_/PseudoNamespaceToNamespaceRector/Fixture/use_statement.php.inc @@ -0,0 +1,30 @@ + +----- + diff --git a/tests/Rector/Namespace_/PseudoNamespaceToNamespaceRector/PseudoNamespaceToNamespaceRectorTest.php b/tests/Rector/Namespace_/PseudoNamespaceToNamespaceRector/PseudoNamespaceToNamespaceRectorTest.php index d088e21ad170..c83925551d7e 100644 --- a/tests/Rector/Namespace_/PseudoNamespaceToNamespaceRector/PseudoNamespaceToNamespaceRectorTest.php +++ b/tests/Rector/Namespace_/PseudoNamespaceToNamespaceRector/PseudoNamespaceToNamespaceRectorTest.php @@ -27,6 +27,7 @@ public function provideDataForTest(): iterable yield [__DIR__ . '/Fixture/fixture5.php.inc']; yield [__DIR__ . '/Fixture/fixture6.php.inc']; yield [__DIR__ . '/Fixture/var_doc.php.inc']; + yield [__DIR__ . '/Fixture/use_statement.php.inc']; } /** @@ -40,6 +41,7 @@ protected function getRectorsWithConfiguration(): array // namespace prefix => excluded classes 'PHPUnit_' => ['PHPUnit_Framework_MockObject_MockObject'], 'ChangeMe_' => ['KeepMe_'], + 'Rector_Tests_Rector_Namespace__PseudoNamespaceToNamespaceRector_Fixture_' => [], ], ], ]; From bccf6026bc521a1a1b45874eb8c812f4f7bc5276 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 25 Sep 2019 10:49:53 +0200 Subject: [PATCH 2/2] update docs --- docs/AllRectorsOverview.md | 2121 +++++++++++++++++++----------------- 1 file changed, 1095 insertions(+), 1026 deletions(-) diff --git a/docs/AllRectorsOverview.md b/docs/AllRectorsOverview.md index 2b31ec7d6dd9..c7fade92369f 100644 --- a/docs/AllRectorsOverview.md +++ b/docs/AllRectorsOverview.md @@ -1,4 +1,4 @@ -# All 354 Rectors Overview +# All 357 Rectors Overview - [Projects](#projects) - [General](#general) @@ -25,9 +25,20 @@ - [PHPUnit](#phpunit) - [PHPUnitSymfony](#phpunitsymfony) - [PSR4](#psr4) -- [Php](#php) +- [Php52](#php52) +- [Php53](#php53) +- [Php54](#php54) +- [Php55](#php55) +- [Php56](#php56) +- [Php70](#php70) +- [Php71](#php71) +- [Php72](#php72) +- [Php73](#php73) +- [Php74](#php74) - [PhpSpecToPHPUnit](#phpspectophpunit) +- [Refactoring](#refactoring) - [RemovingStatic](#removingstatic) +- [Renaming](#renaming) - [Restoration](#restoration) - [SOLID](#solid) - [Sensio](#sensio) @@ -937,22 +948,6 @@ Changes in_array() with single element to ===
-### `TernaryToElvisRector` - -- class: `Rector\CodeQuality\Rector\Ternary\TernaryToElvisRector` - -Use ?: instead of ?, where useful - -```diff - function elvis() - { -- $value = $a ? $a : false; -+ $value = $a ?: false; - } -``` - -
- ### `ThrowWithPreviousExceptionRector` - class: `Rector\CodeQuality\Rector\Catch_\ThrowWithPreviousExceptionRector` @@ -1265,6 +1260,33 @@ Changes negate of empty comparison of nullable value to explicit === or !== comp
+### `PreferThisOrSelfMethodCallRector` + +- class: `Rector\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector` + +Changes $this->... to self:: or vise versa for specific types + +```yaml +services: + Rector\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector: + PHPUnit\TestCase: self +``` + +↓ + +```diff + class SomeClass extends PHPUnit\TestCase + { + public function run() + { +- $this->assertThis(); ++ self::assertThis(); + } + } +``` + +
+ ### `RemoveUnusedAliasRector` - class: `Rector\CodingStyle\Rector\Use_\RemoveUnusedAliasRector` @@ -3572,170 +3594,174 @@ Changes namespace and class names to match PSR-4 in composer.json autoload secti
-## Php +## Php52 -### `AddDefaultValueForUndefinedVariableRector` +### `ContinueToBreakInSwitchRector` -- class: `Rector\Php\Rector\FunctionLike\AddDefaultValueForUndefinedVariableRector` +- class: `Rector\Php52\Rector\Switch_\ContinueToBreakInSwitchRector` -Adds default value for undefined variable +Use break instead of continue in switch statements ```diff - class SomeClass + function some_run($value) { - public function run() - { -+ $a = null; - if (rand(0, 1)) { - $a = 5; - } - echo $a; + switch ($value) { + case 1: + echo 'Hi'; +- continue; ++ break; + case 2: + echo 'Hello'; + break; } } ```
-### `AddLiteralSeparatorToNumberRector` +### `VarToPublicPropertyRector` -- class: `Rector\Php\Rector\LNumber\AddLiteralSeparatorToNumberRector` +- class: `Rector\Php52\Rector\Property\VarToPublicPropertyRector` -Add "_" as thousands separator in numbers +Remove unused private method ```diff - class SomeClass + final class SomeController { - public function run() - { -- $int = 1000; -- $float = 1000500.001; -+ $int = 1_000; -+ $float = 1_000_500.001; - } +- var $name = 'Tom'; ++ public $name = 'Tom'; } ```
-### `ArrayKeyExistsOnPropertyRector` +## Php53 + +### `TernaryToElvisRector` -- class: `Rector\Php\Rector\FuncCall\ArrayKeyExistsOnPropertyRector` +- class: `Rector\Php53\Rector\Ternary\TernaryToElvisRector` -Change array_key_exists() on property to property_exists() +Use ?: instead of ?, where useful ```diff - class SomeClass { - public $value; + function elvis() + { +- $value = $a ? $a : false; ++ $value = $a ?: false; } - $someClass = new SomeClass; - --array_key_exists('value', $someClass); -+property_exists($someClass, 'value'); ```
-### `ArrayKeyFirstLastRector` +## Php54 -- class: `Rector\Php\Rector\FuncCall\ArrayKeyFirstLastRector` +### `RemoveReferenceFromCallRector` -Make use of array_key_first() and array_key_last() +- class: `Rector\Php54\Rector\FuncCall\RemoveReferenceFromCallRector` -```diff --reset($items); --$firstKey = key($items); -+$firstKey = array_key_first($items); -``` +Remove & from function and method calls ```diff --end($items); --$lastKey = key($items); -+$lastKey = array_key_last($items); + final class SomeClass + { + public function run($one) + { +- return strlen(&$one); ++ return strlen($one); + } + } ```
-### `ArraySpreadInsteadOfArrayMergeRector` +## Php55 -- class: `Rector\Php\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector` +### `PregReplaceEModifierRector` -Change array_merge() to spread operator, except values with possible string key values +- class: `Rector\Php55\Rector\FuncCall\PregReplaceEModifierRector` + +The /e modifier is no longer supported, use preg_replace_callback instead ```diff class SomeClass { - public function run($iter1, $iter2) + public function run() { -- $values = array_merge(iterator_to_array($iter1), iterator_to_array($iter2)); -+ $values = [...$iter1, ...$iter2]; - - // Or to generalize to all iterables -- $anotherValues = array_merge( -- is_array($iter1) ? $iter1 : iterator_to_array($iter1), -- is_array($iter2) ? $iter2 : iterator_to_array($iter2) -- ); -+ $anotherValues = [...$iter1, ...$iter2]; +- $comment = preg_replace('~\b(\w)(\w+)~e', '"$1".strtolower("$2")', $comment); ++ $comment = preg_replace_callback('~\b(\w)(\w+)~', function ($matches) { ++ return($matches[1].strtolower($matches[2])); ++ }, , $comment); } } ```
-### `AssignArrayToStringRector` +### `StringClassNameToClassConstantRector` -- class: `Rector\Php\Rector\Assign\AssignArrayToStringRector` +- class: `Rector\Php55\Rector\String_\StringClassNameToClassConstantRector` -String cannot be turned into array by assignment anymore +Replace string class names by ::class constant ```diff --$string = ''; -+$string = []; - $string[] = 1; + class AnotherClass + { + } + + class SomeClass + { + public function run() + { +- return 'AnotherClass'; ++ return \AnotherClass::class; + } + } ```
-### `BarewordStringRector` +## Php56 -- class: `Rector\Php\Rector\ConstFetch\BarewordStringRector` +### `AddDefaultValueForUndefinedVariableRector` -Changes unquoted non-existing constants to strings +- class: `Rector\Php56\Rector\FunctionLike\AddDefaultValueForUndefinedVariableRector` + +Adds default value for undefined variable ```diff --var_dump(VAR); -+var_dump("VAR"); + class SomeClass + { + public function run() + { ++ $a = null; + if (rand(0, 1)) { + $a = 5; + } + echo $a; + } + } ```
-### `BinaryOpBetweenNumberAndStringRector` +### `PowToExpRector` -- class: `Rector\Php\Rector\BinaryOp\BinaryOpBetweenNumberAndStringRector` +- class: `Rector\Php56\Rector\FuncCall\PowToExpRector` -Change binary operation between some number + string to PHP 7.1 compatible version +Changes pow(val, val2) to ** (exp) parameter ```diff - class SomeClass - { - public function run() - { -- $value = 5 + ''; -- $value = 5.0 + 'hi'; -+ $value = 5 + 0; -+ $value = 5.0 + 0 - - $name = 'Tom'; -- $value = 5 * $name; -+ $value = 5 * 0; - } - } +-pow(1, 2); ++1**2; ```
+## Php70 + ### `BreakNotInLoopOrSwitchToReturnRector` -- class: `Rector\Php\Rector\Break_\BreakNotInLoopOrSwitchToReturnRector` +- class: `Rector\Php70\Rector\Break_\BreakNotInLoopOrSwitchToReturnRector` Convert break outside for/foreach/switch context to return @@ -3760,7 +3786,7 @@ Convert break outside for/foreach/switch context to return ### `CallUserMethodRector` -- class: `Rector\Php\Rector\FuncCall\CallUserMethodRector` +- class: `Rector\Php70\Rector\FuncCall\CallUserMethodRector` Changes call_user_method()/call_user_method_array() to call_user_func()/call_user_func_array() @@ -3771,276 +3797,314 @@ Changes call_user_method()/call_user_method_array() to call_user_func()/call_use
-### `ClassConstantToSelfClassRector` +### `EmptyListRector` -- class: `Rector\Php\Rector\MagicConstClass\ClassConstantToSelfClassRector` +- class: `Rector\Php70\Rector\List_\EmptyListRector` -Change __CLASS__ to self::class +list() cannot be empty ```diff - class SomeClass - { - public function callOnMe() - { -- var_dump(__CLASS__); -+ var_dump(self::class); - } - } +-list() = $values; ++list($generated) = $values; ```
-### `ClosureToArrowFunctionRector` +### `EregToPregMatchRector` -- class: `Rector\Php\Rector\Closure\ClosureToArrowFunctionRector` +- class: `Rector\Php70\Rector\FuncCall\EregToPregMatchRector` -Change closure to arrow function +Changes ereg*() to preg*() calls ```diff - class SomeClass - { - public function run($meetups) - { -- return array_filter($meetups, function (Meetup $meetup) { -- return is_object($meetup); -- }); -+ return array_filter($meetups, fn(Meetup $meetup) => is_object($meetup)); - } - } +-ereg("hi") ++preg_match("#hi#"); ```
-### `CompleteVarDocTypePropertyRector` +### `ExceptionHandlerTypehintRector` -- class: `Rector\Php\Rector\Property\CompleteVarDocTypePropertyRector` +- class: `Rector\Php70\Rector\FunctionLike\ExceptionHandlerTypehintRector` -Complete property `@var` annotations or correct the old ones +Changes property `@var` annotations from annotation to type. ```diff - final class SomeClass - { -+ /** -+ * @var EventDispatcher -+ */ - private $eventDispatcher; +-function handler(Exception $exception) { ... } ++function handler(Throwable $exception) { ... } + set_exception_handler('handler'); +``` - public function __construct(EventDispatcher $eventDispatcher) +
+ +### `IfToSpaceshipRector` + +- class: `Rector\Php70\Rector\If_\IfToSpaceshipRector` + +Changes if/else to spaceship <=> where useful + +```diff + class SomeClass + { + public function run() { - $this->eventDispatcher = $eventDispatcher; + usort($languages, function ($a, $b) { +- if ($a[0] === $b[0]) { +- return 0; +- } +- +- return ($a[0] < $b[0]) ? 1 : -1; ++ return $b[0] <=> $a[0]; + }); } } ```
-### `ContinueToBreakInSwitchRector` +### `ListSplitStringRector` -- class: `Rector\Php\Rector\Switch_\ContinueToBreakInSwitchRector` +- class: `Rector\Php70\Rector\List_\ListSplitStringRector` -Use break instead of continue in switch statements +list() cannot split string directly anymore, use str_split() ```diff - function some_run($value) - { - switch ($value) { - case 1: - echo 'Hi'; -- continue; -+ break; - case 2: - echo 'Hello'; - break; - } - } +-list($foo) = "string"; ++list($foo) = str_split("string"); ```
-### `CountOnNullRector` +### `ListSwapArrayOrderRector` -- class: `Rector\Php\Rector\FuncCall\CountOnNullRector` +- class: `Rector\Php70\Rector\List_\ListSwapArrayOrderRector` -Changes count() on null to safe ternary check +list() assigns variables in reverse order - relevant in array assign ```diff - $values = null; --$count = count($values); -+$count = is_array($values) || $values instanceof Countable ? count($values) : 0; +-list($a[], $a[]) = [1, 2]; ++list($a[], $a[]) = array_reverse([1, 2]); ```
-### `CreateFunctionToAnonymousFunctionRector` +### `MultiDirnameRector` -- class: `Rector\Php\Rector\FuncCall\CreateFunctionToAnonymousFunctionRector` +- class: `Rector\Php70\Rector\FuncCall\MultiDirnameRector` -Use anonymous functions instead of deprecated create_function() +Changes multiple dirname() calls to one with nesting level ```diff - class ClassWithCreateFunction +-dirname(dirname($path)); ++dirname($path, 2); +``` + +
+ +### `Php4ConstructorRector` + +- class: `Rector\Php70\Rector\FunctionLike\Php4ConstructorRector` + +Changes PHP 4 style constructor to __construct. + +```diff + class SomeClass { - public function run() +- public function SomeClass() ++ public function __construct() { -- $callable = create_function('$matches', "return '$delimiter' . strtolower(\$matches[1]);"); -+ $callable = function($matches) use ($delimiter) { -+ return $delimiter . strtolower($matches[1]); -+ }; } } ```
-### `EmptyListRector` +### `RandomFunctionRector` -- class: `Rector\Php\Rector\List_\EmptyListRector` +- class: `Rector\Php70\Rector\FuncCall\RandomFunctionRector` -list() cannot be empty +Changes rand, srand and getrandmax by new md_* alternatives. ```diff --list() = $values; -+list($generated) = $values; +-rand(); ++mt_rand(); ```
-### `EregToPregMatchRector` +### `ReduceMultipleDefaultSwitchRector` -- class: `Rector\Php\Rector\FuncCall\EregToPregMatchRector` +- class: `Rector\Php70\Rector\Switch_\ReduceMultipleDefaultSwitchRector` -Changes ereg*() to preg*() calls +Remove first default switch, that is ignored ```diff --ereg("hi") -+preg_match("#hi#"); + switch ($expr) { + default: +- echo "Hello World"; +- +- default: + echo "Goodbye Moon!"; + break; + } ```
-### `ExceptionHandlerTypehintRector` - -- class: `Rector\Php\Rector\FunctionLike\ExceptionHandlerTypehintRector` +### `RenameMktimeWithoutArgsToTimeRector` -Changes property `@var` annotations from annotation to type. +- class: `Rector\Php70\Rector\FuncCall\RenameMktimeWithoutArgsToTimeRector` ```diff --function handler(Exception $exception) { ... } -+function handler(Throwable $exception) { ... } - set_exception_handler('handler'); + class SomeClass + { + public function run() + { + $time = mktime(1, 2, 3); +- $nextTime = mktime(); ++ $nextTime = time(); + } + } ```
-### `ExportToReflectionFunctionRector` +### `StaticCallOnNonStaticToInstanceCallRector` -- class: `Rector\Php\Rector\StaticCall\ExportToReflectionFunctionRector` +- class: `Rector\Php70\Rector\StaticCall\StaticCallOnNonStaticToInstanceCallRector` -Change export() to ReflectionFunction alternatives +Changes static call to instance call, where not useful ```diff --$reflectionFunction = ReflectionFunction::export('foo'); --$reflectionFunctionAsString = ReflectionFunction::export('foo', true); -+$reflectionFunction = new ReflectionFunction('foo'); -+$reflectionFunctionAsString = (string) new ReflectionFunction('foo'); + class Something + { + public function doWork() + { + } + } + + class Another + { + public function run() + { +- return Something::doWork(); ++ return (new Something)->doWork(); + } + } ```
-### `FilterVarToAddSlashesRector` +### `TernaryToNullCoalescingRector` -- class: `Rector\Php\Rector\FuncCall\FilterVarToAddSlashesRector` +- class: `Rector\Php70\Rector\Ternary\TernaryToNullCoalescingRector` -Change filter_var() with slash escaping to addslashes() +Changes unneeded null check to ?? operator ```diff - $var= "Satya's here!"; --filter_var($var, FILTER_SANITIZE_MAGIC_QUOTES); -+addslashes($var); +-$value === null ? 10 : $value; ++$value ?? 10; +``` + +```diff +-isset($value) ? $value : 10; ++$value ?? 10; ```
-### `GetCalledClassToStaticClassRector` +### `TernaryToSpaceshipRector` -- class: `Rector\Php\Rector\FuncCall\GetCalledClassToStaticClassRector` +- class: `Rector\Php70\Rector\Ternary\TernaryToSpaceshipRector` -Change __CLASS__ to self::class +Use <=> spaceship instead of ternary with same effect ```diff - class SomeClass - { - public function callOnMe() - { -- var_dump(get_called_class()); -+ var_dump(static::class); - } + function order_func($a, $b) { +- return ($a < $b) ? -1 : (($a > $b) ? 1 : 0); ++ return $a <=> $b; } ```
-### `GetClassOnNullRector` +### `ThisCallOnStaticMethodToStaticCallRector` -- class: `Rector\Php\Rector\FuncCall\GetClassOnNullRector` +- class: `Rector\Php70\Rector\MethodCall\ThisCallOnStaticMethodToStaticCallRector` -Null is no more allowed in get_class() +Changes $this->call() to static method to static call ```diff - final class SomeClass + class SomeClass { - public function getItem() + public static function run() + { +- $this->eat(); ++ self::eat(); + } + + public static function eat() { - $value = null; -- return get_class($value); -+ return $value !== null ? get_class($value) : self::class; } } ```
-### `IfToSpaceshipRector` +## Php71 + +### `AssignArrayToStringRector` -- class: `Rector\Php\Rector\If_\IfToSpaceshipRector` +- class: `Rector\Php71\Rector\Assign\AssignArrayToStringRector` -Changes if/else to spaceship <=> where useful +String cannot be turned into array by assignment anymore + +```diff +-$string = ''; ++$string = []; + $string[] = 1; +``` + +
+ +### `BinaryOpBetweenNumberAndStringRector` + +- class: `Rector\Php71\Rector\BinaryOp\BinaryOpBetweenNumberAndStringRector` + +Change binary operation between some number + string to PHP 7.1 compatible version ```diff class SomeClass { public function run() { - usort($languages, function ($a, $b) { -- if ($a[0] === $b[0]) { -- return 0; -- } -- -- return ($a[0] < $b[0]) ? 1 : -1; -+ return $b[0] <=> $a[0]; - }); +- $value = 5 + ''; +- $value = 5.0 + 'hi'; ++ $value = 5 + 0; ++ $value = 5.0 + 0 } } ```
-### `IsCountableRector` +### `CountOnNullRector` -- class: `Rector\Php\Rector\BinaryOp\IsCountableRector` +- class: `Rector\Php71\Rector\FuncCall\CountOnNullRector` -Changes is_array + Countable check to is_countable +Changes count() on null to safe ternary check ```diff --is_array($foo) || $foo instanceof Countable; -+is_countable($foo); + $values = null; +-$count = count($values); ++$count = is_array($values) || $values instanceof Countable ? count($values) : 0; ```
### `IsIterableRector` -- class: `Rector\Php\Rector\BinaryOp\IsIterableRector` +- class: `Rector\Php71\Rector\BinaryOp\IsIterableRector` Changes is_array + Traversable check to is_iterable @@ -4051,152 +4115,156 @@ Changes is_array + Traversable check to is_iterable
-### `IsObjectOnIncompleteClassRector` +### `MultiExceptionCatchRector` -- class: `Rector\Php\Rector\FuncCall\IsObjectOnIncompleteClassRector` +- class: `Rector\Php71\Rector\TryCatch\MultiExceptionCatchRector` -Incomplete class returns inverted bool on is_object() +Changes multi catch of same exception to single one | separated. ```diff - $incompleteObject = new __PHP_Incomplete_Class; --$isObject = is_object($incompleteObject); -+$isObject = ! is_object($incompleteObject); + try { + // Some code... +-} catch (ExceptionType1 $exception) { +- $sameCode; +-} catch (ExceptionType2 $exception) { ++} catch (ExceptionType1 | ExceptionType2 $exception) { + $sameCode; + } ```
-### `JsonThrowOnErrorRector` +### `PublicConstantVisibilityRector` -- class: `Rector\Php\Rector\FuncCall\JsonThrowOnErrorRector` +- class: `Rector\Php71\Rector\ClassConst\PublicConstantVisibilityRector` -Adds JSON_THROW_ON_ERROR to json_encode() and json_decode() to throw JsonException on error +Add explicit public constant visibility. ```diff --json_encode($content); --json_decode($json); -+json_encode($content, JSON_THROW_ON_ERROR); -+json_decode($json, null, null, JSON_THROW_ON_ERROR); + class SomeClass + { +- const HEY = 'you'; ++ public const HEY = 'you'; + } ```
-### `ListEachRector` +### `RemoveExtraParametersRector` -- class: `Rector\Php\Rector\Each\ListEachRector` +- class: `Rector\Php71\Rector\FuncCall\RemoveExtraParametersRector` -each() function is deprecated, use key() and current() instead +Remove extra parameters ```diff --list($key, $callback) = each($callbacks); -+$key = key($opt->option); -+$val = current($opt->option); +-strlen("asdf", 1); ++strlen("asdf"); ```
-### `ListSplitStringRector` +### `ReservedObjectRector` -- class: `Rector\Php\Rector\List_\ListSplitStringRector` +- class: `Rector\Php71\Rector\Name\ReservedObjectRector` -list() cannot split string directly anymore, use str_split() +Changes reserved "Object" name to "Object" where can be configured ```diff --list($foo) = "string"; -+list($foo) = str_split("string"); +-class Object ++class SmartObject + { + } ```
-### `ListSwapArrayOrderRector` +## Php72 -- class: `Rector\Php\Rector\List_\ListSwapArrayOrderRector` +### `BarewordStringRector` -list() assigns variables in reverse order - relevant in array assign +- class: `Rector\Php72\Rector\ConstFetch\BarewordStringRector` + +Changes unquoted non-existing constants to strings ```diff --list($a[], $a[]) = [1, 2]; -+list($a[], $a[]) = array_reverse([1, 2]); +-var_dump(VAR); ++var_dump("VAR"); ```
-### `MbStrrposEncodingArgumentPositionRector` +### `CreateFunctionToAnonymousFunctionRector` -- class: `Rector\Php\Rector\FuncCall\MbStrrposEncodingArgumentPositionRector` +- class: `Rector\Php72\Rector\FuncCall\CreateFunctionToAnonymousFunctionRector` -Change mb_strrpos() encoding argument position +Use anonymous functions instead of deprecated create_function() ```diff --mb_strrpos($text, "abc", "UTF-8"); -+mb_strrpos($text, "abc", 0, "UTF-8"); -``` - -
- -### `MultiDirnameRector` - -- class: `Rector\Php\Rector\FuncCall\MultiDirnameRector` - -Changes multiple dirname() calls to one with nesting level - -```diff --dirname(dirname($path)); -+dirname($path, 2); + class ClassWithCreateFunction + { + public function run() + { +- $callable = create_function('$matches', "return '$delimiter' . strtolower(\$matches[1]);"); ++ $callable = function($matches) use ($delimiter) { ++ return $delimiter . strtolower($matches[1]); ++ }; + } + } ```
-### `MultiExceptionCatchRector` +### `GetClassOnNullRector` -- class: `Rector\Php\Rector\TryCatch\MultiExceptionCatchRector` +- class: `Rector\Php72\Rector\FuncCall\GetClassOnNullRector` -Changes multi catch of same exception to single one | separated. +Null is no more allowed in get_class() ```diff - try { - // Some code... --} catch (ExceptionType1 $exception) { -- $sameCode; --} catch (ExceptionType2 $exception) { -+} catch (ExceptionType1 | ExceptionType2 $exception) { - $sameCode; + final class SomeClass + { + public function getItem() + { + $value = null; +- return get_class($value); ++ return $value !== null ? get_class($value) : self::class; + } } ```
-### `MysqlAssignToMysqliRector` +### `IsObjectOnIncompleteClassRector` -- class: `Rector\Php\Rector\Assign\MysqlAssignToMysqliRector` +- class: `Rector\Php72\Rector\FuncCall\IsObjectOnIncompleteClassRector` -Converts more complex mysql functions to mysqli +Incomplete class returns inverted bool on is_object() ```diff --$data = mysql_db_name($result, $row); -+mysqli_data_seek($result, $row); -+$fetch = mysql_fetch_row($result); -+$data = $fetch[0]; + $incompleteObject = new __PHP_Incomplete_Class; +-$isObject = is_object($incompleteObject); ++$isObject = ! is_object($incompleteObject); ```
-### `NullCoalescingOperatorRector` +### `ListEachRector` -- class: `Rector\Php\Rector\Assign\NullCoalescingOperatorRector` +- class: `Rector\Php72\Rector\Each\ListEachRector` -Use null coalescing operator ??= +each() function is deprecated, use key() and current() instead ```diff - $array = []; --$array['user_id'] = $array['user_id'] ?? 'value'; -+$array['user_id'] ??= 'value'; +-list($key, $callback) = each($callbacks); ++$key = key($opt->option); ++$val = current($opt->option); ```
### `ParseStrWithResultArgumentRector` -- class: `Rector\Php\Rector\FuncCall\ParseStrWithResultArgumentRector` +- class: `Rector\Php72\Rector\FuncCall\ParseStrWithResultArgumentRector` Use $result argument in parse_str() function @@ -4209,157 +4277,132 @@ Use $result argument in parse_str() function
-### `Php4ConstructorRector` +### `StringifyDefineRector` -- class: `Rector\Php\Rector\FunctionLike\Php4ConstructorRector` +- class: `Rector\Php72\Rector\FuncCall\StringifyDefineRector` -Changes PHP 4 style constructor to __construct. +Make first argument of define() string ```diff class SomeClass { -- public function SomeClass() -+ public function __construct() + public function run(int $a) { +- define(CONSTANT_2, 'value'); ++ define('CONSTANT_2', 'value'); + define('CONSTANT', 'value'); } } ```
-### `PowToExpRector` +### `StringsAssertNakedRector` -- class: `Rector\Php\Rector\FuncCall\PowToExpRector` +- class: `Rector\Php72\Rector\FuncCall\StringsAssertNakedRector` -Changes pow(val, val2) to ** (exp) parameter +String asserts must be passed directly to assert() ```diff --pow(1, 2); -+1**2; + function nakedAssert() + { +- assert('true === true'); +- assert("true === true"); ++ assert(true === true); ++ assert(true === true); + } ```
-### `PreferThisOrSelfMethodCallRector` - -- class: `Rector\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector` - -Changes $this->... to self:: or vise versa for specific types +### `UnsetCastRector` -```yaml -services: - Rector\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector: - PHPUnit\TestCase: self -``` +- class: `Rector\Php72\Rector\Unset_\UnsetCastRector` -↓ +Removes (unset) cast ```diff - class SomeClass extends PHPUnit\TestCase - { - public function run() - { -- $this->assertThis(); -+ self::assertThis(); - } - } +-$value = (unset) $value; ++$value = null; ```
-### `PregReplaceEModifierRector` +### `WhileEachToForeachRector` -- class: `Rector\Php55\Rector\FuncCall\PregReplaceEModifierRector` +- class: `Rector\Php72\Rector\Each\WhileEachToForeachRector` -The /e modifier is no longer supported, use preg_replace_callback instead +each() function is deprecated, use foreach() instead. ```diff - class SomeClass - { - public function run() - { -- $comment = preg_replace('~\b(\w)(\w+)~e', '"$1".strtolower("$2")', $comment); -+ $comment = preg_replace_callback('~\b(\w)(\w+)~', function ($matches) { -+ return($matches[1].strtolower($matches[2])); -+ }, , $comment); - } +-while (list($key, $callback) = each($callbacks)) { ++foreach ($callbacks as $key => $callback) { + // ... } ``` -
- -### `PublicConstantVisibilityRector` - -- class: `Rector\Php\Rector\ClassConst\PublicConstantVisibilityRector` - -Add explicit public constant visibility. - ```diff - class SomeClass - { -- const HEY = 'you'; -+ public const HEY = 'you'; +-while (list($key) = each($callbacks)) { ++foreach (array_keys($callbacks) as $key) { + // ... } ```
-### `RandomFunctionRector` +## Php73 -- class: `Rector\Php\Rector\FuncCall\RandomFunctionRector` +### `ArrayKeyFirstLastRector` -Changes rand, srand and getrandmax by new md_* alternatives. +- class: `Rector\Php73\Rector\FuncCall\ArrayKeyFirstLastRector` + +Make use of array_key_first() and array_key_last() ```diff --rand(); -+mt_rand(); +-reset($items); +-$firstKey = key($items); ++$firstKey = array_key_first($items); +``` + +```diff +-end($items); +-$lastKey = key($items); ++$lastKey = array_key_last($items); ```
-### `RealToFloatTypeCastRector` +### `IsCountableRector` -- class: `Rector\Php\Rector\Double\RealToFloatTypeCastRector` +- class: `Rector\Php73\Rector\BinaryOp\IsCountableRector` -Change deprecated (real) to (float) +Changes is_array + Countable check to is_countable ```diff - class SomeClass - { - public function run() - { -- $number = (real) 5; -+ $number = (float) 5; - $number = (float) 5; - $number = (double) 5; - } - } +-is_array($foo) || $foo instanceof Countable; ++is_countable($foo); ```
-### `ReduceMultipleDefaultSwitchRector` +### `JsonThrowOnErrorRector` -- class: `Rector\Php\Rector\Switch_\ReduceMultipleDefaultSwitchRector` +- class: `Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector` -Remove first default switch, that is ignored +Adds JSON_THROW_ON_ERROR to json_encode() and json_decode() to throw JsonException on error ```diff - switch ($expr) { - default: -- echo "Hello World"; -- -- default: - echo "Goodbye Moon!"; - break; - } +-json_encode($content); +-json_decode($json); ++json_encode($content, JSON_THROW_ON_ERROR); ++json_decode($json, null, null, JSON_THROW_ON_ERROR); ```
### `RegexDashEscapeRector` -- class: `Rector\Php\Rector\FuncCall\RegexDashEscapeRector` +- class: `Rector\Php73\Rector\FuncCall\RegexDashEscapeRector` Escape - in some cases @@ -4370,22 +4413,9 @@ Escape - in some cases
-### `RemoveExtraParametersRector` - -- class: `Rector\Php\Rector\FuncCall\RemoveExtraParametersRector` - -Remove extra parameters - -```diff --strlen("asdf", 1); -+strlen("asdf"); -``` - -
- ### `RemoveMissingCompactVariableRector` -- class: `Rector\Php\Rector\FuncCall\RemoveMissingCompactVariableRector` +- class: `Rector\Php73\Rector\FuncCall\RemoveMissingCompactVariableRector` Remove non-existing vars from compact() @@ -4404,316 +4434,286 @@ Remove non-existing vars from compact()
-### `RemoveReferenceFromCallRector` +### `SensitiveConstantNameRector` -- class: `Rector\Php\Rector\FuncCall\RemoveReferenceFromCallRector` +- class: `Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector` -Remove & from function and method calls +Changes case insensitive constants to sensitive ones. ```diff - final class SomeClass - { - public function run($one) - { -- return strlen(&$one); -+ return strlen($one); - } - } + define('FOO', 42, true); + var_dump(FOO); +-var_dump(foo); ++var_dump(FOO); ```
-### `RenameConstantRector` +### `SensitiveDefineRector` -- class: `Rector\Php\Rector\ConstFetch\RenameConstantRector` +- class: `Rector\Php73\Rector\FuncCall\SensitiveDefineRector` -Replace constant by new ones +Changes case insensitive constants to sensitive ones. ```diff - final class SomeClass - { - public function run() - { -- return MYSQL_ASSOC; -+ return MYSQLI_ASSOC; - } - } +-define('FOO', 42, true); ++define('FOO', 42); ```
-### `RenameMktimeWithoutArgsToTimeRector` +### `SensitiveHereNowDocRector` + +- class: `Rector\Php73\Rector\String_\SensitiveHereNowDocRector` -- class: `Rector\Php\Rector\FuncCall\RenameMktimeWithoutArgsToTimeRector` +Changes heredoc/nowdoc that contains closing word to safe wrapper name ```diff - class SomeClass - { - public function run() - { - $time = mktime(1, 2, 3); -- $nextTime = mktime(); -+ $nextTime = time(); - } - } +-$value = << -### `ReservedFnFunctionRector` +### `StringifyStrNeedlesRector` -- class: `Rector\Php\Rector\Function_\ReservedFnFunctionRector` +- class: `Rector\Php73\Rector\FuncCall\StringifyStrNeedlesRector` -Change fn() function name, since it will be reserved keyword +Makes needles explicit strings ```diff - class SomeClass - { - public function run() - { -- function fn($value) -+ function f($value) - { - return $value; - } - -- fn(5); -+ f(5); - } - } + $needle = 5; +-$fivePosition = strpos('725', $needle); ++$fivePosition = strpos('725', (string) $needle); ```
-### `ReservedObjectRector` +## Php74 -- class: `Rector\Php71\Rector\Name\ReservedObjectRector` +### `AddLiteralSeparatorToNumberRector` -Changes reserved "Object" name to "Object" where can be configured +- class: `Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector` + +Add "_" as thousands separator in numbers ```diff --class Object -+class SmartObject + class SomeClass { + public function run() + { +- $int = 1000; +- $float = 1000500.001; ++ $int = 1_000; ++ $float = 1_000_500.001; + } } ```
-### `SensitiveConstantNameRector` - -- class: `Rector\Php\Rector\ConstFetch\SensitiveConstantNameRector` - -Changes case insensitive constants to sensitive ones. - -```diff - define('FOO', 42, true); - var_dump(FOO); --var_dump(foo); -+var_dump(FOO); -``` - -
- -### `SensitiveDefineRector` +### `ArrayKeyExistsOnPropertyRector` -- class: `Rector\Php\Rector\FuncCall\SensitiveDefineRector` +- class: `Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector` -Changes case insensitive constants to sensitive ones. +Change array_key_exists() on property to property_exists() ```diff --define('FOO', 42, true); -+define('FOO', 42); -``` - -
- -### `SensitiveHereNowDocRector` - -- class: `Rector\Php\Rector\String_\SensitiveHereNowDocRector` - -Changes heredoc/nowdoc that contains closing word to safe wrapper name + class SomeClass { + public $value; + } + $someClass = new SomeClass; -```diff --$value = <<
-### `StaticCallOnNonStaticToInstanceCallRector` +### `ArraySpreadInsteadOfArrayMergeRector` -- class: `Rector\Php\Rector\StaticCall\StaticCallOnNonStaticToInstanceCallRector` +- class: `Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector` -Changes static call to instance call, where not useful +Change array_merge() to spread operator, except values with possible string key values ```diff - class Something + class SomeClass { - public function doWork() + public function run($iter1, $iter2) { - } - } +- $values = array_merge(iterator_to_array($iter1), iterator_to_array($iter2)); ++ $values = [...$iter1, ...$iter2]; - class Another - { - public function run() - { -- return Something::doWork(); -+ return (new Something)->doWork(); + // Or to generalize to all iterables +- $anotherValues = array_merge( +- is_array($iter1) ? $iter1 : iterator_to_array($iter1), +- is_array($iter2) ? $iter2 : iterator_to_array($iter2) +- ); ++ $anotherValues = [...$iter1, ...$iter2]; } } ```
-### `StringClassNameToClassConstantRector` +### `ClassConstantToSelfClassRector` -- class: `Rector\Php\Rector\String_\StringClassNameToClassConstantRector` +- class: `Rector\Php74\Rector\MagicConstClass\ClassConstantToSelfClassRector` -Replace string class names by ::class constant +Change __CLASS__ to self::class ```diff - class AnotherClass - { - } - class SomeClass { - public function run() - { -- return 'AnotherClass'; -+ return \AnotherClass::class; - } + public function callOnMe() + { +- var_dump(__CLASS__); ++ var_dump(self::class); + } } ```
-### `StringifyDefineRector` +### `ClosureToArrowFunctionRector` -- class: `Rector\Php\Rector\FuncCall\StringifyDefineRector` +- class: `Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector` -Make first argument of define() string +Change closure to arrow function ```diff class SomeClass { - public function run(int $a) + public function run($meetups) { -- define(CONSTANT_2, 'value'); -+ define('CONSTANT_2', 'value'); - define('CONSTANT', 'value'); +- return array_filter($meetups, function (Meetup $meetup) { +- return is_object($meetup); +- }); ++ return array_filter($meetups, fn(Meetup $meetup) => is_object($meetup)); } } ```
-### `StringifyStrNeedlesRector` +### `ExportToReflectionFunctionRector` -- class: `Rector\Php\Rector\FuncCall\StringifyStrNeedlesRector` +- class: `Rector\Php74\Rector\StaticCall\ExportToReflectionFunctionRector` -Makes needles explicit strings +Change export() to ReflectionFunction alternatives ```diff - $needle = 5; --$fivePosition = strpos('725', $needle); -+$fivePosition = strpos('725', (string) $needle); +-$reflectionFunction = ReflectionFunction::export('foo'); +-$reflectionFunctionAsString = ReflectionFunction::export('foo', true); ++$reflectionFunction = new ReflectionFunction('foo'); ++$reflectionFunctionAsString = (string) new ReflectionFunction('foo'); ```
-### `StringsAssertNakedRector` +### `FilterVarToAddSlashesRector` -- class: `Rector\Php\Rector\FuncCall\StringsAssertNakedRector` +- class: `Rector\Php74\Rector\FuncCall\FilterVarToAddSlashesRector` -String asserts must be passed directly to assert() +Change filter_var() with slash escaping to addslashes() ```diff - function nakedAssert() - { -- assert('true === true'); -- assert("true === true"); -+ assert(true === true); -+ assert(true === true); - } + $var= "Satya's here!"; +-filter_var($var, FILTER_SANITIZE_MAGIC_QUOTES); ++addslashes($var); ```
-### `SwapFuncCallArgumentsRector` +### `GetCalledClassToStaticClassRector` -- class: `Rector\Rector\Argument\SwapFuncCallArgumentsRector` +- class: `Rector\Php74\Rector\FuncCall\GetCalledClassToStaticClassRector` -Swap arguments in function calls +Change __CLASS__ to self::class ```diff - final class SomeClass + class SomeClass { - public function run($one, $two) - { -- return some_function($one, $two); -+ return some_function($two, $one); - } + public function callOnMe() + { +- var_dump(get_called_class()); ++ var_dump(static::class); + } } ```
-### `TernaryToNullCoalescingRector` +### `MbStrrposEncodingArgumentPositionRector` -- class: `Rector\Php\Rector\Ternary\TernaryToNullCoalescingRector` +- class: `Rector\Php74\Rector\FuncCall\MbStrrposEncodingArgumentPositionRector` -Changes unneeded null check to ?? operator +Change mb_strrpos() encoding argument position ```diff --$value === null ? 10 : $value; -+$value ?? 10; +-mb_strrpos($text, "abc", "UTF-8"); ++mb_strrpos($text, "abc", 0, "UTF-8"); ``` +
+ +### `NullCoalescingOperatorRector` + +- class: `Rector\Php74\Rector\Assign\NullCoalescingOperatorRector` + +Use null coalescing operator ??= + ```diff --isset($value) ? $value : 10; -+$value ?? 10; + $array = []; +-$array['user_id'] = $array['user_id'] ?? 'value'; ++$array['user_id'] ??= 'value'; ```
-### `TernaryToSpaceshipRector` +### `RealToFloatTypeCastRector` -- class: `Rector\Php\Rector\Ternary\TernaryToSpaceshipRector` +- class: `Rector\Php74\Rector\Double\RealToFloatTypeCastRector` -Use <=> spaceship instead of ternary with same effect +Change deprecated (real) to (float) ```diff - function order_func($a, $b) { -- return ($a < $b) ? -1 : (($a > $b) ? 1 : 0); -+ return $a <=> $b; + class SomeClass + { + public function run() + { +- $number = (real) 5; ++ $number = (float) 5; + $number = (float) 5; + $number = (double) 5; + } } ```
-### `ThisCallOnStaticMethodToStaticCallRector` +### `ReservedFnFunctionRector` -- class: `Rector\Php\Rector\MethodCall\ThisCallOnStaticMethodToStaticCallRector` +- class: `Rector\Php74\Rector\Function_\ReservedFnFunctionRector` -Changes $this->call() to static method to static call +Change fn() function name, since it will be reserved keyword ```diff class SomeClass { - public static function run() + public function run() { -- $this->eat(); -+ self::eat(); - } +- function fn($value) ++ function f($value) + { + return $value; + } - public static function eat() - { +- fn(5); ++ f(5); } } ``` @@ -4722,7 +4722,7 @@ Changes $this->call() to static method to static call ### `TypedPropertyRector` -- class: `Rector\Php\Rector\Property\TypedPropertyRector` +- class: `Rector\Php74\Rector\Property\TypedPropertyRector` Changes property `@var` annotations from annotation to type. @@ -4739,62 +4739,45 @@ Changes property `@var` annotations from annotation to type.
-### `UnsetCastRector` +## PhpSpecToPHPUnit + +### `AddMockPropertiesRector` -- class: `Rector\Php\Rector\Unset_\UnsetCastRector` +- class: `Rector\PhpSpecToPHPUnit\Rector\Class_\AddMockPropertiesRector` -Removes (unset) cast +Migrate PhpSpec behavior to PHPUnit test ```diff --$value = (unset) $value; -+$value = null; + namespace spec\SomeNamespaceForThisTest; + +-use PhpSpec\ObjectBehavior; +- + class OrderSpec extends ObjectBehavior + { +- public function let(OrderFactory $factory, ShippingMethod $shippingMethod) ++ /** ++ * @var \SomeNamespaceForThisTest\Order ++ */ ++ private $order; ++ protected function setUp() + { +- $factory->createShippingMethodFor(Argument::any())->shouldBeCalled()->willReturn($shippingMethod); ++ /** @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject $factory */ ++ $factory = $this->createMock(OrderFactory::class); ++ ++ /** @var ShippingMethod|\PHPUnit\Framework\MockObject\MockObject $shippingMethod */ ++ $shippingMethod = $this->createMock(ShippingMethod::class); ++ ++ $factory->expects($this->once())->method('createShippingMethodFor')->willReturn($shippingMethod); + } + } ```
-### `VarToPublicPropertyRector` +### `MockVariableToPropertyFetchRector` -- class: `Rector\Php\Rector\Property\VarToPublicPropertyRector` - -Remove unused private method - -```diff - final class SomeController - { -- var $name = 'Tom'; -+ public $name = 'Tom'; - } -``` - -
- -### `WhileEachToForeachRector` - -- class: `Rector\Php\Rector\Each\WhileEachToForeachRector` - -each() function is deprecated, use foreach() instead. - -```diff --while (list($key, $callback) = each($callbacks)) { -+foreach ($callbacks as $key => $callback) { - // ... - } -``` - -```diff --while (list($key) = each($callbacks)) { -+foreach (array_keys($callbacks) as $key) { - // ... - } -``` - -
- -## PhpSpecToPHPUnit - -### `AddMockPropertiesRector` - -- class: `Rector\PhpSpecToPHPUnit\Rector\Class_\AddMockPropertiesRector` +- class: `Rector\PhpSpecToPHPUnit\Rector\ClassMethod\MockVariableToPropertyFetchRector` Migrate PhpSpec behavior to PHPUnit test @@ -4826,9 +4809,9 @@ Migrate PhpSpec behavior to PHPUnit test
-### `MockVariableToPropertyFetchRector` +### `PhpSpecClassToPHPUnitClassRector` -- class: `Rector\PhpSpecToPHPUnit\Rector\ClassMethod\MockVariableToPropertyFetchRector` +- class: `Rector\PhpSpecToPHPUnit\Rector\Class_\PhpSpecClassToPHPUnitClassRector` Migrate PhpSpec behavior to PHPUnit test @@ -4860,9 +4843,9 @@ Migrate PhpSpec behavior to PHPUnit test
-### `PhpSpecClassToPHPUnitClassRector` +### `PhpSpecMethodToPHPUnitMethodRector` -- class: `Rector\PhpSpecToPHPUnit\Rector\Class_\PhpSpecClassToPHPUnitClassRector` +- class: `Rector\PhpSpecToPHPUnit\Rector\ClassMethod\PhpSpecMethodToPHPUnitMethodRector` Migrate PhpSpec behavior to PHPUnit test @@ -4894,9 +4877,9 @@ Migrate PhpSpec behavior to PHPUnit test
-### `PhpSpecMethodToPHPUnitMethodRector` +### `PhpSpecMocksToPHPUnitMocksRector` -- class: `Rector\PhpSpecToPHPUnit\Rector\ClassMethod\PhpSpecMethodToPHPUnitMethodRector` +- class: `Rector\PhpSpecToPHPUnit\Rector\MethodCall\PhpSpecMocksToPHPUnitMocksRector` Migrate PhpSpec behavior to PHPUnit test @@ -4928,9 +4911,9 @@ Migrate PhpSpec behavior to PHPUnit test
-### `PhpSpecMocksToPHPUnitMocksRector` +### `PhpSpecPromisesToPHPUnitAssertRector` -- class: `Rector\PhpSpecToPHPUnit\Rector\MethodCall\PhpSpecMocksToPHPUnitMocksRector` +- class: `Rector\PhpSpecToPHPUnit\Rector\MethodCall\PhpSpecPromisesToPHPUnitAssertRector` Migrate PhpSpec behavior to PHPUnit test @@ -4962,233 +4945,457 @@ Migrate PhpSpec behavior to PHPUnit test
-### `PhpSpecPromisesToPHPUnitAssertRector` +### `RenameSpecFileToTestFileRector` -- class: `Rector\PhpSpecToPHPUnit\Rector\MethodCall\PhpSpecPromisesToPHPUnitAssertRector` +- class: `Rector\PhpSpecToPHPUnit\Rector\FileSystem\RenameSpecFileToTestFileRector` -Migrate PhpSpec behavior to PHPUnit test +Rename "*Spec.php" file to "*Test.php" file -```diff - namespace spec\SomeNamespaceForThisTest; +
--use PhpSpec\ObjectBehavior; +## Refactoring + +### `MoveAndRenameClassRector` + +- class: `Rector\Refactoring\Rector\FileSystem\MoveAndRenameClassRector` + +Move class to respect new location with respect to PSR-4 + follow up with class rename + +
+ +### `MoveAndRenameNamespaceRector` + +- class: `Rector\Refactoring\Rector\FileSystem\MoveAndRenameNamespaceRector` + +Move namespace to new location with respect to PSR-4 + follow up with files in the namespace move + +
+ +## RemovingStatic + +### `NewUniqueObjectToEntityFactoryRector` + +- class: `Rector\RemovingStatic\Rector\Class_\NewUniqueObjectToEntityFactoryRector` + +Convert new X to new factories + +```diff +-anotherClassFactory = $anotherClassFactory; ++ } ++ + public function run() + { +- return new AnotherClass; ++ return $this->anotherClassFactory->create(); + } + } + + class AnotherClass + { + public function someFun() + { + return StaticClass::staticMethod(); + } + } +``` + +
+ +### `PHPUnitStaticToKernelTestCaseGetRector` + +- class: `Rector\RemovingStatic\Rector\Class_\PHPUnitStaticToKernelTestCaseGetRector` + +Convert static calls in PHPUnit test cases, to get() from the container of KernelTestCase + +```yaml +services: + Rector\RemovingStatic\Rector\Class_\PHPUnitStaticToKernelTestCaseGetRector: + staticClassTypes: + - EntityFactory +``` + +↓ + +```diff +-entityFactory = self::$container->get(EntityFactory::class); ++ } + +-final class SomeTestCase extends TestCase +-{ + public function test() { -- $factory->createShippingMethodFor(Argument::any())->shouldBeCalled()->willReturn($shippingMethod); -+ /** @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject $factory */ -+ $factory = $this->createMock(OrderFactory::class); +- $product = EntityFactory::create('product'); ++ $product = $this->entityFactory->create('product'); + } + } +``` + +
+ +### `PassFactoryToUniqueObjectRector` + +- class: `Rector\RemovingStatic\Rector\Class_\PassFactoryToUniqueObjectRector` + +Convert new X/Static::call() to factories in entities, pass them via constructor to each other + +```yaml +services: + Rector\RemovingStatic\Rector\Class_\PassFactoryToUniqueObjectRector: + typesToServices: + - StaticClass +``` + +↓ + +```diff +-anotherClassFactory = $anotherClassFactory; ++ } + -+ /** @var ShippingMethod|\PHPUnit\Framework\MockObject\MockObject $shippingMethod */ -+ $shippingMethod = $this->createMock(ShippingMethod::class); + public function run() + { +- return new AnotherClass; ++ return $this->anotherClassFactory->create(); + } + } + + class AnotherClass + { ++ public function __construct(StaticClass $staticClass) ++ { ++ $this->staticClass = $staticClass; ++ } + -+ $factory->expects($this->once())->method('createShippingMethodFor')->willReturn($shippingMethod); + public function someFun() + { +- return StaticClass::staticMethod(); ++ return $this->staticClass->staticMethod(); ++ } ++} ++ ++final class AnotherClassFactory ++{ ++ /** ++ * @var StaticClass ++ */ ++ private $staticClass; ++ ++ public function __construct(StaticClass $staticClass) ++ { ++ $this->staticClass = $staticClass; ++ } ++ ++ public function create(): AnotherClass ++ { ++ return new AnotherClass($this->staticClass); } } ```
-### `RenameSpecFileToTestFileRector` +### `StaticTypeToSetterInjectionRector` -- class: `Rector\PhpSpecToPHPUnit\Rector\FileSystem\RenameSpecFileToTestFileRector` +- class: `Rector\RemovingStatic\Rector\Class_\StaticTypeToSetterInjectionRector` -Rename "*Spec.php" file to "*Test.php" file +Changes types to setter injection + +```yaml +services: + Rector\RemovingStatic\Rector\Class_\StaticTypeToSetterInjectionRector: + $staticTypes: + - SomeStaticClass +``` + +↓ + +```diff + someStaticClass = $someStaticClass; ++ } ++ + public function run() + { +- return SomeStaticClass::go(); ++ return $this->someStaticClass->go(); + } +-} ++} +``` + +
+ +## Renaming + +### `RenameAnnotationRector` + +- class: `Rector\Renaming\Rector\Annotation\RenameAnnotationRector` + +Turns defined annotations above properties and methods to their new values. + +```yaml +services: + Rector\Renaming\Rector\Annotation\RenameAnnotationRector: + $classToAnnotationMap: + PHPUnit\Framework\TestCase: + test: scenario +``` + +↓ + +```diff + class SomeTest extends PHPUnit\Framework\TestCase + { +- /** +- * @test ++ /** ++ * @scenario + */ + public function someMethod() + { + } + } +``` + +
+ +### `RenameClassConstantRector` + +- class: `Rector\Renaming\Rector\Constant\RenameClassConstantRector` + +Replaces defined class constants in their calls. + +```yaml +services: + Rector\Renaming\Rector\Constant\RenameClassConstantRector: + SomeClass: + OLD_CONSTANT: NEW_CONSTANT + OTHER_OLD_CONSTANT: 'DifferentClass::NEW_CONSTANT' +``` + +↓ + +```diff +-$value = SomeClass::OLD_CONSTANT; +-$value = SomeClass::OTHER_OLD_CONSTANT; ++$value = SomeClass::NEW_CONSTANT; ++$value = DifferentClass::NEW_CONSTANT; +``` + +
+ +### `RenameClassRector` + +- class: `Rector\Renaming\Rector\Class_\RenameClassRector` + +Replaces defined classes by new ones. + +```yaml +services: + Rector\Renaming\Rector\Class_\RenameClassRector: + $oldToNewClasses: + App\SomeOldClass: App\SomeNewClass +``` + +↓ + +```diff + namespace App; + +-use SomeOldClass; ++use SomeNewClass; + +-function someFunction(SomeOldClass $someOldClass): SomeOldClass ++function someFunction(SomeNewClass $someOldClass): SomeNewClass + { +- if ($someOldClass instanceof SomeOldClass) { +- return new SomeOldClass; ++ if ($someOldClass instanceof SomeNewClass) { ++ return new SomeNewClass; + } + } +``` + +
+ +### `RenameConstantRector` + +- class: `Rector\Renaming\Rector\ConstFetch\RenameConstantRector` + +Replace constant by new ones + +```diff + final class SomeClass + { + public function run() + { +- return MYSQL_ASSOC; ++ return MYSQLI_ASSOC; + } + } +``` + +
+ +### `RenameFunctionRector` + +- class: `Rector\Renaming\Rector\Function_\RenameFunctionRector` + +Turns defined function call new one. + +```yaml +services: + Rector\Renaming\Rector\Function_\RenameFunctionRector: + view: Laravel\Templating\render +``` + +↓ + +```diff +-view("...", []); ++Laravel\Templating\render("...", []); +```
-## RemovingStatic +### `RenameMethodCallRector` -### `NewUniqueObjectToEntityFactoryRector` +- class: `Rector\Renaming\Rector\MethodCall\RenameMethodCallRector` -- class: `Rector\RemovingStatic\Rector\Class_\NewUniqueObjectToEntityFactoryRector` +Turns method call names to new ones. -Convert new X to new factories +```yaml +services: + Rector\Renaming\Rector\MethodCall\RenameMethodCallRector: + SomeExampleClass: + oldMethod: newMethod +``` -```diff --anotherClassFactory = $anotherClassFactory; -+ } -+ - public function run() - { -- return new AnotherClass; -+ return $this->anotherClassFactory->create(); - } - } +↓ - class AnotherClass - { - public function someFun() - { - return StaticClass::staticMethod(); - } - } +```diff + $someObject = new SomeExampleClass; +-$someObject->oldMethod(); ++$someObject->newMethod(); ```
-### `PHPUnitStaticToKernelTestCaseGetRector` +### `RenameMethodRector` -- class: `Rector\RemovingStatic\Rector\Class_\PHPUnitStaticToKernelTestCaseGetRector` +- class: `Rector\Renaming\Rector\MethodCall\RenameMethodRector` -Convert static calls in PHPUnit test cases, to get() from the container of KernelTestCase +Turns method names to new ones. ```yaml services: - Rector\RemovingStatic\Rector\Class_\PHPUnitStaticToKernelTestCaseGetRector: - staticClassTypes: - - EntityFactory + Rector\Renaming\Rector\MethodCall\RenameMethodRector: + SomeExampleClass: + oldMethod: newMethod ``` ↓ ```diff --entityFactory = self::$container->get(EntityFactory::class); -+ } - --final class SomeTestCase extends TestCase --{ - public function test() - { -- $product = EntityFactory::create('product'); -+ $product = $this->entityFactory->create('product'); - } - } + $someObject = new SomeExampleClass; +-$someObject->oldMethod(); ++$someObject->newMethod(); ```
-### `PassFactoryToUniqueObjectRector` +### `RenameNamespaceRector` -- class: `Rector\RemovingStatic\Rector\Class_\PassFactoryToUniqueObjectRector` +- class: `Rector\Renaming\Rector\Namespace_\RenameNamespaceRector` -Convert new X/Static::call() to factories in entities, pass them via constructor to each other +Replaces old namespace by new one. ```yaml services: - Rector\RemovingStatic\Rector\Class_\PassFactoryToUniqueObjectRector: - typesToServices: - - StaticClass + Rector\Renaming\Rector\Namespace_\RenameNamespaceRector: + $oldToNewNamespaces: + SomeOldNamespace: SomeNewNamespace ``` ↓ ```diff --anotherClassFactory = $anotherClassFactory; -+ } -+ - public function run() - { -- return new AnotherClass; -+ return $this->anotherClassFactory->create(); - } - } - - class AnotherClass - { -+ public function __construct(StaticClass $staticClass) -+ { -+ $this->staticClass = $staticClass; -+ } -+ - public function someFun() - { -- return StaticClass::staticMethod(); -+ return $this->staticClass->staticMethod(); -+ } -+} -+ -+final class AnotherClassFactory -+{ -+ /** -+ * @var StaticClass -+ */ -+ private $staticClass; -+ -+ public function __construct(StaticClass $staticClass) -+ { -+ $this->staticClass = $staticClass; -+ } -+ -+ public function create(): AnotherClass -+ { -+ return new AnotherClass($this->staticClass); - } - } +-$someObject = new SomeOldNamespace\SomeClass; ++$someObject = new SomeNewNamespace\SomeClass; ```
-### `StaticTypeToSetterInjectionRector` +### `RenameStaticMethodRector` -- class: `Rector\RemovingStatic\Rector\Class_\StaticTypeToSetterInjectionRector` +- class: `Rector\Renaming\Rector\MethodCall\RenameStaticMethodRector` -Changes types to setter injection +Turns method names to new ones. ```yaml services: - Rector\RemovingStatic\Rector\Class_\StaticTypeToSetterInjectionRector: - $staticTypes: - - SomeStaticClass + Rector\Renaming\Rector\MethodCall\RenameStaticMethodRector: + SomeClass: + oldMethod: + - AnotherExampleClass + - newStaticMethod ``` ↓ ```diff - someStaticClass = $someStaticClass; -+ } -+ - public function run() - { -- return SomeStaticClass::go(); -+ return $this->someStaticClass->go(); - } --} -+} +```yaml +services: + Rector\Renaming\Rector\MethodCall\RenameStaticMethodRector: + $oldToNewMethodByClasses: + SomeClass: + oldMethod: newStaticMethod +``` + +↓ + +```diff +-SomeClass::oldStaticMethod(); ++SomeClass::newStaticMethod(); ```
@@ -5726,6 +5933,31 @@ Make event object a first argument of dispatch() method, event name as second
+### `MergeMethodAnnotationToRouteAnnotationRector` + +- class: `Rector\Symfony\Rector\ClassMethod\MergeMethodAnnotationToRouteAnnotationRector` + +Merge removed @Method annotation to @Route one + +```diff +-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; + use Symfony\Component\Routing\Annotation\Route; + + class DefaultController extends Controller + { + /** +- * @Route("/show/{id}") +- * @Method({"GET", "HEAD"}) ++ * @Route("/show/{id}", methods={"GET","HEAD"}) + */ + public function show($id) + { + } + } +``` + +
+ ### `OptionNameRector` - class: `Rector\Symfony\Rector\Form\OptionNameRector` @@ -6112,10 +6344,61 @@ Add known return type to functions { public function run($meetups) { -- return array_filter($meetups, function (Meetup $meetup) { -+ return array_filter($meetups, function (Meetup $meetup): bool { - return is_object($meetup); - }); +- return array_filter($meetups, function (Meetup $meetup) { ++ return array_filter($meetups, function (Meetup $meetup): bool { + return is_object($meetup); + }); + } + } +``` + +
+ +### `AddMethodCallBasedParamTypeRector` + +- class: `Rector\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedParamTypeRector` + +Change param type of passed getId() to UuidInterface type declaration + +```diff + class SomeClass + { +- public function getById($id) ++ public function getById(\Ramsey\Uuid\UuidInterface $id) + { + } + } + + class CallerClass + { + public function run() + { + $building = new Building(); + $someClass = new SomeClass(); + $someClass->getById($building->getId()); + } + } +``` + +
+ +### `CompleteVarDocTypePropertyRector` + +- class: `Rector\TypeDeclaration\Rector\Property\CompleteVarDocTypePropertyRector` + +Complete property `@var` annotations or correct the old ones + +```diff + final class SomeClass + { ++ /** ++ * @var EventDispatcher ++ */ + private $eventDispatcher; + + public function __construct(EventDispatcher $eventDispatcher) + { + $this->eventDispatcher = $eventDispatcher; } } ``` @@ -7143,21 +7426,7 @@ Replaces defined Pseudo_Namespaces by Namespace\Ones. ```yaml services: Rector\Rector\Namespace_\PseudoNamespaceToNamespaceRector: - - - Some_: { } -``` - -↓ - -```diff --$someService = new Some_Object; -+$someService = new Some\Object; -``` - -```yaml -services: - Rector\Rector\Namespace_\PseudoNamespaceToNamespaceRector: - - + $namespacePrefixesWithExcludedClasses: Some_: - Some_Class_To_Keep ``` @@ -7165,10 +7434,10 @@ services: ↓ ```diff --/** @var Some_Object $someService */ --$someService = new Some_Object; -+/** @var Some\Object $someService */ -+$someService = new Some\Object; +-/** @var Some_Chicken $someService */ +-$someService = new Some_Chicken; ++/** @var Some\Chicken $someService */ ++$someService = new Some\Chicken; $someClassToKeep = new Some_Class_To_Keep; ``` @@ -7212,63 +7481,6 @@ Remove specific traits from code
-### `RenameAnnotationRector` - -- class: `Rector\Renaming\Rector\Annotation\RenameAnnotationRector` - -Turns defined annotations above properties and methods to their new values. - -```yaml -services: - Rector\Renaming\Rector\Annotation\RenameAnnotationRector: - $classToAnnotationMap: - PHPUnit\Framework\TestCase: - test: scenario -``` - -↓ - -```diff - class SomeTest extends PHPUnit\Framework\TestCase - { -- /** -- * @test -+ /** -+ * @scenario - */ - public function someMethod() - { - } - } -``` - -
- -### `RenameClassConstantRector` - -- class: `Rector\Renaming\Rector\Constant\RenameClassConstantRector` - -Replaces defined class constants in their calls. - -```yaml -services: - Rector\Renaming\Rector\Constant\RenameClassConstantRector: - SomeClass: - OLD_CONSTANT: NEW_CONSTANT - OTHER_OLD_CONSTANT: 'DifferentClass::NEW_CONSTANT' -``` - -↓ - -```diff --$value = SomeClass::OLD_CONSTANT; --$value = SomeClass::OTHER_OLD_CONSTANT; -+$value = SomeClass::NEW_CONSTANT; -+$value = DifferentClass::NEW_CONSTANT; -``` - -
- ### `RenameClassConstantsUseToStringsRector` - class: `Rector\Rector\Constant\RenameClassConstantsUseToStringsRector` @@ -7292,129 +7504,6 @@ services:
-### `RenameClassRector` - -- class: `Rector\Renaming\Rector\Class_\RenameClassRector` - -Replaces defined classes by new ones. - -```yaml -services: - Rector\Renaming\Rector\Class_\RenameClassRector: - $oldToNewClasses: - App\SomeOldClass: App\SomeNewClass -``` - -↓ - -```diff - namespace App; - --use SomeOldClass; -+use SomeNewClass; - --function someFunction(SomeOldClass $someOldClass): SomeOldClass -+function someFunction(SomeNewClass $someOldClass): SomeNewClass - { -- if ($someOldClass instanceof SomeOldClass) { -- return new SomeOldClass; -+ if ($someOldClass instanceof SomeNewClass) { -+ return new SomeNewClass; - } - } -``` - -
- -### `RenameFunctionRector` - -- class: `Rector\Renaming\Rector\Function_\RenameFunctionRector` - -Turns defined function call new one. - -```yaml -services: - Rector\Renaming\Rector\Function_\RenameFunctionRector: - view: Laravel\Templating\render -``` - -↓ - -```diff --view("...", []); -+Laravel\Templating\render("...", []); -``` - -
- -### `RenameMethodCallRector` - -- class: `Rector\Renaming\Rector\MethodCall\RenameMethodCallRector` - -Turns method call names to new ones. - -```yaml -services: - Rector\Renaming\Rector\MethodCall\RenameMethodCallRector: - SomeExampleClass: - oldMethod: newMethod -``` - -↓ - -```diff - $someObject = new SomeExampleClass; --$someObject->oldMethod(); -+$someObject->newMethod(); -``` - -
- -### `RenameMethodRector` - -- class: `Rector\Renaming\Rector\MethodCall\RenameMethodRector` - -Turns method names to new ones. - -```yaml -services: - Rector\Renaming\Rector\MethodCall\RenameMethodRector: - SomeExampleClass: - oldMethod: newMethod -``` - -↓ - -```diff - $someObject = new SomeExampleClass; --$someObject->oldMethod(); -+$someObject->newMethod(); -``` - -
- -### `RenameNamespaceRector` - -- class: `Rector\Renaming\Rector\Namespace_\RenameNamespaceRector` - -Replaces old namespace by new one. - -```yaml -services: - Rector\Renaming\Rector\Namespace_\RenameNamespaceRector: - $oldToNewNamespaces: - SomeOldNamespace: SomeNewNamespace -``` - -↓ - -```diff --$someObject = new SomeOldNamespace\SomeClass; -+$someObject = new SomeNewNamespace\SomeClass; -``` - -
- ### `RenamePropertyRector` - class: `Rector\Rector\Property\RenamePropertyRector` @@ -7438,45 +7527,6 @@ services:
-### `RenameStaticMethodRector` - -- class: `Rector\Renaming\Rector\MethodCall\RenameStaticMethodRector` - -Turns method names to new ones. - -```yaml -services: - Rector\Renaming\Rector\MethodCall\RenameStaticMethodRector: - SomeClass: - oldMethod: - - AnotherExampleClass - - newStaticMethod -``` - -↓ - -```diff --SomeClass::oldStaticMethod(); -+AnotherExampleClass::newStaticMethod(); -``` - -```yaml -services: - Rector\Renaming\Rector\MethodCall\RenameStaticMethodRector: - $oldToNewMethodByClasses: - SomeClass: - oldMethod: newStaticMethod -``` - -↓ - -```diff --SomeClass::oldStaticMethod(); -+SomeClass::newStaticMethod(); -``` - -
- ### `ReplaceParentRepositoryCallsByRepositoryPropertyRector` - class: `Rector\Rector\Architecture\RepositoryAsService\ReplaceParentRepositoryCallsByRepositoryPropertyRector` @@ -7707,6 +7757,25 @@ services:
+### `SwapFuncCallArgumentsRector` + +- class: `Rector\Rector\Argument\SwapFuncCallArgumentsRector` + +Swap arguments in function calls + +```diff + final class SomeClass + { + public function run($one, $two) + { +- return some_function($one, $two); ++ return some_function($two, $one); + } + } +``` + +
+ ### `ToStringToMethodCallRector` - class: `Rector\Rector\MagicDisclosure\ToStringToMethodCallRector`