mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-02 09:20:52 +00:00
Compare commits
223 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e1b3f1a772 | ||
|
c5d04be877 | ||
|
b5cb9152fe | ||
|
f010267a7c | ||
|
0aec9f98bf | ||
|
7498eeeea2 | ||
|
8384715773 | ||
|
2f4d37d623 | ||
|
59fdd48d61 | ||
|
42e9685318 | ||
|
600218d107 | ||
|
7470aa5cdd | ||
|
df92a40a00 | ||
|
ad8eee4201 | ||
|
c9f15d2f2a | ||
|
f07c3528a8 | ||
|
2065cb44be | ||
|
21e5977c28 | ||
|
cf6f6c099f | ||
|
2b945fac7b | ||
|
354aa8fd07 | ||
|
6fa5131124 | ||
|
8a83c1053a | ||
|
8be3783a6a | ||
|
b6e05a08f9 | ||
|
216442a257 | ||
|
6b071141dc | ||
|
b153174db5 | ||
|
74ec7b2331 | ||
|
5d71d0b09c | ||
|
81725974a0 | ||
|
43c823a1fe | ||
|
670c768551 | ||
|
cee60661e8 | ||
|
83b82dd7bb | ||
|
7a1293fda7 | ||
|
39908b6b4e | ||
|
fce5bf1293 | ||
|
9a455bf300 | ||
|
2210bace5e | ||
|
9f86c20c73 | ||
|
f7ce209bd1 | ||
|
4cadabfe9a | ||
|
3f56884569 | ||
|
22d3d1949d | ||
|
62a900a1c0 | ||
|
b98d0a8754 | ||
|
7ac6f7bf7e | ||
|
556509e2dc | ||
|
dfaafdbd3a | ||
|
dd1dd510f5 | ||
|
c6998bfca9 | ||
|
264e16fdae | ||
|
1931c635c0 | ||
|
df8a377557 | ||
|
6372b90b19 | ||
|
6cf705918e | ||
|
3c1e41f006 | ||
|
7d70c5853e | ||
|
049336a81a | ||
|
efe89cff77 | ||
|
89f91b63be | ||
|
5dfd1c664c | ||
|
4bcc8bbea0 | ||
|
faba2d1971 | ||
|
c74c9ca74f | ||
|
b5b172a4b9 | ||
|
49d837e2a6 | ||
|
af81b5db1b | ||
|
5ca50de6b7 | ||
|
efb3c476c7 | ||
|
73eb63e4f9 | ||
|
322f3ad55c | ||
|
fe891363d5 | ||
|
f7723ed647 | ||
|
ed1310b8dc | ||
|
9da012cd97 | ||
|
dcdff77130 | ||
|
582a864f33 | ||
|
2dc9d28496 | ||
|
5c55f54e78 | ||
|
87c26777cb | ||
|
19b93eeeab | ||
|
fb4bddec05 | ||
|
ee17c27a72 | ||
|
346b5723b4 | ||
|
029097acda | ||
|
12c115e6f6 | ||
|
b70df4cb6b | ||
|
78e3d54584 | ||
|
c747b603a3 | ||
|
aff937886f | ||
|
343a691722 | ||
|
e9ca0b2469 | ||
|
7141ae6e56 | ||
|
d5e203a6e9 | ||
|
a3b725126c | ||
|
09acbdda13 | ||
|
fdfd07f062 | ||
|
c041415e42 | ||
|
3e1d355024 | ||
|
6cbc8ec497 | ||
|
1c323223b2 | ||
|
655c2aa498 | ||
|
584e892a51 | ||
|
b9839a24cb | ||
|
1e8aeb3de9 | ||
|
8aefc5e967 | ||
|
6db496ec6b | ||
|
24418026e3 | ||
|
e01fd7276e | ||
|
61037dab6c | ||
|
f42da12667 | ||
|
83bfbc18b8 | ||
|
b7b08c4396 | ||
|
4f94d24171 | ||
|
59f76a0fe3 | ||
|
ea0464beb9 | ||
|
f3e4fee4bc | ||
|
284531ceed | ||
|
2b9acd03a1 | ||
|
885a3f6ed3 | ||
|
7d4734bb64 | ||
|
7f89a08ca2 | ||
|
51fa5a731d | ||
|
3a03381bf8 | ||
|
6059061e25 | ||
|
f2cac5e2a0 | ||
|
76a58d63f0 | ||
|
0c2b95ea62 | ||
|
f53efcffe8 | ||
|
67791a9582 | ||
|
9427cdb84c | ||
|
d495dc4fe7 | ||
|
e56fb5adb0 | ||
|
415f0bbf34 | ||
|
8fba5b95f7 | ||
|
53fb366ec6 | ||
|
6fb3352189 | ||
|
530c01c201 | ||
|
707e3d8942 | ||
|
b8bbd024cd | ||
|
6678ca05d4 | ||
|
6e04d0eb08 | ||
|
d59efe6a88 | ||
|
e004423e08 | ||
|
f81fa92915 | ||
|
d36c8ad1a5 | ||
|
b352c8473a | ||
|
6e65fef1e7 | ||
|
81fd362a59 | ||
|
a210882e56 | ||
|
77aab2e2a3 | ||
|
d4fd813b33 | ||
|
36ab30b476 | ||
|
3fdaba944f | ||
|
dc2feca4d5 | ||
|
717507e265 | ||
|
9f2e48fa07 | ||
|
bc02e10427 | ||
|
dc2205094c | ||
|
664f4e3a6b | ||
|
755e0f4a8c | ||
|
9369a862b6 | ||
|
9b731daab1 | ||
|
0a7d532276 | ||
|
f2feb272ed | ||
|
42078c4127 | ||
|
7af3ed15e0 | ||
|
30adaf3fc0 | ||
|
c23b2384d3 | ||
|
e538a96c9b | ||
|
045db2fd56 | ||
|
014254f0df | ||
|
4c2b400cdb | ||
|
cc37bbf217 | ||
|
be393d497b | ||
|
078e4b92d7 | ||
|
ca1cc37af8 | ||
|
5d8e196d67 | ||
|
52addb1dde | ||
|
e14c8a528b | ||
|
bb8b99d70c | ||
|
0e57251e46 | ||
|
e18e5ef364 | ||
|
74b8ed7cd4 | ||
|
e6bfc79aa2 | ||
|
024ebc62a1 | ||
|
e10d636f62 | ||
|
ce9cc3aafc | ||
|
dd51f7ceed | ||
|
11b9220a05 | ||
|
9811962c70 | ||
|
de2b2cf2b4 | ||
|
1a710b92cc | ||
|
c1338c4c07 | ||
|
50c2e61f1d | ||
|
7a69e542ca | ||
|
c950e4d97b | ||
|
00697fa4b6 | ||
|
817ab2f7cb | ||
|
b38b8f3e85 | ||
|
e94ff85194 | ||
|
5ac9de7a83 | ||
|
ceff1cad27 | ||
|
ac990f2560 | ||
|
dac0717196 | ||
|
d028a05e61 | ||
|
b1eb18f499 | ||
|
0268ca2b1c | ||
|
8d1aee03a3 | ||
|
51090bc214 | ||
|
b50605a40a | ||
|
2bf9bab235 | ||
|
29535d04eb | ||
|
dd371cdca2 | ||
|
d5d197b9bf | ||
|
9ab2b8bc07 | ||
|
ae50c0e5a3 | ||
|
d3357ab3eb | ||
|
c0820093ad | ||
|
edd8901ea0 | ||
|
d7faacd4a0 |
|
@ -101,6 +101,7 @@ Among there projects belong:
|
||||||
* [cakephp/upgrade](https://github.com/cakephp/upgrade)
|
* [cakephp/upgrade](https://github.com/cakephp/upgrade)
|
||||||
* [driftingly/rector-laravel](https://github.com/driftingly/rector-laravel)
|
* [driftingly/rector-laravel](https://github.com/driftingly/rector-laravel)
|
||||||
* [contao/contao-rector](https://github.com/contao/contao-rector)
|
* [contao/contao-rector](https://github.com/contao/contao-rector)
|
||||||
|
* [php-static-analysis/rector-rule](https://github.com/php-static-analysis/rector-rule)
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
// this is part of downgrade build
|
// this is part of downgrade build
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\FileSystem;
|
use RectorPrefix202406\Nette\Utils\FileSystem;
|
||||||
use RectorPrefix202403\Nette\Utils\Json;
|
use RectorPrefix202406\Nette\Utils\Json;
|
||||||
require __DIR__ . '/../vendor/autoload.php';
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
$composerJsonFileContents = FileSystem::read(__DIR__ . '/../composer.json');
|
$composerJsonFileContents = FileSystem::read(__DIR__ . '/../composer.json');
|
||||||
$composerJson = Json::decode($composerJsonFileContents, Json::FORCE_ARRAY);
|
$composerJson = Json::decode($composerJsonFileContents, \true);
|
||||||
$composerJson['replace']['phpstan/phpstan'] = $composerJson['require']['phpstan/phpstan'];
|
$composerJson['replace']['phpstan/phpstan'] = $composerJson['require']['phpstan/phpstan'];
|
||||||
$modifiedComposerJsonFileContents = Json::encode($composerJson, Json::PRETTY);
|
$modifiedComposerJsonFileContents = Json::encode($composerJson, \true);
|
||||||
FileSystem::write(__DIR__ . '/../composer.json', $modifiedComposerJsonFileContents, null);
|
FileSystem::write(__DIR__ . '/../composer.json', $modifiedComposerJsonFileContents, null);
|
||||||
echo 'Done!' . \PHP_EOL;
|
echo 'Done!' . \PHP_EOL;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env php
|
#!/usr/bin/env php
|
||||||
<?php
|
<?php
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
require_once __DIR__ . '/rector.php';
|
require_once __DIR__ . '/rector.php';
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Json;
|
use RectorPrefix202406\Nette\Utils\Json;
|
||||||
use Rector\Bootstrap\RectorConfigsResolver;
|
use Rector\Bootstrap\RectorConfigsResolver;
|
||||||
use Rector\ChangesReporting\Output\JsonOutputFormatter;
|
use Rector\ChangesReporting\Output\JsonOutputFormatter;
|
||||||
use Rector\Configuration\Option;
|
use Rector\Configuration\Option;
|
||||||
|
@ -11,9 +11,9 @@ use Rector\Console\Style\SymfonyStyleFactory;
|
||||||
use Rector\DependencyInjection\LazyContainerFactory;
|
use Rector\DependencyInjection\LazyContainerFactory;
|
||||||
use Rector\DependencyInjection\RectorContainerFactory;
|
use Rector\DependencyInjection\RectorContainerFactory;
|
||||||
use Rector\Util\Reflection\PrivatesAccessor;
|
use Rector\Util\Reflection\PrivatesAccessor;
|
||||||
use RectorPrefix202403\Symfony\Component\Console\Application;
|
use RectorPrefix202406\Symfony\Component\Console\Application;
|
||||||
use RectorPrefix202403\Symfony\Component\Console\Command\Command;
|
use RectorPrefix202406\Symfony\Component\Console\Command\Command;
|
||||||
use RectorPrefix202403\Symfony\Component\Console\Input\ArgvInput;
|
use RectorPrefix202406\Symfony\Component\Console\Input\ArgvInput;
|
||||||
// @ intentionally: continue anyway
|
// @ intentionally: continue anyway
|
||||||
@\ini_set('memory_limit', '-1');
|
@\ini_set('memory_limit', '-1');
|
||||||
// Performance boost
|
// Performance boost
|
||||||
|
@ -93,7 +93,7 @@ final class AutoloadIncluder
|
||||||
require_once $filePath;
|
require_once $filePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\class_alias('RectorPrefix202403\\AutoloadIncluder', 'AutoloadIncluder', \false);
|
\class_alias('RectorPrefix202406\\AutoloadIncluder', 'AutoloadIncluder', \false);
|
||||||
if (\file_exists(__DIR__ . '/../preload.php') && \is_dir(__DIR__ . '/../vendor')) {
|
if (\file_exists(__DIR__ . '/../preload.php') && \is_dir(__DIR__ . '/../vendor')) {
|
||||||
require_once __DIR__ . '/../preload.php';
|
require_once __DIR__ . '/../preload.php';
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2|^8.0",
|
"php": "^7.2|^8.0",
|
||||||
"phpstan/phpstan": "^1.10.57"
|
"phpstan/phpstan": "^1.11"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"files": [
|
"files": [
|
||||||
|
@ -22,5 +22,8 @@
|
||||||
"rector/rector-downgrade-php": "*"
|
"rector/rector-downgrade-php": "*"
|
||||||
},
|
},
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"prefer-stable": true
|
"prefer-stable": true,
|
||||||
|
"suggest": {
|
||||||
|
"ext-dom": "To manipulate phpunit.xml via the custom-rule command"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use RectorPrefix202403\OndraM\CiDetector\CiDetector;
|
use RectorPrefix202406\OndraM\CiDetector\CiDetector;
|
||||||
use Rector\Bootstrap\ExtensionConfigResolver;
|
use Rector\Bootstrap\ExtensionConfigResolver;
|
||||||
use Rector\Caching\ValueObject\Storage\MemoryCacheStorage;
|
use Rector\Caching\ValueObject\Storage\MemoryCacheStorage;
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
|
@ -31,4 +31,6 @@ return static function (RectorConfig $rectorConfig) : void {
|
||||||
foreach ($extensionConfigResolver->provide() as $extensionConfigFile) {
|
foreach ($extensionConfigResolver->provide() as $extensionConfigFile) {
|
||||||
$rectorConfig->import($extensionConfigFile);
|
$rectorConfig->import($extensionConfigFile);
|
||||||
}
|
}
|
||||||
|
// use original php-parser printer to avoid BC break on fluent call
|
||||||
|
$rectorConfig->newLineOnFluentCall(\false);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,115 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector;
|
use Rector\Config\Level\CodeQualityLevel;
|
||||||
use Rector\CodeQuality\Rector\Assign\CombinedAssignRector;
|
|
||||||
use Rector\CodeQuality\Rector\BooleanAnd\RemoveUselessIsObjectCheckRector;
|
|
||||||
use Rector\CodeQuality\Rector\BooleanAnd\SimplifyEmptyArrayCheckRector;
|
|
||||||
use Rector\CodeQuality\Rector\BooleanNot\ReplaceMultipleBooleanNotRector;
|
|
||||||
use Rector\CodeQuality\Rector\BooleanNot\SimplifyDeMorganBinaryRector;
|
|
||||||
use Rector\CodeQuality\Rector\Catch_\ThrowWithPreviousExceptionRector;
|
|
||||||
use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector;
|
|
||||||
use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
|
|
||||||
use Rector\CodeQuality\Rector\Class_\StaticToSelfStaticMethodCallOnFinalClassRector;
|
|
||||||
use Rector\CodeQuality\Rector\ClassConstFetch\ConvertStaticPrivateConstantToSelfRector;
|
|
||||||
use Rector\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector;
|
|
||||||
use Rector\CodeQuality\Rector\ClassMethod\LocallyCalledStaticMethodToNonStaticRector;
|
|
||||||
use Rector\CodeQuality\Rector\ClassMethod\OptionalParametersAfterRequiredRector;
|
|
||||||
use Rector\CodeQuality\Rector\Concat\JoinStringConcatRector;
|
|
||||||
use Rector\CodeQuality\Rector\Empty_\SimplifyEmptyCheckOnEmptyArrayRector;
|
|
||||||
use Rector\CodeQuality\Rector\Equal\UseIdenticalOverEqualWithSameTypeRector;
|
|
||||||
use Rector\CodeQuality\Rector\Expression\InlineIfToExplicitIfRector;
|
|
||||||
use Rector\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector;
|
|
||||||
use Rector\CodeQuality\Rector\For_\ForRepeatedCountToOwnVariableRector;
|
|
||||||
use Rector\CodeQuality\Rector\Foreach_\ForeachItemsAssignToEmptyArrayToAssignRector;
|
|
||||||
use Rector\CodeQuality\Rector\Foreach_\ForeachToInArrayRector;
|
|
||||||
use Rector\CodeQuality\Rector\Foreach_\SimplifyForeachToCoalescingRector;
|
|
||||||
use Rector\CodeQuality\Rector\Foreach_\UnusedForeachValueToArrayKeysRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\ArrayMergeOfNonArraysToSimpleArrayRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\BoolvalToTypeCastRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\CallUserFuncWithArrowFunctionToInlineRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\ChangeArrayPushToArrayAssignRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\CompactToVariablesRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\FloatvalToTypeCastRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\InlineIsAInstanceOfRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\IntvalToTypeCastRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\IsAWithStringWithThirdArgumentRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\RemoveSoleValueSprintfRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\SetTypeToCastRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\SimplifyFuncGetArgsCountRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\SimplifyInArrayValuesRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\SimplifyRegexPatternRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\SimplifyStrposLowerRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\SingleInArrayToCompareRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\StrvalToTypeCastRector;
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\UnwrapSprintfOneArgumentRector;
|
|
||||||
use Rector\CodeQuality\Rector\FunctionLike\SimplifyUselessVariableRector;
|
|
||||||
use Rector\CodeQuality\Rector\Identical\BooleanNotIdenticalToNotIdenticalRector;
|
|
||||||
use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector;
|
|
||||||
use Rector\CodeQuality\Rector\Identical\GetClassToInstanceOfRector;
|
|
||||||
use Rector\CodeQuality\Rector\Identical\SimplifyArraySearchRector;
|
|
||||||
use Rector\CodeQuality\Rector\Identical\SimplifyBoolIdenticalTrueRector;
|
|
||||||
use Rector\CodeQuality\Rector\Identical\SimplifyConditionsRector;
|
|
||||||
use Rector\CodeQuality\Rector\Identical\StrlenZeroToIdenticalEmptyStringRector;
|
|
||||||
use Rector\CodeQuality\Rector\If_\CombineIfRector;
|
|
||||||
use Rector\CodeQuality\Rector\If_\CompleteMissingIfElseBracketRector;
|
|
||||||
use Rector\CodeQuality\Rector\If_\ConsecutiveNullCompareReturnsToNullCoalesceQueueRector;
|
|
||||||
use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector;
|
|
||||||
use Rector\CodeQuality\Rector\If_\ShortenElseIfRector;
|
|
||||||
use Rector\CodeQuality\Rector\If_\SimplifyIfElseToTernaryRector;
|
|
||||||
use Rector\CodeQuality\Rector\If_\SimplifyIfNotNullReturnRector;
|
|
||||||
use Rector\CodeQuality\Rector\If_\SimplifyIfNullableReturnRector;
|
|
||||||
use Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector;
|
|
||||||
use Rector\CodeQuality\Rector\Include_\AbsolutizeRequireAndIncludePathRector;
|
|
||||||
use Rector\CodeQuality\Rector\Isset_\IssetOnPropertyObjectToPropertyExistsRector;
|
|
||||||
use Rector\CodeQuality\Rector\LogicalAnd\AndAssignsToSeparateLinesRector;
|
|
||||||
use Rector\CodeQuality\Rector\LogicalAnd\LogicalToBooleanRector;
|
|
||||||
use Rector\CodeQuality\Rector\New_\NewStaticToNewSelfRector;
|
|
||||||
use Rector\CodeQuality\Rector\NotEqual\CommonNotEqualRector;
|
|
||||||
use Rector\CodeQuality\Rector\NullsafeMethodCall\CleanupUnneededNullsafeOperatorRector;
|
|
||||||
use Rector\CodeQuality\Rector\Switch_\SingularSwitchToIfRector;
|
|
||||||
use Rector\CodeQuality\Rector\Switch_\SwitchTrueToIfRector;
|
|
||||||
use Rector\CodeQuality\Rector\Ternary\ArrayKeyExistsTernaryThenValueToCoalescingRector;
|
|
||||||
use Rector\CodeQuality\Rector\Ternary\NumberCompareToMaxFuncCallRector;
|
|
||||||
use Rector\CodeQuality\Rector\Ternary\SimplifyTautologyTernaryRector;
|
|
||||||
use Rector\CodeQuality\Rector\Ternary\SwitchNegatedTernaryRector;
|
|
||||||
use Rector\CodeQuality\Rector\Ternary\TernaryEmptyArrayArrayDimFetchToCoalesceRector;
|
|
||||||
use Rector\CodeQuality\Rector\Ternary\UnnecessaryTernaryExpressionRector;
|
|
||||||
use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector;
|
|
||||||
use Rector\CodingStyle\Rector\FuncCall\CallUserFuncToMethodCallRector;
|
|
||||||
use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector;
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php52\Rector\Property\VarToPublicPropertyRector;
|
|
||||||
use Rector\Php71\Rector\FuncCall\RemoveExtraParametersRector;
|
|
||||||
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;
|
|
||||||
use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector;
|
|
||||||
return static function (RectorConfig $rectorConfig) : void {
|
return static function (RectorConfig $rectorConfig) : void {
|
||||||
$rectorConfig->ruleWithConfiguration(RenameFunctionRector::class, [
|
foreach (CodeQualityLevel::RULES_WITH_CONFIGURATION as $rectorClass => $configuration) {
|
||||||
'split' => 'explode',
|
$rectorConfig->ruleWithConfiguration($rectorClass, $configuration);
|
||||||
'join' => 'implode',
|
}
|
||||||
'sizeof' => 'count',
|
// the rule order matters, as its used in withCodeQualityLevel() method
|
||||||
# https://www.php.net/manual/en/aliases.php
|
// place the safest rules first, follow by more complex ones
|
||||||
'chop' => 'rtrim',
|
$rectorConfig->rules(CodeQualityLevel::RULES);
|
||||||
'doubleval' => 'floatval',
|
|
||||||
'gzputs' => 'gzwrites',
|
|
||||||
'fputs' => 'fwrite',
|
|
||||||
'ini_alter' => 'ini_set',
|
|
||||||
'is_double' => 'is_float',
|
|
||||||
'is_integer' => 'is_int',
|
|
||||||
'is_long' => 'is_int',
|
|
||||||
'is_real' => 'is_float',
|
|
||||||
'is_writeable' => 'is_writable',
|
|
||||||
'key_exists' => 'array_key_exists',
|
|
||||||
'pos' => 'current',
|
|
||||||
'strchr' => 'strstr',
|
|
||||||
# mb
|
|
||||||
'mbstrcut' => 'mb_strcut',
|
|
||||||
'mbstrlen' => 'mb_strlen',
|
|
||||||
'mbstrpos' => 'mb_strpos',
|
|
||||||
'mbstrrpos' => 'mb_strrpos',
|
|
||||||
'mbsubstr' => 'mb_substr',
|
|
||||||
]);
|
|
||||||
$rectorConfig->rules([CombinedAssignRector::class, SimplifyEmptyArrayCheckRector::class, ReplaceMultipleBooleanNotRector::class, ForeachToInArrayRector::class, SimplifyForeachToCoalescingRector::class, SimplifyFuncGetArgsCountRector::class, SimplifyInArrayValuesRector::class, SimplifyStrposLowerRector::class, GetClassToInstanceOfRector::class, SimplifyArraySearchRector::class, SimplifyConditionsRector::class, SimplifyIfNotNullReturnRector::class, SimplifyIfReturnBoolRector::class, SimplifyUselessVariableRector::class, UnnecessaryTernaryExpressionRector::class, RemoveExtraParametersRector::class, SimplifyDeMorganBinaryRector::class, SimplifyTautologyTernaryRector::class, SingleInArrayToCompareRector::class, SimplifyIfElseToTernaryRector::class, JoinStringConcatRector::class, ConsecutiveNullCompareReturnsToNullCoalesceQueueRector::class, ExplicitBoolCompareRector::class, CombineIfRector::class, UseIdenticalOverEqualWithSameTypeRector::class, SimplifyBoolIdenticalTrueRector::class, SimplifyRegexPatternRector::class, BooleanNotIdenticalToNotIdenticalRector::class, StrvalToTypeCastRector::class, FloatvalToTypeCastRector::class, CallableThisArrayToAnonymousFunctionRector::class, AndAssignsToSeparateLinesRector::class, CompactToVariablesRector::class, CompleteDynamicPropertiesRector::class, IsAWithStringWithThirdArgumentRector::class, StrlenZeroToIdenticalEmptyStringRector::class, ThrowWithPreviousExceptionRector::class, RemoveSoleValueSprintfRector::class, ShortenElseIfRector::class, ArrayMergeOfNonArraysToSimpleArrayRector::class, IntvalToTypeCastRector::class, BoolvalToTypeCastRector::class, ArrayKeyExistsTernaryThenValueToCoalescingRector::class, AbsolutizeRequireAndIncludePathRector::class, ChangeArrayPushToArrayAssignRector::class, ForRepeatedCountToOwnVariableRector::class, ForeachItemsAssignToEmptyArrayToAssignRector::class, InlineIfToExplicitIfRector::class, UnusedForeachValueToArrayKeysRector::class, CommonNotEqualRector::class, SetTypeToCastRector::class, LogicalToBooleanRector::class, VarToPublicPropertyRector::class, IssetOnPropertyObjectToPropertyExistsRector::class, NewStaticToNewSelfRector::class, UnwrapSprintfOneArgumentRector::class, SwitchNegatedTernaryRector::class, SingularSwitchToIfRector::class, SimplifyIfNullableReturnRector::class, FuncGetArgsToVariadicParamRector::class, CallUserFuncToMethodCallRector::class, CallUserFuncWithArrowFunctionToInlineRector::class, CountArrayToEmptyArrayComparisonRector::class, FlipTypeControlToUseExclusiveTypeRector::class, InlineArrayReturnAssignRector::class, InlineIsAInstanceOfRector::class, TernaryFalseExpressionToIfRector::class, InlineConstructorDefaultToPropertyRector::class, TernaryEmptyArrayArrayDimFetchToCoalesceRector::class, OptionalParametersAfterRequiredRector::class, SimplifyEmptyCheckOnEmptyArrayRector::class, SwitchTrueToIfRector::class, CleanupUnneededNullsafeOperatorRector::class, DisallowedEmptyRuleFixerRector::class, ConvertStaticPrivateConstantToSelfRector::class, LocallyCalledStaticMethodToNonStaticRector::class, NumberCompareToMaxFuncCallRector::class, CompleteMissingIfElseBracketRector::class, RemoveUselessIsObjectCheckRector::class, StaticToSelfStaticMethodCallOnFinalClassRector::class]);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\CodingStyle\Rector\ArrowFunction\StaticArrowFunctionRector;
|
|
||||||
use Rector\CodingStyle\Rector\Assign\SplitDoubleAssignRector;
|
use Rector\CodingStyle\Rector\Assign\SplitDoubleAssignRector;
|
||||||
use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector;
|
use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector;
|
||||||
use Rector\CodingStyle\Rector\ClassConst\RemoveFinalFromConstRector;
|
use Rector\CodingStyle\Rector\ClassConst\RemoveFinalFromConstRector;
|
||||||
|
@ -11,7 +10,6 @@ use Rector\CodingStyle\Rector\ClassConst\SplitGroupedClassConstantsRector;
|
||||||
use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector;
|
use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector;
|
||||||
use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector;
|
use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector;
|
||||||
use Rector\CodingStyle\Rector\ClassMethod\NewlineBeforeNewAssignSetRector;
|
use Rector\CodingStyle\Rector\ClassMethod\NewlineBeforeNewAssignSetRector;
|
||||||
use Rector\CodingStyle\Rector\Closure\StaticClosureRector;
|
|
||||||
use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
|
use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
|
||||||
use Rector\CodingStyle\Rector\Encapsed\WrapEncapsedVariableInCurlyBracesRector;
|
use Rector\CodingStyle\Rector\Encapsed\WrapEncapsedVariableInCurlyBracesRector;
|
||||||
use Rector\CodingStyle\Rector\FuncCall\CallUserFuncArrayToVariadicRector;
|
use Rector\CodingStyle\Rector\FuncCall\CallUserFuncArrayToVariadicRector;
|
||||||
|
@ -21,8 +19,6 @@ use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector;
|
||||||
use Rector\CodingStyle\Rector\FuncCall\StrictArraySearchRector;
|
use Rector\CodingStyle\Rector\FuncCall\StrictArraySearchRector;
|
||||||
use Rector\CodingStyle\Rector\FuncCall\VersionCompareFuncCallToConstantRector;
|
use Rector\CodingStyle\Rector\FuncCall\VersionCompareFuncCallToConstantRector;
|
||||||
use Rector\CodingStyle\Rector\If_\NullableCompareToNullRector;
|
use Rector\CodingStyle\Rector\If_\NullableCompareToNullRector;
|
||||||
use Rector\CodingStyle\Rector\Plus\UseIncrementAssignRector;
|
|
||||||
use Rector\CodingStyle\Rector\PostInc\PostIncDecToPreIncDecRector;
|
|
||||||
use Rector\CodingStyle\Rector\Property\SplitGroupedPropertiesRector;
|
use Rector\CodingStyle\Rector\Property\SplitGroupedPropertiesRector;
|
||||||
use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
|
use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
|
||||||
use Rector\CodingStyle\Rector\Stmt\RemoveUselessAliasInUseStatementRector;
|
use Rector\CodingStyle\Rector\Stmt\RemoveUselessAliasInUseStatementRector;
|
||||||
|
@ -36,5 +32,5 @@ use Rector\Transform\Rector\FuncCall\FuncCallToConstFetchRector;
|
||||||
use Rector\Visibility\Rector\ClassMethod\ExplicitPublicClassMethodRector;
|
use Rector\Visibility\Rector\ClassMethod\ExplicitPublicClassMethodRector;
|
||||||
return static function (RectorConfig $rectorConfig) : void {
|
return static function (RectorConfig $rectorConfig) : void {
|
||||||
$rectorConfig->ruleWithConfiguration(FuncCallToConstFetchRector::class, ['php_sapi_name' => 'PHP_SAPI', 'pi' => 'M_PI']);
|
$rectorConfig->ruleWithConfiguration(FuncCallToConstFetchRector::class, ['php_sapi_name' => 'PHP_SAPI', 'pi' => 'M_PI']);
|
||||||
$rectorConfig->rules([SeparateMultiUseImportsRector::class, PostIncDecToPreIncDecRector::class, NewlineAfterStatementRector::class, RemoveFinalFromConstRector::class, NullableCompareToNullRector::class, ConsistentImplodeRector::class, TernaryConditionVariableAssignmentRector::class, SymplifyQuoteEscapeRector::class, StringClassNameToClassConstantRector::class, CatchExceptionNameMatchingTypeRector::class, UseIncrementAssignRector::class, SplitDoubleAssignRector::class, EncapsedStringsToSprintfRector::class, WrapEncapsedVariableInCurlyBracesRector::class, NewlineBeforeNewAssignSetRector::class, MakeInheritedMethodVisibilitySameAsParentRector::class, CallUserFuncArrayToVariadicRector::class, VersionCompareFuncCallToConstantRector::class, StaticArrowFunctionRector::class, StaticClosureRector::class, CountArrayToEmptyArrayComparisonRector::class, CallUserFuncToMethodCallRector::class, FuncGetArgsToVariadicParamRector::class, StrictArraySearchRector::class, UseClassKeywordForClassNameResolutionRector::class, SplitGroupedPropertiesRector::class, SplitGroupedClassConstantsRector::class, ExplicitPublicClassMethodRector::class, RemoveUselessAliasInUseStatementRector::class]);
|
$rectorConfig->rules([SeparateMultiUseImportsRector::class, NewlineAfterStatementRector::class, RemoveFinalFromConstRector::class, NullableCompareToNullRector::class, ConsistentImplodeRector::class, TernaryConditionVariableAssignmentRector::class, SymplifyQuoteEscapeRector::class, StringClassNameToClassConstantRector::class, CatchExceptionNameMatchingTypeRector::class, SplitDoubleAssignRector::class, EncapsedStringsToSprintfRector::class, WrapEncapsedVariableInCurlyBracesRector::class, NewlineBeforeNewAssignSetRector::class, MakeInheritedMethodVisibilitySameAsParentRector::class, CallUserFuncArrayToVariadicRector::class, VersionCompareFuncCallToConstantRector::class, CountArrayToEmptyArrayComparisonRector::class, CallUserFuncToMethodCallRector::class, FuncGetArgsToVariadicParamRector::class, StrictArraySearchRector::class, UseClassKeywordForClassNameResolutionRector::class, SplitGroupedPropertiesRector::class, SplitGroupedClassConstantsRector::class, ExplicitPublicClassMethodRector::class, RemoveUselessAliasInUseStatementRector::class]);
|
||||||
};
|
};
|
||||||
|
|
13
config/set/datetime-to-carbon.php
Normal file
13
config/set/datetime-to-carbon.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
|
use Rector\Carbon\Rector\FuncCall\DateFuncCallToCarbonRector;
|
||||||
|
use Rector\Carbon\Rector\FuncCall\TimeFuncCallToCarbonRector;
|
||||||
|
use Rector\Carbon\Rector\MethodCall\DateTimeMethodCallToCarbonRector;
|
||||||
|
use Rector\Carbon\Rector\New_\DateTimeInstanceToCarbonRector;
|
||||||
|
use Rector\Config\RectorConfig;
|
||||||
|
return static function (RectorConfig $rectorConfig) : void {
|
||||||
|
$rectorConfig->rules([DateFuncCallToCarbonRector::class, DateTimeInstanceToCarbonRector::class, DateTimeMethodCallToCarbonRector::class, TimeFuncCallToCarbonRector::class]);
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\Level\DeadCodeLevel;
|
use Rector\Config\Level\DeadCodeLevel;
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\EarlyReturn\Rector\Foreach_\ChangeNestedForeachIfsToEarlyContinueRector;
|
use Rector\EarlyReturn\Rector\Foreach_\ChangeNestedForeachIfsToEarlyContinueRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
|
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\CodeQuality\Rector\FuncCall\InlineIsAInstanceOfRector;
|
use Rector\CodeQuality\Rector\FuncCall\InlineIsAInstanceOfRector;
|
||||||
use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector;
|
use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\SetList;
|
use Rector\Set\ValueObject\SetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Set\ValueObject\LevelSetList;
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
|
11
config/set/level/up-to-php84.php
Normal file
11
config/set/level/up-to-php84.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
|
use Rector\Config\RectorConfig;
|
||||||
|
use Rector\Set\ValueObject\LevelSetList;
|
||||||
|
use Rector\Set\ValueObject\SetList;
|
||||||
|
return static function (RectorConfig $rectorConfig) : void {
|
||||||
|
$rectorConfig->sets([SetList::PHP_84, LevelSetList::UP_TO_PHP_83]);
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Naming\Rector\Assign\RenameVariableToMatchMethodCallReturnTypeRector;
|
use Rector\Naming\Rector\Assign\RenameVariableToMatchMethodCallReturnTypeRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php52\Rector\Property\VarToPublicPropertyRector;
|
use Rector\Php52\Rector\Property\VarToPublicPropertyRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php53\Rector\FuncCall\DirNameFileConstantToDirConstantRector;
|
use Rector\Php53\Rector\FuncCall\DirNameFileConstantToDirConstantRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php54\Rector\Array_\LongArrayToShortArrayRector;
|
use Rector\Php54\Rector\Array_\LongArrayToShortArrayRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php55\Rector\Class_\ClassConstantToSelfClassRector;
|
use Rector\Php55\Rector\Class_\ClassConstantToSelfClassRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php56\Rector\FuncCall\PowToExpRector;
|
use Rector\Php56\Rector\FuncCall\PowToExpRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php70\Rector\Assign\ListSplitStringRector;
|
use Rector\Php70\Rector\Assign\ListSplitStringRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php71\Rector\Assign\AssignArrayToStringRector;
|
use Rector\Php71\Rector\Assign\AssignArrayToStringRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php72\Rector\Assign\ListEachRector;
|
use Rector\Php72\Rector\Assign\ListEachRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php52\Rector\Switch_\ContinueToBreakInSwitchRector;
|
use Rector\Php52\Rector\Switch_\ContinueToBreakInSwitchRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector;
|
use Rector\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Arguments\Rector\ClassMethod\ArgumentAdderRector;
|
use Rector\Arguments\Rector\ClassMethod\ArgumentAdderRector;
|
||||||
use Rector\Arguments\Rector\FuncCall\FunctionArgumentDefaultValueReplacerRector;
|
use Rector\Arguments\Rector\FuncCall\FunctionArgumentDefaultValueReplacerRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php81\Rector\Array_\FirstClassCallableRector;
|
use Rector\Php81\Rector\Array_\FirstClassCallableRector;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php82\Rector\Class_\ReadOnlyClassRector;
|
use Rector\Php82\Rector\Class_\ReadOnlyClassRector;
|
||||||
|
use Rector\Php82\Rector\Encapsed\VariableInStringInterpolationFixerRector;
|
||||||
use Rector\Php82\Rector\FuncCall\Utf8DecodeEncodeToMbConvertEncodingRector;
|
use Rector\Php82\Rector\FuncCall\Utf8DecodeEncodeToMbConvertEncodingRector;
|
||||||
use Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector;
|
use Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector;
|
||||||
return static function (RectorConfig $rectorConfig) : void {
|
return static function (RectorConfig $rectorConfig) : void {
|
||||||
$rectorConfig->rules([ReadOnlyClassRector::class, Utf8DecodeEncodeToMbConvertEncodingRector::class, FilesystemIteratorSkipDotsRector::class]);
|
$rectorConfig->rules([ReadOnlyClassRector::class, Utf8DecodeEncodeToMbConvertEncodingRector::class, FilesystemIteratorSkipDotsRector::class, VariableInStringInterpolationFixerRector::class]);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Php83\Rector\ClassConst\AddTypeToConstRector;
|
use Rector\Php83\Rector\ClassConst\AddTypeToConstRector;
|
||||||
|
|
10
config/set/php84.php
Normal file
10
config/set/php84.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
|
use Rector\Config\RectorConfig;
|
||||||
|
use Rector\Php84\Rector\Param\ExplicitNullableParamTypeRector;
|
||||||
|
return static function (RectorConfig $rectorConfig) : void {
|
||||||
|
$rectorConfig->rules([ExplicitNullableParamTypeRector::class]);
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector;
|
use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector;
|
||||||
|
|
19
config/set/rector-preset.php
Normal file
19
config/set/rector-preset.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
|
use Rector\CodeQuality\Rector\FuncCall\BoolvalToTypeCastRector;
|
||||||
|
use Rector\CodeQuality\Rector\FuncCall\FloatvalToTypeCastRector;
|
||||||
|
use Rector\CodeQuality\Rector\FuncCall\IntvalToTypeCastRector;
|
||||||
|
use Rector\CodeQuality\Rector\FuncCall\StrvalToTypeCastRector;
|
||||||
|
use Rector\CodingStyle\Rector\Plus\UseIncrementAssignRector;
|
||||||
|
use Rector\CodingStyle\Rector\PostInc\PostIncDecToPreIncDecRector;
|
||||||
|
use Rector\Config\RectorConfig;
|
||||||
|
use Rector\Privatization\Rector\Class_\FinalizeTestCaseClassRector;
|
||||||
|
use Rector\TypeDeclaration\Rector\BooleanAnd\BinaryOpNullableToInstanceofRector;
|
||||||
|
use Rector\TypeDeclaration\Rector\StmtsAwareInterface\DeclareStrictTypesRector;
|
||||||
|
use Rector\TypeDeclaration\Rector\While_\WhileNullableToInstanceofRector;
|
||||||
|
return static function (RectorConfig $rectorConfig) : void {
|
||||||
|
$rectorConfig->rules([DeclareStrictTypesRector::class, BinaryOpNullableToInstanceofRector::class, WhileNullableToInstanceofRector::class, IntvalToTypeCastRector::class, StrvalToTypeCastRector::class, BoolvalToTypeCastRector::class, FloatvalToTypeCastRector::class, PostIncDecToPreIncDecRector::class, UseIncrementAssignRector::class, FinalizeTestCaseClassRector::class]);
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
use Rector\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector;
|
use Rector\Strict\Rector\BooleanNot\BooleanInBooleanNotRuleFixerRector;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace RectorPrefix202403;
|
namespace RectorPrefix202406;
|
||||||
|
|
||||||
use Rector\Config\Level\TypeDeclarationLevel;
|
use Rector\Config\Level\TypeDeclarationLevel;
|
||||||
use Rector\Config\RectorConfig;
|
use Rector\Config\RectorConfig;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# 364 Rules Overview
|
# 380 Rules Overview
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -6,11 +6,13 @@
|
||||||
|
|
||||||
- [Arguments](#arguments) (4)
|
- [Arguments](#arguments) (4)
|
||||||
|
|
||||||
- [CodeQuality](#codequality) (74)
|
- [Carbon](#carbon) (4)
|
||||||
|
|
||||||
|
- [CodeQuality](#codequality) (75)
|
||||||
|
|
||||||
- [CodingStyle](#codingstyle) (28)
|
- [CodingStyle](#codingstyle) (28)
|
||||||
|
|
||||||
- [DeadCode](#deadcode) (42)
|
- [DeadCode](#deadcode) (45)
|
||||||
|
|
||||||
- [EarlyReturn](#earlyreturn) (9)
|
- [EarlyReturn](#earlyreturn) (9)
|
||||||
|
|
||||||
|
@ -42,10 +44,12 @@
|
||||||
|
|
||||||
- [Php81](#php81) (9)
|
- [Php81](#php81) (9)
|
||||||
|
|
||||||
- [Php82](#php82) (4)
|
- [Php82](#php82) (5)
|
||||||
|
|
||||||
- [Php83](#php83) (3)
|
- [Php83](#php83) (3)
|
||||||
|
|
||||||
|
- [Php84](#php84) (1)
|
||||||
|
|
||||||
- [Privatization](#privatization) (5)
|
- [Privatization](#privatization) (5)
|
||||||
|
|
||||||
- [Removing](#removing) (5)
|
- [Removing](#removing) (5)
|
||||||
|
@ -54,9 +58,9 @@
|
||||||
|
|
||||||
- [Strict](#strict) (5)
|
- [Strict](#strict) (5)
|
||||||
|
|
||||||
- [Transform](#transform) (24)
|
- [Transform](#transform) (25)
|
||||||
|
|
||||||
- [TypeDeclaration](#typedeclaration) (45)
|
- [TypeDeclaration](#typedeclaration) (50)
|
||||||
|
|
||||||
- [Visibility](#visibility) (3)
|
- [Visibility](#visibility) (3)
|
||||||
|
|
||||||
|
@ -140,6 +144,78 @@ Replaces defined map of arguments in defined methods and their calls.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
## Carbon
|
||||||
|
|
||||||
|
### DateFuncCallToCarbonRector
|
||||||
|
|
||||||
|
Convert `date()` function call to `Carbon::now()->format(*)`
|
||||||
|
|
||||||
|
- class: [`Rector\Carbon\Rector\FuncCall\DateFuncCallToCarbonRector`](../rules/Carbon/Rector/FuncCall/DateFuncCallToCarbonRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
- $date = date('Y-m-d');
|
||||||
|
+ $date = \Carbon\Carbon::now()->format('Y-m-d');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### DateTimeInstanceToCarbonRector
|
||||||
|
|
||||||
|
Convert new `DateTime()` to Carbon::*()
|
||||||
|
|
||||||
|
- class: [`Rector\Carbon\Rector\New_\DateTimeInstanceToCarbonRector`](../rules/Carbon/Rector/New_/DateTimeInstanceToCarbonRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
-$date = new \DateTime('today');
|
||||||
|
+$date = \Carbon\Carbon::today();
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### DateTimeMethodCallToCarbonRector
|
||||||
|
|
||||||
|
Convert new `DateTime()` with a method call to Carbon::*()
|
||||||
|
|
||||||
|
- class: [`Rector\Carbon\Rector\MethodCall\DateTimeMethodCallToCarbonRector`](../rules/Carbon/Rector/MethodCall/DateTimeMethodCallToCarbonRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
- $date = (new \DateTime('today +20 day'))->format('Y-m-d');
|
||||||
|
+ $date = \Carbon\Carbon::today()->addDays(20)->format('Y-m-d')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### TimeFuncCallToCarbonRector
|
||||||
|
|
||||||
|
Convert `time()` function call to `Carbon::now()->timestamp`
|
||||||
|
|
||||||
|
- class: [`Rector\Carbon\Rector\FuncCall\TimeFuncCallToCarbonRector`](../rules/Carbon/Rector/FuncCall/TimeFuncCallToCarbonRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
- $time = time();
|
||||||
|
+ $time = \Carbon\Carbon::now()->timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## CodeQuality
|
## CodeQuality
|
||||||
|
|
||||||
### AbsolutizeRequireAndIncludePathRector
|
### AbsolutizeRequireAndIncludePathRector
|
||||||
|
@ -547,6 +623,32 @@ Make if conditions more explicit
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### ExplicitReturnNullRector
|
||||||
|
|
||||||
|
Add explicit return null to method/function that returns a value, but missed main return
|
||||||
|
|
||||||
|
- class: [`Rector\CodeQuality\Rector\ClassMethod\ExplicitReturnNullRector`](../rules/CodeQuality/Rector/ClassMethod/ExplicitReturnNullRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
- * @return string|void
|
||||||
|
+ * @return string|null
|
||||||
|
*/
|
||||||
|
public function run(int $number)
|
||||||
|
{
|
||||||
|
if ($number > 50) {
|
||||||
|
return 'yes';
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
### FlipTypeControlToUseExclusiveTypeRector
|
### FlipTypeControlToUseExclusiveTypeRector
|
||||||
|
|
||||||
Flip type control from null compare to use exclusive instanceof object
|
Flip type control from null compare to use exclusive instanceof object
|
||||||
|
@ -2155,6 +2257,29 @@ Removes recasting of the same type
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### ReduceAlwaysFalseIfOrRector
|
||||||
|
|
||||||
|
Reduce always false in a if ( || ) condition
|
||||||
|
|
||||||
|
- class: [`Rector\DeadCode\Rector\If_\ReduceAlwaysFalseIfOrRector`](../rules/DeadCode/Rector/If_/ReduceAlwaysFalseIfOrRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run(int $number)
|
||||||
|
{
|
||||||
|
- if (! is_int($number) || $number > 50) {
|
||||||
|
+ if ($number > 50) {
|
||||||
|
return 'yes';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'no';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
### RemoveAlwaysTrueIfConditionRector
|
### RemoveAlwaysTrueIfConditionRector
|
||||||
|
|
||||||
Remove if condition that is always true
|
Remove if condition that is always true
|
||||||
|
@ -2796,6 +2921,25 @@ Remove unused promoted property
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### RemoveUnusedPublicMethodParameterRector
|
||||||
|
|
||||||
|
Remove unused parameter in public method on final class without extends and interface
|
||||||
|
|
||||||
|
- class: [`Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPublicMethodParameterRector`](../rules/DeadCode/Rector/ClassMethod/RemoveUnusedPublicMethodParameterRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
final class SomeClass
|
||||||
|
{
|
||||||
|
- public function run($a, $b)
|
||||||
|
+ public function run($a)
|
||||||
|
{
|
||||||
|
echo $a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
### RemoveUnusedVariableAssignRector
|
### RemoveUnusedVariableAssignRector
|
||||||
|
|
||||||
Remove unused assigns to variables
|
Remove unused assigns to variables
|
||||||
|
@ -2835,6 +2979,29 @@ Remove `@param` docblock with same type as parameter type
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### RemoveUselessReadOnlyTagRector
|
||||||
|
|
||||||
|
Remove useless `@readonly` annotation on native readonly type
|
||||||
|
|
||||||
|
- class: [`Rector\DeadCode\Rector\Property\RemoveUselessReadOnlyTagRector`](../rules/DeadCode/Rector/Property/RemoveUselessReadOnlyTagRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
final class SomeClass
|
||||||
|
{
|
||||||
|
- /**
|
||||||
|
- * @readonly
|
||||||
|
- */
|
||||||
|
private readonly string $name;
|
||||||
|
|
||||||
|
public function __construct(string $name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
### RemoveUselessReturnExprInConstructRector
|
### RemoveUselessReturnExprInConstructRector
|
||||||
|
|
||||||
Remove useless return Expr in `__construct()`
|
Remove useless return Expr in `__construct()`
|
||||||
|
@ -5272,6 +5439,20 @@ Change deprecated utf8_decode and utf8_encode to mb_convert_encoding
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### VariableInStringInterpolationFixerRector
|
||||||
|
|
||||||
|
Replace deprecated "${var}" to "{$var}"
|
||||||
|
|
||||||
|
- class: [`Rector\Php82\Rector\Encapsed\VariableInStringInterpolationFixerRector`](../rules/Php82/Rector/Encapsed/VariableInStringInterpolationFixerRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
$c = "football";
|
||||||
|
-echo "I like playing ${c}";
|
||||||
|
+echo "I like playing {$c}";
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## Php83
|
## Php83
|
||||||
|
|
||||||
### AddOverrideAttributeToOverriddenMethodsRector
|
### AddOverrideAttributeToOverriddenMethodsRector
|
||||||
|
@ -5301,7 +5482,7 @@ Add override attribute to overridden methods
|
||||||
|
|
||||||
### AddTypeToConstRector
|
### AddTypeToConstRector
|
||||||
|
|
||||||
Add const to type
|
Add type to constants
|
||||||
|
|
||||||
- class: [`Rector\Php83\Rector\ClassConst\AddTypeToConstRector`](../rules/Php83/Rector/ClassConst/AddTypeToConstRector.php)
|
- class: [`Rector\Php83\Rector\ClassConst\AddTypeToConstRector`](../rules/Php83/Rector/ClassConst/AddTypeToConstRector.php)
|
||||||
|
|
||||||
|
@ -5328,6 +5509,21 @@ Combine separated host and port on `ldap_connect()` args
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
## Php84
|
||||||
|
|
||||||
|
### ExplicitNullableParamTypeRector
|
||||||
|
|
||||||
|
Make implicit nullable param to explicit
|
||||||
|
|
||||||
|
- class: [`Rector\Php84\Rector\Param\ExplicitNullableParamTypeRector`](../rules/Php84/Rector/Param/ExplicitNullableParamTypeRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
-function foo(string $param = null) {}
|
||||||
|
+function foo(?string $param = null) {}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
## Privatization
|
## Privatization
|
||||||
|
|
||||||
### FinalizeClassesWithoutChildrenRector
|
### FinalizeClassesWithoutChildrenRector
|
||||||
|
@ -5356,10 +5552,10 @@ PHPUnit test case will be finalized
|
||||||
- class: [`Rector\Privatization\Rector\Class_\FinalizeTestCaseClassRector`](../rules/Privatization/Rector/Class_/FinalizeTestCaseClassRector.php)
|
- class: [`Rector\Privatization\Rector\Class_\FinalizeTestCaseClassRector`](../rules/Privatization/Rector/Class_/FinalizeTestCaseClassRector.php)
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
-use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
+final use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
class SomeClass extends TestCase
|
-class SomeClass extends TestCase
|
||||||
|
+final class SomeClass extends TestCase
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -5852,6 +6048,21 @@ Add interface by used trait
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### ArrayDimFetchToMethodCallRector
|
||||||
|
|
||||||
|
Change array dim fetch to method call
|
||||||
|
|
||||||
|
:wrench: **configure it!**
|
||||||
|
|
||||||
|
- class: [`Rector\Transform\Rector\ArrayDimFetch\ArrayDimFetchToMethodCallRector`](../rules/Transform/Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
-$app['someService'];
|
||||||
|
+$app->make('someService');
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
### AttributeKeyToClassConstFetchRector
|
### AttributeKeyToClassConstFetchRector
|
||||||
|
|
||||||
Replace key value on specific attribute to class constant
|
Replace key value on specific attribute to class constant
|
||||||
|
@ -6584,6 +6795,37 @@ Add void to PHPUnit test methods
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### AddTypeFromResourceDocblockRector
|
||||||
|
|
||||||
|
Add param and return types on resource docblock
|
||||||
|
|
||||||
|
:wrench: **configure it!**
|
||||||
|
|
||||||
|
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\AddTypeFromResourceDocblockRector`](../rules/TypeDeclaration/Rector/ClassMethod/AddTypeFromResourceDocblockRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
- /**
|
||||||
|
- * @param resource|null $resource
|
||||||
|
- */
|
||||||
|
- public function setResource($resource)
|
||||||
|
+ public function setResource(?App\ValueObject\Resource $resource)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- /**
|
||||||
|
- * @return resource|null
|
||||||
|
- */
|
||||||
|
- public function getResource()
|
||||||
|
+ public function getResource(): ?App\ValueObject\Resource
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
### AddVoidReturnTypeWhereNoReturnRector
|
### AddVoidReturnTypeWhereNoReturnRector
|
||||||
|
|
||||||
Add return type void to function like without any return
|
Add return type void to function like without any return
|
||||||
|
@ -6649,7 +6891,7 @@ Change return type based on strict returns type operations
|
||||||
|
|
||||||
### ChildDoctrineRepositoryClassTypeRector
|
### ChildDoctrineRepositoryClassTypeRector
|
||||||
|
|
||||||
Add return type to classes that extend `Doctrine\ORM\EntityRepository`
|
Add return type to classes that extend `Doctrine\ORM\EntityRepository` based on return Doctrine method names
|
||||||
|
|
||||||
- class: [`Rector\TypeDeclaration\Rector\Class_\ChildDoctrineRepositoryClassTypeRector`](../rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php)
|
- class: [`Rector\TypeDeclaration\Rector\Class_\ChildDoctrineRepositoryClassTypeRector`](../rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php)
|
||||||
|
|
||||||
|
@ -6712,6 +6954,24 @@ Change `empty()` on nullable object to instanceof check
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### IncreaseDeclareStrictTypesRector
|
||||||
|
|
||||||
|
Add declare strict types to a limited amount of classes at a time, to try out in the wild and increase level gradually
|
||||||
|
|
||||||
|
:wrench: **configure it!**
|
||||||
|
|
||||||
|
- class: [`Rector\TypeDeclaration\Rector\StmtsAwareInterface\IncreaseDeclareStrictTypesRector`](../rules/TypeDeclaration/Rector/StmtsAwareInterface/IncreaseDeclareStrictTypesRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
+declare(strict_types=1);
|
||||||
|
+
|
||||||
|
function someFunction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
### MergeDateTimePropertyTypeDeclarationRector
|
### MergeDateTimePropertyTypeDeclarationRector
|
||||||
|
|
||||||
Set DateTime to DateTimeInterface for DateTime property with DateTimeInterface docblock
|
Set DateTime to DateTimeInterface for DateTime property with DateTimeInterface docblock
|
||||||
|
@ -6852,6 +7112,30 @@ Add "never" return-type for methods that never return anything
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### ReturnTypeFromReturnCastRector
|
||||||
|
|
||||||
|
Add return type to function like with return cast
|
||||||
|
|
||||||
|
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnCastRector`](../rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnCastRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
final class SomeClass
|
||||||
|
{
|
||||||
|
- public function action($param)
|
||||||
|
+ public function action($param): array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return (array) $param;
|
||||||
|
} catch (Exception $exception) {
|
||||||
|
// some logging
|
||||||
|
throw $exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
### ReturnTypeFromReturnDirectArrayRector
|
### ReturnTypeFromReturnDirectArrayRector
|
||||||
|
|
||||||
Add return type from return direct array
|
Add return type from return direct array
|
||||||
|
@ -7103,6 +7387,27 @@ Add return method return type based on strict typed property
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### ReturnTypeFromSymfonySerializerRector
|
||||||
|
|
||||||
|
Add return type from symfony serializer
|
||||||
|
|
||||||
|
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromSymfonySerializerRector`](../rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromSymfonySerializerRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
final class SomeClass
|
||||||
|
{
|
||||||
|
private \Symfony\Component\Serializer\Serializer $serializer;
|
||||||
|
|
||||||
|
- public function resolveEntity($data)
|
||||||
|
+ public function resolveEntity($data): SomeType
|
||||||
|
{
|
||||||
|
return $this->serializer->deserialize($data, SomeType::class, 'json');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
### ReturnUnionTypeRector
|
### ReturnUnionTypeRector
|
||||||
|
|
||||||
Add union return type
|
Add union return type
|
||||||
|
@ -7191,6 +7496,23 @@ Add typed property from assigned types
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
### TypedPropertyFromJMSSerializerAttributeTypeRector
|
||||||
|
|
||||||
|
Add typed property from JMS Serializer Type attribute
|
||||||
|
|
||||||
|
- class: [`Rector\TypeDeclaration\Rector\Class_\TypedPropertyFromJMSSerializerAttributeTypeRector`](../rules/TypeDeclaration/Rector/Class_/TypedPropertyFromJMSSerializerAttributeTypeRector.php)
|
||||||
|
|
||||||
|
```diff
|
||||||
|
final class SomeClass
|
||||||
|
{
|
||||||
|
#[\JMS\Serializer\Annotation\Type('string')]
|
||||||
|
- private $name;
|
||||||
|
+ private ?string $name = null;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
### TypedPropertyFromStrictConstructorRector
|
### TypedPropertyFromStrictConstructorRector
|
||||||
|
|
||||||
Add typed properties based only on strict constructor types
|
Add typed properties based only on strict constructor types
|
||||||
|
|
|
@ -291,6 +291,9 @@ require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/InvalidTagV
|
||||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueNode.php';
|
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueNode.php';
|
||||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueParameterNode.php';
|
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueParameterNode.php';
|
||||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MixinTagValueNode.php';
|
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MixinTagValueNode.php';
|
||||||
|
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamClosureThisTagValueNode.php';
|
||||||
|
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamImmediatelyInvokedCallableTagValueNode.php';
|
||||||
|
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamLaterInvokedCallableTagValueNode.php';
|
||||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamOutTagValueNode.php';
|
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamOutTagValueNode.php';
|
||||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamTagValueNode.php';
|
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamTagValueNode.php';
|
||||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocChildNode.php';
|
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocChildNode.php';
|
||||||
|
|
|
@ -4,7 +4,6 @@ declare (strict_types=1);
|
||||||
namespace Rector\Arguments;
|
namespace Rector\Arguments;
|
||||||
|
|
||||||
use PhpParser\BuilderHelpers;
|
use PhpParser\BuilderHelpers;
|
||||||
use PhpParser\Node;
|
|
||||||
use PhpParser\Node\Arg;
|
use PhpParser\Node\Arg;
|
||||||
use PhpParser\Node\Expr;
|
use PhpParser\Node\Expr;
|
||||||
use PhpParser\Node\Expr\ClassConstFetch;
|
use PhpParser\Node\Expr\ClassConstFetch;
|
||||||
|
@ -35,9 +34,12 @@ final class ArgumentDefaultValueReplacer
|
||||||
$this->valueResolver = $valueResolver;
|
$this->valueResolver = $valueResolver;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
* @template TCall as (MethodCall|StaticCall|ClassMethod|FuncCall|New_)
|
||||||
|
*
|
||||||
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\New_ $node
|
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\New_ $node
|
||||||
|
* @return TCall|null
|
||||||
*/
|
*/
|
||||||
public function processReplaces($node, ReplaceArgumentDefaultValueInterface $replaceArgumentDefaultValue) : ?Node
|
public function processReplaces($node, ReplaceArgumentDefaultValueInterface $replaceArgumentDefaultValue)
|
||||||
{
|
{
|
||||||
if ($node instanceof ClassMethod) {
|
if ($node instanceof ClassMethod) {
|
||||||
if (!isset($node->params[$replaceArgumentDefaultValue->getPosition()])) {
|
if (!isset($node->params[$replaceArgumentDefaultValue->getPosition()])) {
|
||||||
|
@ -78,7 +80,10 @@ final class ArgumentDefaultValueReplacer
|
||||||
return $classMethod;
|
return $classMethod;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
* @template TCall as (MethodCall|StaticCall|FuncCall|New_)
|
||||||
|
*
|
||||||
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\New_ $expr
|
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\New_ $expr
|
||||||
|
* @return TCall|null
|
||||||
*/
|
*/
|
||||||
private function processArgs($expr, ReplaceArgumentDefaultValueInterface $replaceArgumentDefaultValue) : ?Expr
|
private function processArgs($expr, ReplaceArgumentDefaultValueInterface $replaceArgumentDefaultValue) : ?Expr
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,7 +29,7 @@ use Rector\Rector\AbstractRector;
|
||||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
use Rector\StaticTypeMapper\StaticTypeMapper;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
use RectorPrefix202403\Webmozart\Assert\Assert;
|
use RectorPrefix202406\Webmozart\Assert\Assert;
|
||||||
/**
|
/**
|
||||||
* @see \Rector\Tests\Arguments\Rector\ClassMethod\ArgumentAdderRector\ArgumentAdderRectorTest
|
* @see \Rector\Tests\Arguments\Rector\ClassMethod\ArgumentAdderRector\ArgumentAdderRectorTest
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -15,7 +15,7 @@ use Rector\Rector\AbstractRector;
|
||||||
use Rector\ValueObject\MethodName;
|
use Rector\ValueObject\MethodName;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
use RectorPrefix202403\Webmozart\Assert\Assert;
|
use RectorPrefix202406\Webmozart\Assert\Assert;
|
||||||
/**
|
/**
|
||||||
* @api used in rector-symfony
|
* @api used in rector-symfony
|
||||||
* @see \Rector\Tests\Arguments\Rector\ClassMethod\ReplaceArgumentDefaultValueRector\ReplaceArgumentDefaultValueRectorTest
|
* @see \Rector\Tests\Arguments\Rector\ClassMethod\ReplaceArgumentDefaultValueRector\ReplaceArgumentDefaultValueRectorTest
|
||||||
|
|
|
@ -11,7 +11,7 @@ use Rector\Contract\Rector\ConfigurableRectorInterface;
|
||||||
use Rector\Rector\AbstractRector;
|
use Rector\Rector\AbstractRector;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
use RectorPrefix202403\Webmozart\Assert\Assert;
|
use RectorPrefix202406\Webmozart\Assert\Assert;
|
||||||
/**
|
/**
|
||||||
* @changelog https://php.watch/versions/8.1/version_compare-operator-restrictions
|
* @changelog https://php.watch/versions/8.1/version_compare-operator-restrictions
|
||||||
* @changelog https://github.com/rectorphp/rector/issues/6271
|
* @changelog https://github.com/rectorphp/rector/issues/6271
|
||||||
|
|
|
@ -11,7 +11,7 @@ use Rector\Contract\Rector\ConfigurableRectorInterface;
|
||||||
use Rector\Rector\AbstractRector;
|
use Rector\Rector\AbstractRector;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
use RectorPrefix202403\Webmozart\Assert\Assert;
|
use RectorPrefix202406\Webmozart\Assert\Assert;
|
||||||
/**
|
/**
|
||||||
* @see \Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\RemoveMethodCallParamRectorTest
|
* @see \Rector\Tests\Arguments\Rector\MethodCall\RemoveMethodCallParamRector\RemoveMethodCallParamRectorTest
|
||||||
*/
|
*/
|
||||||
|
|
58
rules/Carbon/NodeFactory/CarbonCallFactory.php
Normal file
58
rules/Carbon/NodeFactory/CarbonCallFactory.php
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace Rector\Carbon\NodeFactory;
|
||||||
|
|
||||||
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
|
use PhpParser\Node\Arg;
|
||||||
|
use PhpParser\Node\Expr\MethodCall;
|
||||||
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
|
use PhpParser\Node\Identifier;
|
||||||
|
use PhpParser\Node\Name\FullyQualified;
|
||||||
|
use PhpParser\Node\Scalar\LNumber;
|
||||||
|
use PhpParser\Node\Scalar\String_;
|
||||||
|
final class CarbonCallFactory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @see https://regex101.com/r/9vGt8r/1
|
||||||
|
*/
|
||||||
|
private const DAY_COUNT_REGEX = '#\\+(\\s+)?(?<count>\\d+)(\\s+)?(day|days)#';
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @see https://regex101.com/r/6VUUQF/1
|
||||||
|
*/
|
||||||
|
private const MONTH_COUNT_REGEX = '#\\+(\\s+)?(?<count>\\d+)(\\s+)?(month|months)#';
|
||||||
|
/**
|
||||||
|
* @var array<self::*_REGEX, string>
|
||||||
|
*/
|
||||||
|
private const REGEX_TO_METHOD_NAME_MAP = [self::DAY_COUNT_REGEX => 'addDays', self::MONTH_COUNT_REGEX => 'addMonths'];
|
||||||
|
/**
|
||||||
|
* @return \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall
|
||||||
|
*/
|
||||||
|
public function createFromDateTimeString(FullyQualified $carbonFullyQualified, String_ $string)
|
||||||
|
{
|
||||||
|
$dateTimeValue = $string->value;
|
||||||
|
if ($dateTimeValue === 'now') {
|
||||||
|
return new StaticCall($carbonFullyQualified, new Identifier('now'));
|
||||||
|
}
|
||||||
|
if ($dateTimeValue === 'today') {
|
||||||
|
return new StaticCall($carbonFullyQualified, new Identifier('today'));
|
||||||
|
}
|
||||||
|
$hasToday = Strings::match($dateTimeValue, '#today#');
|
||||||
|
if ($hasToday !== null) {
|
||||||
|
$carbonCall = new StaticCall($carbonFullyQualified, new Identifier('today'));
|
||||||
|
} else {
|
||||||
|
$carbonCall = new StaticCall($carbonFullyQualified, new Identifier('now'));
|
||||||
|
}
|
||||||
|
foreach (self::REGEX_TO_METHOD_NAME_MAP as $regex => $methodName) {
|
||||||
|
$match = Strings::match($dateTimeValue, $regex);
|
||||||
|
if ($match === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$countLNumber = new LNumber((int) $match['count']);
|
||||||
|
$carbonCall = new MethodCall($carbonCall, new Identifier($methodName), [new Arg($countLNumber)]);
|
||||||
|
}
|
||||||
|
return $carbonCall;
|
||||||
|
}
|
||||||
|
}
|
72
rules/Carbon/Rector/FuncCall/DateFuncCallToCarbonRector.php
Normal file
72
rules/Carbon/Rector/FuncCall/DateFuncCallToCarbonRector.php
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace Rector\Carbon\Rector\FuncCall;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Arg;
|
||||||
|
use PhpParser\Node\Expr\FuncCall;
|
||||||
|
use PhpParser\Node\Expr\MethodCall;
|
||||||
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
|
use PhpParser\Node\Name\FullyQualified;
|
||||||
|
use PhpParser\Node\Scalar\String_;
|
||||||
|
use Rector\Rector\AbstractRector;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
|
/**
|
||||||
|
* @see \Rector\Tests\Carbon\Rector\FuncCall\DateFuncCallToCarbonRector\DateFuncCallToCarbonRectorTest
|
||||||
|
*/
|
||||||
|
final class DateFuncCallToCarbonRector extends AbstractRector
|
||||||
|
{
|
||||||
|
public function getRuleDefinition() : RuleDefinition
|
||||||
|
{
|
||||||
|
return new RuleDefinition('Convert date() function call to Carbon::now()->format(*)', [new CodeSample(<<<'CODE_SAMPLE'
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$date = date('Y-m-d');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
, <<<'CODE_SAMPLE'
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$date = \Carbon\Carbon::now()->format('Y-m-d');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
)]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return array<class-string<Node>>
|
||||||
|
*/
|
||||||
|
public function getNodeTypes() : array
|
||||||
|
{
|
||||||
|
return [FuncCall::class];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param FuncCall $node
|
||||||
|
*/
|
||||||
|
public function refactor(Node $node) : ?Node
|
||||||
|
{
|
||||||
|
if (!$this->isName($node->name, 'date')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ($node->isFirstClassCallable()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (\count($node->getArgs()) !== 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$firstArg = $node->getArgs()[0];
|
||||||
|
if (!$firstArg->value instanceof String_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// create now and format()
|
||||||
|
$nowStaticCall = new StaticCall(new FullyQualified('Carbon\\Carbon'), 'now');
|
||||||
|
return new MethodCall($nowStaticCall, 'format', [new Arg($firstArg->value)]);
|
||||||
|
}
|
||||||
|
}
|
69
rules/Carbon/Rector/FuncCall/TimeFuncCallToCarbonRector.php
Normal file
69
rules/Carbon/Rector/FuncCall/TimeFuncCallToCarbonRector.php
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace Rector\Carbon\Rector\FuncCall;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Expr\ArrowFunction;
|
||||||
|
use PhpParser\Node\Expr\FuncCall;
|
||||||
|
use PhpParser\Node\Expr\PropertyFetch;
|
||||||
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
|
use PhpParser\Node\Name\FullyQualified;
|
||||||
|
use Rector\Rector\AbstractRector;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
|
/**
|
||||||
|
* @see \Rector\Tests\Carbon\Rector\FuncCall\DateFuncCallToCarbonRector\DateFuncCallToCarbonRectorTest
|
||||||
|
*/
|
||||||
|
final class TimeFuncCallToCarbonRector extends AbstractRector
|
||||||
|
{
|
||||||
|
public function getRuleDefinition() : RuleDefinition
|
||||||
|
{
|
||||||
|
return new RuleDefinition('Convert time() function call to Carbon::now()->timestamp', [new CodeSample(<<<'CODE_SAMPLE'
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$time = time();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
, <<<'CODE_SAMPLE'
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$time = \Carbon\Carbon::now()->timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
)]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return array<class-string<Node>>
|
||||||
|
*/
|
||||||
|
public function getNodeTypes() : array
|
||||||
|
{
|
||||||
|
return [FuncCall::class];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param FuncCall $node
|
||||||
|
*/
|
||||||
|
public function refactor(Node $node) : ?Node
|
||||||
|
{
|
||||||
|
if (!$this->isName($node->name, 'time')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$firstClassCallable = $node->isFirstClassCallable();
|
||||||
|
if (!$firstClassCallable && \count($node->getArgs()) !== 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// create now and format()
|
||||||
|
$nowStaticCall = new StaticCall(new FullyQualified('Carbon\\Carbon'), 'now');
|
||||||
|
$propertyFetch = new PropertyFetch($nowStaticCall, 'timestamp');
|
||||||
|
if ($firstClassCallable) {
|
||||||
|
return new ArrowFunction(['static' => \true, 'expr' => $propertyFetch]);
|
||||||
|
}
|
||||||
|
return $propertyFetch;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace Rector\Carbon\Rector\MethodCall;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Expr\MethodCall;
|
||||||
|
use PhpParser\Node\Expr\New_;
|
||||||
|
use PhpParser\Node\Name;
|
||||||
|
use PhpParser\Node\Name\FullyQualified;
|
||||||
|
use PhpParser\Node\Scalar\String_;
|
||||||
|
use Rector\Carbon\NodeFactory\CarbonCallFactory;
|
||||||
|
use Rector\Rector\AbstractRector;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
|
/**
|
||||||
|
* @see \Rector\Tests\Carbon\Rector\MethodCall\DateTimeMethodCallToCarbonRector\DateTimeMethodCallToCarbonRectorTest
|
||||||
|
*/
|
||||||
|
final class DateTimeMethodCallToCarbonRector extends AbstractRector
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\Carbon\NodeFactory\CarbonCallFactory
|
||||||
|
*/
|
||||||
|
private $carbonCallFactory;
|
||||||
|
public function __construct(CarbonCallFactory $carbonCallFactory)
|
||||||
|
{
|
||||||
|
$this->carbonCallFactory = $carbonCallFactory;
|
||||||
|
}
|
||||||
|
public function getRuleDefinition() : RuleDefinition
|
||||||
|
{
|
||||||
|
return new RuleDefinition('Convert new DateTime() with a method call to Carbon::*()', [new CodeSample(<<<'CODE_SAMPLE'
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$date = (new \DateTime('today +20 day'))->format('Y-m-d');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
, <<<'CODE_SAMPLE'
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$date = \Carbon\Carbon::today()->addDays(20)->format('Y-m-d')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
)]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return array<class-string<Node>>
|
||||||
|
*/
|
||||||
|
public function getNodeTypes() : array
|
||||||
|
{
|
||||||
|
return [MethodCall::class];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param MethodCall $node
|
||||||
|
*/
|
||||||
|
public function refactor(Node $node) : ?Node
|
||||||
|
{
|
||||||
|
if (!$node->var instanceof New_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$new = $node->var;
|
||||||
|
if (!$new->class instanceof Name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!$this->isName($new->class, 'DateTime') && !$this->isName($new->class, 'DateTimeImmutable')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ($new->isFirstClassCallable()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (\count($new->getArgs()) !== 1) {
|
||||||
|
// @todo handle in separate static call
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$firstArg = $new->getArgs()[0];
|
||||||
|
if (!$firstArg->value instanceof String_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ($this->isName($new->class, 'DateTime')) {
|
||||||
|
$carbonFullyQualified = new FullyQualified('Carbon\\Carbon');
|
||||||
|
} else {
|
||||||
|
$carbonFullyQualified = new FullyQualified('Carbon\\CarbonImmutable');
|
||||||
|
}
|
||||||
|
$carbonCall = $this->carbonCallFactory->createFromDateTimeString($carbonFullyQualified, $firstArg->value);
|
||||||
|
$node->var = $carbonCall;
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
}
|
84
rules/Carbon/Rector/New_/DateTimeInstanceToCarbonRector.php
Normal file
84
rules/Carbon/Rector/New_/DateTimeInstanceToCarbonRector.php
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace Rector\Carbon\Rector\New_;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Expr\MethodCall;
|
||||||
|
use PhpParser\Node\Expr\New_;
|
||||||
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
|
use PhpParser\Node\Identifier;
|
||||||
|
use PhpParser\Node\Name\FullyQualified;
|
||||||
|
use PhpParser\Node\Scalar\String_;
|
||||||
|
use Rector\Carbon\NodeFactory\CarbonCallFactory;
|
||||||
|
use Rector\Rector\AbstractRector;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
|
/**
|
||||||
|
* @changelog https://github.com/briannesbitt/Carbon/issues/231
|
||||||
|
*
|
||||||
|
* @see \Rector\Tests\Carbon\Rector\New_\DateTimeInstanceToCarbonRector\DateTimeInstanceToCarbonRectorTest
|
||||||
|
*/
|
||||||
|
final class DateTimeInstanceToCarbonRector extends AbstractRector
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\Carbon\NodeFactory\CarbonCallFactory
|
||||||
|
*/
|
||||||
|
private $carbonCallFactory;
|
||||||
|
public function __construct(CarbonCallFactory $carbonCallFactory)
|
||||||
|
{
|
||||||
|
$this->carbonCallFactory = $carbonCallFactory;
|
||||||
|
}
|
||||||
|
public function getRuleDefinition() : RuleDefinition
|
||||||
|
{
|
||||||
|
return new RuleDefinition('Convert new DateTime() to Carbon::*()', [new CodeSample(<<<'CODE_SAMPLE'
|
||||||
|
$date = new \DateTime('today');
|
||||||
|
CODE_SAMPLE
|
||||||
|
, <<<'CODE_SAMPLE'
|
||||||
|
$date = \Carbon\Carbon::today();
|
||||||
|
CODE_SAMPLE
|
||||||
|
)]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return array<class-string<Node>>
|
||||||
|
*/
|
||||||
|
public function getNodeTypes() : array
|
||||||
|
{
|
||||||
|
return [New_::class];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param New_ $node
|
||||||
|
*/
|
||||||
|
public function refactor(Node $node) : ?Node
|
||||||
|
{
|
||||||
|
if ($node->isFirstClassCallable()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ($this->isName($node->class, 'DateTime')) {
|
||||||
|
return $this->refactorWithClass($node, 'Carbon\\Carbon');
|
||||||
|
}
|
||||||
|
if ($this->isName($node->class, 'DateTimeImmutable')) {
|
||||||
|
return $this->refactorWithClass($node, 'Carbon\\CarbonImmutable');
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|null
|
||||||
|
*/
|
||||||
|
private function refactorWithClass(New_ $new, string $className)
|
||||||
|
{
|
||||||
|
// no arg? ::now()
|
||||||
|
$carbonFullyQualified = new FullyQualified($className);
|
||||||
|
if ($new->args === []) {
|
||||||
|
return new StaticCall($carbonFullyQualified, new Identifier('now'));
|
||||||
|
}
|
||||||
|
if (\count($new->getArgs()) === 1) {
|
||||||
|
$firstArg = $new->getArgs()[0];
|
||||||
|
if ($firstArg->value instanceof String_) {
|
||||||
|
return $this->carbonCallFactory->createFromDateTimeString($carbonFullyQualified, $firstArg->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,9 @@ namespace Rector\CodeQuality\Rector\Array_;
|
||||||
|
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr\Array_;
|
use PhpParser\Node\Expr\Array_;
|
||||||
|
use PhpParser\Node\Stmt\ClassConst;
|
||||||
|
use PhpParser\Node\Stmt\Property;
|
||||||
|
use PhpParser\NodeTraverser;
|
||||||
use PHPStan\Analyser\Scope;
|
use PHPStan\Analyser\Scope;
|
||||||
use PHPStan\Reflection\Php\PhpMethodReflection;
|
use PHPStan\Reflection\Php\PhpMethodReflection;
|
||||||
use Rector\NodeCollector\NodeAnalyzer\ArrayCallableMethodMatcher;
|
use Rector\NodeCollector\NodeAnalyzer\ArrayCallableMethodMatcher;
|
||||||
|
@ -20,6 +23,9 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
* @changelog https://3v4l.org/KM1Ji
|
* @changelog https://3v4l.org/KM1Ji
|
||||||
*
|
*
|
||||||
* @see \Rector\Tests\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector\CallableThisArrayToAnonymousFunctionRectorTest
|
* @see \Rector\Tests\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector\CallableThisArrayToAnonymousFunctionRectorTest
|
||||||
|
*
|
||||||
|
* @deprecated This rule is surpassed by more advanced one
|
||||||
|
* Use @see FirstClassCallableRector instead
|
||||||
*/
|
*/
|
||||||
final class CallableThisArrayToAnonymousFunctionRector extends AbstractScopeAwareRector
|
final class CallableThisArrayToAnonymousFunctionRector extends AbstractScopeAwareRector
|
||||||
{
|
{
|
||||||
|
@ -89,13 +95,17 @@ CODE_SAMPLE
|
||||||
*/
|
*/
|
||||||
public function getNodeTypes() : array
|
public function getNodeTypes() : array
|
||||||
{
|
{
|
||||||
return [Array_::class];
|
return [Property::class, ClassConst::class, Array_::class];
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param Array_ $node
|
* @param Property|ClassConst|Array_ $node
|
||||||
|
* @return null|int|\PhpParser\Node
|
||||||
*/
|
*/
|
||||||
public function refactorWithScope(Node $node, Scope $scope) : ?Node
|
public function refactorWithScope(Node $node, Scope $scope)
|
||||||
{
|
{
|
||||||
|
if ($node instanceof Property || $node instanceof ClassConst) {
|
||||||
|
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
|
||||||
|
}
|
||||||
if ($this->shouldSkipTwigExtension($scope)) {
|
if ($this->shouldSkipTwigExtension($scope)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace Rector\CodeQuality\Rector\ClassMethod;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\Closure;
|
||||||
|
use PhpParser\Node\Expr\ConstFetch;
|
||||||
|
use PhpParser\Node\Name;
|
||||||
|
use PhpParser\Node\Stmt\Class_;
|
||||||
|
use PhpParser\Node\Stmt\ClassMethod;
|
||||||
|
use PhpParser\Node\Stmt\Function_;
|
||||||
|
use PhpParser\Node\Stmt\Return_;
|
||||||
|
use PhpParser\NodeTraverser;
|
||||||
|
use PHPStan\Type\NullType;
|
||||||
|
use PHPStan\Type\UnionType;
|
||||||
|
use PHPStan\Type\VoidType;
|
||||||
|
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||||
|
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
|
||||||
|
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
|
||||||
|
use Rector\Rector\AbstractRector;
|
||||||
|
use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer;
|
||||||
|
use Rector\TypeDeclaration\TypeInferer\SilentVoidResolver;
|
||||||
|
use Rector\ValueObject\MethodName;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
|
/**
|
||||||
|
* @see \Rector\Tests\CodeQuality\Rector\ClassMethod\ExplicitReturnNullRector\ExplicitReturnNullRectorTest
|
||||||
|
*/
|
||||||
|
final class ExplicitReturnNullRector extends AbstractRector
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\TypeDeclaration\TypeInferer\SilentVoidResolver
|
||||||
|
*/
|
||||||
|
private $silentVoidResolver;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory
|
||||||
|
*/
|
||||||
|
private $phpDocInfoFactory;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\NodeTypeResolver\PHPStan\Type\TypeFactory
|
||||||
|
*/
|
||||||
|
private $typeFactory;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger
|
||||||
|
*/
|
||||||
|
private $phpDocTypeChanger;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer
|
||||||
|
*/
|
||||||
|
private $returnTypeInferer;
|
||||||
|
public function __construct(SilentVoidResolver $silentVoidResolver, PhpDocInfoFactory $phpDocInfoFactory, TypeFactory $typeFactory, PhpDocTypeChanger $phpDocTypeChanger, ReturnTypeInferer $returnTypeInferer)
|
||||||
|
{
|
||||||
|
$this->silentVoidResolver = $silentVoidResolver;
|
||||||
|
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||||
|
$this->typeFactory = $typeFactory;
|
||||||
|
$this->phpDocTypeChanger = $phpDocTypeChanger;
|
||||||
|
$this->returnTypeInferer = $returnTypeInferer;
|
||||||
|
}
|
||||||
|
public function getRuleDefinition() : RuleDefinition
|
||||||
|
{
|
||||||
|
return new RuleDefinition('Add explicit return null to method/function that returns a value, but missed main return', [new CodeSample(<<<'CODE_SAMPLE'
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return string|void
|
||||||
|
*/
|
||||||
|
public function run(int $number)
|
||||||
|
{
|
||||||
|
if ($number > 50) {
|
||||||
|
return 'yes';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
, <<<'CODE_SAMPLE'
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function run(int $number)
|
||||||
|
{
|
||||||
|
if ($number > 50) {
|
||||||
|
return 'yes';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
)]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return array<class-string<Node>>
|
||||||
|
*/
|
||||||
|
public function getNodeTypes() : array
|
||||||
|
{
|
||||||
|
return [ClassMethod::class, Function_::class];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param ClassMethod|Function_ $node
|
||||||
|
*/
|
||||||
|
public function refactor(Node $node) : ?Node
|
||||||
|
{
|
||||||
|
// known return type, nothing to improve
|
||||||
|
if ($node->returnType instanceof Node) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ($node instanceof ClassMethod && $this->isName($node, MethodName::CONSTRUCT)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$returnType = $this->returnTypeInferer->inferFunctionLike($node);
|
||||||
|
if (!$returnType instanceof UnionType) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$hasChanged = \false;
|
||||||
|
$this->traverseNodesWithCallable((array) $node->stmts, static function (Node $node) use(&$hasChanged) {
|
||||||
|
if ($node instanceof Class_ || $node instanceof Function_ || $node instanceof Closure) {
|
||||||
|
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
|
||||||
|
}
|
||||||
|
if ($node instanceof Return_ && !$node->expr instanceof Expr) {
|
||||||
|
$hasChanged = \true;
|
||||||
|
$node->expr = new ConstFetch(new Name('null'));
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
if (!$this->silentVoidResolver->hasSilentVoid($node)) {
|
||||||
|
if ($hasChanged) {
|
||||||
|
$this->transformDocUnionVoidToUnionNull($node);
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$node->stmts[] = new Return_(new ConstFetch(new Name('null')));
|
||||||
|
$this->transformDocUnionVoidToUnionNull($node);
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $node
|
||||||
|
*/
|
||||||
|
private function transformDocUnionVoidToUnionNull($node) : void
|
||||||
|
{
|
||||||
|
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||||
|
$returnType = $phpDocInfo->getReturnType();
|
||||||
|
if (!$returnType instanceof UnionType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$newTypes = [];
|
||||||
|
$hasChanged = \false;
|
||||||
|
foreach ($returnType->getTypes() as $type) {
|
||||||
|
if ($type instanceof VoidType) {
|
||||||
|
$type = new NullType();
|
||||||
|
$hasChanged = \true;
|
||||||
|
}
|
||||||
|
$newTypes[] = $type;
|
||||||
|
}
|
||||||
|
if (!$hasChanged) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$type = $this->typeFactory->createMixedPassedOrUnionTypeAndKeepConstant($newTypes);
|
||||||
|
if (!$type instanceof UnionType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->phpDocTypeChanger->changeReturnType($node, $phpDocInfo, $type);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,12 +4,16 @@ declare (strict_types=1);
|
||||||
namespace Rector\CodeQuality\Rector\ClassMethod;
|
namespace Rector\CodeQuality\Rector\ClassMethod;
|
||||||
|
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Expr\FuncCall;
|
||||||
use PhpParser\Node\Expr\MethodCall;
|
use PhpParser\Node\Expr\MethodCall;
|
||||||
use PhpParser\Node\Expr\New_;
|
use PhpParser\Node\Expr\New_;
|
||||||
use PhpParser\Node\Expr\StaticCall;
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
use PhpParser\Node\Stmt\ClassMethod;
|
use PhpParser\Node\Stmt\ClassMethod;
|
||||||
|
use PhpParser\Node\Stmt\Function_;
|
||||||
use PHPStan\Analyser\Scope;
|
use PHPStan\Analyser\Scope;
|
||||||
|
use PHPStan\Reflection\FunctionReflection;
|
||||||
use PHPStan\Reflection\MethodReflection;
|
use PHPStan\Reflection\MethodReflection;
|
||||||
|
use PHPStan\Reflection\Native\NativeFunctionReflection;
|
||||||
use Rector\CodingStyle\Reflection\VendorLocationDetector;
|
use Rector\CodingStyle\Reflection\VendorLocationDetector;
|
||||||
use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper;
|
use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper;
|
||||||
use Rector\Php80\NodeResolver\ArgumentSorter;
|
use Rector\Php80\NodeResolver\ArgumentSorter;
|
||||||
|
@ -81,41 +85,49 @@ CODE_SAMPLE
|
||||||
*/
|
*/
|
||||||
public function getNodeTypes() : array
|
public function getNodeTypes() : array
|
||||||
{
|
{
|
||||||
return [ClassMethod::class, New_::class, MethodCall::class, StaticCall::class];
|
return [ClassMethod::class, Function_::class, New_::class, MethodCall::class, StaticCall::class, FuncCall::class];
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param ClassMethod|New_|MethodCall|StaticCall $node
|
* @param ClassMethod|Function_|New_|MethodCall|StaticCall|FuncCall $node
|
||||||
* @return \PhpParser\Node\Stmt\ClassMethod|null|\PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall
|
* @return \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|null|\PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall
|
||||||
*/
|
*/
|
||||||
public function refactorWithScope(Node $node, Scope $scope)
|
public function refactorWithScope(Node $node, Scope $scope)
|
||||||
{
|
{
|
||||||
if ($node instanceof ClassMethod) {
|
if ($node instanceof ClassMethod || $node instanceof Function_) {
|
||||||
return $this->refactorClassMethod($node, $scope);
|
return $this->refactorClassMethodOrFunction($node, $scope);
|
||||||
}
|
}
|
||||||
if ($node instanceof New_) {
|
if ($node instanceof New_) {
|
||||||
return $this->refactorNew($node, $scope);
|
return $this->refactorNew($node, $scope);
|
||||||
}
|
}
|
||||||
return $this->refactorMethodCall($node, $scope);
|
return $this->refactorMethodCallOrFuncCall($node, $scope);
|
||||||
}
|
}
|
||||||
private function refactorClassMethod(ClassMethod $classMethod, Scope $scope) : ?ClassMethod
|
/**
|
||||||
|
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $node
|
||||||
|
* @return \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|null
|
||||||
|
*/
|
||||||
|
private function refactorClassMethodOrFunction($node, Scope $scope)
|
||||||
{
|
{
|
||||||
if ($classMethod->params === []) {
|
if ($node->params === []) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if ($classMethod->getAttribute(self::HAS_SWAPPED_PARAMS, \false) === \true) {
|
if ($node->getAttribute(self::HAS_SWAPPED_PARAMS, \false) === \true) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$classMethodReflection = $this->reflectionResolver->resolveMethodReflectionFromClassMethod($classMethod, $scope);
|
if ($node instanceof ClassMethod) {
|
||||||
if (!$classMethodReflection instanceof MethodReflection) {
|
$reflection = $this->reflectionResolver->resolveMethodReflectionFromClassMethod($node, $scope);
|
||||||
|
} else {
|
||||||
|
$reflection = $this->reflectionResolver->resolveFunctionReflectionFromFunction($node, $scope);
|
||||||
|
}
|
||||||
|
if (!$reflection instanceof MethodReflection && !$reflection instanceof FunctionReflection) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($classMethodReflection, $classMethod, $scope);
|
$expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($reflection, $node, $scope);
|
||||||
if ($expectedArgOrParamOrder === null) {
|
if ($expectedArgOrParamOrder === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$classMethod->params = $this->argumentSorter->sortArgsByExpectedParamOrder($classMethod->params, $expectedArgOrParamOrder);
|
$node->params = $this->argumentSorter->sortArgsByExpectedParamOrder($node->params, $expectedArgOrParamOrder);
|
||||||
$classMethod->setAttribute(self::HAS_SWAPPED_PARAMS, \true);
|
$node->setAttribute(self::HAS_SWAPPED_PARAMS, \true);
|
||||||
return $classMethod;
|
return $node;
|
||||||
}
|
}
|
||||||
private function refactorNew(New_ $new, Scope $scope) : ?New_
|
private function refactorNew(New_ $new, Scope $scope) : ?New_
|
||||||
{
|
{
|
||||||
|
@ -137,39 +149,46 @@ CODE_SAMPLE
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall $methodCall
|
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall $node
|
||||||
* @return \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|null
|
* @return \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall|null
|
||||||
*/
|
*/
|
||||||
private function refactorMethodCall($methodCall, Scope $scope)
|
private function refactorMethodCallOrFuncCall($node, Scope $scope)
|
||||||
{
|
{
|
||||||
if ($methodCall->isFirstClassCallable()) {
|
if ($node->isFirstClassCallable()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$methodReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($methodCall);
|
$reflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node);
|
||||||
if (!$methodReflection instanceof MethodReflection) {
|
if (!$reflection instanceof MethodReflection && !$reflection instanceof FunctionReflection) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($methodReflection, $methodCall, $scope);
|
$expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($reflection, $node, $scope);
|
||||||
if ($expectedArgOrParamOrder === null) {
|
if ($expectedArgOrParamOrder === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$newArgs = $this->argumentSorter->sortArgsByExpectedParamOrder($methodCall->getArgs(), $expectedArgOrParamOrder);
|
$newArgs = $this->argumentSorter->sortArgsByExpectedParamOrder($node->getArgs(), $expectedArgOrParamOrder);
|
||||||
if ($methodCall->args === $newArgs) {
|
if ($node->args === $newArgs) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$methodCall->args = $newArgs;
|
$node->args = $newArgs;
|
||||||
return $methodCall;
|
return $node;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @return int[]|null
|
* @return int[]|null
|
||||||
* @param \PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Expr\StaticCall $node
|
* @param \PHPStan\Reflection\MethodReflection|\PHPStan\Reflection\FunctionReflection $reflection
|
||||||
|
* @param \PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall $node
|
||||||
*/
|
*/
|
||||||
private function resolveExpectedArgParamOrderIfDifferent(MethodReflection $methodReflection, $node, Scope $scope) : ?array
|
private function resolveExpectedArgParamOrderIfDifferent($reflection, $node, Scope $scope) : ?array
|
||||||
{
|
{
|
||||||
if ($this->vendorLocationDetector->detectMethodReflection($methodReflection)) {
|
if ($reflection instanceof NativeFunctionReflection) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($methodReflection, $node, $scope);
|
if ($reflection instanceof MethodReflection && $this->vendorLocationDetector->detectMethodReflection($reflection)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ($reflection instanceof FunctionReflection && $this->vendorLocationDetector->detectFunctionReflection($reflection)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($reflection, $node, $scope);
|
||||||
$expectedParameterReflections = $this->requireOptionalParamResolver->resolveFromParametersAcceptor($parametersAcceptor);
|
$expectedParameterReflections = $this->requireOptionalParamResolver->resolveFromParametersAcceptor($parametersAcceptor);
|
||||||
if ($expectedParameterReflections === $parametersAcceptor->getParameters()) {
|
if ($expectedParameterReflections === $parametersAcceptor->getParameters()) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodeQuality\Rector\Concat;
|
namespace Rector\CodeQuality\Rector\Concat;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr\BinaryOp\Concat;
|
use PhpParser\Node\Expr\BinaryOp\Concat;
|
||||||
use PhpParser\Node\Scalar\String_;
|
use PhpParser\Node\Scalar\String_;
|
||||||
|
|
|
@ -6,10 +6,11 @@ namespace Rector\CodeQuality\Rector\Expression;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr;
|
use PhpParser\Node\Expr;
|
||||||
use PhpParser\Node\Expr\Ternary;
|
use PhpParser\Node\Expr\Ternary;
|
||||||
|
use PhpParser\Node\Expr\Variable;
|
||||||
use PhpParser\Node\Stmt\Expression;
|
use PhpParser\Node\Stmt\Expression;
|
||||||
use PhpParser\Node\Stmt\If_;
|
use PhpParser\Node\Stmt\If_;
|
||||||
use PHPStan\Analyser\Scope;
|
use PHPStan\Analyser\Scope;
|
||||||
use Rector\DeadCode\SideEffect\SideEffectNodeDetector;
|
use Rector\NodeAnalyzer\ExprAnalyzer;
|
||||||
use Rector\Rector\AbstractScopeAwareRector;
|
use Rector\Rector\AbstractScopeAwareRector;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
|
@ -20,12 +21,12 @@ final class TernaryFalseExpressionToIfRector extends AbstractScopeAwareRector
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @readonly
|
* @readonly
|
||||||
* @var \Rector\DeadCode\SideEffect\SideEffectNodeDetector
|
* @var \Rector\NodeAnalyzer\ExprAnalyzer
|
||||||
*/
|
*/
|
||||||
private $sideEffectNodeDetector;
|
private $exprAnalyzer;
|
||||||
public function __construct(SideEffectNodeDetector $sideEffectNodeDetector)
|
public function __construct(ExprAnalyzer $exprAnalyzer)
|
||||||
{
|
{
|
||||||
$this->sideEffectNodeDetector = $sideEffectNodeDetector;
|
$this->exprAnalyzer = $exprAnalyzer;
|
||||||
}
|
}
|
||||||
public function getRuleDefinition() : RuleDefinition
|
public function getRuleDefinition() : RuleDefinition
|
||||||
{
|
{
|
||||||
|
@ -70,7 +71,7 @@ CODE_SAMPLE
|
||||||
if (!$ternary->if instanceof Expr) {
|
if (!$ternary->if instanceof Expr) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if ($this->sideEffectNodeDetector->detect($ternary->else, $scope) || $this->sideEffectNodeDetector->detectCallExpr($ternary->else, $scope)) {
|
if (!$ternary->else instanceof Variable && $this->exprAnalyzer->isDynamicExpr($ternary->else)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new If_($ternary->cond, ['stmts' => [new Expression($ternary->if)]]);
|
return new If_($ternary->cond, ['stmts' => [new Expression($ternary->if)]]);
|
||||||
|
|
|
@ -13,13 +13,14 @@ use PhpParser\Node\Expr\Variable;
|
||||||
use PhpParser\Node\Stmt;
|
use PhpParser\Node\Stmt;
|
||||||
use PhpParser\Node\Stmt\Expression;
|
use PhpParser\Node\Stmt\Expression;
|
||||||
use PhpParser\Node\Stmt\For_;
|
use PhpParser\Node\Stmt\For_;
|
||||||
use Rector\Rector\AbstractRector;
|
use PHPStan\Analyser\Scope;
|
||||||
|
use Rector\Rector\AbstractScopeAwareRector;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
/**
|
/**
|
||||||
* @see \Rector\Tests\CodeQuality\Rector\For_\ForRepeatedCountToOwnVariableRector\ForRepeatedCountToOwnVariableRectorTest
|
* @see \Rector\Tests\CodeQuality\Rector\For_\ForRepeatedCountToOwnVariableRector\ForRepeatedCountToOwnVariableRectorTest
|
||||||
*/
|
*/
|
||||||
final class ForRepeatedCountToOwnVariableRector extends AbstractRector
|
final class ForRepeatedCountToOwnVariableRector extends AbstractScopeAwareRector
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
|
@ -63,8 +64,11 @@ CODE_SAMPLE
|
||||||
* @param For_ $node
|
* @param For_ $node
|
||||||
* @return Stmt[]|null
|
* @return Stmt[]|null
|
||||||
*/
|
*/
|
||||||
public function refactor(Node $node) : ?array
|
public function refactorWithScope(Node $node, Scope $scope) : ?array
|
||||||
{
|
{
|
||||||
|
if ($scope->hasVariableType(self::COUNTER_NAME)->yes()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
$countInCond = null;
|
$countInCond = null;
|
||||||
$counterVariable = new Variable(self::COUNTER_NAME);
|
$counterVariable = new Variable(self::COUNTER_NAME);
|
||||||
foreach ($node->cond as $condExpr) {
|
foreach ($node->cond as $condExpr) {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodeQuality\Rector\FuncCall;
|
namespace Rector\CodeQuality\Rector\FuncCall;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Scalar\String_;
|
use PhpParser\Node\Scalar\String_;
|
||||||
use Rector\NodeNameResolver\Regex\RegexPatternDetector;
|
use Rector\NodeNameResolver\Regex\RegexPatternDetector;
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodeQuality\Rector\FuncCall;
|
namespace Rector\CodeQuality\Rector\FuncCall;
|
||||||
|
|
||||||
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr\FuncCall;
|
use PhpParser\Node\Expr\FuncCall;
|
||||||
use PhpParser\Node\Name;
|
use PhpParser\Node\Name;
|
||||||
|
use PhpParser\Node\Scalar\String_;
|
||||||
use Rector\Rector\AbstractRector;
|
use Rector\Rector\AbstractRector;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
|
@ -14,6 +16,11 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
*/
|
*/
|
||||||
final class SimplifyStrposLowerRector extends AbstractRector
|
final class SimplifyStrposLowerRector extends AbstractRector
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
* @see https://regex101.com/r/Jokjt8/1
|
||||||
|
*/
|
||||||
|
private const UPPERCASE_REGEX = '#[A-Z]#';
|
||||||
public function getRuleDefinition() : RuleDefinition
|
public function getRuleDefinition() : RuleDefinition
|
||||||
{
|
{
|
||||||
return new RuleDefinition('Simplify strpos(strtolower(), "...") calls', [new CodeSample('strpos(strtolower($var), "...")', 'stripos($var, "...")')]);
|
return new RuleDefinition('Simplify strpos(strtolower(), "...") calls', [new CodeSample('strpos(strtolower($var), "...")', 'stripos($var, "...")')]);
|
||||||
|
@ -36,10 +43,11 @@ final class SimplifyStrposLowerRector extends AbstractRector
|
||||||
if ($node->isFirstClassCallable()) {
|
if ($node->isFirstClassCallable()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!isset($node->getArgs()[0])) {
|
$args = $node->getArgs();
|
||||||
|
if (!isset($args[0], $args[1])) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$firstArg = $node->getArgs()[0];
|
$firstArg = $args[0];
|
||||||
if (!$firstArg->value instanceof FuncCall) {
|
if (!$firstArg->value instanceof FuncCall) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +56,13 @@ final class SimplifyStrposLowerRector extends AbstractRector
|
||||||
if (!$this->isName($innerFuncCall, 'strtolower')) {
|
if (!$this->isName($innerFuncCall, 'strtolower')) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
$secondArg = $args[1];
|
||||||
|
if (!$secondArg->value instanceof String_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (Strings::match($secondArg->value->value, self::UPPERCASE_REGEX) !== null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
// pop 1 level up
|
// pop 1 level up
|
||||||
$node->args[0] = $innerFuncCall->getArgs()[0];
|
$node->args[0] = $innerFuncCall->getArgs()[0];
|
||||||
$node->name = new Name('stripos');
|
$node->name = new Name('stripos');
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodeQuality\Rector\Include_;
|
namespace Rector\CodeQuality\Rector\Include_;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr\BinaryOp\Concat;
|
use PhpParser\Node\Expr\BinaryOp\Concat;
|
||||||
use PhpParser\Node\Expr\Include_;
|
use PhpParser\Node\Expr\Include_;
|
||||||
|
|
|
@ -53,6 +53,6 @@ final class SimplifyTautologyTernaryRector extends AbstractRector
|
||||||
if (!$twoNodeMatch instanceof TwoNodeMatch) {
|
if (!$twoNodeMatch instanceof TwoNodeMatch) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return $node->if;
|
return $node->cond instanceof NotIdentical ? $node->if : $node->else;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodingStyle\Application;
|
namespace Rector\CodingStyle\Application;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node\Name;
|
use PhpParser\Node\Name;
|
||||||
use PhpParser\Node\Stmt;
|
use PhpParser\Node\Stmt;
|
||||||
use PhpParser\Node\Stmt\Declare_;
|
use PhpParser\Node\Stmt\Declare_;
|
||||||
|
|
|
@ -3,11 +3,10 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodingStyle\ClassNameImport\ClassNameImportSkipVoter;
|
namespace Rector\CodingStyle\ClassNameImport\ClassNameImportSkipVoter;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use Rector\CodingStyle\ClassNameImport\ShortNameResolver;
|
use Rector\CodingStyle\ClassNameImport\ShortNameResolver;
|
||||||
use Rector\CodingStyle\Contract\ClassNameImport\ClassNameImportSkipVoterInterface;
|
use Rector\CodingStyle\Contract\ClassNameImport\ClassNameImportSkipVoterInterface;
|
||||||
use Rector\Configuration\RenamedClassesDataCollector;
|
|
||||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
||||||
use Rector\ValueObject\Application\File;
|
use Rector\ValueObject\Application\File;
|
||||||
/**
|
/**
|
||||||
|
@ -26,15 +25,9 @@ final class FullyQualifiedNameClassNameImportSkipVoter implements ClassNameImpor
|
||||||
* @var \Rector\CodingStyle\ClassNameImport\ShortNameResolver
|
* @var \Rector\CodingStyle\ClassNameImport\ShortNameResolver
|
||||||
*/
|
*/
|
||||||
private $shortNameResolver;
|
private $shortNameResolver;
|
||||||
/**
|
public function __construct(ShortNameResolver $shortNameResolver)
|
||||||
* @readonly
|
|
||||||
* @var \Rector\Configuration\RenamedClassesDataCollector
|
|
||||||
*/
|
|
||||||
private $renamedClassesDataCollector;
|
|
||||||
public function __construct(ShortNameResolver $shortNameResolver, RenamedClassesDataCollector $renamedClassesDataCollector)
|
|
||||||
{
|
{
|
||||||
$this->shortNameResolver = $shortNameResolver;
|
$this->shortNameResolver = $shortNameResolver;
|
||||||
$this->renamedClassesDataCollector = $renamedClassesDataCollector;
|
|
||||||
}
|
}
|
||||||
public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool
|
public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool
|
||||||
{
|
{
|
||||||
|
@ -43,7 +36,6 @@ final class FullyQualifiedNameClassNameImportSkipVoter implements ClassNameImpor
|
||||||
$shortNamesToFullyQualifiedNames = $this->shortNameResolver->resolveFromFile($file);
|
$shortNamesToFullyQualifiedNames = $this->shortNameResolver->resolveFromFile($file);
|
||||||
$fullyQualifiedObjectTypeShortName = $fullyQualifiedObjectType->getShortName();
|
$fullyQualifiedObjectTypeShortName = $fullyQualifiedObjectType->getShortName();
|
||||||
$className = $fullyQualifiedObjectType->getClassName();
|
$className = $fullyQualifiedObjectType->getClassName();
|
||||||
$removedUses = $this->renamedClassesDataCollector->getOldClasses();
|
|
||||||
foreach ($shortNamesToFullyQualifiedNames as $shortName => $fullyQualifiedName) {
|
foreach ($shortNamesToFullyQualifiedNames as $shortName => $fullyQualifiedName) {
|
||||||
if ($fullyQualifiedObjectTypeShortName !== $shortName) {
|
if ($fullyQualifiedObjectTypeShortName !== $shortName) {
|
||||||
$shortName = $this->cleanShortName($shortName);
|
$shortName = $this->cleanShortName($shortName);
|
||||||
|
@ -52,10 +44,7 @@ final class FullyQualifiedNameClassNameImportSkipVoter implements ClassNameImpor
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$fullyQualifiedName = \ltrim($fullyQualifiedName, '\\');
|
$fullyQualifiedName = \ltrim($fullyQualifiedName, '\\');
|
||||||
if ($className === $fullyQualifiedName) {
|
return $className !== $fullyQualifiedName;
|
||||||
return \false;
|
|
||||||
}
|
|
||||||
return !\in_array($fullyQualifiedName, $removedUses, \true);
|
|
||||||
}
|
}
|
||||||
return \false;
|
return \false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ namespace Rector\CodingStyle\ClassNameImport\ClassNameImportSkipVoter;
|
||||||
|
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use Rector\CodingStyle\Contract\ClassNameImport\ClassNameImportSkipVoterInterface;
|
use Rector\CodingStyle\Contract\ClassNameImport\ClassNameImportSkipVoterInterface;
|
||||||
use Rector\Configuration\RenamedClassesDataCollector;
|
|
||||||
use Rector\PostRector\Collector\UseNodesToAddCollector;
|
use Rector\PostRector\Collector\UseNodesToAddCollector;
|
||||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
||||||
use Rector\ValueObject\Application\File;
|
use Rector\ValueObject\Application\File;
|
||||||
|
@ -23,24 +22,14 @@ final class UsesClassNameImportSkipVoter implements ClassNameImportSkipVoterInte
|
||||||
* @var \Rector\PostRector\Collector\UseNodesToAddCollector
|
* @var \Rector\PostRector\Collector\UseNodesToAddCollector
|
||||||
*/
|
*/
|
||||||
private $useNodesToAddCollector;
|
private $useNodesToAddCollector;
|
||||||
/**
|
public function __construct(UseNodesToAddCollector $useNodesToAddCollector)
|
||||||
* @readonly
|
|
||||||
* @var \Rector\Configuration\RenamedClassesDataCollector
|
|
||||||
*/
|
|
||||||
private $renamedClassesDataCollector;
|
|
||||||
public function __construct(UseNodesToAddCollector $useNodesToAddCollector, RenamedClassesDataCollector $renamedClassesDataCollector)
|
|
||||||
{
|
{
|
||||||
$this->useNodesToAddCollector = $useNodesToAddCollector;
|
$this->useNodesToAddCollector = $useNodesToAddCollector;
|
||||||
$this->renamedClassesDataCollector = $renamedClassesDataCollector;
|
|
||||||
}
|
}
|
||||||
public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool
|
public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool
|
||||||
{
|
{
|
||||||
$useImportTypes = $this->useNodesToAddCollector->getUseImportTypesByNode($file, $node);
|
$useImportTypes = $this->useNodesToAddCollector->getUseImportTypesByNode($file);
|
||||||
foreach ($useImportTypes as $useImportType) {
|
foreach ($useImportTypes as $useImportType) {
|
||||||
// if the class is renamed, the use import is no longer blocker
|
|
||||||
if ($this->renamedClassesDataCollector->hasOldClass($useImportType->getClassName())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!$useImportType->equals($fullyQualifiedObjectType) && $useImportType->areShortNamesEqual($fullyQualifiedObjectType)) {
|
if (!$useImportType->equals($fullyQualifiedObjectType) && $useImportType->areShortNamesEqual($fullyQualifiedObjectType)) {
|
||||||
return \true;
|
return \true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodingStyle\ClassNameImport;
|
namespace Rector\CodingStyle\ClassNameImport;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Reflection;
|
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Identifier;
|
use PhpParser\Node\Identifier;
|
||||||
use PhpParser\Node\Name;
|
use PhpParser\Node\Name;
|
||||||
|
@ -12,8 +11,6 @@ use PhpParser\Node\Stmt\ClassLike;
|
||||||
use PhpParser\Node\Stmt\Namespace_;
|
use PhpParser\Node\Stmt\Namespace_;
|
||||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||||
use PHPStan\Reflection\ClassReflection;
|
|
||||||
use PHPStan\Reflection\ReflectionProvider;
|
|
||||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||||
use Rector\CodingStyle\NodeAnalyzer\UseImportNameMatcher;
|
use Rector\CodingStyle\NodeAnalyzer\UseImportNameMatcher;
|
||||||
|
@ -24,7 +21,6 @@ use Rector\PhpDocParser\PhpDocParser\PhpDocNodeTraverser;
|
||||||
use Rector\PhpParser\Node\BetterNodeFinder;
|
use Rector\PhpParser\Node\BetterNodeFinder;
|
||||||
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
|
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
|
||||||
use Rector\ValueObject\Application\File;
|
use Rector\ValueObject\Application\File;
|
||||||
use ReflectionClass;
|
|
||||||
/**
|
/**
|
||||||
* @see \Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\ShortNameResolverTest
|
* @see \Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\ShortNameResolverTest
|
||||||
*/
|
*/
|
||||||
|
@ -40,11 +36,6 @@ final class ShortNameResolver
|
||||||
* @var \Rector\NodeNameResolver\NodeNameResolver
|
* @var \Rector\NodeNameResolver\NodeNameResolver
|
||||||
*/
|
*/
|
||||||
private $nodeNameResolver;
|
private $nodeNameResolver;
|
||||||
/**
|
|
||||||
* @readonly
|
|
||||||
* @var \PHPStan\Reflection\ReflectionProvider
|
|
||||||
*/
|
|
||||||
private $reflectionProvider;
|
|
||||||
/**
|
/**
|
||||||
* @readonly
|
* @readonly
|
||||||
* @var \Rector\PhpParser\Node\BetterNodeFinder
|
* @var \Rector\PhpParser\Node\BetterNodeFinder
|
||||||
|
@ -64,11 +55,10 @@ final class ShortNameResolver
|
||||||
* @var array<string, string[]>
|
* @var array<string, string[]>
|
||||||
*/
|
*/
|
||||||
private $shortNamesByFilePath = [];
|
private $shortNamesByFilePath = [];
|
||||||
public function __construct(SimpleCallableNodeTraverser $simpleCallableNodeTraverser, NodeNameResolver $nodeNameResolver, ReflectionProvider $reflectionProvider, BetterNodeFinder $betterNodeFinder, UseImportNameMatcher $useImportNameMatcher, PhpDocInfoFactory $phpDocInfoFactory)
|
public function __construct(SimpleCallableNodeTraverser $simpleCallableNodeTraverser, NodeNameResolver $nodeNameResolver, BetterNodeFinder $betterNodeFinder, UseImportNameMatcher $useImportNameMatcher, PhpDocInfoFactory $phpDocInfoFactory)
|
||||||
{
|
{
|
||||||
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
|
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
|
||||||
$this->nodeNameResolver = $nodeNameResolver;
|
$this->nodeNameResolver = $nodeNameResolver;
|
||||||
$this->reflectionProvider = $reflectionProvider;
|
|
||||||
$this->betterNodeFinder = $betterNodeFinder;
|
$this->betterNodeFinder = $betterNodeFinder;
|
||||||
$this->useImportNameMatcher = $useImportNameMatcher;
|
$this->useImportNameMatcher = $useImportNameMatcher;
|
||||||
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||||
|
@ -152,7 +142,6 @@ final class ShortNameResolver
|
||||||
*/
|
*/
|
||||||
private function resolveFromStmtsDocBlocks(array $stmts) : array
|
private function resolveFromStmtsDocBlocks(array $stmts) : array
|
||||||
{
|
{
|
||||||
$classReflection = $this->resolveClassReflection($stmts);
|
|
||||||
$shortNames = [];
|
$shortNames = [];
|
||||||
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($stmts, function (Node $node) use(&$shortNames) {
|
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($stmts, function (Node $node) use(&$shortNames) {
|
||||||
// speed up for nodes that are
|
// speed up for nodes that are
|
||||||
|
@ -176,42 +165,22 @@ final class ShortNameResolver
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
return $this->fqnizeShortNames($shortNames, $classReflection, $stmts);
|
return $this->fqnizeShortNames($shortNames, $stmts);
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param Node[] $stmts
|
|
||||||
*/
|
|
||||||
private function resolveClassReflection(array $stmts) : ?ClassReflection
|
|
||||||
{
|
|
||||||
$firstClassLike = $this->betterNodeFinder->findFirstInstanceOf($stmts, ClassLike::class);
|
|
||||||
if (!$firstClassLike instanceof ClassLike) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$className = (string) $this->nodeNameResolver->getName($firstClassLike);
|
|
||||||
if (!$this->reflectionProvider->hasClass($className)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $this->reflectionProvider->getClass($className);
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param string[] $shortNames
|
* @param string[] $shortNames
|
||||||
* @param Stmt[] $stmts
|
* @param Stmt[] $stmts
|
||||||
* @return array<string, string>
|
* @return array<string, string>
|
||||||
*/
|
*/
|
||||||
private function fqnizeShortNames(array $shortNames, ?ClassReflection $classReflection, array $stmts) : array
|
private function fqnizeShortNames(array $shortNames, array $stmts) : array
|
||||||
{
|
{
|
||||||
$shortNamesToFullyQualifiedNames = [];
|
$shortNamesToFullyQualifiedNames = [];
|
||||||
$nativeReflectionClass = $classReflection instanceof ClassReflection && !$classReflection->isAnonymous() ? $classReflection->getNativeReflection() : null;
|
|
||||||
foreach ($shortNames as $shortName) {
|
foreach ($shortNames as $shortName) {
|
||||||
$stmtsMatchedName = $this->useImportNameMatcher->matchNameWithStmts($shortName, $stmts);
|
$stmtsMatchedName = $this->useImportNameMatcher->matchNameWithStmts($shortName, $stmts);
|
||||||
if ($nativeReflectionClass instanceof ReflectionClass) {
|
if ($stmtsMatchedName == null) {
|
||||||
$fullyQualifiedName = Reflection::expandClassName($shortName, $nativeReflectionClass);
|
continue;
|
||||||
} elseif (\is_string($stmtsMatchedName)) {
|
|
||||||
$fullyQualifiedName = $stmtsMatchedName;
|
|
||||||
} else {
|
|
||||||
$fullyQualifiedName = $shortName;
|
|
||||||
}
|
}
|
||||||
$shortNamesToFullyQualifiedNames[$shortName] = $fullyQualifiedName;
|
$shortNamesToFullyQualifiedNames[$shortName] = $stmtsMatchedName;
|
||||||
}
|
}
|
||||||
return $shortNamesToFullyQualifiedNames;
|
return $shortNamesToFullyQualifiedNames;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodingStyle\Naming;
|
namespace Rector\CodingStyle\Naming;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node\Identifier;
|
use PhpParser\Node\Identifier;
|
||||||
use PhpParser\Node\Name;
|
use PhpParser\Node\Name;
|
||||||
use PhpParser\Node\Stmt\ClassLike;
|
use PhpParser\Node\Stmt\ClassLike;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use Rector\Configuration\Option;
|
||||||
use Rector\Configuration\Parameter\SimpleParameterProvider;
|
use Rector\Configuration\Parameter\SimpleParameterProvider;
|
||||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||||
use Rector\PostRector\Collector\UseNodesToAddCollector;
|
use Rector\PostRector\Collector\UseNodesToAddCollector;
|
||||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
use Rector\StaticTypeMapper\PhpParser\FullyQualifiedNodeMapper;
|
||||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
||||||
use Rector\ValueObject\Application\File;
|
use Rector\ValueObject\Application\File;
|
||||||
final class NameImporter
|
final class NameImporter
|
||||||
|
@ -22,18 +22,18 @@ final class NameImporter
|
||||||
private $classNameImportSkipper;
|
private $classNameImportSkipper;
|
||||||
/**
|
/**
|
||||||
* @readonly
|
* @readonly
|
||||||
* @var \Rector\StaticTypeMapper\StaticTypeMapper
|
* @var \Rector\StaticTypeMapper\PhpParser\FullyQualifiedNodeMapper
|
||||||
*/
|
*/
|
||||||
private $staticTypeMapper;
|
private $fullyQualifiedNodeMapper;
|
||||||
/**
|
/**
|
||||||
* @readonly
|
* @readonly
|
||||||
* @var \Rector\PostRector\Collector\UseNodesToAddCollector
|
* @var \Rector\PostRector\Collector\UseNodesToAddCollector
|
||||||
*/
|
*/
|
||||||
private $useNodesToAddCollector;
|
private $useNodesToAddCollector;
|
||||||
public function __construct(ClassNameImportSkipper $classNameImportSkipper, StaticTypeMapper $staticTypeMapper, UseNodesToAddCollector $useNodesToAddCollector)
|
public function __construct(ClassNameImportSkipper $classNameImportSkipper, FullyQualifiedNodeMapper $fullyQualifiedNodeMapper, UseNodesToAddCollector $useNodesToAddCollector)
|
||||||
{
|
{
|
||||||
$this->classNameImportSkipper = $classNameImportSkipper;
|
$this->classNameImportSkipper = $classNameImportSkipper;
|
||||||
$this->staticTypeMapper = $staticTypeMapper;
|
$this->fullyQualifiedNodeMapper = $fullyQualifiedNodeMapper;
|
||||||
$this->useNodesToAddCollector = $useNodesToAddCollector;
|
$this->useNodesToAddCollector = $useNodesToAddCollector;
|
||||||
}
|
}
|
||||||
public function importName(FullyQualified $fullyQualified, File $file) : ?Name
|
public function importName(FullyQualified $fullyQualified, File $file) : ?Name
|
||||||
|
@ -41,7 +41,7 @@ final class NameImporter
|
||||||
if ($this->shouldSkipName($fullyQualified)) {
|
if ($this->shouldSkipName($fullyQualified)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$staticType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($fullyQualified);
|
$staticType = $this->fullyQualifiedNodeMapper->mapToPHPStan($fullyQualified);
|
||||||
if (!$staticType instanceof FullyQualifiedObjectType) {
|
if (!$staticType instanceof FullyQualifiedObjectType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodingStyle\NodeAnalyzer;
|
namespace Rector\CodingStyle\NodeAnalyzer;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node\Identifier;
|
use PhpParser\Node\Identifier;
|
||||||
use PhpParser\Node\Stmt;
|
use PhpParser\Node\Stmt;
|
||||||
use PhpParser\Node\Stmt\GroupUse;
|
use PhpParser\Node\Stmt\GroupUse;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodingStyle\Rector\Catch_;
|
namespace Rector\CodingStyle\Rector\Catch_;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr\Assign;
|
use PhpParser\Node\Expr\Assign;
|
||||||
use PhpParser\Node\Expr\Closure;
|
use PhpParser\Node\Expr\Closure;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodingStyle\Rector\Encapsed;
|
namespace Rector\CodingStyle\Rector\Encapsed;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Arg;
|
use PhpParser\Node\Arg;
|
||||||
use PhpParser\Node\Expr;
|
use PhpParser\Node\Expr;
|
||||||
|
|
|
@ -123,7 +123,7 @@ CODE_SAMPLE
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param int|float $rangeLine
|
* @param int|float $rangeLine
|
||||||
* @return int|float
|
* @return float|int
|
||||||
*/
|
*/
|
||||||
private function resolveRangeLineFromComment($rangeLine, int $line, int $endLine, Stmt $nextStmt)
|
private function resolveRangeLineFromComment($rangeLine, int $line, int $endLine, Stmt $nextStmt)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodingStyle\Rector\Stmt;
|
namespace Rector\CodingStyle\Rector\Stmt;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Identifier;
|
use PhpParser\Node\Identifier;
|
||||||
use PhpParser\Node\Stmt\Namespace_;
|
use PhpParser\Node\Stmt\Namespace_;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodingStyle\Rector\String_;
|
namespace Rector\CodingStyle\Rector\String_;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr\ClassConstFetch;
|
use PhpParser\Node\Expr\ClassConstFetch;
|
||||||
use PhpParser\Node\Name\FullyQualified;
|
use PhpParser\Node\Name\FullyQualified;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\CodingStyle\Reflection;
|
namespace Rector\CodingStyle\Reflection;
|
||||||
|
|
||||||
|
use PHPStan\Reflection\FunctionReflection;
|
||||||
use PHPStan\Reflection\MethodReflection;
|
use PHPStan\Reflection\MethodReflection;
|
||||||
use Rector\FileSystem\FilePathHelper;
|
use Rector\FileSystem\FilePathHelper;
|
||||||
final class VendorLocationDetector
|
final class VendorLocationDetector
|
||||||
|
@ -20,6 +21,15 @@ final class VendorLocationDetector
|
||||||
{
|
{
|
||||||
$declaringClassReflection = $methodReflection->getDeclaringClass();
|
$declaringClassReflection = $methodReflection->getDeclaringClass();
|
||||||
$fileName = $declaringClassReflection->getFileName();
|
$fileName = $declaringClassReflection->getFileName();
|
||||||
|
return $this->detect($fileName);
|
||||||
|
}
|
||||||
|
public function detectFunctionReflection(FunctionReflection $functionReflection) : bool
|
||||||
|
{
|
||||||
|
$fileName = $functionReflection->getFileName();
|
||||||
|
return $this->detect($fileName);
|
||||||
|
}
|
||||||
|
private function detect(?string $fileName = null) : bool
|
||||||
|
{
|
||||||
// probably internal
|
// probably internal
|
||||||
if ($fileName === null) {
|
if ($fileName === null) {
|
||||||
return \false;
|
return \false;
|
||||||
|
|
|
@ -4,6 +4,7 @@ declare (strict_types=1);
|
||||||
namespace Rector\DeadCode\NodeAnalyzer;
|
namespace Rector\DeadCode\NodeAnalyzer;
|
||||||
|
|
||||||
use PhpParser\Node\Expr\MethodCall;
|
use PhpParser\Node\Expr\MethodCall;
|
||||||
|
use PhpParser\Node\Expr\NullsafeMethodCall;
|
||||||
use PhpParser\Node\Expr\StaticCall;
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
use PhpParser\Node\Identifier;
|
use PhpParser\Node\Identifier;
|
||||||
use PhpParser\Node\Name;
|
use PhpParser\Node\Name;
|
||||||
|
@ -29,7 +30,7 @@ final class CallCollectionAnalyzer
|
||||||
$this->nodeNameResolver = $nodeNameResolver;
|
$this->nodeNameResolver = $nodeNameResolver;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param StaticCall[]|MethodCall[] $calls
|
* @param StaticCall[]|MethodCall[]|NullsafeMethodCall[] $calls
|
||||||
*/
|
*/
|
||||||
public function isExists(array $calls, string $classMethodName, string $className) : bool
|
public function isExists(array $calls, string $classMethodName, string $className) : bool
|
||||||
{
|
{
|
||||||
|
@ -52,14 +53,14 @@ final class CallCollectionAnalyzer
|
||||||
return \false;
|
return \false;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall $call
|
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\NullsafeMethodCall $call
|
||||||
*/
|
*/
|
||||||
private function isSelfStatic($call) : bool
|
private function isSelfStatic($call) : bool
|
||||||
{
|
{
|
||||||
return $call instanceof StaticCall && $call->class instanceof Name && \in_array($call->class->toString(), [ObjectReference::SELF, ObjectReference::STATIC], \true);
|
return $call instanceof StaticCall && $call->class instanceof Name && \in_array($call->class->toString(), [ObjectReference::SELF, ObjectReference::STATIC], \true);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param \PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\MethodCall $call
|
* @param \PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\NullsafeMethodCall $call
|
||||||
*/
|
*/
|
||||||
private function shouldSkip($call, string $classMethodName) : bool
|
private function shouldSkip($call, string $classMethodName) : bool
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,7 @@ use PhpParser\Node\Expr\Array_;
|
||||||
use PhpParser\Node\Expr\ArrayItem;
|
use PhpParser\Node\Expr\ArrayItem;
|
||||||
use PhpParser\Node\Expr\CallLike;
|
use PhpParser\Node\Expr\CallLike;
|
||||||
use PhpParser\Node\Expr\MethodCall;
|
use PhpParser\Node\Expr\MethodCall;
|
||||||
|
use PhpParser\Node\Expr\NullsafeMethodCall;
|
||||||
use PhpParser\Node\Expr\StaticCall;
|
use PhpParser\Node\Expr\StaticCall;
|
||||||
use PhpParser\Node\Name;
|
use PhpParser\Node\Name;
|
||||||
use PhpParser\Node\Stmt\Class_;
|
use PhpParser\Node\Stmt\Class_;
|
||||||
|
@ -88,11 +89,15 @@ final class IsClassMethodUsedAnalyzer
|
||||||
if ($this->isClassMethodCalledInLocalMethodCall($class, $classMethodName)) {
|
if ($this->isClassMethodCalledInLocalMethodCall($class, $classMethodName)) {
|
||||||
return \true;
|
return \true;
|
||||||
}
|
}
|
||||||
// 2. direct static calls
|
// 2. direct null-safe calls
|
||||||
|
if ($this->isClassMethodCalledInLocalNullsafeMethodCall($class, $classMethodName)) {
|
||||||
|
return \true;
|
||||||
|
}
|
||||||
|
// 3. direct static calls
|
||||||
if ($this->isClassMethodUsedInLocalStaticCall($class, $classMethodName)) {
|
if ($this->isClassMethodUsedInLocalStaticCall($class, $classMethodName)) {
|
||||||
return \true;
|
return \true;
|
||||||
}
|
}
|
||||||
// 3. magic array calls!
|
// 4. magic array calls!
|
||||||
if ($this->isClassMethodCalledInLocalArrayCall($class, $classMethod, $scope)) {
|
if ($this->isClassMethodCalledInLocalArrayCall($class, $classMethod, $scope)) {
|
||||||
return \true;
|
return \true;
|
||||||
}
|
}
|
||||||
|
@ -113,6 +118,13 @@ final class IsClassMethodUsedAnalyzer
|
||||||
$methodCalls = $this->betterNodeFinder->findInstanceOf($class, MethodCall::class);
|
$methodCalls = $this->betterNodeFinder->findInstanceOf($class, MethodCall::class);
|
||||||
return $this->callCollectionAnalyzer->isExists($methodCalls, $classMethodName, $className);
|
return $this->callCollectionAnalyzer->isExists($methodCalls, $classMethodName, $className);
|
||||||
}
|
}
|
||||||
|
private function isClassMethodCalledInLocalNullsafeMethodCall(Class_ $class, string $classMethodName) : bool
|
||||||
|
{
|
||||||
|
$className = (string) $this->nodeNameResolver->getName($class);
|
||||||
|
/** @var NullsafeMethodCall[] $methodCalls */
|
||||||
|
$methodCalls = $this->betterNodeFinder->findInstanceOf($class, NullsafeMethodCall::class);
|
||||||
|
return $this->callCollectionAnalyzer->isExists($methodCalls, $classMethodName, $className);
|
||||||
|
}
|
||||||
private function isInArrayMap(Class_ $class, Array_ $array) : bool
|
private function isInArrayMap(Class_ $class, Array_ $array) : bool
|
||||||
{
|
{
|
||||||
if (!$array->getAttribute(ArrayMapArgVisitor::ATTRIBUTE_NAME) instanceof Arg) {
|
if (!$array->getAttribute(ArrayMapArgVisitor::ATTRIBUTE_NAME) instanceof Arg) {
|
||||||
|
@ -134,11 +146,12 @@ final class IsClassMethodUsedAnalyzer
|
||||||
{
|
{
|
||||||
/** @var Array_[] $arrays */
|
/** @var Array_[] $arrays */
|
||||||
$arrays = $this->betterNodeFinder->findInstanceOf($class, Array_::class);
|
$arrays = $this->betterNodeFinder->findInstanceOf($class, Array_::class);
|
||||||
|
$classMethodName = $this->nodeNameResolver->getName($classMethod);
|
||||||
foreach ($arrays as $array) {
|
foreach ($arrays as $array) {
|
||||||
if ($this->isInArrayMap($class, $array)) {
|
if ($this->isInArrayMap($class, $array)) {
|
||||||
return \true;
|
return \true;
|
||||||
}
|
}
|
||||||
$arrayCallable = $this->arrayCallableMethodMatcher->match($array, $scope);
|
$arrayCallable = $this->arrayCallableMethodMatcher->match($array, $scope, $classMethodName);
|
||||||
if ($arrayCallable instanceof ArrayCallableDynamicMethod) {
|
if ($arrayCallable instanceof ArrayCallableDynamicMethod) {
|
||||||
return \true;
|
return \true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Rector\DeadCode\NodeAnalyzer;
|
||||||
|
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr;
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\NullsafePropertyFetch;
|
||||||
use PhpParser\Node\Expr\PropertyFetch;
|
use PhpParser\Node\Expr\PropertyFetch;
|
||||||
use PhpParser\Node\Expr\StaticPropertyFetch;
|
use PhpParser\Node\Expr\StaticPropertyFetch;
|
||||||
use PhpParser\Node\Stmt\Class_;
|
use PhpParser\Node\Stmt\Class_;
|
||||||
|
@ -24,7 +25,7 @@ final class PropertyWriteonlyAnalyzer
|
||||||
public function hasClassDynamicPropertyNames(Class_ $class) : bool
|
public function hasClassDynamicPropertyNames(Class_ $class) : bool
|
||||||
{
|
{
|
||||||
return (bool) $this->betterNodeFinder->findFirst($class, static function (Node $node) : bool {
|
return (bool) $this->betterNodeFinder->findFirst($class, static function (Node $node) : bool {
|
||||||
if (!$node instanceof PropertyFetch) {
|
if (!$node instanceof PropertyFetch && !$node instanceof NullsafePropertyFetch) {
|
||||||
return \false;
|
return \false;
|
||||||
}
|
}
|
||||||
// has dynamic name - could be anything
|
// has dynamic name - could be anything
|
||||||
|
@ -34,7 +35,7 @@ final class PropertyWriteonlyAnalyzer
|
||||||
/**
|
/**
|
||||||
* The property fetches are always only assigned to, nothing else
|
* The property fetches are always only assigned to, nothing else
|
||||||
*
|
*
|
||||||
* @param array<PropertyFetch|StaticPropertyFetch> $propertyFetches
|
* @param array<PropertyFetch|StaticPropertyFetch|NullsafePropertyFetch> $propertyFetches
|
||||||
*/
|
*/
|
||||||
public function arePropertyFetchesExclusivelyBeingAssignedTo(array $propertyFetches) : bool
|
public function arePropertyFetchesExclusivelyBeingAssignedTo(array $propertyFetches) : bool
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace Rector\DeadCode\NodeAnalyzer;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Expr\ArrayDimFetch;
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
|
||||||
|
use PhpParser\Node\Expr\Instanceof_;
|
||||||
|
use PhpParser\Node\Expr\PropertyFetch;
|
||||||
|
use PhpParser\Node\Expr\StaticPropertyFetch;
|
||||||
|
use PhpParser\Node\Expr\Variable;
|
||||||
|
use PHPStan\Reflection\ClassReflection;
|
||||||
|
use Rector\NodeAnalyzer\ExprAnalyzer;
|
||||||
|
use Rector\PhpParser\Node\BetterNodeFinder;
|
||||||
|
use Rector\Reflection\ReflectionResolver;
|
||||||
|
final class SafeLeftTypeBooleanAndOrAnalyzer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\PhpParser\Node\BetterNodeFinder
|
||||||
|
*/
|
||||||
|
private $betterNodeFinder;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\NodeAnalyzer\ExprAnalyzer
|
||||||
|
*/
|
||||||
|
private $exprAnalyzer;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\Reflection\ReflectionResolver
|
||||||
|
*/
|
||||||
|
private $reflectionResolver;
|
||||||
|
public function __construct(BetterNodeFinder $betterNodeFinder, ExprAnalyzer $exprAnalyzer, ReflectionResolver $reflectionResolver)
|
||||||
|
{
|
||||||
|
$this->betterNodeFinder = $betterNodeFinder;
|
||||||
|
$this->exprAnalyzer = $exprAnalyzer;
|
||||||
|
$this->reflectionResolver = $reflectionResolver;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param \PhpParser\Node\Expr\BinaryOp\BooleanAnd|\PhpParser\Node\Expr\BinaryOp\BooleanOr $booleanAnd
|
||||||
|
*/
|
||||||
|
public function isSafe($booleanAnd) : bool
|
||||||
|
{
|
||||||
|
$hasNonTypedFromParam = (bool) $this->betterNodeFinder->findFirst($booleanAnd->left, function (Node $node) : bool {
|
||||||
|
return $node instanceof Variable && $this->exprAnalyzer->isNonTypedFromParam($node);
|
||||||
|
});
|
||||||
|
if ($hasNonTypedFromParam) {
|
||||||
|
return \false;
|
||||||
|
}
|
||||||
|
$hasPropertyFetchOrArrayDimFetch = (bool) $this->betterNodeFinder->findFirst($booleanAnd->left, static function (Node $node) : bool {
|
||||||
|
return $node instanceof PropertyFetch || $node instanceof StaticPropertyFetch || $node instanceof ArrayDimFetch;
|
||||||
|
});
|
||||||
|
// get type from Property and ArrayDimFetch is unreliable
|
||||||
|
if ($hasPropertyFetchOrArrayDimFetch) {
|
||||||
|
return \false;
|
||||||
|
}
|
||||||
|
// skip trait this
|
||||||
|
$classReflection = $this->reflectionResolver->resolveClassReflection($booleanAnd);
|
||||||
|
if ($classReflection instanceof ClassReflection && $classReflection->isTrait()) {
|
||||||
|
return !$booleanAnd->left instanceof Instanceof_;
|
||||||
|
}
|
||||||
|
return \true;
|
||||||
|
}
|
||||||
|
}
|
44
rules/DeadCode/NodeManipulator/ClassMethodParamRemover.php
Normal file
44
rules/DeadCode/NodeManipulator/ClassMethodParamRemover.php
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace Rector\DeadCode\NodeManipulator;
|
||||||
|
|
||||||
|
use PhpParser\Node\Stmt\ClassMethod;
|
||||||
|
use Rector\NodeAnalyzer\ParamAnalyzer;
|
||||||
|
use Rector\Removing\NodeManipulator\ComplexNodeRemover;
|
||||||
|
final class ClassMethodParamRemover
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\NodeAnalyzer\ParamAnalyzer
|
||||||
|
*/
|
||||||
|
private $paramAnalyzer;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\Removing\NodeManipulator\ComplexNodeRemover
|
||||||
|
*/
|
||||||
|
private $complexNodeRemover;
|
||||||
|
public function __construct(ParamAnalyzer $paramAnalyzer, ComplexNodeRemover $complexNodeRemover)
|
||||||
|
{
|
||||||
|
$this->paramAnalyzer = $paramAnalyzer;
|
||||||
|
$this->complexNodeRemover = $complexNodeRemover;
|
||||||
|
}
|
||||||
|
public function processRemoveParams(ClassMethod $classMethod) : ?ClassMethod
|
||||||
|
{
|
||||||
|
$paramKeysToBeRemoved = [];
|
||||||
|
foreach ($classMethod->params as $key => $param) {
|
||||||
|
if ($this->paramAnalyzer->isParamUsedInClassMethod($classMethod, $param)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$paramKeysToBeRemoved[] = $key;
|
||||||
|
}
|
||||||
|
if ($paramKeysToBeRemoved === []) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$removedParamKeys = $this->complexNodeRemover->processRemoveParamWithKeys($classMethod, $paramKeysToBeRemoved);
|
||||||
|
if ($removedParamKeys !== []) {
|
||||||
|
return $classMethod;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
|
||||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||||
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
|
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
|
||||||
use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode;
|
use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode;
|
||||||
|
use Rector\DeadCode\PhpDoc\Guard\StandaloneTypeRemovalGuard;
|
||||||
use Rector\DeadCode\TypeNodeAnalyzer\GenericTypeNodeAnalyzer;
|
use Rector\DeadCode\TypeNodeAnalyzer\GenericTypeNodeAnalyzer;
|
||||||
use Rector\DeadCode\TypeNodeAnalyzer\MixedArrayTypeNodeAnalyzer;
|
use Rector\DeadCode\TypeNodeAnalyzer\MixedArrayTypeNodeAnalyzer;
|
||||||
use Rector\NodeNameResolver\NodeNameResolver;
|
use Rector\NodeNameResolver\NodeNameResolver;
|
||||||
|
@ -47,7 +48,12 @@ final class DeadParamTagValueNodeAnalyzer
|
||||||
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger
|
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger
|
||||||
*/
|
*/
|
||||||
private $phpDocTypeChanger;
|
private $phpDocTypeChanger;
|
||||||
public function __construct(NodeNameResolver $nodeNameResolver, TypeComparator $typeComparator, GenericTypeNodeAnalyzer $genericTypeNodeAnalyzer, MixedArrayTypeNodeAnalyzer $mixedArrayTypeNodeAnalyzer, ParamAnalyzer $paramAnalyzer, PhpDocTypeChanger $phpDocTypeChanger)
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\DeadCode\PhpDoc\Guard\StandaloneTypeRemovalGuard
|
||||||
|
*/
|
||||||
|
private $standaloneTypeRemovalGuard;
|
||||||
|
public function __construct(NodeNameResolver $nodeNameResolver, TypeComparator $typeComparator, GenericTypeNodeAnalyzer $genericTypeNodeAnalyzer, MixedArrayTypeNodeAnalyzer $mixedArrayTypeNodeAnalyzer, ParamAnalyzer $paramAnalyzer, PhpDocTypeChanger $phpDocTypeChanger, StandaloneTypeRemovalGuard $standaloneTypeRemovalGuard)
|
||||||
{
|
{
|
||||||
$this->nodeNameResolver = $nodeNameResolver;
|
$this->nodeNameResolver = $nodeNameResolver;
|
||||||
$this->typeComparator = $typeComparator;
|
$this->typeComparator = $typeComparator;
|
||||||
|
@ -55,6 +61,7 @@ final class DeadParamTagValueNodeAnalyzer
|
||||||
$this->mixedArrayTypeNodeAnalyzer = $mixedArrayTypeNodeAnalyzer;
|
$this->mixedArrayTypeNodeAnalyzer = $mixedArrayTypeNodeAnalyzer;
|
||||||
$this->paramAnalyzer = $paramAnalyzer;
|
$this->paramAnalyzer = $paramAnalyzer;
|
||||||
$this->phpDocTypeChanger = $phpDocTypeChanger;
|
$this->phpDocTypeChanger = $phpDocTypeChanger;
|
||||||
|
$this->standaloneTypeRemovalGuard = $standaloneTypeRemovalGuard;
|
||||||
}
|
}
|
||||||
public function isDead(ParamTagValueNode $paramTagValueNode, FunctionLike $functionLike) : bool
|
public function isDead(ParamTagValueNode $paramTagValueNode, FunctionLike $functionLike) : bool
|
||||||
{
|
{
|
||||||
|
@ -78,11 +85,15 @@ final class DeadParamTagValueNodeAnalyzer
|
||||||
return \false;
|
return \false;
|
||||||
}
|
}
|
||||||
if (!$paramTagValueNode->type instanceof BracketsAwareUnionTypeNode) {
|
if (!$paramTagValueNode->type instanceof BracketsAwareUnionTypeNode) {
|
||||||
return \true;
|
return $this->standaloneTypeRemovalGuard->isLegal($paramTagValueNode->type, $param->type);
|
||||||
}
|
}
|
||||||
if ($this->mixedArrayTypeNodeAnalyzer->hasMixedArrayType($paramTagValueNode->type)) {
|
return $this->isAllowedBracketAwareUnion($paramTagValueNode->type);
|
||||||
|
}
|
||||||
|
private function isAllowedBracketAwareUnion(BracketsAwareUnionTypeNode $bracketsAwareUnionTypeNode) : bool
|
||||||
|
{
|
||||||
|
if ($this->mixedArrayTypeNodeAnalyzer->hasMixedArrayType($bracketsAwareUnionTypeNode)) {
|
||||||
return \false;
|
return \false;
|
||||||
}
|
}
|
||||||
return !$this->genericTypeNodeAnalyzer->hasGenericType($paramTagValueNode->type);
|
return !$this->genericTypeNodeAnalyzer->hasGenericType($bracketsAwareUnionTypeNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use PhpParser\Node\FunctionLike;
|
||||||
use PHPStan\PhpDocParser\Ast\Node;
|
use PHPStan\PhpDocParser\Ast\Node;
|
||||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
|
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
|
||||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||||
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
|
use PHPStan\Type\Type;
|
||||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||||
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
|
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
|
||||||
use Rector\DeadCode\PhpDoc\DeadParamTagValueNodeAnalyzer;
|
use Rector\DeadCode\PhpDoc\DeadParamTagValueNodeAnalyzer;
|
||||||
|
@ -29,11 +29,11 @@ final class ParamTagRemover
|
||||||
$this->deadParamTagValueNodeAnalyzer = $deadParamTagValueNodeAnalyzer;
|
$this->deadParamTagValueNodeAnalyzer = $deadParamTagValueNodeAnalyzer;
|
||||||
$this->docBlockUpdater = $docBlockUpdater;
|
$this->docBlockUpdater = $docBlockUpdater;
|
||||||
}
|
}
|
||||||
public function removeParamTagsIfUseless(PhpDocInfo $phpDocInfo, FunctionLike $functionLike) : bool
|
public function removeParamTagsIfUseless(PhpDocInfo $phpDocInfo, FunctionLike $functionLike, ?Type $type = null) : bool
|
||||||
{
|
{
|
||||||
$hasChanged = \false;
|
$hasChanged = \false;
|
||||||
$phpDocNodeTraverser = new PhpDocNodeTraverser();
|
$phpDocNodeTraverser = new PhpDocNodeTraverser();
|
||||||
$phpDocNodeTraverser->traverseWithCallable($phpDocInfo->getPhpDocNode(), '', function (Node $docNode) use($functionLike, &$hasChanged) : ?int {
|
$phpDocNodeTraverser->traverseWithCallable($phpDocInfo->getPhpDocNode(), '', function (Node $docNode) use($functionLike, &$hasChanged, $type, $phpDocInfo) : ?int {
|
||||||
if (!$docNode instanceof PhpDocTagNode) {
|
if (!$docNode instanceof PhpDocTagNode) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,11 @@ final class ParamTagRemover
|
||||||
if ($docNode->name !== '@param') {
|
if ($docNode->name !== '@param') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// skip union types
|
if ($type instanceof Type) {
|
||||||
if ($docNode->value->type instanceof UnionTypeNode) {
|
$paramType = $phpDocInfo->getParamType($docNode->value->parameterName);
|
||||||
return null;
|
if (!$type->equals($paramType)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!$this->deadParamTagValueNodeAnalyzer->isDead($docNode->value, $functionLike)) {
|
if (!$this->deadParamTagValueNodeAnalyzer->isDead($docNode->value, $functionLike)) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -93,7 +93,7 @@ CODE_SAMPLE
|
||||||
if (!isset(self::CAST_CLASS_TO_NODE_TYPE[$nodeClass])) {
|
if (!isset(self::CAST_CLASS_TO_NODE_TYPE[$nodeClass])) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$nodeType = $this->getType($node->expr);
|
$nodeType = $this->nodeTypeResolver->getNativeType($node->expr);
|
||||||
if ($nodeType instanceof MixedType) {
|
if ($nodeType instanceof MixedType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ use Rector\Contract\Rector\ConfigurableRectorInterface;
|
||||||
use Rector\Rector\AbstractRector;
|
use Rector\Rector\AbstractRector;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
use RectorPrefix202403\Webmozart\Assert\Assert;
|
use RectorPrefix202406\Webmozart\Assert\Assert;
|
||||||
/**
|
/**
|
||||||
* @see \Rector\Tests\DeadCode\Rector\ClassLike\RemoveAnnotationRector\RemoveAnnotationRectorTest
|
* @see \Rector\Tests\DeadCode\Rector\ClassLike\RemoveAnnotationRector\RemoveAnnotationRectorTest
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -6,9 +6,11 @@ namespace Rector\DeadCode\Rector\ClassMethod;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Stmt\Class_;
|
use PhpParser\Node\Stmt\Class_;
|
||||||
use PhpParser\Node\Stmt\ClassMethod;
|
use PhpParser\Node\Stmt\ClassMethod;
|
||||||
|
use PHPStan\Reflection\ClassReflection;
|
||||||
|
use Rector\DeadCode\NodeManipulator\ClassMethodParamRemover;
|
||||||
use Rector\NodeAnalyzer\ParamAnalyzer;
|
use Rector\NodeAnalyzer\ParamAnalyzer;
|
||||||
use Rector\Rector\AbstractRector;
|
use Rector\Rector\AbstractRector;
|
||||||
use Rector\Removing\NodeManipulator\ComplexNodeRemover;
|
use Rector\Reflection\ReflectionResolver;
|
||||||
use Rector\ValueObject\MethodName;
|
use Rector\ValueObject\MethodName;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
|
@ -24,13 +26,19 @@ final class RemoveUnusedConstructorParamRector extends AbstractRector
|
||||||
private $paramAnalyzer;
|
private $paramAnalyzer;
|
||||||
/**
|
/**
|
||||||
* @readonly
|
* @readonly
|
||||||
* @var \Rector\Removing\NodeManipulator\ComplexNodeRemover
|
* @var \Rector\Reflection\ReflectionResolver
|
||||||
*/
|
*/
|
||||||
private $complexNodeRemover;
|
private $reflectionResolver;
|
||||||
public function __construct(ParamAnalyzer $paramAnalyzer, ComplexNodeRemover $complexNodeRemover)
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\DeadCode\NodeManipulator\ClassMethodParamRemover
|
||||||
|
*/
|
||||||
|
private $classMethodParamRemover;
|
||||||
|
public function __construct(ParamAnalyzer $paramAnalyzer, ReflectionResolver $reflectionResolver, ClassMethodParamRemover $classMethodParamRemover)
|
||||||
{
|
{
|
||||||
$this->paramAnalyzer = $paramAnalyzer;
|
$this->paramAnalyzer = $paramAnalyzer;
|
||||||
$this->complexNodeRemover = $complexNodeRemover;
|
$this->reflectionResolver = $reflectionResolver;
|
||||||
|
$this->classMethodParamRemover = $classMethodParamRemover;
|
||||||
}
|
}
|
||||||
public function getRuleDefinition() : RuleDefinition
|
public function getRuleDefinition() : RuleDefinition
|
||||||
{
|
{
|
||||||
|
@ -83,28 +91,20 @@ CODE_SAMPLE
|
||||||
if ($constructorClassMethod->isAbstract()) {
|
if ($constructorClassMethod->isAbstract()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$changedConstructorClassMethod = $this->processRemoveParams($constructorClassMethod);
|
$classReflection = $this->reflectionResolver->resolveClassReflection($node);
|
||||||
|
if (!$classReflection instanceof ClassReflection) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$interfaces = $classReflection->getInterfaces();
|
||||||
|
foreach ($interfaces as $interface) {
|
||||||
|
if ($interface->hasNativeMethod(MethodName::CONSTRUCT)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$changedConstructorClassMethod = $this->classMethodParamRemover->processRemoveParams($constructorClassMethod);
|
||||||
if (!$changedConstructorClassMethod instanceof ClassMethod) {
|
if (!$changedConstructorClassMethod instanceof ClassMethod) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return $node;
|
return $node;
|
||||||
}
|
}
|
||||||
private function processRemoveParams(ClassMethod $classMethod) : ?ClassMethod
|
|
||||||
{
|
|
||||||
$paramKeysToBeRemoved = [];
|
|
||||||
foreach ($classMethod->params as $key => $param) {
|
|
||||||
if ($this->paramAnalyzer->isParamUsedInClassMethod($classMethod, $param)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$paramKeysToBeRemoved[] = $key;
|
|
||||||
}
|
|
||||||
if ($paramKeysToBeRemoved === []) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$removedParamKeys = $this->complexNodeRemover->processRemoveParamWithKeys($classMethod, $paramKeysToBeRemoved);
|
|
||||||
if ($removedParamKeys !== []) {
|
|
||||||
return $classMethod;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,12 @@ use PhpParser\Node\Stmt\Class_;
|
||||||
use PhpParser\Node\Stmt\ClassMethod;
|
use PhpParser\Node\Stmt\ClassMethod;
|
||||||
use PhpParser\Node\Stmt\TraitUse;
|
use PhpParser\Node\Stmt\TraitUse;
|
||||||
use PHPStan\Analyser\Scope;
|
use PHPStan\Analyser\Scope;
|
||||||
|
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
|
||||||
use PHPStan\Reflection\ClassReflection;
|
use PHPStan\Reflection\ClassReflection;
|
||||||
|
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||||
|
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||||
|
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover;
|
||||||
|
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
|
||||||
use Rector\DeadCode\NodeAnalyzer\PropertyWriteonlyAnalyzer;
|
use Rector\DeadCode\NodeAnalyzer\PropertyWriteonlyAnalyzer;
|
||||||
use Rector\PhpParser\Node\BetterNodeFinder;
|
use Rector\PhpParser\Node\BetterNodeFinder;
|
||||||
use Rector\PhpParser\NodeFinder\PropertyFetchFinder;
|
use Rector\PhpParser\NodeFinder\PropertyFetchFinder;
|
||||||
|
@ -52,13 +57,31 @@ final class RemoveUnusedPromotedPropertyRector extends AbstractScopeAwareRector
|
||||||
* @var \Rector\Reflection\ReflectionResolver
|
* @var \Rector\Reflection\ReflectionResolver
|
||||||
*/
|
*/
|
||||||
private $reflectionResolver;
|
private $reflectionResolver;
|
||||||
public function __construct(PropertyFetchFinder $propertyFetchFinder, VisibilityManipulator $visibilityManipulator, PropertyWriteonlyAnalyzer $propertyWriteonlyAnalyzer, BetterNodeFinder $betterNodeFinder, ReflectionResolver $reflectionResolver)
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory
|
||||||
|
*/
|
||||||
|
private $phpDocInfoFactory;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover
|
||||||
|
*/
|
||||||
|
private $phpDocTagRemover;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\Comments\NodeDocBlock\DocBlockUpdater
|
||||||
|
*/
|
||||||
|
private $docBlockUpdater;
|
||||||
|
public function __construct(PropertyFetchFinder $propertyFetchFinder, VisibilityManipulator $visibilityManipulator, PropertyWriteonlyAnalyzer $propertyWriteonlyAnalyzer, BetterNodeFinder $betterNodeFinder, ReflectionResolver $reflectionResolver, PhpDocInfoFactory $phpDocInfoFactory, PhpDocTagRemover $phpDocTagRemover, DocBlockUpdater $docBlockUpdater)
|
||||||
{
|
{
|
||||||
$this->propertyFetchFinder = $propertyFetchFinder;
|
$this->propertyFetchFinder = $propertyFetchFinder;
|
||||||
$this->visibilityManipulator = $visibilityManipulator;
|
$this->visibilityManipulator = $visibilityManipulator;
|
||||||
$this->propertyWriteonlyAnalyzer = $propertyWriteonlyAnalyzer;
|
$this->propertyWriteonlyAnalyzer = $propertyWriteonlyAnalyzer;
|
||||||
$this->betterNodeFinder = $betterNodeFinder;
|
$this->betterNodeFinder = $betterNodeFinder;
|
||||||
$this->reflectionResolver = $reflectionResolver;
|
$this->reflectionResolver = $reflectionResolver;
|
||||||
|
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||||
|
$this->phpDocTagRemover = $phpDocTagRemover;
|
||||||
|
$this->docBlockUpdater = $docBlockUpdater;
|
||||||
}
|
}
|
||||||
public function getRuleDefinition() : RuleDefinition
|
public function getRuleDefinition() : RuleDefinition
|
||||||
{
|
{
|
||||||
|
@ -116,6 +139,7 @@ CODE_SAMPLE
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$hasChanged = \false;
|
$hasChanged = \false;
|
||||||
|
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($constructClassMethod);
|
||||||
foreach ($constructClassMethod->params as $key => $param) {
|
foreach ($constructClassMethod->params as $key => $param) {
|
||||||
// only private local scope; removing public property might be dangerous
|
// only private local scope; removing public property might be dangerous
|
||||||
if (!$this->visibilityManipulator->hasVisibility($param, Visibility::PRIVATE)) {
|
if (!$this->visibilityManipulator->hasVisibility($param, Visibility::PRIVATE)) {
|
||||||
|
@ -129,15 +153,23 @@ CODE_SAMPLE
|
||||||
if (!$this->propertyWriteonlyAnalyzer->arePropertyFetchesExclusivelyBeingAssignedTo($propertyFetches)) {
|
if (!$this->propertyWriteonlyAnalyzer->arePropertyFetchesExclusivelyBeingAssignedTo($propertyFetches)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// always changed on below code
|
||||||
|
$hasChanged = \true;
|
||||||
// is variable used? only remove property, keep param
|
// is variable used? only remove property, keep param
|
||||||
$variable = $this->betterNodeFinder->findVariableOfName((array) $constructClassMethod->stmts, $paramName);
|
$variable = $this->betterNodeFinder->findVariableOfName((array) $constructClassMethod->stmts, $paramName);
|
||||||
if ($variable instanceof Variable) {
|
if ($variable instanceof Variable) {
|
||||||
$param->flags = 0;
|
$param->flags = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if ($phpDocInfo instanceof PhpDocInfo) {
|
||||||
|
$paramTagValueNode = $phpDocInfo->getParamTagValueByName($paramName);
|
||||||
|
if ($paramTagValueNode instanceof ParamTagValueNode) {
|
||||||
|
$this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $paramTagValueNode);
|
||||||
|
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($constructClassMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
// remove param
|
// remove param
|
||||||
unset($constructClassMethod->params[$key]);
|
unset($constructClassMethod->params[$key]);
|
||||||
$hasChanged = \true;
|
|
||||||
}
|
}
|
||||||
if ($hasChanged) {
|
if ($hasChanged) {
|
||||||
return $node;
|
return $node;
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace Rector\DeadCode\Rector\ClassMethod;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Name\FullyQualified;
|
||||||
|
use PhpParser\Node\Stmt\Class_;
|
||||||
|
use PhpParser\Node\Stmt\ClassMethod;
|
||||||
|
use Rector\DeadCode\NodeManipulator\ClassMethodParamRemover;
|
||||||
|
use Rector\DeadCode\NodeManipulator\VariadicFunctionLikeDetector;
|
||||||
|
use Rector\NodeAnalyzer\MagicClassMethodAnalyzer;
|
||||||
|
use Rector\Rector\AbstractRector;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
|
/**
|
||||||
|
* @see \Rector\Tests\DeadCode\Rector\ClassMethod\RemoveUnusedPublicMethodParameterRector\RemoveUnusedPublicMethodParameterRectorTest
|
||||||
|
*/
|
||||||
|
final class RemoveUnusedPublicMethodParameterRector extends AbstractRector
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\DeadCode\NodeManipulator\VariadicFunctionLikeDetector
|
||||||
|
*/
|
||||||
|
private $variadicFunctionLikeDetector;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\DeadCode\NodeManipulator\ClassMethodParamRemover
|
||||||
|
*/
|
||||||
|
private $classMethodParamRemover;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\NodeAnalyzer\MagicClassMethodAnalyzer
|
||||||
|
*/
|
||||||
|
private $magicClassMethodAnalyzer;
|
||||||
|
public function __construct(VariadicFunctionLikeDetector $variadicFunctionLikeDetector, ClassMethodParamRemover $classMethodParamRemover, MagicClassMethodAnalyzer $magicClassMethodAnalyzer)
|
||||||
|
{
|
||||||
|
$this->variadicFunctionLikeDetector = $variadicFunctionLikeDetector;
|
||||||
|
$this->classMethodParamRemover = $classMethodParamRemover;
|
||||||
|
$this->magicClassMethodAnalyzer = $magicClassMethodAnalyzer;
|
||||||
|
}
|
||||||
|
public function getRuleDefinition() : RuleDefinition
|
||||||
|
{
|
||||||
|
return new RuleDefinition('Remove unused parameter in public method on final class without extends and interface', [new CodeSample(<<<'CODE_SAMPLE'
|
||||||
|
final class SomeClass
|
||||||
|
{
|
||||||
|
public function run($a, $b)
|
||||||
|
{
|
||||||
|
echo $a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
, <<<'CODE_SAMPLE'
|
||||||
|
final class SomeClass
|
||||||
|
{
|
||||||
|
public function run($a)
|
||||||
|
{
|
||||||
|
echo $a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
)]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return array<class-string<Node>>
|
||||||
|
*/
|
||||||
|
public function getNodeTypes() : array
|
||||||
|
{
|
||||||
|
return [Class_::class];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param Class_ $node
|
||||||
|
*/
|
||||||
|
public function refactor(Node $node) : ?Node
|
||||||
|
{
|
||||||
|
// may has child, or override parent that needs follow signature
|
||||||
|
if (!$node->isFinal() || $node->extends instanceof FullyQualified || $node->implements !== []) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$hasChanged = \false;
|
||||||
|
foreach ($node->getMethods() as $classMethod) {
|
||||||
|
if (!$classMethod->isPublic()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($classMethod->params === []) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($this->magicClassMethodAnalyzer->isUnsafeOverridden($classMethod)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($this->variadicFunctionLikeDetector->isVariadic($classMethod)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$changedMethod = $this->classMethodParamRemover->processRemoveParams($classMethod);
|
||||||
|
if (!$changedMethod instanceof ClassMethod) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$hasChanged = \true;
|
||||||
|
}
|
||||||
|
if ($hasChanged) {
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
87
rules/DeadCode/Rector/If_/ReduceAlwaysFalseIfOrRector.php
Normal file
87
rules/DeadCode/Rector/If_/ReduceAlwaysFalseIfOrRector.php
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace Rector\DeadCode\Rector\If_;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
|
||||||
|
use PhpParser\Node\Stmt\If_;
|
||||||
|
use PHPStan\Type\Constant\ConstantBooleanType;
|
||||||
|
use Rector\DeadCode\NodeAnalyzer\SafeLeftTypeBooleanAndOrAnalyzer;
|
||||||
|
use Rector\Rector\AbstractRector;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
|
/**
|
||||||
|
* @see \Rector\Tests\DeadCode\Rector\If_\ReduceAlwaysFalseIfOrRector\ReduceAlwaysFalseIfOrRectorTest
|
||||||
|
*/
|
||||||
|
final class ReduceAlwaysFalseIfOrRector extends AbstractRector
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\DeadCode\NodeAnalyzer\SafeLeftTypeBooleanAndOrAnalyzer
|
||||||
|
*/
|
||||||
|
private $safeLeftTypeBooleanAndOrAnalyzer;
|
||||||
|
public function __construct(SafeLeftTypeBooleanAndOrAnalyzer $safeLeftTypeBooleanAndOrAnalyzer)
|
||||||
|
{
|
||||||
|
$this->safeLeftTypeBooleanAndOrAnalyzer = $safeLeftTypeBooleanAndOrAnalyzer;
|
||||||
|
}
|
||||||
|
public function getRuleDefinition() : RuleDefinition
|
||||||
|
{
|
||||||
|
return new RuleDefinition('Reduce always false in a if ( || ) condition', [new CodeSample(<<<'CODE_SAMPLE'
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run(int $number)
|
||||||
|
{
|
||||||
|
if (! is_int($number) || $number > 50) {
|
||||||
|
return 'yes';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'no';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
, <<<'CODE_SAMPLE'
|
||||||
|
class SomeClass
|
||||||
|
{
|
||||||
|
public function run(int $number)
|
||||||
|
{
|
||||||
|
if ($number > 50) {
|
||||||
|
return 'yes';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'no';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
)]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return array<class-string<Node>>
|
||||||
|
*/
|
||||||
|
public function getNodeTypes() : array
|
||||||
|
{
|
||||||
|
return [If_::class];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param If_ $node
|
||||||
|
*/
|
||||||
|
public function refactor(Node $node) : ?Node
|
||||||
|
{
|
||||||
|
if (!$node->cond instanceof BooleanOr) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$booleanOr = $node->cond;
|
||||||
|
$conditionStaticType = $this->getType($booleanOr->left);
|
||||||
|
if (!$conditionStaticType instanceof ConstantBooleanType) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ($conditionStaticType->getValue()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!$this->safeLeftTypeBooleanAndOrAnalyzer->isSafe($booleanOr)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$node->cond = $booleanOr->right;
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,9 @@ namespace Rector\DeadCode\Rector\If_;
|
||||||
|
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr;
|
use PhpParser\Node\Expr;
|
||||||
|
use PhpParser\Node\Expr\ArrayDimFetch;
|
||||||
use PhpParser\Node\Expr\Assign;
|
use PhpParser\Node\Expr\Assign;
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
|
||||||
use PhpParser\Node\Expr\PropertyFetch;
|
use PhpParser\Node\Expr\PropertyFetch;
|
||||||
use PhpParser\Node\Expr\StaticPropertyFetch;
|
use PhpParser\Node\Expr\StaticPropertyFetch;
|
||||||
use PhpParser\Node\Expr\Variable;
|
use PhpParser\Node\Expr\Variable;
|
||||||
|
@ -13,12 +15,11 @@ use PhpParser\Node\Stmt;
|
||||||
use PhpParser\Node\Stmt\Else_;
|
use PhpParser\Node\Stmt\Else_;
|
||||||
use PhpParser\Node\Stmt\If_;
|
use PhpParser\Node\Stmt\If_;
|
||||||
use PhpParser\NodeTraverser;
|
use PhpParser\NodeTraverser;
|
||||||
use PHPStan\Reflection\ClassReflection;
|
|
||||||
use PHPStan\Type\Constant\ConstantBooleanType;
|
use PHPStan\Type\Constant\ConstantBooleanType;
|
||||||
|
use Rector\DeadCode\NodeAnalyzer\SafeLeftTypeBooleanAndOrAnalyzer;
|
||||||
use Rector\NodeAnalyzer\ExprAnalyzer;
|
use Rector\NodeAnalyzer\ExprAnalyzer;
|
||||||
use Rector\PhpParser\Node\BetterNodeFinder;
|
use Rector\PhpParser\Node\BetterNodeFinder;
|
||||||
use Rector\Rector\AbstractRector;
|
use Rector\Rector\AbstractRector;
|
||||||
use Rector\Reflection\ReflectionResolver;
|
|
||||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
/**
|
/**
|
||||||
|
@ -26,11 +27,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
*/
|
*/
|
||||||
final class RemoveAlwaysTrueIfConditionRector extends AbstractRector
|
final class RemoveAlwaysTrueIfConditionRector extends AbstractRector
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @readonly
|
|
||||||
* @var \Rector\Reflection\ReflectionResolver
|
|
||||||
*/
|
|
||||||
private $reflectionResolver;
|
|
||||||
/**
|
/**
|
||||||
* @readonly
|
* @readonly
|
||||||
* @var \Rector\NodeAnalyzer\ExprAnalyzer
|
* @var \Rector\NodeAnalyzer\ExprAnalyzer
|
||||||
|
@ -41,11 +37,16 @@ final class RemoveAlwaysTrueIfConditionRector extends AbstractRector
|
||||||
* @var \Rector\PhpParser\Node\BetterNodeFinder
|
* @var \Rector\PhpParser\Node\BetterNodeFinder
|
||||||
*/
|
*/
|
||||||
private $betterNodeFinder;
|
private $betterNodeFinder;
|
||||||
public function __construct(ReflectionResolver $reflectionResolver, ExprAnalyzer $exprAnalyzer, BetterNodeFinder $betterNodeFinder)
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\DeadCode\NodeAnalyzer\SafeLeftTypeBooleanAndOrAnalyzer
|
||||||
|
*/
|
||||||
|
private $safeLeftTypeBooleanAndOrAnalyzer;
|
||||||
|
public function __construct(ExprAnalyzer $exprAnalyzer, BetterNodeFinder $betterNodeFinder, SafeLeftTypeBooleanAndOrAnalyzer $safeLeftTypeBooleanAndOrAnalyzer)
|
||||||
{
|
{
|
||||||
$this->reflectionResolver = $reflectionResolver;
|
|
||||||
$this->exprAnalyzer = $exprAnalyzer;
|
$this->exprAnalyzer = $exprAnalyzer;
|
||||||
$this->betterNodeFinder = $betterNodeFinder;
|
$this->betterNodeFinder = $betterNodeFinder;
|
||||||
|
$this->safeLeftTypeBooleanAndOrAnalyzer = $safeLeftTypeBooleanAndOrAnalyzer;
|
||||||
}
|
}
|
||||||
public function getRuleDefinition() : RuleDefinition
|
public function getRuleDefinition() : RuleDefinition
|
||||||
{
|
{
|
||||||
|
@ -84,10 +85,13 @@ CODE_SAMPLE
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param If_ $node
|
* @param If_ $node
|
||||||
* @return int|null|Stmt[]
|
* @return int|null|Stmt[]|If_
|
||||||
*/
|
*/
|
||||||
public function refactor(Node $node)
|
public function refactor(Node $node)
|
||||||
{
|
{
|
||||||
|
if ($node->cond instanceof BooleanAnd) {
|
||||||
|
return $this->refactorIfWithBooleanAnd($node);
|
||||||
|
}
|
||||||
if ($node->else instanceof Else_) {
|
if ($node->else instanceof Else_) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -102,7 +106,7 @@ CODE_SAMPLE
|
||||||
if (!$conditionStaticType->getValue()) {
|
if (!$conditionStaticType->getValue()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if ($this->shouldSkipPropertyFetch($node->cond)) {
|
if ($this->shouldSkipExpr($node->cond)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if ($this->shouldSkipFromParam($node->cond)) {
|
if ($this->shouldSkipFromParam($node->cond)) {
|
||||||
|
@ -128,25 +132,27 @@ CODE_SAMPLE
|
||||||
}
|
}
|
||||||
return \false;
|
return \false;
|
||||||
}
|
}
|
||||||
private function shouldSkipPropertyFetch(Expr $expr) : bool
|
private function shouldSkipExpr(Expr $expr) : bool
|
||||||
{
|
{
|
||||||
/** @var PropertyFetch[]|StaticPropertyFetch[] $propertyFetches */
|
return (bool) $this->betterNodeFinder->findInstancesOf($expr, [PropertyFetch::class, StaticPropertyFetch::class, ArrayDimFetch::class]);
|
||||||
$propertyFetches = $this->betterNodeFinder->findInstancesOf($expr, [PropertyFetch::class, StaticPropertyFetch::class]);
|
}
|
||||||
foreach ($propertyFetches as $propertyFetch) {
|
private function refactorIfWithBooleanAnd(If_ $if) : ?If_
|
||||||
$classReflection = $this->reflectionResolver->resolveClassReflectionSourceObject($propertyFetch);
|
{
|
||||||
if (!$classReflection instanceof ClassReflection) {
|
if (!$if->cond instanceof BooleanAnd) {
|
||||||
// cannot get parent Trait_ from Property Fetch
|
return null;
|
||||||
return \true;
|
|
||||||
}
|
|
||||||
$propertyName = (string) $this->nodeNameResolver->getName($propertyFetch);
|
|
||||||
if (!$classReflection->hasNativeProperty($propertyName)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$nativeProperty = $classReflection->getNativeProperty($propertyName);
|
|
||||||
if (!$nativeProperty->hasNativeType()) {
|
|
||||||
return \true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return \false;
|
$booleanAnd = $if->cond;
|
||||||
|
$leftType = $this->getType($booleanAnd->left);
|
||||||
|
if (!$leftType instanceof ConstantBooleanType) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!$leftType->getValue()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!$this->safeLeftTypeBooleanAndOrAnalyzer->isSafe($booleanAnd)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$if->cond = $booleanAnd->right;
|
||||||
|
return $if;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace Rector\DeadCode\Rector\If_;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr;
|
use PhpParser\Node\Expr;
|
||||||
use PhpParser\Node\Expr\Assign;
|
use PhpParser\Node\Expr\Assign;
|
||||||
|
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
|
||||||
use PhpParser\Node\Expr\BooleanNot;
|
use PhpParser\Node\Expr\BooleanNot;
|
||||||
use PhpParser\Node\Expr\CallLike;
|
use PhpParser\Node\Expr\CallLike;
|
||||||
use PhpParser\Node\Expr\Instanceof_;
|
use PhpParser\Node\Expr\Instanceof_;
|
||||||
|
@ -16,9 +17,11 @@ use PhpParser\Node\Stmt;
|
||||||
use PhpParser\Node\Stmt\Expression;
|
use PhpParser\Node\Stmt\Expression;
|
||||||
use PhpParser\Node\Stmt\If_;
|
use PhpParser\Node\Stmt\If_;
|
||||||
use PhpParser\NodeTraverser;
|
use PhpParser\NodeTraverser;
|
||||||
|
use PHPStan\Reflection\ClassReflection;
|
||||||
use PHPStan\Type\MixedType;
|
use PHPStan\Type\MixedType;
|
||||||
use Rector\NodeManipulator\IfManipulator;
|
use Rector\NodeManipulator\IfManipulator;
|
||||||
use Rector\Rector\AbstractRector;
|
use Rector\Rector\AbstractRector;
|
||||||
|
use Rector\Reflection\ReflectionResolver;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
/**
|
/**
|
||||||
|
@ -31,9 +34,15 @@ final class RemoveDeadInstanceOfRector extends AbstractRector
|
||||||
* @var \Rector\NodeManipulator\IfManipulator
|
* @var \Rector\NodeManipulator\IfManipulator
|
||||||
*/
|
*/
|
||||||
private $ifManipulator;
|
private $ifManipulator;
|
||||||
public function __construct(IfManipulator $ifManipulator)
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\Reflection\ReflectionResolver
|
||||||
|
*/
|
||||||
|
private $reflectionResolver;
|
||||||
|
public function __construct(IfManipulator $ifManipulator, ReflectionResolver $reflectionResolver)
|
||||||
{
|
{
|
||||||
$this->ifManipulator = $ifManipulator;
|
$this->ifManipulator = $ifManipulator;
|
||||||
|
$this->reflectionResolver = $reflectionResolver;
|
||||||
}
|
}
|
||||||
public function getRuleDefinition() : RuleDefinition
|
public function getRuleDefinition() : RuleDefinition
|
||||||
{
|
{
|
||||||
|
@ -64,7 +73,7 @@ CODE_SAMPLE
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param If_ $node
|
* @param If_ $node
|
||||||
* @return Stmt[]|null|int
|
* @return Stmt[]|null|int|If_
|
||||||
*/
|
*/
|
||||||
public function refactor(Node $node)
|
public function refactor(Node $node)
|
||||||
{
|
{
|
||||||
|
@ -74,6 +83,9 @@ CODE_SAMPLE
|
||||||
if ($node->cond instanceof BooleanNot && $node->cond->expr instanceof Instanceof_) {
|
if ($node->cond instanceof BooleanNot && $node->cond->expr instanceof Instanceof_) {
|
||||||
return $this->refactorStmtAndInstanceof($node, $node->cond->expr);
|
return $this->refactorStmtAndInstanceof($node, $node->cond->expr);
|
||||||
}
|
}
|
||||||
|
if ($node->cond instanceof BooleanAnd) {
|
||||||
|
return $this->refactorIfWithBooleanAnd($node);
|
||||||
|
}
|
||||||
if ($node->cond instanceof Instanceof_) {
|
if ($node->cond instanceof Instanceof_) {
|
||||||
return $this->refactorStmtAndInstanceof($node, $node->cond);
|
return $this->refactorStmtAndInstanceof($node, $node->cond);
|
||||||
}
|
}
|
||||||
|
@ -84,17 +96,7 @@ CODE_SAMPLE
|
||||||
*/
|
*/
|
||||||
private function refactorStmtAndInstanceof(If_ $if, Instanceof_ $instanceof)
|
private function refactorStmtAndInstanceof(If_ $if, Instanceof_ $instanceof)
|
||||||
{
|
{
|
||||||
if (!$instanceof->class instanceof Name) {
|
if ($this->isInstanceofTheSameType($instanceof) !== \true) {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// handle in another rule
|
|
||||||
if ($this->isPropertyFetch($instanceof->expr) || $instanceof->expr instanceof CallLike) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$classType = $this->nodeTypeResolver->getType($instanceof->class);
|
|
||||||
$exprType = $this->nodeTypeResolver->getType($instanceof->expr);
|
|
||||||
$isSameStaticTypeOrSubtype = $classType->equals($exprType) || $classType->isSuperTypeOf($exprType)->yes();
|
|
||||||
if (!$isSameStaticTypeOrSubtype) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if ($this->shouldSkipFromNotTypedParam($instanceof)) {
|
if ($this->shouldSkipFromNotTypedParam($instanceof)) {
|
||||||
|
@ -125,4 +127,40 @@ CODE_SAMPLE
|
||||||
}
|
}
|
||||||
return $expr instanceof StaticPropertyFetch;
|
return $expr instanceof StaticPropertyFetch;
|
||||||
}
|
}
|
||||||
|
private function isInstanceofTheSameType(Instanceof_ $instanceof) : ?bool
|
||||||
|
{
|
||||||
|
if (!$instanceof->class instanceof Name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// handled in another rule
|
||||||
|
if ($this->isPropertyFetch($instanceof->expr) || $instanceof->expr instanceof CallLike) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$classReflection = $this->reflectionResolver->resolveClassReflection($instanceof);
|
||||||
|
if ($classReflection instanceof ClassReflection && $classReflection->isTrait()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$classType = $this->nodeTypeResolver->getType($instanceof->class);
|
||||||
|
$exprType = $this->nodeTypeResolver->getNativeType($instanceof->expr);
|
||||||
|
if ($classType->equals($exprType)) {
|
||||||
|
return \true;
|
||||||
|
}
|
||||||
|
return $classType->isSuperTypeOf($exprType)->yes();
|
||||||
|
}
|
||||||
|
private function refactorIfWithBooleanAnd(If_ $if) : ?\PhpParser\Node\Stmt\If_
|
||||||
|
{
|
||||||
|
if (!$if->cond instanceof BooleanAnd) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$booleanAnd = $if->cond;
|
||||||
|
if (!$booleanAnd->left instanceof Instanceof_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$instanceof = $booleanAnd->left;
|
||||||
|
if ($this->isInstanceofTheSameType($instanceof) !== \true) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$if->cond = $booleanAnd->right;
|
||||||
|
return $if;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare (strict_types=1);
|
||||||
|
namespace Rector\DeadCode\Rector\Property;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Param;
|
||||||
|
use PhpParser\Node\Stmt\Class_;
|
||||||
|
use PhpParser\Node\Stmt\Property;
|
||||||
|
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
|
||||||
|
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||||
|
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||||
|
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
|
||||||
|
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
|
||||||
|
use Rector\Rector\AbstractRector;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||||
|
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||||
|
/**
|
||||||
|
* @see \Rector\Tests\DeadCode\Rector\Property\RemoveUselessReadOnlyTagRector\RemoveUselessReadOnlyTagRectorTest
|
||||||
|
*/
|
||||||
|
final class RemoveUselessReadOnlyTagRector extends AbstractRector
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\Privatization\NodeManipulator\VisibilityManipulator
|
||||||
|
*/
|
||||||
|
private $visibilityManipulator;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory
|
||||||
|
*/
|
||||||
|
private $phpDocInfoFactory;
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @var \Rector\Comments\NodeDocBlock\DocBlockUpdater
|
||||||
|
*/
|
||||||
|
private $docBlockUpdater;
|
||||||
|
public function __construct(VisibilityManipulator $visibilityManipulator, PhpDocInfoFactory $phpDocInfoFactory, DocBlockUpdater $docBlockUpdater)
|
||||||
|
{
|
||||||
|
$this->visibilityManipulator = $visibilityManipulator;
|
||||||
|
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||||
|
$this->docBlockUpdater = $docBlockUpdater;
|
||||||
|
}
|
||||||
|
public function getRuleDefinition() : RuleDefinition
|
||||||
|
{
|
||||||
|
return new RuleDefinition('Remove useless @readonly annotation on native readonly type', [new CodeSample(<<<'CODE_SAMPLE'
|
||||||
|
final class SomeClass
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
private readonly string $name;
|
||||||
|
|
||||||
|
public function __construct(string $name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
, <<<'CODE_SAMPLE'
|
||||||
|
final class SomeClass
|
||||||
|
{
|
||||||
|
private readonly string $name;
|
||||||
|
|
||||||
|
public function __construct(string $name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODE_SAMPLE
|
||||||
|
)]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return array<class-string<Node>>
|
||||||
|
*/
|
||||||
|
public function getNodeTypes() : array
|
||||||
|
{
|
||||||
|
return [Class_::class, Property::class, Param::class];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param Class_|Property|Param $node
|
||||||
|
*/
|
||||||
|
public function refactor(Node $node) : ?Node
|
||||||
|
{
|
||||||
|
// for param, only on property promotion
|
||||||
|
if ($node instanceof Param && $node->flags === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!$this->visibilityManipulator->isReadonly($node)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||||
|
$readonlyDoc = $phpDocInfo->getByName('readonly');
|
||||||
|
if (!$readonlyDoc instanceof PhpDocTagNode) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!$readonlyDoc->value instanceof GenericTagValueNode) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ($readonlyDoc->value->value !== '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$phpDocInfo->removeByName('readonly');
|
||||||
|
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node);
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
declare (strict_types=1);
|
declare (strict_types=1);
|
||||||
namespace Rector\DeadCode\SideEffect;
|
namespace Rector\DeadCode\SideEffect;
|
||||||
|
|
||||||
use RectorPrefix202403\Nette\Utils\Strings;
|
use RectorPrefix202406\Nette\Utils\Strings;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr;
|
use PhpParser\Node\Expr;
|
||||||
use PhpParser\Node\Expr\ArrayDimFetch;
|
use PhpParser\Node\Expr\ArrayDimFetch;
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace Rector\EarlyReturn\Rector\Return_;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Expr;
|
use PhpParser\Node\Expr;
|
||||||
use PhpParser\Node\Expr\Assign;
|
use PhpParser\Node\Expr\Assign;
|
||||||
|
use PhpParser\Node\Expr\AssignOp;
|
||||||
use PhpParser\Node\Expr\Variable;
|
use PhpParser\Node\Expr\Variable;
|
||||||
use PhpParser\Node\Stmt;
|
use PhpParser\Node\Stmt;
|
||||||
use PhpParser\Node\Stmt\Expression;
|
use PhpParser\Node\Stmt\Expression;
|
||||||
|
@ -98,6 +99,9 @@ CODE_SAMPLE
|
||||||
$initialAssign = null;
|
$initialAssign = null;
|
||||||
$initialAssignPosition = null;
|
$initialAssignPosition = null;
|
||||||
foreach ($node->stmts as $key => $stmt) {
|
foreach ($node->stmts as $key => $stmt) {
|
||||||
|
if ($stmt instanceof Expression && $stmt->expr instanceof AssignOp) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if ($stmt instanceof If_) {
|
if ($stmt instanceof If_) {
|
||||||
$ifs[$key] = $stmt;
|
$ifs[$key] = $stmt;
|
||||||
continue;
|
continue;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user