Repository navigation
Only check a filter callback's own returns in AlwaysReturnInFilter - #907
Merged
Merged
Conversation
AlwaysReturnInFilter looked at every return in the callback body, including those in nested closures and anonymous class methods. A callback that never returned passed when a nested closure did, and an intentional `return;` in a nested closure, such as an add_action() callback, was reported as the filter returning void. It also treated a return as conditional when an if wrapped the whole callback. A function inside a function_exists() check that returned only from try and catch was reported as missing a return, while the same function without the wrapper passed.
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.
AlwaysReturnInFilterlooked at everyreturnin a filter callback's body, including returns that belong to a nested closure or an anonymous class method. It also treated areturnas conditional whenever there was anifanywhere above it, even anifoutside the callback. That gave two false positive errors and one false negative.An intentional
return;in a nested closure was reported as the filter returning void:A callback wrapped in a
function_exists()check that returns only fromtryandcatchwas reported as missing a return. The same function without the wrapper passed:A callback that never returns passed if a nested closure inside it did:
The sniff now skips any
returnwhose nearest enclosing function or closure is not the callback, usingConditions::getLastCondition()from PHPCSUtils. When it decides whether areturnis conditional, it only countsifstatements inside the callback.The last case means code that passed before can now get a
MissingReturnStatementerror. That is the correct result, but it may be worth a line in the changelog.Two related gaps are left for another time. A
returnthat appears only in anelsestill counts as unconditional, because the sniff only treatsifas a control structure (see #520).hasTerminatingStatement()also still sees anexitorthrowinside a nested closure. That only changes whether a callback with no direct return gets the warning or the error.This came up while reviewing #904 and #905.