Skip to content

Fix RemoveParentCallWithoutParentRector removing valid call when ancestor hierarchy is unresolvable#8018

Merged
TomasVotruba merged 1 commit into
mainfrom
fix/9700-broken-parent-hierarchy
May 31, 2026
Merged

Fix RemoveParentCallWithoutParentRector removing valid call when ancestor hierarchy is unresolvable#8018
TomasVotruba merged 1 commit into
mainfrom
fix/9700-broken-parent-hierarchy

Conversation

@TomasVotruba
Copy link
Copy Markdown
Member

Fixes rectorphp/rector#9700

Problem

RemoveParentCallWithoutParentRector decides whether a parent::method() call is dead by walking ClassReflection::getParents() via hasParentMethodOrInterfaceMethod(). When an intermediate ancestor in the chain cannot be resolved (e.g. a grandparent class is not autoloadable), getParents() silently stops at the unresolvable class. The method actually defined further up the chain is therefore not found, and a valid parent::method() call gets removed.

Fix

When the method is not found among the resolvable parents, walk the declared extends chain through the AST (AstResolver). If any declared ancestor cannot be resolved by the ReflectionProvider, we cannot safely conclude the method does not exist, so the call is kept.

Test

Added skip_broken_hierarchy.php.inc: a class whose parent (SkipBrokenHierarchyParent) extends a non-autoloadable grandparent. The parent::run() call must be preserved. Verified the fixture fails before the fix and passes after.

@TomasVotruba TomasVotruba merged commit 02dfcad into main May 31, 2026
62 checks passed
@TomasVotruba
Copy link
Copy Markdown
Member Author

Thanks !

@TomasVotruba TomasVotruba deleted the fix/9700-broken-parent-hierarchy branch May 31, 2026 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

RemoveParentCallWithoutParentRector doesn't always detect parent class correctly

1 participant