Repository navigation
Return phpdoc-parser name nodes for class names from Type::toPhpDocNode() - #6875
Merged
Merged
Conversation
phpdoc-parser 2.4 adds FullyQualifiedNameNode and RelativeNameNode for class names. They do not extend IdentifierTypeNode, and GenericTypeNode::$type, CallableTypeNode::$identifier and TypeAliasImportTagValueNode::$importedFrom can now hold them. TypeNodeResolver resolves a name node as a class against the name scope, before keywords, type aliases and template types are considered, so a RelativeNameNode named Int or T is a class, not int or a template type. The tag resolvers and IntersectionType::toPhpDocNode() no longer assume an IdentifierTypeNode there. Amp-Thread-ID: https://ampcode.com/threads/T-01a179f2-995f-7745-8d8c-4c174ba5c0ce
Type::toPhpDocNode() returned a plain IdentifierTypeNode for both keywords (int, mixed, non-falsy-string) and class names, so consumers like Rector had to guess which is which and how to print it. ObjectType, GenericObjectType, ClosureType and GetTemplateTypeType now return phpdoc-parser's FullyQualifiedNameNode, and EnumCaseObjectType a fully qualified ConstFetchNode, so a printed node resolves to the same class in any namespace. Keywords, pure-/static-Closure and template type names stay IdentifierTypeNode. describe() output is unchanged: TypeNodeDescriber prints names without the leading backslash. The turbo extension returns the same nodes. Amp-Thread-ID: https://ampcode.com/threads/T-01a179f2-995f-7745-8d8c-4c174ba5c0ce
ondrejmirtes
force-pushed
the
phpdoc-name-nodes
branch
from
October 28, 2026 20:49
1a8834e to
17f4072
Compare
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.
Type::toPhpDocNode()returned a plainIdentifierTypeNodefor both keywords (int,mixed,non-falsy-string) and class names, so consumers had to guess which was which and how to print or import it.This now uses phpdoc-parser 2.4's
NameNode,FullyQualifiedNameNodeandRelativeNameNode(phpstan/phpdoc-parser#339, pulled in by #6877). They don't extendIdentifierTypeNode, so PHPStan doesn't ship its own copies any more.Commit 1: handle name nodes when resolving PHPDocs. With phpdoc-parser 2.4, 2.3.x currently has 7
make phpstanerrors where code reads->namefrom a node that can now be aNameNode. This commit fixes them:TypeNodeResolverresolves a name node as a class against the name scope, before keywords, type aliases and template types. ARelativeNameNode('Int')in namespaceAppis the classApp\Int, whileIdentifierTypeNode('Int')is stillint.PhpDocNodeResolver(@extends,@implements,@use,@phpstan-import-type) andIntersectionType::toPhpDocNode()(PHP and turbo) no longer assume anIdentifierTypeNode.Commit 2: return name nodes from
toPhpDocNode().ObjectType,GenericObjectType,ClosureTypeandGetTemplateTypeTypereturnFullyQualifiedNameNode, andEnumCaseObjectTypea fully qualifiedConstFetchNode. A printed node resolves to the same class in any namespace and with any uses. Keywords,pure-/static-Closureand template type names stayIdentifierTypeNode.describe()output is unchanged:TypeNodeDescriberprints names without the leading backslash. That also coversOffsetAccessTypeandLateResolvableArrayShapeType.Printerclass ref is gone;fullyQualifiedNameNodeis a new one.Rector counterpart (local prototype, not opened yet): with these nodes Rector can delete its whole
PHPStanStaticTypeMapperpackage (all 30mapToPHPStanPhpDocTypeNode()mappers), about −1750 lines, with its full test suite green after a small style pass and 14 fixtures with equivalent output.