Track PHPDoc and modifier flags on ExportedParameterNode for result cache invalidation#5518
Merged
ondrejmirtes merged 1 commit intoApr 23, 2026
Conversation
… cache invalidation - Add `?ExportedPhpDocNode $phpDoc` and `int $flags` fields to `ExportedParameterNode` so that changes to `@var` annotations and visibility/readonly modifiers on promoted constructor properties invalidate the result cache - Update `ExportedNodeResolver::exportParameterNodes()` to accept file name and class name context, extract parameter doc comments, and pass modifier flags - Update all three call sites (functions, class methods, property hooks) to pass the new context parameters - Add e2e test (result-cache-9) for `@var` annotation change on a promoted property - Add e2e test (result-cache-10) for visibility change on a promoted property (public → protected)
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.
Summary
When a
@varannotation on a constructor promoted property was modified, the result cache was not invalidated becauseExportedParameterNodedid not track PHPDoc annotations or modifier flags. This meant dependent files were not re-analysed, leading to stale cached results.Changes
?ExportedPhpDocNode $phpDocandint $flagsfields toExportedParameterNode(src/Dependency/ExportedNode/ExportedParameterNode.php)equals()to compare PHPDoc nodes and flagsjsonSerialize(),decode(), and__set_state()with backward-compatible defaults (nulland0)ExportedNodeResolver::exportParameterNodes()(src/Dependency/ExportedNodeResolver.php) to:$fileNameand?string $classNamecontext parameters for PHPDoc resolution$param->getDocComment()$param->flagsto capture visibility (public/protected/private) andreadonlymodifiersresult-cache-9for the reported bug:@varannotation change on a promoted propertyresult-cache-10for an analogous case: visibility change (public→protected) on a promoted property.github/workflows/e2e-tests.ymlRoot cause
ExportedParameterNodetracked only the parameter's name, native type, by-ref, variadic, default, and attributes. It did not track:/** @var list<string> */on a promoted property parameter defines the property's PHPDoc type. Changing it to/** @var list<int> */did not change any tracked field, soequals()returnedtrueand the cache was not invalidated.readonlyflags on the parameter node (not as a separatePropertystatement). Changingpublictoprotectedon a promoted property did not invalidate the cache either, since flags were not tracked.Both issues are fixed by adding
$phpDocand$flagsto the exported parameter node.Analogous cases probed and found to be already correct:
ExportedPropertiesNode(non-promoted properties) — already tracks PHPDoc, visibility, readonly, and all flags correctlyExportedMethodNode— already tracks PHPDocExportedClassConstantsNode— already tracks PHPDocTest
Foohas/** @var list<string> */ public array $xpromoted property. ClassBarcallsacceptStrings(list<string>)with$foo->x. Patch changes annotation tolist<int>. Without the fix, the cache is not invalidated and the type error is missed.Foohaspublic string $xpromoted property. ClassBaraccesses$foo->x. Patch changespublictoprotected. Without the fix (tracking flags), the access error would be missed.Fixes phpstan/phpstan#14520