Skip to content

Remove Reflector from StubFilesExtensionLoader, replace with version checks#486

Merged
staabm merged 2 commits intophpstan:2.0.xfrom
xificurk:stub-loader-without-reflection
May 9, 2026
Merged

Remove Reflector from StubFilesExtensionLoader, replace with version checks#486
staabm merged 2 commits intophpstan:2.0.xfrom
xificurk:stub-loader-without-reflection

Conversation

@xificurk
Copy link
Copy Markdown
Contributor

@xificurk xificurk commented May 7, 2026

The loader previously used BetterReflection's Reflector to check whether InputBag existed before loading its stubs. This triggered SourceLocator initialization (an expensive cache-populating operation) on every analysis run.

Replace the reflectClass() call with an isInstalledVersionBelow() version check (InputBag was introduced in symfony/http-foundation 5.1). Add a test that wires a ThrowingSourceLocator into the DI container's betterReflectionSourceLocator service, so any future regression that causes getFiles() to touch BetterReflection will fail the test explicitly.

--

Related:

@VincentLanglet
Copy link
Copy Markdown
Contributor

@VincentLanglet VincentLanglet requested a review from staabm May 7, 2026 21:24
@staabm
Copy link
Copy Markdown
Contributor

staabm commented May 8, 2026

I think it would be useful if we could have a phpbench here (similar as in phpstan-src), which makes sure changes in the extension will not regress performance in the future (actually such a benchmark would be useful for all the 1st party extensions).

how can the improvement of this change be reproduced?

@xificurk xificurk force-pushed the stub-loader-without-reflection branch 3 times, most recently from 17f1a0d to 6562df2 Compare May 8, 2026 11:21
@xificurk
Copy link
Copy Markdown
Contributor Author

xificurk commented May 8, 2026

@staabm I have updated the regression test to more closely cover the real use case, which is to avoid BetterReflection initialization just for ResultCache.

BetterReflection cache init cost becomes significant only on larger code base. I'm not sure how useful would phpbench be to guard this case - the dummy codebase would need to be big to avoid false positive regression signals.

use PHPStan\Command\Output;
use PHPStan\Testing\PHPStanTestCase;

final class ResultCacheNoReflectionTest extends PHPStanTestCase
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thanks for this test.

@ondrejmirtes do you think this one would make sense directly in phpstan-src?
that way we could assert that ResultCache construction will not trigger reflection.

this assumption might be useful as general logic, and is not specific to phpstan-symfony

Copy link
Copy Markdown
Contributor

@staabm staabm May 9, 2026

Choose a reason for hiding this comment

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

based on the test added by @xificurk here, I added one in phpstan-src with phpstan/phpstan-src#5617

I think this is more useful, as we can later on cover all phpstan 1st party extensions with a single test

@staabm staabm force-pushed the stub-loader-without-reflection branch from 6562df2 to 27d013e Compare May 9, 2026 06:58
@staabm
Copy link
Copy Markdown
Contributor

staabm commented May 9, 2026

this got approved by vincent, so I will merge this with the fix-only to verify the newly added phpstan-src test works as expected.

thank you @xificurk

@staabm staabm merged commit 912e769 into phpstan:2.0.x May 9, 2026
43 checks passed
@ondrejmirtes
Copy link
Copy Markdown
Member

Please don't forget to tag the release 😊

@staabm
Copy link
Copy Markdown
Contributor

staabm commented May 9, 2026

ok cool. I was waiting for a signal that this is fine for you. thanks

@xificurk xificurk deleted the stub-loader-without-reflection branch May 9, 2026 08:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants