mirror of
https://github.com/rectorphp/rector.git
synced 2025-04-22 16:32:27 +02:00
[NetteCodeQuality] Fix ChangeFormArrayAccessToAnnotatedControlVariableRector for in-closure (#4506)
* [NetteCodeQuality] Fix ChangeFormArrayAccessToAnnotatedControlVariableRector for in-closure * [ci-review] Rector Rectify * [ci-review] Rector Rectify * [ci-review] Rector Rectify * fix name * fix unknown mixed type on fluent * [ci-review] Rector Rectify Co-authored-by: rector-bot <tomas@getrector.org>
This commit is contained in:
parent
a2ae659e0a
commit
91a354c080
@ -180,8 +180,8 @@ final class PhpDocInfo
|
||||
|
||||
public function getParamType(string $name): Type
|
||||
{
|
||||
$paramTagValue = $this->getParamTagValueByName($name);
|
||||
return $this->getTypeOrMixed($paramTagValue);
|
||||
$attributeAwareParamTagValueNode = $this->getParamTagValueByName($name);
|
||||
return $this->getTypeOrMixed($attributeAwareParamTagValueNode);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,8 +190,8 @@ final class PhpDocInfo
|
||||
public function getParamTypes(): array
|
||||
{
|
||||
$paramTypes = [];
|
||||
foreach ($this->phpDocNode->getParamTagValues() as $paramTagValue) {
|
||||
$paramTypes[] = $this->staticTypeMapper->mapPHPStanPhpDocTypeToPHPStanType($paramTagValue, $this->node);
|
||||
foreach ($this->phpDocNode->getParamTagValues() as $paramTagValueNode) {
|
||||
$paramTypes[] = $this->staticTypeMapper->mapPHPStanPhpDocTypeToPHPStanType($paramTagValueNode, $this->node);
|
||||
}
|
||||
|
||||
return $paramTypes;
|
||||
@ -199,12 +199,12 @@ final class PhpDocInfo
|
||||
|
||||
public function getParamTagValueNodeByName(string $parameterName): ?ParamTagValueNode
|
||||
{
|
||||
foreach ($this->phpDocNode->getParamTagValues() as $paramTagValue) {
|
||||
if ($paramTagValue->parameterName !== '$' . $parameterName) {
|
||||
foreach ($this->phpDocNode->getParamTagValues() as $paramTagValueNode) {
|
||||
if ($paramTagValueNode->parameterName !== '$' . $parameterName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $paramTagValue;
|
||||
return $paramTagValueNode;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -485,9 +485,9 @@ final class PhpDocInfo
|
||||
{
|
||||
$throwsTypes = [];
|
||||
|
||||
foreach ($this->phpDocNode->getThrowsTagValues() as $throwsPhpDocNode) {
|
||||
foreach ($this->phpDocNode->getThrowsTagValues() as $throwsTagValueNode) {
|
||||
$throwsTypes[] = $this->staticTypeMapper->mapPHPStanPhpDocTypeToPHPStanType(
|
||||
$throwsPhpDocNode,
|
||||
$throwsTagValueNode,
|
||||
$this->node
|
||||
);
|
||||
}
|
||||
|
@ -18,9 +18,10 @@ final class ParentScopeFinder
|
||||
*/
|
||||
public function find(Node $node): ?Node
|
||||
{
|
||||
return $node->getAttribute(AttributeKey::METHOD_NODE)
|
||||
?? $node->getAttribute(AttributeKey::FUNCTION_NODE)
|
||||
?? $node->getAttribute(AttributeKey::CLASS_NODE)
|
||||
?? $node->getAttribute(AttributeKey::NAMESPACE_NODE);
|
||||
return $node->getAttribute(AttributeKey::CLOSURE_NODE) ??
|
||||
$node->getAttribute(AttributeKey::FUNCTION_NODE) ??
|
||||
$node->getAttribute(AttributeKey::METHOD_NODE) ??
|
||||
$node->getAttribute(AttributeKey::CLASS_NODE) ??
|
||||
$node->getAttribute(AttributeKey::NAMESPACE_NODE);
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,10 @@ final class FunctionMethodAndClassNodeVisitor extends NodeVisitorAbstract
|
||||
$this->methodName = (string) $this->methodName;
|
||||
}
|
||||
|
||||
if ($node instanceof Closure) {
|
||||
$this->closure = null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -115,9 +115,9 @@ final class ShortNameResolver
|
||||
return $fileInfo->getRealPath();
|
||||
}
|
||||
|
||||
$currentFileInfo = $this->currentFileInfoProvider->getSmartFileInfo();
|
||||
if ($currentFileInfo !== null) {
|
||||
return $currentFileInfo->getRealPath();
|
||||
$smartFileInfo = $this->currentFileInfoProvider->getSmartFileInfo();
|
||||
if ($smartFileInfo !== null) {
|
||||
return $smartFileInfo->getRealPath();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -70,14 +70,14 @@ final class UsedClassConstsExtractor
|
||||
private function getClassConstByName(Class_ $class, string $classConstName): ClassConst
|
||||
{
|
||||
$classConstantNames = [];
|
||||
foreach ($class->getConstants() as $constant) {
|
||||
$classConstantNames[] = $this->nodeNameResolver->getName($constant);
|
||||
foreach ($class->getConstants() as $classConst) {
|
||||
$classConstantNames[] = $this->nodeNameResolver->getName($classConst);
|
||||
|
||||
if (! $this->nodeNameResolver->isName($constant, $classConstName)) {
|
||||
if (! $this->nodeNameResolver->isName($classConst, $classConstName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $constant;
|
||||
return $classConst;
|
||||
}
|
||||
|
||||
$className = $this->nodeNameResolver->getName($class);
|
||||
|
@ -7,6 +7,7 @@ namespace Rector\Defluent\NodeFactory;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Defluent\NodeAnalyzer\FluentChainMethodCallRootExtractor;
|
||||
use Rector\Defluent\ValueObject\FirstAssignFluentCall;
|
||||
use Rector\Defluent\ValueObject\FluentMethodCalls;
|
||||
@ -40,7 +41,7 @@ final class ReturnFluentMethodCallFactory
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
}
|
||||
|
||||
public function createFromFluentMethodCalls(FluentMethodCalls $fluentMethodCalls): FirstAssignFluentCall
|
||||
public function createFromFluentMethodCalls(FluentMethodCalls $fluentMethodCalls): ?FirstAssignFluentCall
|
||||
{
|
||||
$rootMethodCall = $fluentMethodCalls->getRootMethodCall();
|
||||
|
||||
@ -58,6 +59,10 @@ final class ReturnFluentMethodCallFactory
|
||||
// we need a variable to assign the stuff into
|
||||
// the method call, does not belong to the
|
||||
$staticType = $this->nodeTypeResolver->getStaticType($rootMethodCall);
|
||||
if (! $staticType instanceof ObjectType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$variableName = $this->propertyNaming->fqnToVariableName($staticType);
|
||||
$assignExpr = new Variable($variableName);
|
||||
}
|
||||
|
@ -125,6 +125,10 @@ CODE_SAMPLE
|
||||
$fluentMethodCalls
|
||||
);
|
||||
|
||||
if ($firstAssignFluentCall === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// should be skipped?
|
||||
if ($this->fluentMethodCallSkipper->shouldSkipFirstAssignFluentCall($firstAssignFluentCall)) {
|
||||
return [];
|
||||
|
@ -181,7 +181,7 @@ CODE_SAMPLE
|
||||
|
||||
private function addRepositoryProperty(Class_ $class, Expr $entityReferenceExpr): void
|
||||
{
|
||||
$repositoryPropertyType = $this->repositoryTypeFactory->createRepositoryPropertyType($entityReferenceExpr);
|
||||
$this->addPropertyToClass($class, $repositoryPropertyType, 'repository');
|
||||
$genericObjectType = $this->repositoryTypeFactory->createRepositoryPropertyType($entityReferenceExpr);
|
||||
$this->addPropertyToClass($class, $genericObjectType, 'repository');
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +200,6 @@ final class ExpectedNameResolver
|
||||
}
|
||||
|
||||
$returnedType = $this->nodeTypeResolver->getStaticType($expr);
|
||||
|
||||
if ($returnedType->isIterable()->no()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteCodeQuality\NodeAdding;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\NodeNestingScope\ParentScopeFinder;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
final class FunctionLikeFirstLevelStatementResolver
|
||||
{
|
||||
/**
|
||||
* @var ParentScopeFinder
|
||||
*/
|
||||
private $parentScopeFinder;
|
||||
|
||||
public function __construct(ParentScopeFinder $parentScopeFinder)
|
||||
{
|
||||
$this->parentScopeFinder = $parentScopeFinder;
|
||||
}
|
||||
|
||||
public function resolveFirstLevelStatement(Node $node): Node
|
||||
{
|
||||
$multiplierClosure = $this->matchMultiplierClosure($node);
|
||||
$functionLike = $multiplierClosure ?? $this->parentScopeFinder->find($node);
|
||||
|
||||
/** @var ClassMethod|Closure|null $functionLike */
|
||||
if ($functionLike === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$currentStatement = $node->getAttribute(AttributeKey::CURRENT_STATEMENT);
|
||||
if (! $currentStatement instanceof Node) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
while (! in_array($currentStatement, (array) $functionLike->stmts, true)) {
|
||||
$parent = $currentStatement->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parent instanceof Node) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$currentStatement = $parent->getAttribute(AttributeKey::CURRENT_STATEMENT);
|
||||
}
|
||||
|
||||
return $currentStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form might be costructured inside private closure for multiplier
|
||||
* @see https://doc.nette.org/en/3.0/multiplier
|
||||
*/
|
||||
private function matchMultiplierClosure(Node $node): ?Closure
|
||||
{
|
||||
/** @var Closure|null $closure */
|
||||
$closure = $node->getAttribute(AttributeKey::CLOSURE_NODE);
|
||||
if ($closure === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parent = $closure->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parent instanceof Arg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parentParent = $parent->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parentParent instanceof New_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $closure;
|
||||
}
|
||||
}
|
@ -4,20 +4,16 @@ declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteCodeQuality\Rector\ArrayDimFetch;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\ArrayDimFetch;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\BetterPhpDocParser\PhpDocManipulator\VarAnnotationManipulator;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\NetteCodeQuality\Naming\NetteControlNaming;
|
||||
use Rector\NetteCodeQuality\NodeAdding\FunctionLikeFirstLevelStatementResolver;
|
||||
use Rector\NetteCodeQuality\NodeAnalyzer\ControlDimFetchAnalyzer;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
@ -46,17 +42,24 @@ abstract class AbstractArrayDimFetchToAnnotatedControlVariableRector extends Abs
|
||||
*/
|
||||
private $alreadyInitializedAssignsClassMethodObjectHashes = [];
|
||||
|
||||
/**
|
||||
* @var FunctionLikeFirstLevelStatementResolver
|
||||
*/
|
||||
private $functionLikeFirstLevelStatementResolver;
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function autowireAbstractArrayDimFetchToAnnotatedControlVariableRector(
|
||||
VarAnnotationManipulator $varAnnotationManipulator,
|
||||
ControlDimFetchAnalyzer $controlDimFetchAnalyzer,
|
||||
NetteControlNaming $netteControlNaming
|
||||
NetteControlNaming $netteControlNaming,
|
||||
FunctionLikeFirstLevelStatementResolver $functionLikeFirstLevelStatementResolver
|
||||
): void {
|
||||
$this->controlDimFetchAnalyzer = $controlDimFetchAnalyzer;
|
||||
$this->netteControlNaming = $netteControlNaming;
|
||||
$this->varAnnotationManipulator = $varAnnotationManipulator;
|
||||
$this->functionLikeFirstLevelStatementResolver = $functionLikeFirstLevelStatementResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,7 +81,7 @@ abstract class AbstractArrayDimFetchToAnnotatedControlVariableRector extends Abs
|
||||
|
||||
$assignExpression = $this->createAnnotatedAssignExpression($variableName, $arrayDimFetch, $controlObjectType);
|
||||
|
||||
$currentStatement = $this->getClassMethodFirstLevelStatement($arrayDimFetch);
|
||||
$currentStatement = $this->functionLikeFirstLevelStatementResolver->resolveFirstLevelStatement($arrayDimFetch);
|
||||
$this->addNodeBeforeNode($assignExpression, $currentStatement);
|
||||
}
|
||||
|
||||
@ -133,33 +136,6 @@ abstract class AbstractArrayDimFetchToAnnotatedControlVariableRector extends Abs
|
||||
return $assignExpression;
|
||||
}
|
||||
|
||||
private function getClassMethodFirstLevelStatement(Node $node): Node
|
||||
{
|
||||
$multiplierClosure = $this->matchMultiplierClosure($node);
|
||||
$functionLike = $multiplierClosure ?? $node->getAttribute(AttributeKey::METHOD_NODE);
|
||||
|
||||
/** @var ClassMethod|Closure|null $functionLike */
|
||||
if ($functionLike === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$currentStatement = $node->getAttribute(AttributeKey::CURRENT_STATEMENT);
|
||||
if (! $currentStatement instanceof Node) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
while (! in_array($currentStatement, (array) $functionLike->stmts, true)) {
|
||||
$parent = $currentStatement->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parent instanceof Node) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$currentStatement = $parent->getAttribute(AttributeKey::CURRENT_STATEMENT);
|
||||
}
|
||||
|
||||
return $currentStatement;
|
||||
}
|
||||
|
||||
private function createAssignExpression(string $variableName, ArrayDimFetch $arrayDimFetch): Expression
|
||||
{
|
||||
$variable = new Variable($variableName);
|
||||
@ -168,29 +144,4 @@ abstract class AbstractArrayDimFetchToAnnotatedControlVariableRector extends Abs
|
||||
|
||||
return new Expression($assign);
|
||||
}
|
||||
|
||||
/**
|
||||
* Form might be costructured inside private closure for multiplier
|
||||
* @see https://doc.nette.org/en/3.0/multiplier
|
||||
*/
|
||||
private function matchMultiplierClosure(Node $node): ?Closure
|
||||
{
|
||||
/** @var Closure|null $closure */
|
||||
$closure = $node->getAttribute(AttributeKey::CLOSURE_NODE);
|
||||
if ($closure === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parent = $closure->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parent instanceof Arg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parentParent = $parent->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parentParent instanceof New_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $closure;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\NetteCodeQuality\Tests\Rector\ArrayDimFetch\ChangeFormArrayAccessToAnnotatedControlVariableRector\Fixture;
|
||||
|
||||
use Nette\Application\UI\Form;
|
||||
|
||||
final class InOnSuccessCall
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$form = $this->makeForm();
|
||||
|
||||
$onSuccess = function (Form $form) {
|
||||
$form['email_else']->value = 'hey@hi.hello';
|
||||
};
|
||||
}
|
||||
|
||||
public function makeForm(): Form
|
||||
{
|
||||
$form = new Form();
|
||||
$form->addText('email_else', 'Email');
|
||||
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\NetteCodeQuality\Tests\Rector\ArrayDimFetch\ChangeFormArrayAccessToAnnotatedControlVariableRector\Fixture;
|
||||
|
||||
use Nette\Application\UI\Form;
|
||||
|
||||
final class InOnSuccessCall
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$form = $this->makeForm();
|
||||
|
||||
$onSuccess = function (Form $form) {
|
||||
/** @var \Nette\Forms\Controls\TextInput $emailElseControl */
|
||||
$emailElseControl = $form['email_else'];
|
||||
$emailElseControl->value = 'hey@hi.hello';
|
||||
};
|
||||
}
|
||||
|
||||
public function makeForm(): Form
|
||||
{
|
||||
$form = new Form();
|
||||
$form->addText('email_else', 'Email');
|
||||
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -26,6 +26,7 @@ use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\NetteKdyby\Naming\VariableNaming;
|
||||
use Rector\NodeNestingScope\ParentScopeFinder;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\Php70\ValueObject\VariableAssignPair;
|
||||
|
||||
@ -46,10 +47,19 @@ final class NonVariableToVariableOnFunctionCallRector extends AbstractRector
|
||||
*/
|
||||
private $variableNaming;
|
||||
|
||||
public function __construct(CallReflectionResolver $callReflectionResolver, VariableNaming $variableNaming)
|
||||
{
|
||||
/**
|
||||
* @var ParentScopeFinder
|
||||
*/
|
||||
private $parentScopeFinder;
|
||||
|
||||
public function __construct(
|
||||
CallReflectionResolver $callReflectionResolver,
|
||||
VariableNaming $variableNaming,
|
||||
ParentScopeFinder $parentScopeFinder
|
||||
) {
|
||||
$this->callReflectionResolver = $callReflectionResolver;
|
||||
$this->variableNaming = $variableNaming;
|
||||
$this->parentScopeFinder = $parentScopeFinder;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
@ -78,7 +88,10 @@ final class NonVariableToVariableOnFunctionCallRector extends AbstractRector
|
||||
return null;
|
||||
}
|
||||
|
||||
$scopeNode = $this->resolveScopeNode($node);
|
||||
$scopeNode = $this->parentScopeFinder->find($node);
|
||||
if ($scopeNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$currentScope = $scopeNode->getAttribute(AttributeKey::SCOPE);
|
||||
if (! $currentScope instanceof MutatingScope) {
|
||||
@ -151,13 +164,6 @@ final class NonVariableToVariableOnFunctionCallRector extends AbstractRector
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
private function resolveScopeNode(Node $node): Node
|
||||
{
|
||||
return $node->getAttribute(AttributeKey::METHOD_NODE) ??
|
||||
$node->getAttribute(AttributeKey::FUNCTION_NODE) ??
|
||||
$node->getAttribute(AttributeKey::CLOSURE_NODE);
|
||||
}
|
||||
|
||||
private function getReplacementsFor(Expr $expr, MutatingScope $mutatingScope, Node $scopeNode): VariableAssignPair
|
||||
{
|
||||
/** @var Assign|AssignOp|AssignRef $expr */
|
||||
|
@ -5,8 +5,11 @@ namespace Rector\Php70\Tests\Rector\FuncCall\NonVariableToVariableOnFunctionCall
|
||||
function anonymousFunction()
|
||||
{
|
||||
$anonymousFunction = function (&$bar) {};
|
||||
|
||||
$anonymousFunction(bar());
|
||||
|
||||
$staticAnonymousFunction = static function (&$bar) {};
|
||||
|
||||
$staticAnonymousFunction(bar());
|
||||
}
|
||||
|
||||
@ -20,9 +23,12 @@ function anonymousFunction()
|
||||
{
|
||||
$anonymousFunction = function (&$bar) {};
|
||||
$bar = bar();
|
||||
|
||||
$anonymousFunction($bar);
|
||||
|
||||
$staticAnonymousFunction = static function (&$bar) {};
|
||||
$bar2 = bar();
|
||||
|
||||
$staticAnonymousFunction($bar2);
|
||||
}
|
||||
|
||||
|
@ -117,19 +117,19 @@ final class ClassMethodExternalCallNodeAnalyzer
|
||||
|
||||
private function isEventSubscriberMethod(ClassMethod $classMethod, string $methodName): bool
|
||||
{
|
||||
$classNode = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classNode instanceof Class_) {
|
||||
$classLike = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classLike instanceof Class_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->nodeTypeResolver->isObjectType(
|
||||
$classNode,
|
||||
$classLike,
|
||||
'Symfony\Component\EventDispatcher\EventSubscriberInterface')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$getSubscribedEventsClassMethod = $classNode->getMethod('getSubscribedEvents');
|
||||
$getSubscribedEventsClassMethod = $classLike->getMethod('getSubscribedEvents');
|
||||
if ($getSubscribedEventsClassMethod === null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -199,8 +199,8 @@ CODE_SAMPLE
|
||||
}
|
||||
|
||||
if ($type instanceof FloatType) {
|
||||
$isFloat = $this->createFuncCall('is_float', [$variable]);
|
||||
return $this->createFuncCall(self::ASSERT, [$isFloat]);
|
||||
$funcCall = $this->createFuncCall('is_float', [$variable]);
|
||||
return $this->createFuncCall(self::ASSERT, [$funcCall]);
|
||||
}
|
||||
|
||||
if ($type instanceof StringType) {
|
||||
|
@ -270,12 +270,12 @@ final class RectorApplication
|
||||
return;
|
||||
}
|
||||
|
||||
$oldContent = $fileInfo->getContents();
|
||||
$contents = $fileInfo->getContents();
|
||||
|
||||
$newContent = $this->configuration->isDryRun() ? $this->fileProcessor->printToString($fileInfo)
|
||||
: $this->fileProcessor->printToFile($fileInfo);
|
||||
|
||||
$this->errorAndDiffCollector->addFileDiff($fileInfo, $newContent, $oldContent);
|
||||
$this->errorAndDiffCollector->addFileDiff($fileInfo, $newContent, $contents);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -325,13 +325,13 @@ final class ClassMethodAssignManipulator
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var ParameterReflection $parameter */
|
||||
foreach ($parametersAcceptor->getParameters() as $parameter) {
|
||||
if ($parameter->getName() !== $variableName) {
|
||||
/** @var ParameterReflection $parameterReflection */
|
||||
foreach ($parametersAcceptor->getParameters() as $parameterReflection) {
|
||||
if ($parameterReflection->getName() !== $variableName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $parameter->passedByReference()
|
||||
return $parameterReflection->passedByReference()
|
||||
->yes();
|
||||
}
|
||||
|
||||
@ -375,13 +375,13 @@ final class ClassMethodAssignManipulator
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var ParameterReflection $parameter */
|
||||
foreach ($parametersAcceptor->getParameters() as $parameterPosition => $parameter) {
|
||||
/** @var ParameterReflection $parameterReflection */
|
||||
foreach ($parametersAcceptor->getParameters() as $parameterPosition => $parameterReflection) {
|
||||
if ($parameterPosition !== $argumentPosition) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $parameter->passedByReference()
|
||||
return $parameterReflection->passedByReference()
|
||||
->yes();
|
||||
}
|
||||
|
||||
|
@ -92,12 +92,12 @@ final class ClassMethodManipulator
|
||||
return false;
|
||||
}
|
||||
|
||||
$classNode = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classNode instanceof Class_) {
|
||||
$classLike = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classLike instanceof Class_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $classMethod->isPrivate() || (! $classNode->isFinal() && $classMethod->isProtected());
|
||||
return $classMethod->isPrivate() || (! $classLike->isFinal() && $classMethod->isProtected());
|
||||
}
|
||||
|
||||
public function hasParentMethodOrInterfaceMethod(ClassMethod $classMethod, ?string $methodName = null): bool
|
||||
|
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\Tests\RectorCombination\RenameAndFluent\Fixture;
|
||||
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PHPStan\Reflection\ParameterReflection;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
|
||||
final class CyclicParameterReflection
|
||||
{
|
||||
/**
|
||||
* @var CallReflectionResolver
|
||||
*/
|
||||
private $callReflectionResolver;
|
||||
|
||||
public function __construct(CallReflectionResolver $callReflectionResolver)
|
||||
{
|
||||
$this->callReflectionResolver = $callReflectionResolver;
|
||||
}
|
||||
|
||||
private function isParameterReferencedInMethodReflection(New_ $new, int $argumentPosition): bool
|
||||
{
|
||||
$methodReflection = $this->callReflectionResolver->resolveConstructor($new);
|
||||
$parametersAcceptor = $this->callReflectionResolver->resolveParametersAcceptor($methodReflection, $new);
|
||||
|
||||
if ($parametersAcceptor === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var ParameterReflection $parameter */
|
||||
foreach ($parametersAcceptor->getParameters() as $parameterPosition => $parameter) {
|
||||
if ($parameterPosition !== $argumentPosition) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $parameter->passedByReference()->yes();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\Tests\RectorCombination\RenameAndFluent\Fixture;
|
||||
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PHPStan\Reflection\ParameterReflection;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
|
||||
final class CyclicParameterReflection
|
||||
{
|
||||
/**
|
||||
* @var CallReflectionResolver
|
||||
*/
|
||||
private $callReflectionResolver;
|
||||
|
||||
public function __construct(CallReflectionResolver $callReflectionResolver)
|
||||
{
|
||||
$this->callReflectionResolver = $callReflectionResolver;
|
||||
}
|
||||
|
||||
private function isParameterReferencedInMethodReflection(New_ $new, int $argumentPosition): bool
|
||||
{
|
||||
$methodReflection = $this->callReflectionResolver->resolveConstructor($new);
|
||||
$parametersAcceptor = $this->callReflectionResolver->resolveParametersAcceptor($methodReflection, $new);
|
||||
|
||||
if ($parametersAcceptor === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var ParameterReflection $parameterReflection */
|
||||
foreach ($parametersAcceptor->getParameters() as $parameterPosition => $parameterReflection) {
|
||||
if ($parameterPosition !== $argumentPosition) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $parameterReflection->passedByReference()->yes();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\Tests\RectorCombination\RenameAndFluent;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class RenameAndFluentTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function provideConfigFileInfo(): ?SmartFileInfo
|
||||
{
|
||||
return new SmartFileInfo(__DIR__ . '/config/rename_and_fluent.php');
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Defluent\Rector\Return_\ReturnFluentChainMethodCallToNormalMethodCallRector;
|
||||
use Rector\Naming\Rector\Foreach_\RenameForeachValueVariableToMatchMethodCallReturnTypeRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(ReturnFluentChainMethodCallToNormalMethodCallRector::class);
|
||||
$services->set(RenameForeachValueVariableToMatchMethodCallReturnTypeRector::class);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user