Skip to content
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

Prepare for PHPStan 1.0 #6744

Closed
ondrejmirtes opened this issue Oct 14, 2021 · 28 comments
Closed

Prepare for PHPStan 1.0 #6744

ondrejmirtes opened this issue Oct 14, 2021 · 28 comments
Labels

Comments

@ondrejmirtes
Copy link
Contributor

Hello everyone 👋

I announced today that PHPStan 1.0 is going to be released on November 1st 2021.

I'm approaching you as one of the most popular projects using PHPStan internally. I'd love if you could prepare your code for PHPStan 1.0 in advance so that it's ready to release on the same day.

Here's a brief guide how to approach the upgrade:

  1. Create a branch 🌴
  2. Update your composer.json to "phpstan/phpstan": "^1.0", add "minimum-stability": "dev" and "prefer-stable": true if necessary.
  3. Update your code with the BC breaks below in mind. 🔧
  4. Fix the code so that it passes PHPStan's analysis 🤓
  5. Wait for PHPStan 1.0 release on November 1st, merge your branch and tag the next major version 👍

Thank you!


Here are the BC breaks. The list is huge but most of those have very little impact.

There are new rules around using PHPStan internals in regard to backward compatibility promise: https://phpstan.org/developing-extensions/backward-compatibility-promise

It's possible that not everything you use is covered by it - so I'm here to help you to transition to correct usage, or add some @api annotations in PHPStan itself so that more is covered by the promise. Let me know!

BC breaks for end-users

The following are interesting only if you create a custom ruleset in your configuration file:

BC breaks for extension developers

@TomasVotruba
Copy link
Member

TomasVotruba commented Oct 14, 2021

Thanks Ondra, mainly for the list of changes and commit references 👍

Is there Rector set I can run to upgrade all the BC breaks? 😆

@ondrejmirtes
Copy link
Contributor Author

Is there Rector set I can run to upgrade all the BC breaks?

There isn't, and I don't know if it's possible to write one because of the circular dependency nature with PHPStan. People would have to stay on an old version of Rector that requires PHPStan 0.12.x in order to run it.

@TomasVotruba
Copy link
Member

TomasVotruba commented Oct 14, 2021

That can be done, as first you run upgrade code, then composer update.

I'll see how many changes are needed in Rector + Symplify + custom rules in projects I workh with. If it will be more than 50, I'll put a set together 👍

@TomasVotruba
Copy link
Member

TomasVotruba commented Oct 23, 2021

Additional Changes

@ondrejmirtes
Copy link
Contributor Author

Hi, yeah, if you need PHPStan\Parser\Parser, you should create exactly the instance you need and register it as your own service.

Some implementations you can choose from are:

  • SimpleParser - thin wrapper around PhpParser\Parser
  • RichParser - adds some useful attributes to nodes but is more memory hungry
  • CleaningParser - removes function bodies so if you're interested only in function signatures and PHPDocs, and want to cache the AST, this is the one you want. This is the one that PHPStan uses for parsing vendor.
  • PathRoutingParser - wrapper of three different parsers, chooses the right one based on the path of the parsed file. phpstorm-stubs always need to be analysed with PHP 8 parser (using Emulative lexer), analysed files need to be analysed with RichParser, vendor dependencies are analysed with SimpleParser (wrapped in CleaningParser). You probably don't want this one in Rector.
  • CachedParser - caching wrapper around another PHPStan\Parser\Parser instance

In your case, I'd probably create SimpleParser instance with PHP 8 PhpParser inside (created with Emulative lexer) and wrapped it in CachedParser for faster performance.

To see what instances are used in PHPStan, refer to the DI config: https://github.com/phpstan/phpstan-src/blob/99e4ae0dced58fe0be7a7aec3168a5e9d639240a/conf/config.neon#L1517-L1557 and https://github.com/phpstan/phpstan-src/blob/99e4ae0dced58fe0be7a7aec3168a5e9d639240a/conf/config.neon#L1669-L1691

@TomasVotruba
Copy link
Member

TomasVotruba commented Oct 24, 2021

@ondrejmirtes Awesome, thanks for details and links! It's very helpful

In your case, I'd probably create SimpleParser instance with PHP 8 PhpParser inside (created with Emulative lexer) and wrapped it in CachedParser for faster performance.

I'll give it a try 👍

To see what instances are used in PHPStan, refer to the DI config

👏 🥇

@TomasVotruba
Copy link
Member

@ondrejmirtes Hi Ondra, I'm almost finished, thank to your specific commit list. Thank you for that.

