59
59
use PHPStan \Node \ReturnStatement ;
60
60
use PHPStan \Node \UnreachableStatementNode ;
61
61
use PHPStan \Parser \Parser ;
62
- use PHPStan \PhpDoc \PhpDocBlock ;
62
+ use PHPStan \PhpDoc \PhpDocInheritanceResolver ;
63
63
use PHPStan \PhpDoc \ResolvedPhpDocBlock ;
64
64
use PHPStan \PhpDoc \Tag \ParamTag ;
65
65
use PHPStan \Reflection \ClassReflection ;
@@ -110,6 +110,9 @@ class NodeScopeResolver
110
110
/** @var \PHPStan\Type\FileTypeMapper */
111
111
private $ fileTypeMapper ;
112
112
113
+ /** @var \PHPStan\PhpDoc\PhpDocInheritanceResolver */
114
+ private $ phpDocInheritanceResolver ;
115
+
113
116
/** @var \PHPStan\File\FileHelper */
114
117
private $ fileHelper ;
115
118
@@ -138,6 +141,7 @@ class NodeScopeResolver
138
141
* @param \PHPStan\Reflection\ReflectionProvider $reflectionProvider
139
142
* @param Parser $parser
140
143
* @param FileTypeMapper $fileTypeMapper
144
+ * @param PhpDocInheritanceResolver $phpDocInheritanceResolver
141
145
* @param FileHelper $fileHelper
142
146
* @param TypeSpecifier $typeSpecifier
143
147
* @param bool $polluteScopeWithLoopInitialAssignments
@@ -150,6 +154,7 @@ public function __construct(
150
154
ReflectionProvider $ reflectionProvider ,
151
155
Parser $ parser ,
152
156
FileTypeMapper $ fileTypeMapper ,
157
+ PhpDocInheritanceResolver $ phpDocInheritanceResolver ,
153
158
FileHelper $ fileHelper ,
154
159
TypeSpecifier $ typeSpecifier ,
155
160
bool $ polluteScopeWithLoopInitialAssignments ,
@@ -162,6 +167,7 @@ public function __construct(
162
167
$ this ->reflectionProvider = $ reflectionProvider ;
163
168
$ this ->parser = $ parser ;
164
169
$ this ->fileTypeMapper = $ fileTypeMapper ;
170
+ $ this ->phpDocInheritanceResolver = $ phpDocInheritanceResolver ;
165
171
$ this ->fileHelper = $ fileHelper ;
166
172
$ this ->typeSpecifier = $ typeSpecifier ;
167
173
$ this ->polluteScopeWithLoopInitialAssignments = $ polluteScopeWithLoopInitialAssignments ;
@@ -2540,7 +2546,6 @@ private function processNodesForTraitUse($node, ClassReflection $traitReflection
2540
2546
public function getPhpDocs (Scope $ scope , Node \FunctionLike $ functionLike ): array
2541
2547
{
2542
2548
$ templateTypeMap = TemplateTypeMap::createEmpty ();
2543
- $ phpDocBlockTemplateTypeMap = null ;
2544
2549
$ phpDocParameterTypes = [];
2545
2550
$ phpDocReturnType = null ;
2546
2551
$ phpDocThrowType = null ;
@@ -2555,8 +2560,9 @@ public function getPhpDocs(Scope $scope, Node\FunctionLike $functionLike): array
2555
2560
$ file = $ scope ->getFile ();
2556
2561
$ class = $ scope ->isInClass () ? $ scope ->getClassReflection ()->getName () : null ;
2557
2562
$ trait = $ scope ->isInTrait () ? $ scope ->getTraitReflection ()->getName () : null ;
2558
- $ phpDocBlock = null ;
2563
+ $ resolvedPhpDoc = null ;
2559
2564
$ functionName = null ;
2565
+
2560
2566
if ($ functionLike instanceof Node \Stmt \ClassMethod) {
2561
2567
if (!$ scope ->isInClass ()) {
2562
2568
throw new \PHPStan \ShouldNotHappenException ();
@@ -2569,51 +2575,35 @@ public function getPhpDocs(Scope $scope, Node\FunctionLike $functionLike): array
2569
2575
2570
2576
return $ param ->var ->name ;
2571
2577
}, $ functionLike ->getParams ());
2572
- $ phpDocBlock = PhpDocBlock:: resolvePhpDocBlockForMethod (
2578
+ $ resolvedPhpDoc = $ this -> phpDocInheritanceResolver -> resolvePhpDocForMethod (
2573
2579
$ docComment ,
2580
+ $ file ,
2574
2581
$ scope ->getClassReflection (),
2575
2582
$ trait ,
2576
2583
$ functionLike ->name ->name ,
2577
- $ file ,
2578
- null ,
2579
- $ positionalParameterNames ,
2580
2584
$ positionalParameterNames
2581
2585
);
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
- }
2590
2586
} elseif ($ functionLike instanceof Node \Stmt \Function_) {
2591
2587
$ functionName = trim ($ scope ->getNamespace () . '\\' . $ functionLike ->name ->name , '\\' );
2592
2588
}
2593
2589
2594
- if ($ docComment !== null ) {
2590
+ if ($ docComment !== null && $ resolvedPhpDoc === null ) {
2595
2591
$ resolvedPhpDoc = $ this ->fileTypeMapper ->getResolvedPhpDoc (
2596
2592
$ file ,
2597
2593
$ class ,
2598
2594
$ trait ,
2599
2595
$ functionName ,
2600
2596
$ docComment
2601
2597
);
2598
+ }
2599
+
2600
+ if ($ resolvedPhpDoc !== null ) {
2602
2601
$ 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 {
2610
2603
return $ tag ->getType ();
2611
2604
}, $ resolvedPhpDoc ->getParamTags ());
2612
- if ($ phpDocBlock !== null ) {
2613
- $ phpDocParameterTypes = $ phpDocBlock ->transformArrayKeysWithParameterNameMapping ($ phpDocParameterTypes );
2614
- }
2615
2605
$ nativeReturnType = $ scope ->getFunctionType ($ functionLike ->getReturnType (), false , false );
2616
- $ phpDocReturnType = $ this ->getPhpDocReturnType ($ phpDocBlock , $ resolvedPhpDoc , $ nativeReturnType );
2606
+ $ phpDocReturnType = $ this ->getPhpDocReturnType ($ resolvedPhpDoc , $ nativeReturnType );
2617
2607
$ phpDocThrowType = $ resolvedPhpDoc ->getThrowsTag () !== null ? $ resolvedPhpDoc ->getThrowsTag ()->getType () : null ;
2618
2608
$ deprecatedDescription = $ resolvedPhpDoc ->getDeprecatedTag () !== null ? $ resolvedPhpDoc ->getDeprecatedTag ()->getMessage () : null ;
2619
2609
$ isDeprecated = $ resolvedPhpDoc ->isDeprecated ();
@@ -2624,7 +2614,7 @@ public function getPhpDocs(Scope $scope, Node\FunctionLike $functionLike): array
2624
2614
return [$ templateTypeMap , $ phpDocParameterTypes , $ phpDocReturnType , $ phpDocThrowType , $ deprecatedDescription , $ isDeprecated , $ isInternal , $ isFinal ];
2625
2615
}
2626
2616
2627
- private function getPhpDocReturnType (? PhpDocBlock $ phpDocBlock , ResolvedPhpDocBlock $ resolvedPhpDoc , Type $ nativeReturnType ): ?Type
2617
+ private function getPhpDocReturnType (ResolvedPhpDocBlock $ resolvedPhpDoc , Type $ nativeReturnType ): ?Type
2628
2618
{
2629
2619
$ returnTag = $ resolvedPhpDoc ->getReturnTag ();
2630
2620
@@ -2634,14 +2624,7 @@ private function getPhpDocReturnType(?PhpDocBlock $phpDocBlock, ResolvedPhpDocBl
2634
2624
2635
2625
$ phpDocReturnType = $ returnTag ->getType ();
2636
2626
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 ()) {
2645
2628
return $ phpDocReturnType ;
2646
2629
}
2647
2630
0 commit comments