44
55use PHPStan \Reflection \ClassReflection ;
66use PHPStan \Type \FileTypeMapper ;
7+ use ReflectionParameter ;
8+ use function array_map ;
79use function strtolower ;
810
911class PhpDocInheritanceResolver
1012{
1113
1214 private FileTypeMapper $ fileTypeMapper ;
1315
16+ private StubPhpDocProvider $ stubPhpDocProvider ;
17+
1418 public function __construct (
1519 FileTypeMapper $ fileTypeMapper ,
20+ StubPhpDocProvider $ stubPhpDocProvider ,
1621 )
1722 {
1823 $ this ->fileTypeMapper = $ fileTypeMapper ;
24+ $ this ->stubPhpDocProvider = $ stubPhpDocProvider ;
1925 }
2026
2127 public function resolvePhpDocForProperty (
@@ -37,7 +43,7 @@ public function resolvePhpDocForProperty(
3743 [],
3844 );
3945
40- return $ this ->docBlockTreeToResolvedDocBlock ($ phpDocBlock , $ declaringTraitName , null );
46+ return $ this ->docBlockTreeToResolvedDocBlock ($ phpDocBlock , $ declaringTraitName , null , $ propertyName , null );
4147 }
4248
4349 public function resolvePhpDocForConstant (
@@ -58,7 +64,7 @@ public function resolvePhpDocForConstant(
5864 [],
5965 );
6066
61- return $ this ->docBlockTreeToResolvedDocBlock ($ phpDocBlock , null , null );
67+ return $ this ->docBlockTreeToResolvedDocBlock ($ phpDocBlock , null , null , null , $ constantName );
6268 }
6369
6470 /**
@@ -84,10 +90,10 @@ public function resolvePhpDocForMethod(
8490 $ positionalParameterNames ,
8591 );
8692
87- return $ this ->docBlockTreeToResolvedDocBlock ($ phpDocBlock , $ phpDocBlock ->getTrait (), $ methodName );
93+ return $ this ->docBlockTreeToResolvedDocBlock ($ phpDocBlock , $ phpDocBlock ->getTrait (), $ methodName, null , null );
8894 }
8995
90- private function docBlockTreeToResolvedDocBlock (PhpDocBlock $ phpDocBlock , ?string $ traitName , ?string $ functionName ): ResolvedPhpDocBlock
96+ private function docBlockTreeToResolvedDocBlock (PhpDocBlock $ phpDocBlock , ?string $ traitName , ?string $ functionName, ? string $ propertyName , ? string $ constantName ): ResolvedPhpDocBlock
9197 {
9298 $ parents = [];
9399 $ parentPhpDocBlocks = [];
@@ -104,17 +110,40 @@ private function docBlockTreeToResolvedDocBlock(PhpDocBlock $phpDocBlock, ?strin
104110 $ parentPhpDocBlock ,
105111 $ parentPhpDocBlock ->getTrait (),
106112 $ functionName ,
113+ $ propertyName ,
114+ $ constantName ,
107115 );
108116 $ parentPhpDocBlocks [] = $ parentPhpDocBlock ;
109117 }
110118
111- $ oneResolvedDockBlock = $ this ->docBlockToResolvedDocBlock ($ phpDocBlock , $ traitName , $ functionName );
119+ $ oneResolvedDockBlock = $ this ->docBlockToResolvedDocBlock ($ phpDocBlock , $ traitName , $ functionName, $ propertyName , $ constantName );
112120 return $ oneResolvedDockBlock ->merge ($ parents , $ parentPhpDocBlocks );
113121 }
114122
115- private function docBlockToResolvedDocBlock (PhpDocBlock $ phpDocBlock , ?string $ traitName , ?string $ functionName ): ResolvedPhpDocBlock
123+ private function docBlockToResolvedDocBlock (PhpDocBlock $ phpDocBlock , ?string $ traitName , ?string $ functionName, ? string $ propertyName , ? string $ constantName ): ResolvedPhpDocBlock
116124 {
117125 $ classReflection = $ phpDocBlock ->getClassReflection ();
126+ if ($ functionName !== null && $ classReflection ->getNativeReflection ()->hasMethod ($ functionName )) {
127+ $ methodReflection = $ classReflection ->getNativeReflection ()->getMethod ($ functionName );
128+ $ stub = $ this ->stubPhpDocProvider ->findMethodPhpDoc ($ classReflection ->getName (), $ functionName , array_map (static fn (ReflectionParameter $ parameter ): string => $ parameter ->getName (), $ methodReflection ->getParameters ()));
129+ if ($ stub !== null ) {
130+ return $ stub ;
131+ }
132+ }
133+
134+ if ($ propertyName !== null && $ classReflection ->getNativeReflection ()->hasProperty ($ propertyName )) {
135+ $ stub = $ this ->stubPhpDocProvider ->findPropertyPhpDoc ($ classReflection ->getName (), $ propertyName );
136+ if ($ stub !== null ) {
137+ return $ stub ;
138+ }
139+ }
140+
141+ if ($ constantName !== null && $ classReflection ->getNativeReflection ()->hasConstant ($ constantName )) {
142+ $ stub = $ this ->stubPhpDocProvider ->findClassConstantPhpDoc ($ classReflection ->getName (), $ constantName );
143+ if ($ stub !== null ) {
144+ return $ stub ;
145+ }
146+ }
118147
119148 return $ this ->fileTypeMapper ->getResolvedPhpDoc (
120149 $ phpDocBlock ->getFile (),
0 commit comments