@@ -31,18 +31,11 @@ public function __construct()
3131
3232 $ this ->inheritanceHelper = new InheritanceHelper ();
3333 $ this ->unavailableTypeHints = [
34- 'array ' ,
3534 'void ' ,
3635 'self ' ,
3736 '$this ' ,
3837 'mixed ' ,
3938 'callable ' ,
40- 'bool ' ,
41- 'boolean ' ,
42- 'float ' ,
43- 'int ' ,
44- 'integer ' ,
45- 'string ' ,
4639 'resource ' ,
4740 ];
4841 }
@@ -159,85 +152,145 @@ private function validateObjectArguments(
159152 int $ docBlockIndex ,
160153 int $ parenthesesStartIndex ,
161154 int $ parenthesesEndIndex
162- ) {
155+ ): void {
163156 $ currentParenthesesEndIndex = $ parenthesesEndIndex ;
164157 $ docBlock = new DocBlock ($ tokens [$ docBlockIndex ]->getContent ());
165158 for ($ i = $ parenthesesEndIndex ; $ i > $ parenthesesStartIndex ; $ i --) {
166159 if (!$ tokens [$ i ]->isGivenKind (T_VARIABLE )) {
167160 continue ;
168161 }
162+
169163 $ previousTokenIndex = $ tokens ->getPrevMeaningfulToken ($ i );
170164 if (!$ tokens [$ previousTokenIndex ]->isGivenKind (T_STRING )) {
171165 foreach ($ docBlock ->getAnnotationsOfType ('param ' ) as $ annotation ) {
172166 $ variable = $ tokens [$ i ]->getContent ();
173167 if (
174- !preg_match (
175- '#^[^$]+@param\s([^$].*?[^\s])\s \\' . $ variable . '#m ' ,
176- $ annotation ->getContent (),
177- )
178- || preg_match (
179- '#^[^$]+@param\s(.*?\[\])\s \\' . $ variable . '#m ' ,
180- $ annotation ->getContent (),
181- )
168+ $ this ->isAnnotationWrongFormat ($ variable , $ annotation ->getContent ())
169+ || $ this ->isAnnotationArray ($ variable , $ annotation ->getContent ())
182170 ) {
183171 continue ;
184172 }
185173
186174 $ argumentTypes = $ annotation ->getTypes ();
187175 $ argumentTypeCount = count ($ argumentTypes );
176+
177+ $ argumentTypesNotNullable = [];
178+ foreach ($ argumentTypes as $ argumentType ) {
179+ $ argumentTypesNotNullable [] = str_replace ('? ' , '' , $ argumentType );
180+ }
181+
182+ $ nullableFound = false ;
188183 $ nullFound = in_array ('null ' , $ argumentTypes , true );
184+ if (!$ nullFound ) {
185+ $ nullableFound = $ this ->isNullableFound ($ argumentTypes );
186+ }
187+
189188 if (
190- !array_intersect ($ argumentTypes , $ this ->unavailableTypeHints )
191- && (($ argumentTypeCount === 2 && $ nullFound ) || ($ argumentTypeCount === 1 ) && !$ nullFound )
189+ !array_intersect ($ argumentTypesNotNullable , $ this ->unavailableTypeHints )
190+ && (
191+ ($ argumentTypeCount === 2 && $ nullFound )
192+ || ($ argumentTypeCount === 1 && !$ nullFound )
193+ )
194+ || ($ argumentTypeCount === 2 && $ nullableFound )
192195 ) {
193196 $ argumentType = trim (implode ('' , array_diff ($ argumentTypes , ['null ' ])));
194- $ tokens ->insertSlices ([
195- $ i => [
196- new Token ([T_STRING , $ argumentType ]),
197- new Token ([T_WHITESPACE , ' ' ]),
198- ],
199- ]);
200- $ currentParenthesesEndIndex += 2 ;
197+ if (
198+ $ tokens [$ i ]->isGivenKind (T_VARIABLE )
199+ && !$ tokens [$ previousTokenIndex ]->isGivenKind (10005 )
200+ ) {
201+ $ tokens ->insertSlices ([
202+ $ i => [
203+ new Token ([T_STRING , $ argumentType ]),
204+ new Token ([T_WHITESPACE , ' ' ]),
205+ ],
206+ ]);
207+ $ currentParenthesesEndIndex += 2 ;
208+ }
201209 }
202210
203211 if ($ nullFound ) {
204- /** @var Token[] $variables */
205- $ variables = (clone $ tokens )->findGivenKind (
206- T_VARIABLE ,
212+ $ this ->processIfNullFound (
213+ $ tokens ,
207214 $ parenthesesStartIndex ,
208215 $ currentParenthesesEndIndex ,
216+ $ variable
209217 );
210- $ variablePosition = null ;
211- foreach ($ variables as $ key => $ variableToken ) {
212- $ expectedEqual = $ tokens ->getNextMeaningfulToken ($ key );
213- $ expectedNull = $ tokens ->getNextMeaningfulToken ($ expectedEqual );
214- if (
215- $ tokens [$ expectedEqual ]->getContent () === '= '
216- && $ tokens [$ expectedNull ]->getContent () === 'null '
217- ) {
218- continue ;
219- }
220-
221- if ($ variableToken ->getContent () === $ variable ) {
222- $ variablePosition = $ key ;
223- break ;
224- }
225- }
226-
227- if ($ variablePosition !== null ) {
228- $ tokens ->insertSlices ([
229- ++$ variablePosition => [
230- new Token ([T_WHITESPACE , ' ' ]),
231- new Token ('= ' ),
232- new Token ([T_WHITESPACE , ' ' ]),
233- new Token ([T_STRING , 'null ' ]),
234- ],
235- ]);
236- }
237218 }
238219 break ;
239220 }
240221 }
241222 }
242223 }
224+
225+ private function isAnnotationWrongFormat (string $ variable , string $ content ): bool
226+ {
227+ return preg_match (
228+ '#^[^$]+@param\s([^$].*?[^\s])\s \\' . $ variable . '#m ' ,
229+ $ content ,
230+ ) !== 1 ;
231+ }
232+
233+ private function isAnnotationArray (string $ variable , string $ content ): bool
234+ {
235+ return preg_match (
236+ '#^[^$]+@param\s(.*?\[\])\s \\' . $ variable . '#m ' ,
237+ $ content ,
238+ ) === 1 ;
239+ }
240+
241+ private function processIfNullFound (
242+ Tokens $ tokens ,
243+ int $ parenthesesStartIndex ,
244+ int $ currentParenthesesEndIndex ,
245+ string $ variable
246+ ) {
247+ /** @var Token[] $variables */
248+ $ variables = (clone $ tokens )->findGivenKind (
249+ T_VARIABLE ,
250+ $ parenthesesStartIndex ,
251+ $ currentParenthesesEndIndex ,
252+ );
253+ $ variablePosition = null ;
254+ foreach ($ variables as $ key => $ variableToken ) {
255+ $ expectedEqual = $ tokens ->getNextMeaningfulToken ($ key );
256+ $ expectedNull = $ tokens ->getNextMeaningfulToken ($ expectedEqual );
257+ if (
258+ $ tokens [$ expectedEqual ]->getContent () === '= '
259+ && $ tokens [$ expectedNull ]->getContent () === 'null '
260+ ) {
261+ continue ;
262+ }
263+
264+ if ($ variableToken ->getContent () === $ variable ) {
265+ $ variablePosition = $ key ;
266+ break ;
267+ }
268+ }
269+
270+ if ($ variablePosition !== null ) {
271+ $ tokens ->insertSlices ([
272+ ++$ variablePosition => [
273+ new Token ([T_WHITESPACE , ' ' ]),
274+ new Token ('= ' ),
275+ new Token ([T_WHITESPACE , ' ' ]),
276+ new Token ([T_STRING , 'null ' ]),
277+ ],
278+ ]);
279+ }
280+ }
281+
282+ /**
283+ * @param string[] $argumentTypes
284+ * @return bool
285+ */
286+ private function isNullableFound (array $ argumentTypes ): bool
287+ {
288+ foreach ($ argumentTypes as $ argumentType ) {
289+ if (str_contains ($ argumentType , '? ' )) {
290+ return true ;
291+ }
292+ }
293+
294+ return false ;
295+ }
243296}
0 commit comments