Last issue I have is that in ~10 cases the PropertyFetch type analyzer broke. It returned specific type before, but now it returns MixedType. Any idea what could have changed?

@ondrejmirtes
Copy link
Contributor Author

@TomasVotruba Can you show me the code that works with PHPStan and is now broken? Also can it be reproduced on phpstan.org with \PHPStan\dumpType($this->property)?

@ondrejmirtes
Copy link
Contributor Author

Also please show me example of analysed code that now fails and example of code that still passes, so I can get some ideas what changed.

@TomasVotruba
Copy link
Member

TomasVotruba commented Oct 25, 2021

It can be seen in any failing test case in this PR: rectorphp/rector-src#1052

E.g. the most isolated error is property fetch in https://github.com/rectorphp/rector-symfony

This line:
https://github.com/rectorphp/rector-symfony/blob/8020e46c0ea9d7769b896f392ad96ff11bcbb745/tests/Rector/MethodCall/SwiftCreateMessageToNewEmailRector/Fixture/fixture.php.inc#L18

The $this->swift was resolved as ObjectType of Swift_Mailer. Now its MixedType.
The Swift_Mailer exists as a stub an is loaded by composer.json


I'm gonna try to reproduce in demo now.

@TomasVotruba
Copy link
Member

@ondrejmirtes
Copy link
Contributor Author

So which parser did you choose? :) Looks like the analysed code is passed through the CleaningParser mentioned above and https://phpstan.org/config-reference#inferprivatepropertytypefromconstructor doesn't work (because it doesn't see the constructor body).

@TomasVotruba
Copy link
Member

This will be the problematic class in Rector: https://github.com/rectorphp/rector-src/blob/48cb8a256db8cabbf00d7a125fb838d843d9415e/packages/NodeTypeResolver/NodeTypeResolver/PropertyTypeResolver.php#L43-L47

I'm trying to analyse type of property based on fake property fetch.

@TomasVotruba
Copy link
Member

There was no change in parser, we use native php-parser here.

The inferPrivatePropertyTypeFromConstructor is always enabled for PHPStan we use.

I've found 2 commits in PHPStan that might have affected it:

I would try to invert the code manually to verify if thats the place, but due to PHAR I can't change the code.

@ondrejmirtes
Copy link
Contributor Author

There was no change in parser, we use native php-parser here.

That's not true. The code in PHPStan that infers property types from constructor uses some PHPStan's Parser instance. So you need to examine that.

@TomasVotruba
Copy link
Member

I mean in our code, I didn't do any change.

@TomasVotruba
Copy link
Member

So to make inference work, now the PHPStan parser has to be used?
Could you link the commit where this change? Maybe that would help me to understand what should be changed in here.

@ondrejmirtes
Copy link
Contributor Author

You need to do some changes based on this comment #6744 (comment)

Because PHPStan internally still uses its own parser. You might have to override defaultAnalysisParser service with a different implementation so that it works for you.

@ondrejmirtes
Copy link
Contributor Author

We can schedule a call for Wednesday morning if you're struggling with this. 👍

@TomasVotruba
Copy link
Member

TomasVotruba commented Oct 25, 2021

I'm trying to resolve it last 5 hours without much success :D

Call would be very helpful, thank you 👍 At 8/9/10 hrs?

@ondrejmirtes
Copy link
Contributor Author

10:00 would be ideal - we can use Google Meet, or plain old phone call.

@RobinHoutevelts
Copy link

Happy to see such teamwork! 🚀 🤩

@TomasVotruba Is there a timeframe for a next release?

RobinHoutevelts added a commit to RobinHoutevelts/wmcodestyle that referenced this issue Nov 1, 2021
Rector has support for phpstan ^1.0 but hasn't made a release yet. Please follow rectorphp/rector#6744
@bitgandtter
Copy link
Contributor

there is any ETA for this one?

@TomasVotruba
Copy link
Member

Hi, we're currently testing Symplify 10 that is using PHPStan 1.0 and NEON traversing.
There is couple bugs to catch before releasing Rector :)

I think this or start of next week is doable.

@samsonasik
Copy link
Member

samsonasik commented Nov 5, 2021

@TomasVotruba another known issue on PHP 7.x

The CI github action show the error at e2e/define-constant https://github.com/rectorphp/rector/runs/4117180235?check_suite_focus=true

@alexander-schranz
Copy link

Looks like this can be closed now 🎉

@TomasVotruba
Copy link
Member

TomasVotruba commented Nov 12, 2021

Indeed, thanks for reminder 🤗

@Kocal
Copy link

Kocal commented Nov 12, 2021

Yay! Nice work! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants