Updated Rector to commit 074b1781b3fa7c7e23470c57ab85c0bd5fe0bfd2

074b1781b3 Remove RemoveUnusedVariableAssignRector, as could be breaking code in order of excution and hard to do reliable (#3793)
This commit is contained in:
Tomas Votruba 2023-05-11 07:56:32 +00:00
parent 34a9ea6ade
commit 8afa5f961e
51 changed files with 253 additions and 371 deletions

View File

@ -5,7 +5,6 @@ namespace RectorPrefix202305;
use Rector\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector;
use Rector\CodeQuality\Rector\Assign\CombinedAssignRector;
use Rector\CodeQuality\Rector\Assign\SplitListAssignToSeparateLineRector;
use Rector\CodeQuality\Rector\BooleanAnd\SimplifyEmptyArrayCheckRector;
use Rector\CodeQuality\Rector\BooleanNot\ReplaceMultipleBooleanNotRector;
use Rector\CodeQuality\Rector\BooleanNot\SimplifyDeMorganBinaryRector;
@ -115,5 +114,5 @@ return static function (RectorConfig $rectorConfig) : void {
'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, SimplifyForeachToArrayFilterRector::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, RemoveAlwaysTrueConditionSetInConstructorRector::class, ThrowWithPreviousExceptionRector::class, RemoveSoleValueSprintfRector::class, ShortenElseIfRector::class, AddPregQuoteDelimiterRector::class, ArrayMergeOfNonArraysToSimpleArrayRector::class, IntvalToTypeCastRector::class, BoolvalToTypeCastRector::class, ArrayKeyExistsTernaryThenValueToCoalescingRector::class, AbsolutizeRequireAndIncludePathRector::class, ChangeArrayPushToArrayAssignRector::class, ForRepeatedCountToOwnVariableRector::class, ForeachItemsAssignToEmptyArrayToAssignRector::class, InlineIfToExplicitIfRector::class, ArrayKeysAndInArrayToArrayKeyExistsRector::class, SplitListAssignToSeparateLineRector::class, UnusedForeachValueToArrayKeysRector::class, CommonNotEqualRector::class, SetTypeToCastRector::class, LogicalToBooleanRector::class, VarToPublicPropertyRector::class, IssetOnPropertyObjectToPropertyExistsRector::class, NewStaticToNewSelfRector::class, UnwrapSprintfOneArgumentRector::class, SwitchNegatedTernaryRector::class, SingularSwitchToIfRector::class, SimplifyIfNullableReturnRector::class, NarrowUnionTypeDocRector::class, FuncGetArgsToVariadicParamRector::class, CallUserFuncToMethodCallRector::class, CallUserFuncWithArrowFunctionToInlineRector::class, CountArrayToEmptyArrayComparisonRector::class, FlipTypeControlToUseExclusiveTypeRector::class, ExplicitMethodCallOverMagicGetSetRector::class, InlineArrayReturnAssignRector::class, InlineIsAInstanceOfRector::class, TernaryFalseExpressionToIfRector::class, InlineConstructorDefaultToPropertyRector::class, ReturnTypeFromStrictScalarReturnExprRector::class, TernaryEmptyArrayArrayDimFetchToCoalesceRector::class, OptionalParametersAfterRequiredRector::class, SimplifyEmptyCheckOnEmptyArrayRector::class, SwitchTrueToIfRector::class, CleanupUnneededNullsafeOperatorRector::class, MakeTypedPropertyNullableIfCheckedRector::class, RemoveFinalFromEntityRector::class, DisallowedEmptyRuleFixerRector::class]);
$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, SimplifyForeachToArrayFilterRector::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, RemoveAlwaysTrueConditionSetInConstructorRector::class, ThrowWithPreviousExceptionRector::class, RemoveSoleValueSprintfRector::class, ShortenElseIfRector::class, AddPregQuoteDelimiterRector::class, ArrayMergeOfNonArraysToSimpleArrayRector::class, IntvalToTypeCastRector::class, BoolvalToTypeCastRector::class, ArrayKeyExistsTernaryThenValueToCoalescingRector::class, AbsolutizeRequireAndIncludePathRector::class, ChangeArrayPushToArrayAssignRector::class, ForRepeatedCountToOwnVariableRector::class, ForeachItemsAssignToEmptyArrayToAssignRector::class, InlineIfToExplicitIfRector::class, ArrayKeysAndInArrayToArrayKeyExistsRector::class, UnusedForeachValueToArrayKeysRector::class, CommonNotEqualRector::class, SetTypeToCastRector::class, LogicalToBooleanRector::class, VarToPublicPropertyRector::class, IssetOnPropertyObjectToPropertyExistsRector::class, NewStaticToNewSelfRector::class, UnwrapSprintfOneArgumentRector::class, SwitchNegatedTernaryRector::class, SingularSwitchToIfRector::class, SimplifyIfNullableReturnRector::class, NarrowUnionTypeDocRector::class, FuncGetArgsToVariadicParamRector::class, CallUserFuncToMethodCallRector::class, CallUserFuncWithArrowFunctionToInlineRector::class, CountArrayToEmptyArrayComparisonRector::class, FlipTypeControlToUseExclusiveTypeRector::class, ExplicitMethodCallOverMagicGetSetRector::class, InlineArrayReturnAssignRector::class, InlineIsAInstanceOfRector::class, TernaryFalseExpressionToIfRector::class, InlineConstructorDefaultToPropertyRector::class, ReturnTypeFromStrictScalarReturnExprRector::class, TernaryEmptyArrayArrayDimFetchToCoalesceRector::class, OptionalParametersAfterRequiredRector::class, SimplifyEmptyCheckOnEmptyArrayRector::class, SwitchTrueToIfRector::class, CleanupUnneededNullsafeOperatorRector::class, MakeTypedPropertyNullableIfCheckedRector::class, RemoveFinalFromEntityRector::class, DisallowedEmptyRuleFixerRector::class]);
};

View File

@ -1,4 +1,4 @@
# 413 Rules Overview
# 412 Rules Overview
<br>
@ -6,7 +6,7 @@
- [Arguments](#arguments) (6)
- [CodeQuality](#codequality) (77)
- [CodeQuality](#codequality) (76)
- [CodingStyle](#codingstyle) (37)
@ -1612,26 +1612,6 @@ Change switch with only 1 check to if
<br>
### SplitListAssignToSeparateLineRector
Splits `[$a, $b] = [5, 10]` scalar assign to standalone lines
- class: [`Rector\CodeQuality\Rector\Assign\SplitListAssignToSeparateLineRector`](../rules/CodeQuality/Rector/Assign/SplitListAssignToSeparateLineRector.php)
```diff
final class SomeClass
{
public function run(): void
{
- [$a, $b] = [1, 2];
+ $a = 1;
+ $b = 2;
}
}
```
<br>
### StrlenZeroToIdenticalEmptyStringRector
Changes strlen comparison to 0 to direct empty string compare

View File

@ -1,128 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodeQuality\Rector\Assign;
use PhpParser\Node;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\List_;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://mobile.twitter.com/ivanhoe011/status/1246376872931401728
*
* @see \Rector\Tests\CodeQuality\Rector\Assign\SplitListAssignToSeparateLineRector\SplitListAssignToSeparateLineRectorTest
*/
final class SplitListAssignToSeparateLineRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Splits `[$a, $b] = [5, 10]` scalar assign to standalone lines', [new CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
public function run(): void
{
[$a, $b] = [1, 2];
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class SomeClass
{
public function run(): void
{
$a = 1;
$b = 2;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [Expression::class];
}
/**
* @param Expression $node
* @return Expression[]|null
*/
public function refactor(Node $node) : ?array
{
if (!$node->expr instanceof Assign) {
return null;
}
$assign = $node->expr;
if ($this->shouldSkipAssign($assign)) {
return null;
}
/** @var Array_|List_ $leftArray */
$leftArray = $assign->var;
/** @var Array_ $rightArray */
$rightArray = $assign->expr;
return $this->createStandaloneAssignExpressions($leftArray, $rightArray);
}
private function shouldSkipAssign(Assign $assign) : bool
{
if (!$assign->var instanceof Array_ && !$assign->var instanceof List_) {
return \true;
}
$assignExpr = $assign->expr;
if (!$assignExpr instanceof Array_) {
return \true;
}
if (\count($assign->var->items) !== \count($assignExpr->items)) {
return \true;
}
// is value swap
return $this->isValueSwap($assign->var, $assignExpr);
}
/**
* @return Expression[]
* @param \PhpParser\Node\Expr\Array_|\PhpParser\Node\Expr\List_ $expr
*/
private function createStandaloneAssignExpressions($expr, Array_ $rightArray) : array
{
$standaloneAssignExpresssions = [];
foreach ($expr->items as $key => $leftArrayItem) {
if (!$leftArrayItem instanceof ArrayItem) {
continue;
}
$rightArrayItem = $rightArray->items[$key];
if (!$rightArrayItem instanceof ArrayItem) {
continue;
}
$assign = new Assign($leftArrayItem->value, $rightArrayItem);
$standaloneAssignExpresssions[] = new Expression($assign);
}
return $standaloneAssignExpresssions;
}
/**
* @param \PhpParser\Node\Expr\Array_|\PhpParser\Node\Expr\List_ $expr
*/
private function isValueSwap($expr, Array_ $secondArray) : bool
{
$firstArrayItemsHash = $this->getArrayItemsHash($expr);
$secondArrayItemsHash = $this->getArrayItemsHash($secondArray);
return $firstArrayItemsHash === $secondArrayItemsHash;
}
/**
* @param \PhpParser\Node\Expr\Array_|\PhpParser\Node\Expr\List_ $node
*/
private function getArrayItemsHash($node) : string
{
$arrayItemsHashes = [];
foreach ($node->items as $arrayItem) {
$arrayItemsHashes[] = $this->nodeComparator->printWithoutComments($arrayItem);
}
\sort($arrayItemsHashes);
$arrayItemsHash = \implode('', $arrayItemsHashes);
return \sha1($arrayItemsHash);
}
}

View File

@ -23,7 +23,6 @@ use PHPStan\Type\ThisType;
use PHPStan\Type\TypeWithClassName;
use Rector\Core\NodeAnalyzer\CallAnalyzer;
use Rector\Core\PhpParser\AstResolver;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -138,10 +137,7 @@ CODE_SAMPLE
return \true;
}
$parentArg = $this->betterNodeFinder->findParentType($methodCall, Arg::class);
if ($parentArg instanceof Arg) {
return \true;
}
return \false;
return $parentArg instanceof Arg;
}
/**
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\Trait_|\PhpParser\Node\Stmt\Interface_|\PhpParser\Node\Stmt\Enum_ $classLike

View File

@ -15,13 +15,11 @@ use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\ObjectType;
use Rector\CodingStyle\ValueObject\ObjectMagicMethods;
use Rector\Core\Enum\ObjectReference;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeCollector\ScopeResolver\ParentClassScopeResolver;
use Rector\NodeCollector\StaticAnalyzer;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use ReflectionMethod;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;

View File

@ -12,7 +12,6 @@ use PhpParser\Node\Expr\Variable;
use PHPStan\Analyser\Scope;
use PHPStan\Type\ObjectType;
use PHPStan\Type\UnionType;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -127,7 +126,7 @@ CODE_SAMPLE
private function refactorMethodCall(MethodCall $methodCall, Scope $scope) : ?Node
{
$this->collectCallByVariable($methodCall);
if ($this->shouldSkipMethodCall($methodCall, $scope)) {
if ($this->shouldSkipMethodCall($methodCall)) {
return null;
}
if ($this->isReflectionParameterGetTypeMethodCall($methodCall)) {
@ -166,7 +165,7 @@ CODE_SAMPLE
$this->callsByVariable[$variableName][] = $methodName;
}
}
private function shouldSkipMethodCall(MethodCall $methodCall, Scope $scope) : bool
private function shouldSkipMethodCall(MethodCall $methodCall) : bool
{
// is to string retype?
$parentNode = $methodCall->getAttribute(AttributeKey::PARENT_NODE);

View File

@ -26,7 +26,6 @@ use Rector\Core\NodeAnalyzer\PropertyFetchAnalyzer;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'c63dd46e8d8881b576cee60ef09d68f52789a5ee';
public const PACKAGE_VERSION = '074b1781b3fa7c7e23470c57ab85c0bd5fe0bfd2';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2023-05-10 18:44:37';
public const RELEASE_DATE = '2023-05-11 08:51:41';
/**
* @var int
*/

View File

@ -239,39 +239,6 @@ CODE_SAMPLE;
}
return $this->postRefactorProcess($originalNode, $node, $refactoredNode);
}
/**
* @param \PhpParser\Node|mixed[] $refactoredNode
*/
private function postRefactorProcess(?\PhpParser\Node $originalNode, Node $node, $refactoredNode) : Node
{
$originalNode = $originalNode ?? $node;
/** @var non-empty-array<Node>|Node $refactoredNode */
$this->createdByRuleDecorator->decorate($refactoredNode, $originalNode, static::class);
$rectorWithLineChange = new RectorWithLineChange(static::class, $originalNode->getLine());
$this->file->addRectorClassWithLine($rectorWithLineChange);
$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
/** @var MutatingScope|null $currentScope */
$currentScope = $originalNode->getAttribute(AttributeKey::SCOPE);
$filePath = $this->file->getFilePath();
// search "infinite recursion" in https://github.com/nikic/PHP-Parser/blob/master/doc/component/Walking_the_AST.markdown
$originalNodeHash = \spl_object_hash($originalNode);
if (\is_array($refactoredNode)) {
$firstNode = \current($refactoredNode);
$this->mirrorComments($firstNode, $originalNode);
$this->updateParentNodes($refactoredNode, $parentNode);
$this->connectNodes($refactoredNode, $node);
$this->refreshScopeNodes($refactoredNode, $filePath, $currentScope);
$this->nodesToReturn[$originalNodeHash] = $refactoredNode;
// will be replaced in leaveNode() the original node must be passed
return $originalNode;
}
$refactoredNode = $originalNode instanceof Stmt && $refactoredNode instanceof Expr ? new Expression($refactoredNode) : $refactoredNode;
$this->updateParentNodes($refactoredNode, $parentNode);
$this->connectNodes([$refactoredNode], $node);
$this->refreshScopeNodes($refactoredNode, $filePath, $currentScope);
$this->nodesToReturn[$originalNodeHash] = $refactoredNode;
return $refactoredNode;
}
/**
* Replacing nodes in leaveNode() method avoids infinite recursion
* see"infinite recursion" in https://github.com/nikic/PHP-Parser/blob/master/doc/component/Walking_the_AST.markdown
@ -345,6 +312,39 @@ CODE_SAMPLE;
{
$this->nodeRemover->removeNode($node);
}
/**
* @param \PhpParser\Node|mixed[] $refactoredNode
*/
private function postRefactorProcess(?\PhpParser\Node $originalNode, Node $node, $refactoredNode) : Node
{
$originalNode = $originalNode ?? $node;
/** @var non-empty-array<Node>|Node $refactoredNode */
$this->createdByRuleDecorator->decorate($refactoredNode, $originalNode, static::class);
$rectorWithLineChange = new RectorWithLineChange(static::class, $originalNode->getLine());
$this->file->addRectorClassWithLine($rectorWithLineChange);
$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
/** @var MutatingScope|null $currentScope */
$currentScope = $originalNode->getAttribute(AttributeKey::SCOPE);
$filePath = $this->file->getFilePath();
// search "infinite recursion" in https://github.com/nikic/PHP-Parser/blob/master/doc/component/Walking_the_AST.markdown
$originalNodeHash = \spl_object_hash($originalNode);
if (\is_array($refactoredNode)) {
$firstNode = \current($refactoredNode);
$this->mirrorComments($firstNode, $originalNode);
$this->updateParentNodes($refactoredNode, $parentNode);
$this->connectNodes($refactoredNode, $node);
$this->refreshScopeNodes($refactoredNode, $filePath, $currentScope);
$this->nodesToReturn[$originalNodeHash] = $refactoredNode;
// will be replaced in leaveNode() the original node must be passed
return $originalNode;
}
$refactoredNode = $originalNode instanceof Stmt && $refactoredNode instanceof Expr ? new Expression($refactoredNode) : $refactoredNode;
$this->updateParentNodes($refactoredNode, $parentNode);
$this->connectNodes([$refactoredNode], $node);
$this->refreshScopeNodes($refactoredNode, $filePath, $currentScope);
$this->nodesToReturn[$originalNodeHash] = $refactoredNode;
return $refactoredNode;
}
/**
* @param mixed[]|\PhpParser\Node $node
*/

2
vendor/autoload.php vendored
View File

@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit35f66b22857a568b69cf172bed5dca4d::getLoader();
return ComposerAutoloaderInit998f735741fdf236a54d3791488b243e::getLoader();

View File

@ -1218,7 +1218,6 @@ return array(
'Rector\\CodeQuality\\NodeTypeGroup' => $baseDir . '/rules/CodeQuality/NodeTypeGroup.php',
'Rector\\CodeQuality\\Rector\\Array_\\CallableThisArrayToAnonymousFunctionRector' => $baseDir . '/rules/CodeQuality/Rector/Array_/CallableThisArrayToAnonymousFunctionRector.php',
'Rector\\CodeQuality\\Rector\\Assign\\CombinedAssignRector' => $baseDir . '/rules/CodeQuality/Rector/Assign/CombinedAssignRector.php',
'Rector\\CodeQuality\\Rector\\Assign\\SplitListAssignToSeparateLineRector' => $baseDir . '/rules/CodeQuality/Rector/Assign/SplitListAssignToSeparateLineRector.php',
'Rector\\CodeQuality\\Rector\\BooleanAnd\\SimplifyEmptyArrayCheckRector' => $baseDir . '/rules/CodeQuality/Rector/BooleanAnd/SimplifyEmptyArrayCheckRector.php',
'Rector\\CodeQuality\\Rector\\BooleanNot\\ReplaceMultipleBooleanNotRector' => $baseDir . '/rules/CodeQuality/Rector/BooleanNot/ReplaceMultipleBooleanNotRector.php',
'Rector\\CodeQuality\\Rector\\BooleanNot\\SimplifyDeMorganBinaryRector' => $baseDir . '/rules/CodeQuality/Rector/BooleanNot/SimplifyDeMorganBinaryRector.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit35f66b22857a568b69cf172bed5dca4d
class ComposerAutoloaderInit998f735741fdf236a54d3791488b243e
{
private static $loader;
@ -22,17 +22,17 @@ class ComposerAutoloaderInit35f66b22857a568b69cf172bed5dca4d
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit35f66b22857a568b69cf172bed5dca4d', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit998f735741fdf236a54d3791488b243e', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit35f66b22857a568b69cf172bed5dca4d', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit998f735741fdf236a54d3791488b243e', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit35f66b22857a568b69cf172bed5dca4d::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit998f735741fdf236a54d3791488b243e::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInit35f66b22857a568b69cf172bed5dca4d::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticInit998f735741fdf236a54d3791488b243e::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit35f66b22857a568b69cf172bed5dca4d
class ComposerStaticInit998f735741fdf236a54d3791488b243e
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -1460,7 +1460,6 @@ class ComposerStaticInit35f66b22857a568b69cf172bed5dca4d
'Rector\\CodeQuality\\NodeTypeGroup' => __DIR__ . '/../..' . '/rules/CodeQuality/NodeTypeGroup.php',
'Rector\\CodeQuality\\Rector\\Array_\\CallableThisArrayToAnonymousFunctionRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/Array_/CallableThisArrayToAnonymousFunctionRector.php',
'Rector\\CodeQuality\\Rector\\Assign\\CombinedAssignRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/Assign/CombinedAssignRector.php',
'Rector\\CodeQuality\\Rector\\Assign\\SplitListAssignToSeparateLineRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/Assign/SplitListAssignToSeparateLineRector.php',
'Rector\\CodeQuality\\Rector\\BooleanAnd\\SimplifyEmptyArrayCheckRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/BooleanAnd/SimplifyEmptyArrayCheckRector.php',
'Rector\\CodeQuality\\Rector\\BooleanNot\\ReplaceMultipleBooleanNotRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/BooleanNot/ReplaceMultipleBooleanNotRector.php',
'Rector\\CodeQuality\\Rector\\BooleanNot\\SimplifyDeMorganBinaryRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/BooleanNot/SimplifyDeMorganBinaryRector.php',
@ -3111,9 +3110,9 @@ class ComposerStaticInit35f66b22857a568b69cf172bed5dca4d
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit35f66b22857a568b69cf172bed5dca4d::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit35f66b22857a568b69cf172bed5dca4d::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit35f66b22857a568b69cf172bed5dca4d::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit998f735741fdf236a54d3791488b243e::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit998f735741fdf236a54d3791488b243e::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit998f735741fdf236a54d3791488b243e::$classMap;
}, null, ClassLoader::class);
}

View File

@ -2063,12 +2063,12 @@
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-symfony.git",
"reference": "7320d80f74951fb36a2b639c443a70d090d0f1a8"
"reference": "f3495684f149e48ec3eaa3273513acf83f9dfdf6"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/7320d80f74951fb36a2b639c443a70d090d0f1a8",
"reference": "7320d80f74951fb36a2b639c443a70d090d0f1a8",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/f3495684f149e48ec3eaa3273513acf83f9dfdf6",
"reference": "f3495684f149e48ec3eaa3273513acf83f9dfdf6",
"shasum": ""
},
"require": {
@ -2098,7 +2098,7 @@
"tomasvotruba\/type-coverage": "^0.0.9",
"tomasvotruba\/unused-public": "^0.0.34"
},
"time": "2023-05-05T09:52:35+00:00",
"time": "2023-05-11T07:50:29+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ namespace Rector\RectorInstaller;
*/
final class GeneratedConfig
{
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 03df9e3'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 3209c44'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 63d391e'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 7320d80'));
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 03df9e3'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 3209c44'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 63d391e'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main f349568'));
private function __construct()
{
}

View File

@ -19,6 +19,8 @@ return static function (RectorConfig $rectorConfig) : void {
'*/Source*/*',
'*/tests/*/Fixture*/Expected/*',
StringClassNameToClassConstantRector::class => [__DIR__ . '/config'],
// soon to be removed
\Rector\DeadCode\Rector\Assign\RemoveUnusedVariableAssignRector::class,
RenameForeachValueVariableToMatchMethodCallReturnTypeRector::class => [
// "data" => "datum" false positive
__DIR__ . '/src/Rector/ClassMethod/AddRouteAnnotationRector.php',

View File

@ -23,7 +23,7 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/pull/33775/files
* @changelog https://github.com/symfony/symfony/pull/33775/files
* @see \Rector\Symfony\Tests\Rector\ClassMethod\ConsoleExecuteReturnIntRector\ConsoleExecuteReturnIntRectorTest
*/
final class ConsoleExecuteReturnIntRector extends AbstractRector

View File

@ -17,8 +17,8 @@ use Rector\Symfony\Enum\SymfonyAnnotation;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html#method-annotation
* @see https://stackoverflow.com/questions/51171934/how-to-fix-symfony-3-4-route-and-method-deprecation
* @changelog https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html#method-annotation
* @changelog https://stackoverflow.com/questions/51171934/how-to-fix-symfony-3-4-route-and-method-deprecation
*
* @see \Rector\Symfony\Tests\Rector\ClassMethod\MergeMethodAnnotationToRouteAnnotationRector\MergeMethodAnnotationToRouteAnnotationRectorTest
*/

View File

@ -7,6 +7,7 @@ use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Attribute;
use PhpParser\Node\AttributeGroup;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\Variable;
@ -22,13 +23,14 @@ use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://symfony.com/blog/new-in-symfony-6-2-built-in-cache-security-template-and-doctrine-attributes
* @changelog https://symfony.com/blog/new-in-symfony-6-2-built-in-cache-security-template-and-doctrine-attributes
*
* @see \Rector\Symfony\Tests\Rector\ClassMethod\ParamConverterAttributeToMapEntityAttributeRector\ParamConverterAttributeToMapEntityAttributeRectorTest
*/
final class ParamConverterAttributeToMapEntityAttributeRector extends AbstractRector implements MinPhpVersionInterface
{
private const PARAM_CONVERTER_CLASS = 'Sensio\\Bundle\\FrameworkExtraBundle\\Configuration\\ParamConverter';
private const ENTITY_CLASS = 'Sensio\\Bundle\\FrameworkExtraBundle\\Configuration\\Entity';
private const MAP_ENTITY_CLASS = 'Symfony\\Bridge\\Doctrine\\Attribute\\MapEntity';
/**
* @readonly
@ -80,22 +82,21 @@ CODE_SAMPLE
}
public function refactor(Node $node) : ?Node
{
if (!$node instanceof ClassMethod || !$node->isPublic() || !$this->phpAttributeAnalyzer->hasPhpAttribute($node, self::PARAM_CONVERTER_CLASS)) {
if (!$node instanceof ClassMethod || !$node->isPublic() || !$this->phpAttributeAnalyzer->hasPhpAttributes($node, [self::PARAM_CONVERTER_CLASS, self::ENTITY_CLASS])) {
return null;
}
$this->refactorParamConverter($node);
return $node;
}
private function refactorParamConverter(ClassMethod $classMethod) : Node
private function refactorParamConverter(ClassMethod $classMethod) : void
{
foreach ($classMethod->attrGroups as $attrGroup) {
foreach ($attrGroup->attrs as $attr) {
if ($this->isName($attr, self::PARAM_CONVERTER_CLASS)) {
if ($this->isNames($attr, [self::PARAM_CONVERTER_CLASS, self::ENTITY_CLASS])) {
$this->refactorAttribute($classMethod, $attr);
}
}
}
return $classMethod;
}
private function refactorAttribute(ClassMethod $classMethod, Attribute $attribute) : void
{
@ -103,30 +104,24 @@ CODE_SAMPLE
return;
}
$optionsIndex = $this->getIndexForOptionsArg($attribute->args);
if (!$optionsIndex) {
$exprIndex = $this->getIndexForExprArg($attribute->args);
if (!$optionsIndex && !$exprIndex) {
return;
}
$name = $attribute->args[0]->value->value;
$mapping = $attribute->args[$optionsIndex]->value;
if (!$mapping instanceof Array_) {
return;
}
$newArguments = [];
$probablyEntity = \false;
foreach ($mapping->items as $item) {
if (!$item instanceof ArrayItem || !$item->key instanceof String_) {
continue;
}
if (\in_array($item->key->value, ['mapping', 'entity_manager'], \true)) {
$probablyEntity = \true;
}
$newArguments[] = new Arg($item->value, \false, \false, [], new Identifier($item->key->value));
}
if (!$probablyEntity) {
$exprValue = $attribute->args[$exprIndex]->value;
$newArguments = $this->getNewArguments($mapping, $exprValue);
if ($newArguments === []) {
return;
}
$this->removeNode($attribute->args[0]);
$this->removeNode($attribute->args[$optionsIndex]);
if ($optionsIndex) {
$this->removeNode($attribute->args[$optionsIndex]);
}
if ($exprIndex) {
$this->removeNode($attribute->args[$exprIndex]);
}
$attribute->args = \array_merge($attribute->args, $newArguments);
$attribute->name = new FullyQualified(self::MAP_ENTITY_CLASS);
$node = $attribute->getAttribute(AttributeKey::PARENT_NODE);
@ -135,6 +130,32 @@ CODE_SAMPLE
}
$this->addMapEntityAttribute($classMethod, $name, $node);
}
/**
* @return Arg[]
*/
private function getNewArguments(?Expr $mapping, ?Expr $exprValue) : array
{
$newArguments = [];
if ($mapping instanceof Array_) {
$probablyEntity = \false;
foreach ($mapping->items as $item) {
if (!$item instanceof ArrayItem || !$item->key instanceof String_) {
continue;
}
if (\in_array($item->key->value, ['mapping', 'entity_manager'], \true)) {
$probablyEntity = \true;
}
$newArguments[] = new Arg($item->value, \false, \false, [], new Identifier($item->key->value));
}
if (!$probablyEntity) {
return [];
}
}
if ($exprValue instanceof String_) {
$newArguments[] = new Arg($exprValue, \false, \false, [], new Identifier('expr'));
}
return $newArguments;
}
private function addMapEntityAttribute(ClassMethod $classMethod, string $variableName, AttributeGroup $attributeGroup) : void
{
foreach ($classMethod->params as $param) {
@ -159,4 +180,16 @@ CODE_SAMPLE
}
return null;
}
/**
* @param Arg[] $args
*/
private function getIndexForExprArg(array $args) : ?int
{
foreach ($args as $key => $arg) {
if ($arg->name instanceof Identifier && $arg->name->name === 'expr') {
return $key;
}
}
return null;
}
}

View File

@ -17,7 +17,7 @@ use RectorPrefix202305\Symfony\Component\String\UnicodeString;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/blob/3.4/UPGRADE-3.0.md#form
* @changelog https://github.com/symfony/symfony/blob/3.4/UPGRADE-3.0.md#form
*
* @see \Rector\Symfony\Tests\Rector\ClassMethod\RemoveDefaultGetBlockPrefixRector\RemoveDefaultGetBlockPrefixRectorTest
*/

View File

@ -11,7 +11,7 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html#route-annotation
* @changelog https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html#route-annotation
*
* @see \Rector\Symfony\Tests\Rector\ClassMethod\RemoveServiceFromSensioRouteRector\RemoveServiceFromSensioRouteRectorTest
*/

View File

@ -15,8 +15,8 @@ use Rector\Symfony\PhpDocNode\SymfonyRouteTagValueNodeFactory;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://medium.com/@nebkam/symfony-deprecated-route-and-method-annotations-4d5e1d34556a
* @see https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html#method-annotation
* @changelog https://medium.com/@nebkam/symfony-deprecated-route-and-method-annotations-4d5e1d34556a
* @changelog https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html#method-annotation
*
* @see \Rector\Symfony\Tests\Rector\ClassMethod\ReplaceSensioRouteAnnotationWithSymfonyRector\ReplaceSensioRouteAnnotationWithSymfonyRectorTest
*/

View File

@ -16,7 +16,7 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/pull/32937/files
* @changelog https://github.com/symfony/symfony/pull/32937/files
*
* @see \Rector\Symfony\Tests\Rector\ClassMethod\RouteCollectionBuilderToRoutingConfiguratorRector\RouteCollectionBuilderToRoutingConfiguratorRectorTest
*/

View File

@ -38,9 +38,9 @@ use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use RectorPrefix202305\Webmozart\Assert\Assert;
/**
* @see https://github.com/symfony/symfony-docs/pull/12387#discussion_r329551967
* @see https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/view.html
* @see https://github.com/sensiolabs/SensioFrameworkExtraBundle/issues/641
* @changelog https://github.com/symfony/symfony-docs/pull/12387#discussion_r329551967
* @changelog https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/view.html
* @changelog https://github.com/sensiolabs/SensioFrameworkExtraBundle/issues/641
*
* @see \Rector\Symfony\Tests\Rector\ClassMethod\TemplateAnnotationToThisRenderRector\TemplateAnnotationToThisRenderRectorTest
*/

View File

@ -18,7 +18,7 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://symfony.com/blog/new-in-symfony-5-3-lazy-command-description
* @changelog https://symfony.com/blog/new-in-symfony-5-3-lazy-command-description
*
* @see \Rector\Symfony\Tests\Rector\Class_\CommandDescriptionToPropertyRector\CommandDescriptionToPropertyRectorTest
*/

View File

@ -23,7 +23,7 @@ use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://symfony.com/doc/current/console.html#registering-the-command
* @changelog https://symfony.com/doc/current/console.html#registering-the-command
*
* @see \Rector\Symfony\Tests\Rector\Class_\CommandPropertyToAttributeRector\CommandPropertyToAttributeRectorTest
*/

View File

@ -35,7 +35,7 @@ final class EventListenerToEventSubscriberRector extends AbstractRector
private const CONSOLE_EVENTS_CLASS = 'Symfony\\Component\\Console\\ConsoleEvents';
/**
* @var string
* @see https://regex101.com/r/qiHZ4T/1
* @changelog https://regex101.com/r/qiHZ4T/1
*/
private const LISTENER_MATCH_REGEX = '#^(.*?)(Listener)?$#';
/**

View File

@ -25,7 +25,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*
* @see \Rector\Symfony\Tests\Rector\Class_\InvokableControllerRector\InvokableControllerRectorTest
*
* Inspiration @see https://github.com/rectorphp/rector-src/blob/main/rules/PSR4/Rector/Namespace_/MultipleClassFileToPsr4ClassesRector.php
* Inspiration @changelog https://github.com/rectorphp/rector-src/blob/main/rules/PSR4/Rector/Namespace_/MultipleClassFileToPsr4ClassesRector.php
*/
final class InvokableControllerRector extends AbstractRector
{

View File

@ -17,7 +17,7 @@ use Rector\Symfony\ValueObject\EventReferenceToMethodName;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/pull/36243
* @changelog https://github.com/symfony/symfony/pull/36243
*
* @see \Rector\Symfony\Tests\Rector\Class_\LogoutHandlerToLogoutEventSubscriberRector\LogoutHandlerToLogoutEventSubscriberRectorTest
*/

View File

@ -17,7 +17,7 @@ use Rector\Symfony\ValueObject\EventReferenceToMethodNameWithPriority;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/pull/36243
* @changelog https://github.com/symfony/symfony/pull/36243
*
* @see \Rector\Symfony\Tests\Rector\Class_\LogoutSuccessHandlerToLogoutEventSubscriberRector\LogoutSuccessHandlerToLogoutEventSubscriberRectorTest
*/

View File

@ -22,7 +22,7 @@ use Rector\Core\ValueObject\MethodName;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://symfony.com/doc/current/console/commands_as_services.html
* @changelog https://symfony.com/doc/current/console/commands_as_services.html
*
* @see \Rector\Symfony\Tests\Rector\Class_\MakeCommandLazyRector\MakeCommandLazyRectorTest
*/

View File

@ -4,12 +4,12 @@ declare (strict_types=1);
namespace Rector\Symfony\Rector\ConstFetch;
use PhpParser\Node;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Scalar\String_;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
@ -32,38 +32,41 @@ final class ConstraintUrlOptionRector extends AbstractRector
*/
public function getNodeTypes() : array
{
return [ConstFetch::class];
return [New_::class];
}
/**
* @param ConstFetch $node
* @param New_ $node
*/
public function refactor(Node $node) : ?Node
public function refactor(Node $node) : ?New_
{
if (!$this->valueResolver->isTrue($node)) {
if (!$this->isObjectType($node, new ObjectType('Symfony\\Component\\Validator\\Constraints\\Url'))) {
return null;
}
if (!$this->isInsideNewUrl($node)) {
return null;
foreach ($node->getArgs() as $arg) {
if (!$arg->value instanceof Array_) {
continue;
}
foreach ($arg->value->items as $arrayItem) {
if (!$arrayItem instanceof ArrayItem) {
continue;
}
if (!$this->isCheckDNSKey($arrayItem)) {
continue;
}
if (!$this->valueResolver->isTrue($arrayItem->value)) {
return null;
}
$arrayItem->value = $this->nodeFactory->createClassConstFetch(self::URL_CONSTRAINT_CLASS, 'CHECK_DNS_TYPE_ANY');
return $node;
}
}
$prevNode = $node->getAttribute(AttributeKey::PREVIOUS_NODE);
if (!$prevNode instanceof String_) {
return null;
}
if ($prevNode->value !== 'checkDNS') {
return null;
}
return $this->nodeFactory->createClassConstFetch(self::URL_CONSTRAINT_CLASS, 'CHECK_DNS_TYPE_ANY');
return null;
}
private function isInsideNewUrl(ConstFetch $constFetch) : bool
private function isCheckDNSKey(ArrayItem $arrayItem) : bool
{
$new = $this->betterNodeFinder->findParentType($constFetch, New_::class);
if (!$new instanceof New_) {
if (!$arrayItem->key instanceof Expr) {
return \false;
}
$newType = $this->getType($new);
if (!$newType instanceof TypeWithClassName) {
return \false;
}
return $newType->getClassName() === self::URL_CONSTRAINT_CLASS;
return $this->valueResolver->isValue($arrayItem->key, 'checkDNS');
}
}

View File

@ -15,7 +15,7 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://stackoverflow.com/questions/25264922/symfony-2-5-addviolationat-deprecated-use-buildviolation
* @changelog https://stackoverflow.com/questions/25264922/symfony-2-5-addviolationat-deprecated-use-buildviolation
* @see \Rector\Symfony\Tests\Rector\MethodCall\AddViolationToBuildViolationRector\AddViolationToBuildViolationRectorTest
*/
final class AddViolationToBuildViolationRector extends AbstractRector

View File

@ -15,7 +15,7 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/blob/4.4/UPGRADE-4.4.md#security
* @changelog https://github.com/symfony/symfony/blob/4.4/UPGRADE-4.4.md#security
* @see \Rector\Symfony\Tests\Rector\MethodCall\AuthorizationCheckerIsGrantedExtractorRector\AuthorizationCheckerIsGrantedExtractorRectorTest
*/
final class AuthorizationCheckerIsGrantedExtractorRector extends AbstractRector

View File

@ -16,7 +16,7 @@ use Rector\Symfony\NodeAnalyzer\FormOptionsArrayMatcher;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.8.md#form
* @changelog https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.8.md#form
*
* @see \Rector\Symfony\Tests\Rector\MethodCall\ChangeCollectionTypeOptionNameFromTypeToEntryTypeRector\ChangeCollectionTypeOptionNameFromTypeToEntryTypeRectorTest
*/

View File

@ -17,9 +17,9 @@ use Rector\Symfony\NodeAnalyzer\FormOptionsArrayMatcher;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://symfony.com/doc/2.8/form/form_collections.html
* @see https://symfony.com/doc/3.0/form/form_collections.html
* @see https://symfony2-document.readthedocs.io/en/latest/reference/forms/types/collection.html#type
* @changelog https://symfony.com/doc/2.8/form/form_collections.html
* @changelog https://symfony.com/doc/3.0/form/form_collections.html
* @changelog https://symfony2-document.readthedocs.io/en/latest/reference/forms/types/collection.html#type
*
* @see \Rector\Symfony\Tests\Rector\MethodCall\ChangeStringCollectionOptionToConstantRector\ChangeStringCollectionOptionToConstantRectorTest
*/

View File

@ -14,9 +14,9 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/pull/21035
* @see https://github.com/symfony/symfony/blob/4.4/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php
* @see https://symfony.com/doc/4.4/templates.html#bundle-templates
* @changelog https://github.com/symfony/symfony/pull/21035
* @changelog https://github.com/symfony/symfony/blob/4.4/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php
* @changelog https://symfony.com/doc/4.4/templates.html#bundle-templates
*
* @see \Rector\Symfony\Tests\Rector\ClassMethod\TemplateAnnotationToThisRenderRector\TemplateAnnotationToThisRenderRectorTest
*/

View File

@ -12,7 +12,7 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#dependencyinjection
* @changelog https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#dependencyinjection
* @see \Rector\Symfony\Tests\Rector\MethodCall\DefinitionAliasSetPrivateToSetPublicRector\DefinitionAliasSetPrivateToSetPublicRectorTest
*/
final class DefinitionAliasSetPrivateToSetPublicRector extends AbstractRector

View File

@ -13,7 +13,7 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#form
* @changelog https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#form
* @see \Rector\Symfony\Tests\Rector\MethodCall\FormBuilderSetDataMapperRector\FormBuilderSetDataMapperRectorTest
*/
final class FormBuilderSetDataMapperRector extends AbstractRector

View File

@ -7,10 +7,10 @@ use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\If_;
use PHPStan\Type\ObjectType;
use Rector\Core\NodeManipulator\MethodCallManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
@ -44,44 +44,37 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [MethodCall::class];
return [If_::class];
}
/**
* @param MethodCall $node
* @param If_ $node
*/
public function refactor(Node $node) : ?Node
{
if ($this->shouldSkipMethodCall($node)) {
if (!$node->cond instanceof MethodCall) {
return null;
}
/** @var Variable $variable */
$variable = $node->var;
if ($this->isIsSubmittedByAlreadyCalledOnVariable($variable)) {
$methodCall = $node->cond;
if (!$methodCall->var instanceof Variable) {
return null;
}
if ($this->shouldSkipMethodCall($methodCall)) {
return null;
}
if ($this->isIsSubmittedByAlreadyCalledOnVariable($methodCall->var)) {
return null;
}
/** @var string $variableName */
$variableName = $this->getName($node->var);
return new BooleanAnd($this->nodeFactory->createMethodCall($variableName, 'isSubmitted'), $this->nodeFactory->createMethodCall($variableName, 'isValid'));
$variableName = $this->getName($methodCall->var);
$node->cond = new BooleanAnd($this->nodeFactory->createMethodCall($variableName, 'isSubmitted'), $this->nodeFactory->createMethodCall($variableName, 'isValid'));
return $node;
}
private function shouldSkipMethodCall(MethodCall $methodCall) : bool
{
$originalNode = $methodCall->getAttribute(AttributeKey::ORIGINAL_NODE);
// skip just added calls
if (!$originalNode instanceof Node) {
return \true;
}
if (!$this->isName($methodCall->name, 'isValid')) {
return \true;
}
if (!$this->isObjectType($methodCall->var, new ObjectType('Symfony\\Component\\Form\\Form'))) {
return \true;
}
$previousNode = $methodCall->getAttribute(AttributeKey::PREVIOUS_NODE);
if ($previousNode instanceof Node) {
return \true;
}
$variableName = $this->getName($methodCall->var);
return $variableName === null;
return !$this->isObjectType($methodCall->var, new ObjectType('Symfony\\Component\\Form\\Form'));
}
private function isIsSubmittedByAlreadyCalledOnVariable(Variable $variable) : bool
{

View File

@ -75,7 +75,7 @@ CODE_SAMPLE
return $this->refactorStaticCall($node);
}
// for client, the transitional dependency to browser-kit might be missing and cause fatal error on PHPStan reflection
// in most cases that should be skipped, @see https://github.com/rectorphp/rector/issues/7135
// in most cases that should be skipped, @changelog https://github.com/rectorphp/rector/issues/7135
if ($this->reflectionProvider->hasClass('Symfony\\Component\\BrowserKit\\AbstractBrowser') && $this->isObjectType($node->var, new ObjectType('Symfony\\Component\\HttpKernel\\Client'))) {
return $this->refactorClientMethodCall($node);
}

View File

@ -15,7 +15,7 @@ use Rector\NodeTypeResolver\TypeAnalyzer\StringTypeAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://symfony.com/blog/new-in-symfony-4-3-simpler-event-dispatching
* @changelog https://symfony.com/blog/new-in-symfony-4-3-simpler-event-dispatching
*
* @see \Rector\Symfony\Tests\Rector\MethodCall\MakeDispatchFirstArgumentEventRector\MakeDispatchFirstArgumentEventRectorTest
*/

View File

@ -15,7 +15,7 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#propertyinfo
* @changelog https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#propertyinfo
* @see \Rector\Symfony\Tests\Rector\MethodCall\ReflectionExtractorEnableMagicCallExtractorRector\ReflectionExtractorEnableMagicCallExtractorRectorTest
*/
final class ReflectionExtractorEnableMagicCallExtractorRector extends AbstractRector

View File

@ -11,7 +11,7 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#validator
* @changelog https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#validator
* @see \Rector\Symfony\Tests\Rector\MethodCall\ValidatorBuilderEnableAnnotationMappingRector\ValidatorBuilderEnableAnnotationMappingRectorTest
*/
final class ValidatorBuilderEnableAnnotationMappingRector extends AbstractRector

View File

@ -12,7 +12,7 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#propertyaccess
* @changelog https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#propertyaccess
* @see \Rector\Symfony\Tests\Rector\New_\PropertyAccessorCreationBooleanToFlagsRector\PropertyAccessorCreationBooleanToFlagsRectorTest
*/
final class PropertyAccessorCreationBooleanToFlagsRector extends AbstractRector

View File

@ -11,7 +11,7 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#form
* @changelog https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#form
* @see \Rector\Symfony\Tests\Rector\New_\PropertyPathMapperToDataMapperRector\PropertyPathMapperToDataMapperRectorTest
*/
final class PropertyPathMapperToDataMapperRector extends AbstractRector

View File

@ -5,25 +5,27 @@ namespace Rector\Symfony\Rector\New_;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use PHPStan\Type\ObjectType;
use Rector\Core\Contract\PhpParser\Node\StmtsAwareInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/pull/27476
* @changelog https://github.com/symfony/symfony/pull/27476
*
* @see \Rector\Symfony\Tests\Rector\New_\RootNodeTreeBuilderRector\RootNodeTreeBuilderRectorTest
*/
final class RootNodeTreeBuilderRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Changes Process string argument to an array', [new CodeSample(<<<'CODE_SAMPLE'
return new RuleDefinition('Changes TreeBuilder with root() call to constructor passed root and getRootNode() call', [new CodeSample(<<<'CODE_SAMPLE'
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
$treeBuilder = new TreeBuilder();
@ -44,56 +46,64 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [New_::class];
return [StmtsAwareInterface::class];
}
/**
* @param New_ $node
* @param StmtsAwareInterface $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isObjectType($node->class, new ObjectType('Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder'))) {
if ($node->stmts === null) {
return null;
}
if (isset($node->args[1])) {
return null;
foreach ($node->stmts as $stmt) {
if (!$stmt instanceof Expression) {
continue;
}
if (!$stmt->expr instanceof Assign) {
continue;
}
$assign = $stmt->expr;
if (!$assign->expr instanceof New_) {
continue;
}
$new = $assign->expr;
// already has first arg
if (isset($new->getArgs()[1])) {
continue;
}
if (!$this->isObjectType($new->class, new ObjectType('Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder'))) {
continue;
}
$rootMethodCallNode = $this->getRootMethodCallNode($node);
if (!$rootMethodCallNode instanceof MethodCall) {
return null;
}
$firstArg = $rootMethodCallNode->getArgs()[0];
if (!$firstArg->value instanceof String_) {
return null;
}
[$new->args, $rootMethodCallNode->args] = [$rootMethodCallNode->getArgs(), $new->getArgs()];
$rootMethodCallNode->name = new Identifier('getRootNode');
return $node;
}
$rootMethodCallNode = $this->getRootMethodCallNode($node);
if (!$rootMethodCallNode instanceof MethodCall) {
return null;
}
$firstArg = $rootMethodCallNode->args[0];
if (!$firstArg instanceof Arg) {
return null;
}
$rootNameNode = $firstArg->value;
if (!$rootNameNode instanceof String_) {
return null;
}
[$node->args, $rootMethodCallNode->args] = [$rootMethodCallNode->args, $node->args];
$rootMethodCallNode->name = new Identifier('getRootNode');
return $node;
return null;
}
private function getRootMethodCallNode(New_ $new) : ?Node
private function getRootMethodCallNode(StmtsAwareInterface $stmtsAware) : ?Node
{
$currentStmt = $this->betterNodeFinder->resolveCurrentStatement($new);
if (!$currentStmt instanceof Stmt) {
return null;
$methodCalls = $this->betterNodeFinder->findInstanceOf($stmtsAware, MethodCall::class);
foreach ($methodCalls as $methodCall) {
if (!$this->isName($methodCall->name, 'root')) {
continue;
}
if (!$this->isObjectType($methodCall->var, new ObjectType('Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder'))) {
continue;
}
if (!isset($methodCall->getArgs()[0])) {
continue;
}
return $methodCall;
}
$nextExpression = $currentStmt->getAttribute(AttributeKey::NEXT_NODE);
if (!$nextExpression instanceof Node) {
return null;
}
return $this->betterNodeFinder->findFirst([$nextExpression], function (Node $node) : bool {
if (!$node instanceof MethodCall) {
return \false;
}
if (!$this->isName($node->name, 'root')) {
return \false;
}
if (!$this->isObjectType($node->var, new ObjectType('Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder'))) {
return \false;
}
return isset($node->args[0]);
});
return null;
}
}

View File

@ -22,7 +22,7 @@ use RectorPrefix202305\Symfony\Component\Console\Input\StringInput;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/pull/27821/files
* @changelog https://github.com/symfony/symfony/pull/27821/files
* @see \Rector\Symfony\Tests\Rector\New_\StringToArrayArgumentProcessRector\StringToArrayArgumentProcessRectorTest
*/
final class StringToArrayArgumentProcessRector extends AbstractRector

View File

@ -11,7 +11,7 @@ use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#httpfoundation
* @changelog https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#httpfoundation
* @see \Rector\Symfony\Tests\Rector\StaticCall\BinaryFileResponseCreateToNewInstanceRector\BinaryFileResponseCreateToNewInstanceRectorTest
*/
final class BinaryFileResponseCreateToNewInstanceRector extends AbstractRector

View File

@ -23,17 +23,17 @@ final class ParseFileRector extends AbstractRector
{
/**
* @var string
* @see https://regex101.com/r/ZaY42i/1
* @changelog https://regex101.com/r/ZaY42i/1
*/
private const YAML_SUFFIX_IN_QUOTE_REGEX = '#\\.(yml|yaml)(\'|\\")$#';
/**
* @var string
* @see https://regex101.com/r/YHA05g/1
* @changelog https://regex101.com/r/YHA05g/1
*/
private const FILE_SUFFIX_REGEX = '#File$#';
/**
* @var string
* @see https://regex101.com/r/JmNhZj/1
* @changelog https://regex101.com/r/JmNhZj/1
*/
private const YAML_SUFFIX_REGEX = '#\\.(yml|yaml)$#';
/**