-
-
Notifications
You must be signed in to change notification settings - Fork 687
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
Taking advantage of static reflection #3490
Comments
Hi Ondra, I just found out that internal errors were reported as positive in CI 🤦♂️ After fixin that, I've discovered that between PHPStan 0.12.25 and 0.12.26 the reflection broke. It breaks here: rector/packages/node-type-resolver/src/PHPStan/Scope/PHPStanNodeScopeResolver.php Line 162 in 5cb1947
Even if I make Any ideas? |
That's weird, CI on Github Action passes: https://github.com/rectorphp/rector/pull/3628/checks?check_run_id=828250558 I'll investigate |
Allright, deleting all PHPStan, I'll try to use the latest PHPStan version and upgrade to the new static reflection |
I've found it! It seem the robot loader cache stored files. This fixed it: |
PHPStan no longer uses RobotLoader, you shouldn't need it either, it's not exactly static in nature :) |
How do I load the stubs then? |
Learn how the static reflection works - especially source locators. When you set up the static reflection engine, point one of the source locators at the stubs directory. That’s all. |
How exactly can I add such directory in scanDirectories:
- stubs |
Yes but they need to be complete but it doesn't look like they are: https://github.com/rectorphp/rector/blob/master/stubs/PHPUnit/PHPUnit_Framework_TestCase.php which will lead to analysis failures (unknown methods etc). Not sure what you need the "stubs" for - usually these classes already exist in analysed projects, why define them again but empty? |
BTW the fact you currently have the stubs in the current shape and form is the reason why the current dev-master of phpstan/phpstan shows these errors:
You shouldn't have stubs for something you already have in |
I'll take a stab at changing Rector to leverage static reflection. |
@TomasVotruba Since we have cinfirmation that PHPStan no longer uses RobotLoader, it would seem that the I tried my best to create a failing integration test with the latest PHPStan, but I can't. This is either great news or I'm doing something terribly wrong. This test will pass: https://github.com/afilina/rector/pull/1/files |
@ondrejmirtes Will a duplicate symbol from a different file just be ignored once cached? I often analyze cade that has the same class names but are actually different, because they're loaded using different include chains. |
That sounds good. How can we make it work in cases without |
@TomasVotruba I described that already, you need to take advantage of source locators and set them up based on directories passed to Rector. |
@afilina I need to know in which context are you asking about this. Are you talking about PHPStan's analysis and PHPStan's result cache? Multiple classes with the same name are fine as long as they stay local. PHPStan can analyse class |
Of course that can be different when it comes to Rector doing its thing. |
That answers my question, thanks. I'll need to come up with sensible behavior for Rector given this constraint. In the past, with runtime reflection, it would have just crashed on that use case. |
@ondrejmirtes Hi Ondra, I'm looking into this again so we can resolve it and benefit from it. I was not able to find any source locator inside. How can we tell PHPStan that file I did something similar for $nodeScopeResolver->setAnalysedFiles(['some_file.php']); The simpler the better :) I need working even hacky example, the quality of solution can be improved later. |
Source locators are inside the various reflectors here: https://github.com/phpstan/phpstan-src/blob/c1f7aafc47d007cbb82114ce1fb306a971333f26/src/Reflection/BetterReflection/BetterReflectionProvider.php#L45-L49 You can see which source locators (and the order) PHPStan itself uses here: https://github.com/phpstan/phpstan-src/blob/master/src/Reflection/BetterReflection/BetterReflectionSourceLocatorFactory.php To locate sources in a single file, you'd want |
I was able to get |
SourceLocator is the one and only constructor argument of ClassReflector. |
You can also get a lot of knowledge from BetterReflection's docs: https://github.com/Roave/BetterReflection/blob/4.13.x/docs/usage.md |
I think I have idea how to create them and bind them manually apart PHPStan. I'm lacking knowledge on how to set them to PHPStan after PHPStan container is compiled. I've checked the docs and used this package on ApiGen, it seems my use case is not covered. To use my own SourceLocator I have to remove the original one and replace it with Isn't there something on the fly? Like: $sourceLocator->addFile(....); Each test is creating a new file that we need to parse, so I would have to create new PHPStanContainer for every single test 🤔 |
The best way is to create your own factory that returns
|
I see. I'll try to hack in my service that will be both part of Rector and PHPStan. I get it better now. Thanks 👍 |
rectorphp/rector-src@5371408 [Container] Add RectorConfig::containerCacheDirectory() (#3490)
Hi, I'm reacting to #3488 (comment) which is about PHPStan 0.12.26.
Rector can take advantage of it, you should take these steps:
The class blacklist is there so that some certain classes are skipped for the runtime reflection and go straight to static reflection.
If you enable the experimental flag
featureToggles.disableRuntimeReflectionProvider
(set to true) then the reflection provider instance is just going to be the BetterReflectionProvider.The most important thing about BetterReflectionProvider is the source locator chain it uses. In PHPStan it's created in this class: https://github.com/phpstan/phpstan-src/blob/master/src/Reflection/BetterReflection/BetterReflectionSourceLocatorFactory.php (you might want to write your own).
It's quite difficult to construct BetterReflectionProvider by hand but fortunately there's a Nette DI-generated factory based on this interface: https://github.com/phpstan/phpstan-src/blob/master/src/Reflection/BetterReflection/BetterReflectionProviderFactory.php
Here are the services definitions: https://github.com/phpstan/phpstan-src/blob/master/conf/config.neon#L1095-L1125
Let me know if you have any questions 👍
The text was updated successfully, but these errors were encountered: