diff --git a/docs/AllRectorsOverview.md b/docs/AllRectorsOverview.md index 6aa52d59b60c..c8d818a27069 100644 --- a/docs/AllRectorsOverview.md +++ b/docs/AllRectorsOverview.md @@ -1,4 +1,4 @@ -# All 329 Rectors Overview +# All 333 Rectors Overview - [Projects](#projects) - [General](#general) @@ -934,11 +934,11 @@ Use ===/!== over ==/!=, it values have the same type ## CodingStyle -### `ArrayPropertyDefaultValueRector` +### `AddArrayDefaultToArrayPropertyRector` -- class: `Rector\CodingStyle\Rector\Property\ArrayPropertyDefaultValueRector` +- class: `Rector\CodingStyle\Rector\Class_\AddArrayDefaultToArrayPropertyRector` -Array property should have default value, to prevent undefined array issues +Adds array default value to property to prevent foreach over null error ```diff class SomeClass @@ -946,13 +946,13 @@ Array property should have default value, to prevent undefined array issues /** * @var int[] */ -- private $items; -+ private $items = []; +- private $values; ++ private $values = []; - public function run() + public function isEmpty() { - foreach ($items as $item) { - } +- return $this->values === null; ++ return $this->values === []; } } ``` @@ -1139,7 +1139,7 @@ Add extra space before new assign set + 'numberz' => ['id' => 10] + ]; + -+ $someJsonAsString = json_encode($data); ++ $someJsonAsString = Nette\Utils\Json::encode($data); } } ``` @@ -1724,6 +1724,35 @@ Remove unused parent call with no parent class
+### `RemoveSetterOnlyPropertyAndMethodCallRector` + +- class: `Rector\DeadCode\Rector\Class_\RemoveSetterOnlyPropertyAndMethodCallRector` + +Removes method that set values that are never used + +```diff + class SomeClass + { +- private $name; +- +- public function setName($name) +- { +- $this->name = $name; +- } + } + + class ActiveOnlySetter + { + public function run() + { + $someClass = new SomeClass(); +- $someClass->setName('Tom'); + } + } +``` + +
+ ### `RemoveUnusedDoctrineEntityMethodAndPropertyRector` - class: `Rector\DeadCode\Rector\Class_\RemoveUnusedDoctrineEntityMethodAndPropertyRector` @@ -2260,6 +2289,39 @@ Use Nette\Utils\Strings over bare string-functions
+### `JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector` + +- class: `Rector\Nette\Rector\FuncCall\JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector` + +Changes json_encode()/json_decode() to safer and more verbose Nette\Utils\Json::encode()/decode() calls + +```diff + class SomeClass + { + public function decodeJson(string $jsonString) + { +- $stdClass = json_decode($jsonString); ++ $stdClass = \Nette\Utils\Json::decode($jsonString); + +- $array = json_decode($jsonString, true); +- $array = json_decode($jsonString, false); ++ $array = \Nette\Utils\Json::decode($jsonString, \Nette\Utils\Json::FORCE_ARRAY); ++ $array = \Nette\Utils\Json::decode($jsonString); + } + + public function encodeJson(array $data) + { +- $jsonString = json_encode($data); ++ $jsonString = \Nette\Utils\Json::encode($data); + +- $prettyJsonString = json_encode($data, JSON_PRETTY_PRINT); ++ $prettyJsonString = \Nette\Utils\Json::encode($data, \Nette\Utils\Json::PRETTY); + } + } +``` + +
+ ### `PregFunctionToNetteUtilsStringsRector` - class: `Rector\Nette\Rector\FuncCall\PregFunctionToNetteUtilsStringsRector` @@ -5728,6 +5790,58 @@ Changes Twig_Function_Method to Twig_SimpleFunction calls in TwigExtension. ## TypeDeclaration +### `AddArrayParamDocTypeRector` + +- class: `Rector\TypeDeclaration\Rector\ClassMethod\AddArrayParamDocTypeRector` + +Adds @param annotation to array parameters inferred from the rest of the code + +```diff + class SomeClass + { + /** + * @var int[] + */ + private $values; + ++ /** ++ * @param int[] $values ++ */ + public function __construct(array $values) + { + $this->values = $values; + } + } +``` + +
+ +### `AddArrayReturnDocTypeRector` + +- class: `Rector\TypeDeclaration\Rector\ClassMethod\AddArrayReturnDocTypeRector` + +Adds @return annotation to array parameters inferred from the rest of the code + +```diff + class SomeClass + { + /** + * @var int[] + */ + private $values; + ++ /** ++ * @return int[] ++ */ + public function getValues(): array + { + return $this->values; + } + } +``` + +
+ ### `AddClosureReturnTypeRector` - class: `Rector\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector` @@ -6136,7 +6250,7 @@ Turns fluent interface calls to classic ones. ```yaml services: Rector\Rector\MethodBody\FluentReplaceRector: - - + $classesToDefluent: - SomeExampleClass ``` diff --git a/packages/CodingStyle/src/Rector/Property/ArrayPropertyDefaultValueRector.php b/packages/CodingStyle/src/Rector/Property/ArrayPropertyDefaultValueRector.php deleted file mode 100644 index 693950caf624..000000000000 --- a/packages/CodingStyle/src/Rector/Property/ArrayPropertyDefaultValueRector.php +++ /dev/null @@ -1,103 +0,0 @@ -docBlockManipulator = $docBlockManipulator; - } - - public function getDefinition(): RectorDefinition - { - return new RectorDefinition('Array property should have default value, to prevent undefined array issues', [ - new CodeSample( - <<<'CODE_SAMPLE' -class SomeClass -{ - /** - * @var int[] - */ - private $items; - - public function run() - { - foreach ($items as $item) { - } - } -} -CODE_SAMPLE - , - <<<'CODE_SAMPLE' -class SomeClass -{ - /** - * @var int[] - */ - private $items = []; - - public function run() - { - foreach ($items as $item) { - } - } -} -CODE_SAMPLE - ), - ]); - } - - /** - * @return string[] - */ - public function getNodeTypes(): array - { - return [PropertyProperty::class]; - } - - /** - * @param PropertyProperty $node - */ - public function refactor(Node $node): ?Node - { - if ($node->default) { - return null; - } - - /** @var Property $parentNode */ - $parentNode = $node->getAttribute(AttributeKey::PARENT_NODE); - - $varTypeInfo = $this->docBlockManipulator->getVarTypeInfo($parentNode); - if ($varTypeInfo === null) { - return null; - } - - if (! $varTypeInfo->isIterable()) { - return null; - } - - if ($varTypeInfo->isNullable()) { - return null; - } - - $node->default = new Array_(); - - return $node; - } -} diff --git a/packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/AddArrayDefaultToArrayPropertyRectorTest.php b/packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/AddArrayDefaultToArrayPropertyRectorTest.php index 06ff66533f55..d87ed3c9d1d3 100644 --- a/packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/AddArrayDefaultToArrayPropertyRectorTest.php +++ b/packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/AddArrayDefaultToArrayPropertyRectorTest.php @@ -11,8 +11,12 @@ public function test(): void { $this->doTestFiles([ __DIR__ . '/Fixture/fixture.php.inc', + __DIR__ . '/Fixture/fixture_2.php.inc', __DIR__ . '/Fixture/count_on_null.php.inc', + + // new __DIR__ . '/Fixture/skip_nullable_array.php.inc', + __DIR__ . '/Fixture/skip.php.inc', ]); } diff --git a/packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/Fixture/fixture.php.inc b/packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/Fixture/fixture_2.php.inc similarity index 100% rename from packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/Fixture/fixture.php.inc rename to packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/Fixture/fixture_2.php.inc diff --git a/packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/Fixture/skip.php.inc b/packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/Fixture/skip.php.inc similarity index 100% rename from packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/Fixture/skip.php.inc rename to packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/Fixture/skip.php.inc diff --git a/packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/Fixture/skip_nullable_array.php.inc b/packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/Fixture/skip_nullable_array.php.inc index 55e069383413..0e1777bd16b4 100644 --- a/packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/Fixture/skip_nullable_array.php.inc +++ b/packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/Fixture/skip_nullable_array.php.inc @@ -9,6 +9,9 @@ class SkipNullableArray */ private $values; + /** @var string[]|null */ + public $anArrayVariable; + public function isEmpty() { return $this->values === null; diff --git a/packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/Fixture/static_property.php.inc b/packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/Fixture/static_property.php.inc similarity index 100% rename from packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/Fixture/static_property.php.inc rename to packages/CodingStyle/tests/Rector/Class_/AddArrayDefaultToArrayPropertyRector/Fixture/static_property.php.inc diff --git a/packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/ArrayPropertyDefaultValueRectorTest.php b/packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/ArrayPropertyDefaultValueRectorTest.php deleted file mode 100644 index 5630104c0438..000000000000 --- a/packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/ArrayPropertyDefaultValueRectorTest.php +++ /dev/null @@ -1,24 +0,0 @@ -doTestFiles([ - __DIR__ . '/Fixture/fixture.php.inc', - __DIR__ . '/Fixture/skip.php.inc', - __DIR__ . '/Fixture/static_property.php.inc', - __DIR__ . '/Fixture/skip_nullable_array.php.inc', - ]); - } - - protected function getRectorClass(): string - { - return ArrayPropertyDefaultValueRector::class; - } -} diff --git a/packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/Fixture/skip_nullable_array.php.inc b/packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/Fixture/skip_nullable_array.php.inc deleted file mode 100644 index 7ed3b1bb73d7..000000000000 --- a/packages/CodingStyle/tests/Rector/Property/ArrayPropertyDefaultValueRector/Fixture/skip_nullable_array.php.inc +++ /dev/null @@ -1,9 +0,0 @@ -undefinedConstants = []; - $previousErrorHandler = set_error_handler(function ($severity, $message, $file, $line): void { - $match = Strings::match($message, '#Use of undefined constant (?\w+)#'); - if ($match) { - $this->undefinedConstants[] = $match['constant']; + $previousErrorHandler = set_error_handler( + function (int $severity, string $message, string $file, int $line): bool { + $match = Strings::match($message, '#Use of undefined constant (?\w+)#'); + if ($match) { + $this->undefinedConstants[] = $match['constant']; + } + + return true; } - }); + ); // this duplicates the way composer handles it // @see https://github.com/composer/composer/issues/6232 diff --git a/phpstan.neon b/phpstan.neon index 2ff7b3c1bc45..939a31ce3875 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -191,3 +191,5 @@ parameters: - '#Ternary operator condition is always true#' - '#Access to an undefined property PhpParser\\Node\\Expr\\Assign\|PhpParser\\Node\\Stmt\\ClassMethod\|PhpParser\\Node\\Stmt\\Property\:\:\$var#' - '#Parameter \#1 \$node of method Rector\\NodeTypeResolver\\NodeTypeResolver\:\:resolveSingleTypeToStrings\(\) expects PhpParser\\Node, PhpParser\\Node\\Expr\|null given#' + - '#Parameter \#1 \$error_handler of function set_error_handler expects \(callable\(int, string, string, int, array\)\: bool\)\|null, Closure\(int, string, int, array\)\: bool given#' + - '#Parameter \#1 \$name of class ReflectionFunction constructor expects Closure\|string, callable\(\)\: mixed given#'