Skip to content

Commit

Permalink
fix isSubmitted() previous calls for FormIsValidRector
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Oct 2, 2019
1 parent f3783ac commit ec2ec37
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ private function shouldSkip(string $lastName, string $aliasName): bool
}

/**
* @return string[]
* @return string[][]
*/
private function collectUseNamesAliasToName(Use_ $use): array
{
Expand Down
109 changes: 96 additions & 13 deletions packages/Symfony/src/Rector/Form/FormIsValidRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
Expand Down Expand Up @@ -49,31 +50,113 @@ public function getNodeTypes(): array
*/
public function refactor(Node $node): ?Node
{
// skip just added calls
if ($node->getAttribute(AttributeKey::ORIGINAL_NODE) === null) {
if ($this->shouldSkipMethodCall($node)) {
return null;
}

if (! $this->isObjectType($node, Form::class)) {
/** @var Variable $variable */
$variable = $node->var;
if ($this->isIsSubmittedByAlreadyCalledOnVariable($variable)) {
return null;
}

if (! $this->isName($node, 'isValid')) {
return null;
/** @var string $variableName */
$variableName = $this->getName($node->var);

return new BooleanAnd(
$this->createMethodCall($variableName, 'isSubmitted'),
$this->createMethodCall($variableName, 'isValid')
);
}

private function shouldSkipMethodCall(MethodCall $methodCall): bool
{
// skip just added calls
if ($methodCall->getAttribute(AttributeKey::ORIGINAL_NODE) === null) {
return true;
}

if ($node->getAttribute(AttributeKey::PREVIOUS_NODE) !== null) {
return null;
if (! $this->isObjectType($methodCall->var, Form::class)) {
return true;
}

$variableName = $this->getName($node->var);
if (! $this->isName($methodCall->name, 'isValid')) {
return true;
}

if ($methodCall->getAttribute(AttributeKey::PREVIOUS_NODE) !== null) {
return true;
}

$variableName = $this->getName($methodCall->var);
if ($variableName === null) {
return null;
return true;
}

return new BooleanAnd(
$this->createMethodCall($variableName, 'isSubmitted'),
$this->createMethodCall($variableName, 'isValid')
);
return false;
}

/**
* @return string[]
*/
private function findMethodCallNamesOnVariable(Variable $variable): array
{
/** @var Node|null $parentNode */
$parentNode = $variable->getAttribute(AttributeKey::PARENT_NODE);
if ($parentNode === null) {
return [];
}

$variableName = $this->getName($variable);
if ($variableName === null) {
return [];
}

$previousMethodCallNames = [];

do {
$methodCallNames = $this->collectMethodCallsOnVariableName($parentNode, $variableName);
$previousMethodCallNames = array_merge($previousMethodCallNames, $methodCallNames);

$parentNode = $parentNode->getAttribute(AttributeKey::PARENT_NODE);
} while ($parentNode instanceof Node && ! $parentNode instanceof Node\FunctionLike);

return array_unique($previousMethodCallNames);
}

/**
* @return string[]
*/
private function collectMethodCallsOnVariableName(Node $node, string $variableName): array
{
$methodCallNames = [];
$this->traverseNodesWithCallable($node, function (Node $node) use ($variableName, &$methodCallNames) {
if (! $node instanceof MethodCall) {
return null;
}

if (! $this->isName($node->var, $variableName)) {
return null;
}

$methodName = $this->getName($node->name);
if ($methodName === null) {
return null;
}

$methodCallNames[] = $methodName;

return null;
});

return $methodCallNames;
}

private function isIsSubmittedByAlreadyCalledOnVariable(Variable $variable): bool
{
$previousMethodCallNamesOnVariable = $this->findMethodCallNamesOnVariable($variable);

// already checked by isSubmitted()
return in_array('isSubmitted', $previousMethodCallNamesOnVariable, true);
}
}

0 comments on commit ec2ec37

Please sign in to comment.