Failing test case for SimplifyIfElseToTernaryRector and RemoveUnusedAssignVariableRector #788
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
refs: rectorphp/rector#6655
closes: rectorphp/rector#6655
The main reason why this seems to occur is because of an incosistent "statement tree" (not sure what the proper term for this would be). Let me try to explain:
If SimplifyIfElseToTernaryRector changes something it will take an
PhpParser\Node\Stmt\If_
node and return a newPhpParser\Node\Stmt\Expression
node. This works perfectly fine, however, the "parent statements" are not being updated properly.So if I have a structure like so:
and the SimplifyIfElseToTernaryRector returns the new ternary version, the statements of the function are not updated.
So the
PhpParser\Node\Stmt\If_
node that was replaced by anPhpParser\Node\Stmt\Expression
node by the SimplifyIfElseToTernaryRector has a linked parent, this parent is thePhpParser\Node\Stmt\Function_
. ThePhpParser\Node\Stmt\Function_
still has the statements [PhpParser\Node\Stmt\If_
,PhpParser\Node\Stmt\Return_
] while in reality it is now [PhpParser\Node\Stmt\Expression
,PhpParser\Node\Stmt\Return_
]. This results in the "statement tree" (for lack of better words) to be inconsistent, thus resulting in differing results between rectors if they're used in conjunction with each other.Given that information, in the RemoveUnusedAssignVariableRector the NextVariableUsageNodeFinder tries to look up the method / function statements to look for usages, which are now stale references to things that don't exist anymore (namely the
PhpParser\Node\Stmt\If_
node) so it cannot skip the refactoring resulting in the behaviour that can be seen in the failing test case.This is a rare condition though as usually nodes aren't entirely changed and/or two seperate rectors rarely need to touch the same type of statement constructs.
I'd hope someone with a deeper understanding of the rector core to take a look into this and potentially figure out if there's a decent solution for this.
I'd be happy to help implementing it if one was to point me in the right direction, however, currently I'm not sure where to go from here.