Problem/Motivation
Amongst the "new" errors found when running PHPStan on level 2 is: Variable $foo in PHPDoc tag @var does not exist.
This child-issue exists to fix all of those.
Steps to reproduce
# Generate the baseline for level 2.
$ ./vendor/bin/phpstan analyse -c core/phpstan.neon.dist --generate-baseline=core/.phpstan-baseline.php --level=2
# Grep for the error with 1 line before and 4 lines after.
$ grep -B1 -A4 "in PHPDoc tag @var does not exist." core/.phpstan-baseline.php
Proposed resolution
- Solve all of the the above mentioned reported errors.
- Run PHPStan on level 2 and don't see the above mentioned error any more.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|
Issue fork drupal-3322821
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
mondrakeComment #3
spokjeThanks for adding the forgotten tag @mondrake.
The attached level2.txt is the output of
vendor/bin/phpstan analyze --configuration=core/phpstan.neon.distafter setting PHPStan to level 2.We're down from the original
[ERROR] Found 9440 errorsto[ERROR] Found 9398 errors.Nice, for what seems to be low hanging fruit. :)
Comment #4
spokjeComment #5
mondrakeIt looks like we're getting to the point where PHPStan will start changing a bit our habits...
It's rather strange that the PHPDoc follows the variable initialization. Have you tried to init the variable outside the if?
or, if it's necessary to let PHPStan know about the type of a variable after it has been defined, you could use
assert()like e.g.BTW, the if after the assert at that point becomes redundant.
this feels wrong... in the second case $original definitely is not a content entity...
here we probably should use an assert somewhere later... what happens if
method_exists($this, 'configFactory')is false?... and so on ...
Comment #6
spokje1.
Well, that was the original code, which PHPStan doesn't like.
To me it looks like _any_ variable initialization in an
if-statement isn't correctly picked up on by PHPStan, i.e. not recognized at all, making PHPStan believe the typehint is moot.So, should we switch to the
assert?Should we try to fix this issue upstream?
Comment #7
mondrakeWe're not the first... https://github.com/phpstan/phpstan/issues/7934
Comment #8
spokjeHmmm, open since Sep 5, no real action on it afterwards...
Comment #9
mondrakeAs I said, IMHO we should reconsider our habits...
Wouldn't the entire method be better like
for sure, this means this is no longer a low hanging fruit...
PHPStan really drives code to be more declarative.
Comment #10
spokjeShould we perhaps split up this issue in low-hanging-fruit ones and the more difficult ones, like the one mentioned in the comment above this one, to speed up the process?
Comment #11
mondrakeI think #10 makes sense.
Comment #12
spokjeAdded child issue #3323702: Fix PHPStan L2 error "Variable $foo in PHPDoc tag @var does not exist. " - Low Hanging Fruit Edition for the low hanging fruit ones.
Comment #14
spokjeComment #17
mstrelan commentedUpdated steps to reproduce. Rerolled as an MR. Hiding patches.
While I agree it would be nice to use early returns and not assign variables inside if statements, I think it makes sense why phpstan behaves the way it does. If the condition is falsey then the variable will not match the type we're hinting. We can only hint it once we the condition evaluates to true.
Happy to work on refactoring the methods but I fear it would need to be split many more times to satisfy reviewers.
Comment #18
smustgrave commentedNot sure I follow, just looking at the first file core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php isn't it correct there as that's where $revision is set?
Comment #19
mstrelan commented@smustgrave
Well loadRevision can return null, so in that case the @var doc would be wrong. But that is kind of moot because $revision is not used outside the if statement. Either way, phpstan doesn't like it the way it is.
It's worth also noting that loadRevision returns a RevisionableInterface, but invokeFieldMethod and doDeleteRevisionFieldItems expect a ContentEntityInterface, so we need to tell phpstan that we've got the latter.
To avoid the @var tag we could write it like this:
Comment #20
smustgrave commentedSo not 100% sure how to review this one
Comment #21
mstrelan commented@smustgrave did you try the steps in the IS? Try that against 11.x and again against this branch and you should see the diff of errors that are resolved. We could nitpick if the
@vartags have moved to the right places, but if phpstan is happy now then I think that is satisfactory.Also here are some updated steps to avoid touching the baseline file, I like to use
--error-format=rawto get one error per line for easier grepping.That currently gives me 27 errors on 11.x and 0 in this branch.
Comment #22
dcam commentedLooking good. I left a couple of suggestions.
Comment #23
mstrelan commentedResponded to one, hopefully that helps to explain why they are where they are. I don't intend to make further updates, so feel free to try move things around and run the commands. If things still pass feel free to push those changes.
Comment #24
dcam commentedI performed the manual check as described in the issue summary on my suggestions. The suggestions also passed linting. So I pushed them here.
Comment #25
smustgrave commentedSo my only hesitation is the @var that's moving inside the if statements now, makes it harder to read IMHO. Do we care though?
Comment #26
dcam commentedThe change doesn't bother me much since I kind of mentally filter them out. I suppose that means I assume they're for machine consumption. That's a subjective idea, so differing opinions are relevant. But for what it's worth I think it's ok.
I suppose the alternative would be to move assignments out of the conditions.
Comment #28
borisson_#25:
I think it probably doesn't take very long to get used to this style, but it looks a bit funky to me as well.
#26:
I think moving the assignments out of the conditions would probably need to make them look like
@var Thing|null $fooin a lot of places and that decreases the value of these in my opinion.I did not manually test this, leaning on #24 for that.
Comment #29
longwaveA bunch of questions here, I only reviewed the first few pages.
Comment #30
mstrelan commentedFound there were a few annotations we can simply delete because they could be inferred. Some of these were due to improvements in core, some may have been due to improvements in phpstan-drupal and finally some may have never been needed in the first place.
Comment #31
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #32
dcam commentedRebased.
MenuTreeStorageSchemaUpdateTestwas deleted due to the pre-D12 old update function removals.Comment #33
smustgrave commentedbelieve feedback has been addressed for this one, no additional feedback.