Fix false positive when deprecation helper is inside functioncall#989
Open
bbrala wants to merge 2 commits into
Open
Fix false positive when deprecation helper is inside functioncall#989bbrala wants to merge 2 commits into
bbrala wants to merge 2 commits into
Conversation
…This should be handled by the DeprecationHelperScope
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
I'm doing a run of improvements for Druapl Rector. That will now use DeprecationHelper also for deprecations that are called in a rector. When running against contrib i noticed a lot of deprecations where still reported. After some investigation with Claude we noticed the DeprecationHelperScope does not account for the callstack it might be in. See the report below:
Summary
DeprecationHelperScope::isScopeDeprecated()only inspects$callStack[0]fromScope::getFunctionCallStackWithParameters(). WhenDeprecationHelper::backwardsCompatibleCall()is itself passed as an argument to an outer function, PHPStan pushes the outer function onto the
stack first — so index
0is the outer call, notbackwardsCompatibleCall. The deprecated callinside
deprecatedCallableis never suppressed, producing a false-positive deprecation error.Failing patterns
Working pattern (for contrast)
Root cause
getFunctionCallStackWithParameters()returns an array where[0]is the outermost activefunction-argument context and the last element is the innermost. Arrow functions inherit the
parent scope's stack unchanged, so all outer entries are visible when the body is analysed.
For
trim(backwardsCompatibleCall(..., fn() => deprecated_fn())), the stack inside the arrowfunction body is:
Current code:
Fix
Iterate the full stack instead of only checking index
0:This correctly handles any nesting depth, e.g.
trim(strrev(strtolower(backwardsCompatibleCall(...)))).Real-world proof
The project_analysis pipeline runs
drupal-rector followed by upgrade_status/PHPStan on ~1,800 Drupal contrib modules. After rector
correctly wraps all
theme_get_setting()calls in the alice theme, 5 false-positive errorsremain in the post-rector report — all on nested patterns:
— errors at lines 107, 114, 115, 135, 136 are all
trim(backwardsCompatibleCall(...))orarray_filter([backwardsCompatibleCall(...)], 'trim')patterns— confirms rector wrapped all 19 calls correctly; the remaining errors are PHPStan false positives,
not rector misses