5959use PHPStan \Node \ReturnStatement ;
6060use PHPStan \Node \UnreachableStatementNode ;
6161use PHPStan \Parser \Parser ;
62- use PHPStan \PhpDoc \PhpDocBlock ;
62+ use PHPStan \PhpDoc \PhpDocInheritanceResolver ;
6363use PHPStan \PhpDoc \ResolvedPhpDocBlock ;
6464use PHPStan \PhpDoc \Tag \ParamTag ;
6565use PHPStan \Reflection \ClassReflection ;
@@ -110,6 +110,9 @@ class NodeScopeResolver
110110 /** @var \PHPStan\Type\FileTypeMapper */
111111 private $ fileTypeMapper ;
112112
113+ /** @var \PHPStan\PhpDoc\PhpDocInheritanceResolver */
114+ private $ phpDocInheritanceResolver ;
115+ 113116 /** @var \PHPStan\File\FileHelper */
114117 private $ fileHelper ;
115118
@@ -138,6 +141,7 @@ class NodeScopeResolver
138141 * @param \PHPStan\Reflection\ReflectionProvider $reflectionProvider
139142 * @param Parser $parser
140143 * @param FileTypeMapper $fileTypeMapper
144+ * @param PhpDocInheritanceResolver $phpDocInheritanceResolver
141145 * @param FileHelper $fileHelper
142146 * @param TypeSpecifier $typeSpecifier
143147 * @param bool $polluteScopeWithLoopInitialAssignments
@@ -150,6 +154,7 @@ public function __construct(
150154 ReflectionProvider $ reflectionProvider ,
151155 Parser $ parser ,
152156 FileTypeMapper $ fileTypeMapper ,
157+ PhpDocInheritanceResolver $ phpDocInheritanceResolver ,
153158 FileHelper $ fileHelper ,
154159 TypeSpecifier $ typeSpecifier ,
155160 bool $ polluteScopeWithLoopInitialAssignments ,
@@ -162,6 +167,7 @@ public function __construct(
162167 $ this ->reflectionProvider = $ reflectionProvider ;
163168 $ this ->parser = $ parser ;
164169 $ this ->fileTypeMapper = $ fileTypeMapper ;
170+ $ this ->phpDocInheritanceResolver = $ phpDocInheritanceResolver ;
165171 $ this ->fileHelper = $ fileHelper ;
166172 $ this ->typeSpecifier = $ typeSpecifier ;
167173 $ this ->polluteScopeWithLoopInitialAssignments = $ polluteScopeWithLoopInitialAssignments ;
@@ -2540,7 +2546,6 @@ private function processNodesForTraitUse($node, ClassReflection $traitReflection
25402546 public function getPhpDocs (Scope $ scope , Node \FunctionLike $ functionLike ): array
25412547 {
25422548 $ templateTypeMap = TemplateTypeMap::createEmpty ();
2543- $ phpDocBlockTemplateTypeMap = null ;
25442549 $ phpDocParameterTypes = [];
25452550 $ phpDocReturnType = null ;
25462551 $ phpDocThrowType = null ;
@@ -2555,8 +2560,9 @@ public function getPhpDocs(Scope $scope, Node\FunctionLike $functionLike): array
25552560 $ file = $ scope ->getFile ();
25562561 $ class = $ scope ->isInClass () ? $ scope ->getClassReflection ()->getName () : null ;
25572562 $ trait = $ scope ->isInTrait () ? $ scope ->getTraitReflection ()->getName () : null ;
2558- $ phpDocBlock = null ;
2563+ $ resolvedPhpDoc = null ;
25592564 $ functionName = null ;
2565+ 25602566 if ($ functionLike instanceof Node \Stmt \ClassMethod) {
25612567 if (!$ scope ->isInClass ()) {
25622568 throw new \PHPStan \ShouldNotHappenException ();
@@ -2569,51 +2575,35 @@ public function getPhpDocs(Scope $scope, Node\FunctionLike $functionLike): array
25692575
25702576 return $ param ->var ->name ;
25712577 }, $ functionLike ->getParams ());
2572- $ phpDocBlock = PhpDocBlock:: resolvePhpDocBlockForMethod (
2578+ $ resolvedPhpDoc = $ this -> phpDocInheritanceResolver -> resolvePhpDocForMethod (
25732579 $ docComment ,
2580+ $ file ,
25742581 $ scope ->getClassReflection (),
25752582 $ trait ,
25762583 $ functionLike ->name ->name ,
2577- $ file ,
2578- null ,
2579- $ positionalParameterNames ,
25802584 $ positionalParameterNames
25812585 );
2582- 2583- if ($ phpDocBlock !== null ) {
2584- $ docComment = $ phpDocBlock ->getDocComment ();
2585- $ file = $ phpDocBlock ->getFile ();
2586- $ class = $ phpDocBlock ->getClassReflection ()->getName ();
2587- $ trait = $ phpDocBlock ->getTrait ();
2588- $ phpDocBlockTemplateTypeMap = $ phpDocBlock ->getClassReflection ()->getActiveTemplateTypeMap ();
2589- }
25902586 } elseif ($ functionLike instanceof Node \Stmt \Function_) {
25912587 $ functionName = trim ($ scope ->getNamespace () . '\\' . $ functionLike ->name ->name , '\\' );
25922588 }
25932589
2594- if ($ docComment !== null ) {
2590+ if ($ docComment !== null && $ resolvedPhpDoc === null ) {
25952591 $ resolvedPhpDoc = $ this ->fileTypeMapper ->getResolvedPhpDoc (
25962592 $ file ,
25972593 $ class ,
25982594 $ trait ,
25992595 $ functionName ,
26002596 $ docComment
26012597 );
2598+ }
2599+ 2600+ if ($ resolvedPhpDoc !== null ) {
26022601 $ templateTypeMap = $ resolvedPhpDoc ->getTemplateTypeMap ();
2603- $ phpDocParameterTypes = array_map (static function (ParamTag $ tag ) use ($ phpDocBlockTemplateTypeMap ): Type {
2604- if ($ phpDocBlockTemplateTypeMap !== null ) {
2605- return TemplateTypeHelper::resolveTemplateTypes (
2606- $ tag ->getType (),
2607- $ phpDocBlockTemplateTypeMap
2608- );
2609- }
2602+ $ phpDocParameterTypes = array_map (static function (ParamTag $ tag ): Type {
26102603 return $ tag ->getType ();
26112604 }, $ resolvedPhpDoc ->getParamTags ());
2612- if ($ phpDocBlock !== null ) {
2613- $ phpDocParameterTypes = $ phpDocBlock ->transformArrayKeysWithParameterNameMapping ($ phpDocParameterTypes );
2614- }
26152605 $ nativeReturnType = $ scope ->getFunctionType ($ functionLike ->getReturnType (), false , false );
2616- $ phpDocReturnType = $ this ->getPhpDocReturnType ($ phpDocBlock , $ resolvedPhpDoc , $ nativeReturnType );
2606+ $ phpDocReturnType = $ this ->getPhpDocReturnType ($ resolvedPhpDoc , $ nativeReturnType );
26172607 $ phpDocThrowType = $ resolvedPhpDoc ->getThrowsTag () !== null ? $ resolvedPhpDoc ->getThrowsTag ()->getType () : null ;
26182608 $ deprecatedDescription = $ resolvedPhpDoc ->getDeprecatedTag () !== null ? $ resolvedPhpDoc ->getDeprecatedTag ()->getMessage () : null ;
26192609 $ isDeprecated = $ resolvedPhpDoc ->isDeprecated ();
@@ -2624,7 +2614,7 @@ public function getPhpDocs(Scope $scope, Node\FunctionLike $functionLike): array
26242614 return [$ templateTypeMap , $ phpDocParameterTypes , $ phpDocReturnType , $ phpDocThrowType , $ deprecatedDescription , $ isDeprecated , $ isInternal , $ isFinal ];
26252615 }
26262616
2627- private function getPhpDocReturnType (? PhpDocBlock $ phpDocBlock , ResolvedPhpDocBlock $ resolvedPhpDoc , Type $ nativeReturnType ): ?Type
2617+ private function getPhpDocReturnType (ResolvedPhpDocBlock $ resolvedPhpDoc , Type $ nativeReturnType ): ?Type
26282618 {
26292619 $ returnTag = $ resolvedPhpDoc ->getReturnTag ();
26302620
@@ -2634,14 +2624,7 @@ private function getPhpDocReturnType(?PhpDocBlock $phpDocBlock, ResolvedPhpDocBl
26342624
26352625 $ phpDocReturnType = $ returnTag ->getType ();
26362626
2637- if ($ phpDocBlock !== null ) {
2638- $ phpDocReturnType = TemplateTypeHelper::resolveTemplateTypes (
2639- $ phpDocReturnType ,
2640- $ phpDocBlock ->getClassReflection ()->getActiveTemplateTypeMap ()
2641- );
2642- }
2643- 2644- if ($ phpDocBlock === null || $ phpDocBlock ->isExplicit ()) {
2627+ if ($ returnTag ->isExplicit ()) {
26452628 return $ phpDocReturnType ;
26462629 }
26472630
0 commit comments