Update FileTypeMapper name scope with use statements encountered after scope creation#5714
Closed
phpstan-bot wants to merge 1 commit into
Closed
Update FileTypeMapper name scope with use statements encountered after scope creation#5714phpstan-bot wants to merge 1 commit into
FileTypeMapper name scope with use statements encountered after scope creation#5714phpstan-bot wants to merge 1 commit into
Conversation
…after scope creation - In `FileTypeMapper::createPhpDocNodeMap()`, the name scope entry for a file/namespace was created at the first non-excluded statement (e.g. a `Nop` node from `<?php // comment ?>`). If `use` statements appeared later in the file, they were collected into `$uses` but the already- created name scope entry was never updated. - Fix: after processing `Use_` and `GroupUse` nodes, check if the current name scope key already exists in the map and replace it with an updated entry containing the newly collected `$uses` and `$constUses`. - This affects template-style PHP files where inline HTML separates a comment-only PHP block from a later PHP block containing `use` statements. - All PHPDoc tags (@var, @param, @return, @throws, @phpstan-assert, etc.) benefit from this fix since they all resolve names through the same `FileTypeMapper` name scope map.
Contributor
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
usestatements appear after a comment-only PHP block (e.g.<?php // comment ?>) followed by inline HTML, PHPStan failed to resolve class names in PHPDocs through thoseusestatements. The error message showed unresolved class names (e.g.myClassinstead ofpath\to\myClass).Changes
src/Type/FileTypeMapper.php: After processingUse_andGroupUsenodes, if the current name scope key already exists in$nameScopeMap, replace it with an updatedIntermediaryNameScopethat includes the newly collected$usesand$constUses.Use_andGroupUsebranches are now combined under a singleelseifcondition to share the name scope update logic.tests/PHPStan/Rules/PhpDoc/InvalidPhpDocVarTagTypeRuleTest.phpandtests/PHPStan/Rules/PhpDoc/data/bug-14648.php.Root cause
FileTypeMapper::createPhpDocNodeMap()walks the AST depth-first and creates a name scope entry at the first non-excluded statement for each scope key (file-level, class-level, function-level). The entry captures the current$usesmap at creation time and is never updated afterward.In template-style PHP files like:
The AST contains a
Nopnode (from the comment), thenInlineHTML(excluded), thenUse_(excluded), then the expression. TheNopnode creates the name scope entry with an empty$usesmap before theUse_node is processed. Once theUse_adds to$uses, the already-created entry is stale.The fix updates the name scope entry whenever new
usestatements are encountered, ensuring the entry always reflects the complete set of imports.Test
testBug14648: Regression test with a PHP template file containing<?php // comment ?>, inline HTML, thenuse Bug14648Helper\MyClass;followed by a@var MyClassPHPDoc. Verifies the error message correctly shows the resolved class nameBug14648Helper\MyClassinstead of the unresolvedMyClass.testBug4486andtestBug4486Namespacestill pass (these test PHPDocs appearing beforeusestatements within a namespace).Fixes phpstan/phpstan#14648