Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Track PHPDoc and modifier flags on ExportedParameterNode for result cache invalidation#5518

Merged
ondrejmirtes merged 1 commit into
phpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-o0ctj92
Apr 23, 2026
Merged

Track PHPDoc and modifier flags on ExportedParameterNode for result cache invalidation#5518
ondrejmirtes merged 1 commit into
phpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-o0ctj92

Conversation

@phpstan-bot
Copy link
Copy Markdown
Collaborator

Summary

When a @var annotation on a constructor promoted property was modified, the result cache was not invalidated because ExportedParameterNode did not track PHPDoc annotations or modifier flags. This meant dependent files were not re-analysed, leading to stale cached results.

Changes

  • Added ?ExportedPhpDocNode $phpDoc and int $flags fields to ExportedParameterNode (src/Dependency/ExportedNode/ExportedParameterNode.php)
    • Updated equals() to compare PHPDoc nodes and flags
    • Updated jsonSerialize(), decode(), and __set_state() with backward-compatible defaults (null and 0)
  • Updated ExportedNodeResolver::exportParameterNodes() (src/Dependency/ExportedNodeResolver.php) to:
    • Accept $fileName and ?string $className context parameters for PHPDoc resolution
    • Extract doc comments from parameter nodes via $param->getDocComment()
    • Pass $param->flags to capture visibility (public/protected/private) and readonly modifiers
  • Updated all three call sites: function parameters, class method parameters, and property hook parameters
  • Added e2e test result-cache-9 for the reported bug: @var annotation change on a promoted property
  • Added e2e test result-cache-10 for an analogous case: visibility change (publicprotected) on a promoted property
  • Registered both new e2e tests in .github/workflows/e2e-tests.yml

Root cause

ExportedParameterNode tracked only the parameter's name, native type, by-ref, variadic, default, and attributes. It did not track:

  1. PHPDoc annotations — a /** @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, so equals() returned true and the cache was not invalidated.
  2. Modifier flags — promoted properties carry visibility and readonly flags on the parameter node (not as a separate Property statement). Changing public to protected on a promoted property did not invalidate the cache either, since flags were not tracked.

Both issues are fixed by adding $phpDoc and $flags to the exported parameter node.

Analogous cases probed and found to be already correct:

  • Regular (non-promoted) parameter PHPDoc on functions — now also tracked, though less commonly used
  • Property hook parameters — now also receive context for PHPDoc resolution
  • ExportedPropertiesNode (non-promoted properties) — already tracks PHPDoc, visibility, readonly, and all flags correctly
  • ExportedMethodNode — already tracks PHPDoc
  • ExportedClassConstantsNode — already tracks PHPDoc

Test

  • result-cache-9: Class Foo has /** @var list<string> */ public array $x promoted property. Class Bar calls acceptStrings(list<string>) with $foo->x. Patch changes annotation to list<int>. Without the fix, the cache is not invalidated and the type error is missed.
  • result-cache-10: Class Foo has public string $x promoted property. Class Bar accesses $foo->x. Patch changes public to protected. Without the fix (tracking flags), the access error would be missed.

Fixes phpstan/phpstan#14520

… 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)
@ondrejmirtes ondrejmirtes merged commit 4734410 into phpstan:2.1.x Apr 23, 2026
654 checks passed
@ondrejmirtes ondrejmirtes deleted the create-pull-request/patch-o0ctj92 branch April 23, 2026 11:20
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.

2 participants