Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Allow finding arrow function variables when arrow function is in file scope #347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
sirbrillig merged 5 commits into 2.x from arrow-func-in-global-scope
Jan 6, 2025

Conversation

@sirbrillig
Copy link
Owner

@sirbrillig sirbrillig commented Jan 6, 2025

Arrow function variables are a little bit tricky to parse because while other variables always exist in one scope or another, variables found within an arrow function could be local to the arrow function or exist in the scope outside the arrow function.

Therefore, when we find a variable, we first find its largest possible scope – normally this is the function – and then check to see if there is a closer arrow function scope that contains that variable.

However, there's a bug: if the function scope is not found, we return the file scope (token index 0). There is a guard which does not allow searching for an arrow function scope if the larger scope is falsy. I believe this was meant to guard against a null scope, but it was not specific enough and so also was true when it found the file scope 0. As a result, we cannot properly parse function-level variables in arrow functions at the file-level scope.

In this PR, we modify the guard to explicitly check for null.

Fixes #346

ghnp5 reacted with hooray emoji
Copy link
Owner Author

sirbrillig commented Jan 6, 2025
edited
Loading

Some tests are failing because of some dependency issue with phpcs's dev-master branch. It has nothing to do with this PR. See #348

@sirbrillig sirbrillig merged commit ffb6f16 into 2.x Jan 6, 2025
8 of 56 checks passed
@sirbrillig sirbrillig deleted the arrow-func-in-global-scope branch January 6, 2025 17:54
$enclosingScopeIndex = self::findVariableScopeExceptArrowFunctions($phpcsFile, $stackPtr);
if ($enclosingScopeIndex) {

if (!is_null($enclosingScopeIndex)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can self::findVariableScopeExceptArrowFunctions() return false ? Would a check for is_int() instead of !is_null() be more stable ?

Copy link
Owner Author

@sirbrillig sirbrillig Jan 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it can return false. It returns null|int. It has only 3 return statements:

  • this one which is always an integer (guarded by is_int()).
  • this one which is also always an integer.
  • this one which is the return value of getStartOfTokenScope() when it's not an integer or less than or equal to 0. Since that function can return null or 0 or a key from the token conditions stack, I think it is always null|int, unless there's something I don't grok about conditions (can the key of a conditions array be false?).

jrfnl reacted with thumbs up emoji
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair enough. I was mostly asking because the code within the condition seems to expect an int, while the condition doesn't actually strictly safeguard that.

Copy link
Owner Author

@sirbrillig sirbrillig Jan 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. I think that is_int() is probably better for that reason, but I'm going to leave it for now since I already merged and I have to trust the types in the phpdoc, even if they're only enforced by static analysis tools.

I checked, and if I change the return type of findVariableScopeExceptArrowFunctions to int|null|false, I get this error:

Parameter #3 $enclosingScopeIndex of static method VariableAnalysis\Lib\Helpers::getContainingArrowFunctionIndex() expects int, int|false given.

So everything should be safe. Hooray for strong types!

jrfnl reacted with thumbs up emoji
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@jrfnl jrfnl jrfnl left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

False positives of UnusedVariable in fn() functions

AltStyle によって変換されたページ (->オリジナル) /