@@ -26,19 +26,32 @@ class PhpDocBlock
2626 /** @var bool */
2727 private $ explicit ;
2828
29+ /** @var array<string, string> */
30+ private $ parameterNameMapping ;
31+
32+ /**
33+ * @param string $docComment
34+ * @param string $file
35+ * @param \PHPStan\Reflection\ClassReflection $classReflection
36+ * @param string|null $trait
37+ * @param bool $explicit
38+ * @param array<string, string> $parameterNameMapping
39+ */
2940 private function __construct (
3041 string $ docComment ,
3142 string $ file ,
3243 ClassReflection $ classReflection ,
3344 ?string $ trait ,
34- bool $ explicit
45+ bool $ explicit ,
46+ array $ parameterNameMapping
3547 )
3648 {
3749 $ this ->docComment = $ docComment ;
3850 $ this ->file = $ file ;
3951 $ this ->classReflection = $ classReflection ;
4052 $ this ->trait = $ trait ;
4153 $ this ->explicit = $ explicit ;
54+ $ this ->parameterNameMapping = $ parameterNameMapping ;
4255 }
4356
4457 public function getDocComment (): string
@@ -66,13 +79,44 @@ public function isExplicit(): bool
6679 return $ this ->explicit ;
6780 }
6881
82+ /**
83+ * @template T
84+ * @param array<string, T> $array
85+ * @return array<string, T>
86+ */
87+ public function transformArrayKeysWithParameterNameMapping (array $ array ): array
88+ {
89+ $ newArray = [];
90+ foreach ($ array as $ key => $ value ) {
91+ if (!array_key_exists ($ key , $ this ->parameterNameMapping )) {
92+ continue ;
93+ }
94+ $ newArray [$ this ->parameterNameMapping [$ key ]] = $ value ;
95+ }
96+
97+ return $ newArray ;
98+ }
99+
100+ /**
101+ * @param string|null $docComment
102+ * @param \PHPStan\Reflection\ClassReflection $classReflection
103+ * @param string|null $trait
104+ * @param string $propertyName
105+ * @param string $file
106+ * @param bool|null $explicit
107+ * @param array<int, string> $originalPositionalParameterNames
108+ * @param array<int, string> $newPositionalParameterNames
109+ * @return self|null
110+ */
69111 public static function resolvePhpDocBlockForProperty (
70112 ?string $ docComment ,
71113 ClassReflection $ classReflection ,
72114 ?string $ trait ,
73115 string $ propertyName ,
74116 string $ file ,
75- ?bool $ explicit = null
117+ ?bool $ explicit ,
118+ array $ originalPositionalParameterNames , // unused
119+ array $ newPositionalParameterNames // unused
76120 ): ?self
77121 {
78122 return self ::resolvePhpDocBlock (
@@ -84,17 +128,32 @@ public static function resolvePhpDocBlockForProperty(
84128 'hasNativeProperty ' ,
85129 'getNativeProperty ' ,
86130 __FUNCTION__ ,
87- $ explicit
131+ $ explicit ,
132+ [],
133+ []
88134 );
89135 }
90136
137+ /**
138+ * @param string|null $docComment
139+ * @param \PHPStan\Reflection\ClassReflection $classReflection
140+ * @param string|null $trait
141+ * @param string $methodName
142+ * @param string $file
143+ * @param bool|null $explicit
144+ * @param array<int, string> $originalPositionalParameterNames
145+ * @param array<int, string> $newPositionalParameterNames
146+ * @return self|null
147+ */
91148 public static function resolvePhpDocBlockForMethod (
92149 ?string $ docComment ,
93150 ClassReflection $ classReflection ,
94151 ?string $ trait ,
95152 string $ methodName ,
96153 string $ file ,
97- ?bool $ explicit = null
154+ ?bool $ explicit ,
155+ array $ originalPositionalParameterNames ,
156+ array $ newPositionalParameterNames
98157 ): ?self
99158 {
100159 return self ::resolvePhpDocBlock (
@@ -106,10 +165,26 @@ public static function resolvePhpDocBlockForMethod(
106165 'hasNativeMethod ' ,
107166 'getNativeMethod ' ,
108167 __FUNCTION__ ,
109- $ explicit
168+ $ explicit ,
169+ $ originalPositionalParameterNames ,
170+ $ newPositionalParameterNames
110171 );
111172 }
112173
174+ /**
175+ * @param string|null $docComment
176+ * @param \PHPStan\Reflection\ClassReflection $classReflection
177+ * @param string|null $trait
178+ * @param string $name
179+ * @param string $file
180+ * @param string $hasMethodName
181+ * @param string $getMethodName
182+ * @param string $resolveMethodName
183+ * @param bool|null $explicit
184+ * @param array<int, string> $originalPositionalParameterNames
185+ * @param array<int, string> $newPositionalParameterNames
186+ * @return self|null
187+ */
113188 private static function resolvePhpDocBlock (
114189 ?string $ docComment ,
115190 ClassReflection $ classReflection ,
@@ -119,7 +194,9 @@ private static function resolvePhpDocBlock(
119194 string $ hasMethodName ,
120195 string $ getMethodName ,
121196 string $ resolveMethodName ,
122- ?bool $ explicit
197+ ?bool $ explicit ,
198+ array $ originalPositionalParameterNames ,
199+ array $ newPositionalParameterNames
123200 ): ?self
124201 {
125202 if (
@@ -135,7 +212,8 @@ private static function resolvePhpDocBlock(
135212 $ hasMethodName ,
136213 $ getMethodName ,
137214 $ resolveMethodName ,
138- $ explicit ?? $ docComment !== null
215+ $ explicit ?? $ docComment !== null ,
216+ $ originalPositionalParameterNames
139217 );
140218 if ($ phpDocBlockFromClass !== null ) {
141219 return $ phpDocBlockFromClass ;
@@ -149,27 +227,48 @@ private static function resolvePhpDocBlock(
149227 $ hasMethodName ,
150228 $ getMethodName ,
151229 $ resolveMethodName ,
152- $ explicit ?? $ docComment !== null
230+ $ explicit ?? $ docComment !== null ,
231+ $ originalPositionalParameterNames
153232 );
154233 if ($ phpDocBlockFromClass !== null ) {
155234 return $ phpDocBlockFromClass ;
156235 }
157236 }
158237 }
159238
239+ $ parameterNameMapping = [];
240+ foreach ($ originalPositionalParameterNames as $ i => $ parameterName ) {
241+ if (!array_key_exists ($ i , $ newPositionalParameterNames )) {
242+ continue ;
243+ }
244+ $ parameterNameMapping [$ newPositionalParameterNames [$ i ]] = $ parameterName ;
245+ }
246+
160247 return $ docComment !== null
161- ? new self ($ docComment , $ file , $ classReflection , $ trait , $ explicit ?? true )
248+ ? new self ($ docComment , $ file , $ classReflection , $ trait , $ explicit ?? true , $ parameterNameMapping )
162249 : null ;
163250 }
164251
252+ /**
253+ * @param \PHPStan\Reflection\ClassReflection $classReflection
254+ * @param string|null $trait
255+ * @param string $name
256+ * @param string $hasMethodName
257+ * @param string $getMethodName
258+ * @param string $resolveMethodName
259+ * @param bool $explicit
260+ * @param array<int, string> $positionalParameterNames $positionalParameterNames
261+ * @return self|null
262+ */
165263 private static function resolvePhpDocBlockRecursive (
166264 ClassReflection $ classReflection ,
167265 ?string $ trait ,
168266 string $ name ,
169267 string $ hasMethodName ,
170268 string $ getMethodName ,
171269 string $ resolveMethodName ,
172- bool $ explicit
270+ bool $ explicit ,
271+ array $ positionalParameterNames = []
173272 ): ?self
174273 {
175274 $ phpDocBlockFromClass = self ::resolvePhpDocBlockFromClass (
@@ -178,7 +277,8 @@ private static function resolvePhpDocBlockRecursive(
178277 $ hasMethodName ,
179278 $ getMethodName ,
180279 $ resolveMethodName ,
181- $ explicit
280+ $ explicit ,
281+ $ positionalParameterNames
182282 );
183283
184284 if ($ phpDocBlockFromClass !== null ) {
@@ -194,20 +294,32 @@ private static function resolvePhpDocBlockRecursive(
194294 $ hasMethodName ,
195295 $ getMethodName ,
196296 $ resolveMethodName ,
197- $ explicit
297+ $ explicit ,
298+ $ positionalParameterNames
198299 );
199300 }
200301
201302 return null ;
202303 }
203304
305+ /**
306+ * @param \PHPStan\Reflection\ClassReflection $classReflection
307+ * @param string $name
308+ * @param string $hasMethodName
309+ * @param string $getMethodName
310+ * @param string $resolveMethodName
311+ * @param bool $explicit
312+ * @param array<int, string> $positionalParameterNames
313+ * @return self|null
314+ */
204315 private static function resolvePhpDocBlockFromClass (
205316 ClassReflection $ classReflection ,
206317 string $ name ,
207318 string $ hasMethodName ,
208319 string $ getMethodName ,
209320 string $ resolveMethodName ,
210- bool $ explicit
321+ bool $ explicit ,
322+ array $ positionalParameterNames
211323 ): ?self
212324 {
213325 if ($ classReflection ->getFileNameWithPhpDocs () !== null && $ classReflection ->$ hasMethodName ($ name )) {
@@ -223,10 +335,22 @@ private static function resolvePhpDocBlockFromClass(
223335 return null ;
224336 }
225337
226- if ($ parentReflection instanceof PhpPropertyReflection || $ parentReflection instanceof ResolvedPropertyReflection || $ parentReflection instanceof PhpMethodReflection || $ parentReflection instanceof ResolvedMethodReflection) {
338+ if ($ parentReflection instanceof PhpPropertyReflection || $ parentReflection instanceof ResolvedPropertyReflection) {
339+ $ traitReflection = $ parentReflection ->getDeclaringTrait ();
340+ $ positionalMethodParameterNames = [];
341+ } elseif ($ parentReflection instanceof PhpMethodReflection || $ parentReflection instanceof ResolvedMethodReflection) {
227342 $ traitReflection = $ parentReflection ->getDeclaringTrait ();
343+ $ methodVariants = $ parentReflection ->getVariants ();
344+ $ positionalMethodParameterNames = [];
345+ if (count ($ methodVariants ) === 1 ) {
346+ $ methodParameters = $ methodVariants [0 ]->getParameters ();
347+ foreach ($ methodParameters as $ methodParameter ) {
348+ $ positionalMethodParameterNames [] = $ methodParameter ->getName ();
349+ }
350+ }
228351 } else {
229352 $ traitReflection = null ;
353+ $ positionalMethodParameterNames = [];
230354 }
231355
232356 $ trait = $ traitReflection !== null
@@ -240,7 +364,9 @@ private static function resolvePhpDocBlockFromClass(
240364 $ trait ,
241365 $ name ,
242366 $ classReflection ->getFileNameWithPhpDocs (),
243- $ explicit
367+ $ explicit ,
368+ $ positionalParameterNames ,
369+ $ positionalMethodParameterNames
244370 );
245371 }
246372 }
0 commit comments