Fix #12639: phpstan ignoring use paths in trait context#5081
Open
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Open
Fix #12639: phpstan ignoring use paths in trait context#5081phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Conversation
…eclarations - When a trait file had a statement (e.g. `if/die`) before `use` declarations, FileTypeMapper::createPhpDocNodeMap() would create a premature name scope entry with empty `$uses` for non-trait statements during recursive trait processing, preventing the correct entry from being created later - Added condition to skip name scope map entries for statements before the trait is found during recursive trait file processing ($lookForTrait) - New regression tests in FileTypeMapperTest, NSRT, and test data files Closes phpstan/phpstan#12639
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 trait file has a statement (like
if (!defined('Foo')) die();) beforeusedeclarations, PHPStan incorrectly resolves PHPDoc types in trait properties using the current namespace instead of the imported class names. This caused false-positive "unknown class" errors where the class name was resolved to the wrong namespace.Changes
&& ($lookForTrait === null || $traitFound)insrc/Type/FileTypeMapper.php(line 545) to prevent premature name scope map entry creation when recursively processing trait filestests/PHPStan/Analyser/nsrt/bug-12639.phptestBug12639TraitPropertyPhpDocResolutionintests/PHPStan/Type/FileTypeMapperTest.phptests/PHPStan/Type/data/bug-12639-trait.phpandtests/PHPStan/Type/data/bug-12639-class.phpRoot cause
In
FileTypeMapper::createPhpDocNodeMap(), when recursively processing a trait file (with$lookForTraitset), any statement encountered before the trait declaration would trigger creation of a name scope map entry with the current (incomplete)$usesarray. Since the$usesarray hadn't been populated yet (theusedeclarations come after the statement), the entry was created with empty imports. The!array_key_exists($nameScopeKey, $nameScopeMap)guard prevented the correct entry from being created later when the trait was actually found and$useswas properly populated.The fix adds a check that skips name scope entry creation for statements that appear before the target trait is found during recursive trait file processing.
Test
bug-12639.php): Verifies that@var ObjectRefT<Account>in a trait withif (true) {}beforeusedeclarations correctly resolves toBug12639\Types\ObjectRefT<Bug12639\Accounts\Account>both in the same namespace and from a different namespacegetResolvedPhpDoc()with a trait in a separate file that has a statement beforeusedeclarations, verifying the PHPDoc type is resolved using the trait's importsFixes phpstan/phpstan#12639