Repository navigation
Track result cache dependencies instead of a site-wide hash - #1071
Merged
Merged
Conversation
Extract extension discovery, services.yml parsing, and schema directories from DrupalAutoloader into DrupalSite. PHPStan's result cache extensions run before bootstrap files, so they need to read the site without running the bootstrap. No change in behavior: the bootstrap reads the same data from the same place. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace BootstrapResultCacheMetaExtension with value and file dependencies from PHPStan 2.3, and require phpstan/phpstan ^2.3. Changing a service re-analyzes the files asking about it, and changing schema re-analyzes the files reading config. Adding or removing an extension still re-analyzes everything, because the bootstrap registers an autoload namespace for each one. This also fixes stale results on PHPStan 2.3. Restoring the cache runs before bootstrap files, so the old extension hashed empty state and never invalidated. ResultCacheInvalidationTest runs real PHPStan processes against a changing site, because only a real run has the main process and workers disagree this way. Fixes #1061 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1061. Targets 2.3.0: this raises
phpstan/phpstanto^2.3.A bug this also fixes
On PHPStan 2.3,
BootstrapResultCacheMetaExtensionnever invalidates the cache, so users get stale results until they clear it. PHPStan 2.3 defers bootstrap files and doesn't run them when restoring the cache.ServiceMap,ExtensionMap, andConfigSchemaDataare empty at that point, so the extension always hashed the same empty state.Reproduced on the 2.2.3 code with PHPStan 2.3.5:
class.notFoundstill reportedWhat changed
The cache now tracks what each file reads:
argumentsortagsof a service.info.ymleditloadInclude()file created or changedDrupalSitereads extensions, service definitions, and schema directories from disk without the bootstrap. The bootstrap uses it too, so the two can't disagree. This is its own commit with no behavior change.DrupalSite, not the bootstrap-populated maps. A service's value covers its alias target, parent, and decorators.ExtensionListDependencyRulemakes every file depend on the extension list. It never reports an error. A new extension changes which classes exist, and a file whose error is a missing class has no other dependency to re-analyze it.phpcs.xmlnow setssearchAnnotationsonUnusedUses.phpcbfwas deleting theDependencyTrackerimports, since the docs say that type belongs only in the PHPDoc.Known limits
service_provider.*entries and the synthetic services set inDrupalAutoloaderaren't part ofDrupalSite, so their value is alwaysmissing. They're derived from the extension list, which is tracked separately, or are hardcoded.Testing
ResultCacheInvalidationTestruns real PHPStan processes with two workers against a site it changes, and asserts how many files get re-analyzed. It's the only kind of test that could have caught this, because the main process and workers see different state. It adds about 40 seconds per test job. An earlier version of this branch read the bootstrap-populated maps and re-analyzed all files on every run, which is the failure it now guards against.ResultCacheValueExtensionsTestcovers the values themselves.Lint and the full suite pass locally on PHPStan 2.3.5 with 890 tests. I haven't measured the cost of the scan on a large site's warm run.
🤖 Generated with Claude Code