@@ -146,6 +146,7 @@ public function processNode(Node $node, Scope $scope): array
146146 $ methodVariant = ParametersAcceptorSelector::selectSingle ($ method ->getVariants ());
147147 $ methodParameters = $ methodVariant ->getParameters ();
148148
149+ $ prototypeAfterVariadic = false ;
149150 foreach ($ prototypeVariant ->getParameters () as $ i => $ prototypeParameter ) {
150151 if (!array_key_exists ($ i , $ methodParameters )) {
151152 $ messages [] = RuleErrorBuilder::message (sprintf (
@@ -190,19 +191,41 @@ public function processNode(Node $node, Scope $scope): array
190191 }
191192
192193 if ($ prototypeParameter ->isVariadic ()) {
194+ $ prototypeAfterVariadic = true ;
193195 if (!$ methodParameter ->isVariadic ()) {
194- $ messages [] = RuleErrorBuilder::message (sprintf (
195- 'Parameter #%d $%s of method %s::%s() is not variadic but parameter #%d $%s of method %s::%s() is variadic. ' ,
196- $ i + 1 ,
197- $ methodParameter ->getName (),
198- $ method ->getDeclaringClass ()->getDisplayName (),
199- $ method ->getName (),
200- $ i + 1 ,
201- $ prototypeParameter ->getName (),
202- $ prototype ->getDeclaringClass ()->getDisplayName (),
203- $ prototype ->getName ()
204- ))->nonIgnorable ()->build ();
205- continue ;
196+ if (!$ methodParameter ->isOptional ()) {
197+ if (count ($ methodParameters ) !== $ i + 1 ) {
198+ $ messages [] = RuleErrorBuilder::message (sprintf (
199+ 'Parameter #%d $%s of method %s::%s() is not optional. ' ,
200+ $ i + 1 ,
201+ $ methodParameter ->getName (),
202+ $ method ->getDeclaringClass ()->getDisplayName (),
203+ $ method ->getName ()
204+ ))->nonIgnorable ()->build ();
205+ continue ;
206+ }
207+
208+ $ messages [] = RuleErrorBuilder::message (sprintf (
209+ 'Parameter #%d $%s of method %s::%s() is not variadic but parameter #%d $%s of method %s::%s() is variadic. ' ,
210+ $ i + 1 ,
211+ $ methodParameter ->getName (),
212+ $ method ->getDeclaringClass ()->getDisplayName (),
213+ $ method ->getName (),
214+ $ i + 1 ,
215+ $ prototypeParameter ->getName (),
216+ $ prototype ->getDeclaringClass ()->getDisplayName (),
217+ $ prototype ->getName ()
218+ ))->nonIgnorable ()->build ();
219+ continue ;
220+ } elseif (count ($ methodParameters ) === $ i + 1 ) {
221+ $ messages [] = RuleErrorBuilder::message (sprintf (
222+ 'Parameter #%d $%s of method %s::%s() is not variadic. ' ,
223+ $ i + 1 ,
224+ $ methodParameter ->getName (),
225+ $ method ->getDeclaringClass ()->getDisplayName (),
226+ $ method ->getName (),
227+ ))->nonIgnorable ()->build ();
228+ }
206229 }
207230 } elseif ($ methodParameter ->isVariadic ()) {
208231 $ messages [] = RuleErrorBuilder::message (sprintf (
@@ -285,17 +308,31 @@ public function processNode(Node $node, Scope $scope): array
285308 continue ;
286309 }
287310
288- if ($ methodParameter ->isOptional ()) {
311+ if (
312+ $ j === count ($ methodParameters ) - 1
313+ && $ prototypeAfterVariadic
314+ && !$ methodParameter ->isVariadic ()
315+ ) {
316+ $ messages [] = RuleErrorBuilder::message (sprintf (
317+ 'Parameter #%d $%s of method %s::%s() is not variadic. ' ,
318+ $ j + 1 ,
319+ $ methodParameter ->getName (),
320+ $ method ->getDeclaringClass ()->getDisplayName (),
321+ $ method ->getName ()
322+ ))->nonIgnorable ()->build ();
289323 continue ;
290324 }
291325
292- $ messages [] = RuleErrorBuilder::message (sprintf (
293- 'Parameter #%d $%s of method %s::%s() is not optional. ' ,
294- $ j + 1 ,
295- $ methodParameter ->getName (),
296- $ method ->getDeclaringClass ()->getDisplayName (),
297- $ method ->getName ()
298- ))->nonIgnorable ()->build ();
326+ if (!$ methodParameter ->isOptional ()) {
327+ $ messages [] = RuleErrorBuilder::message (sprintf (
328+ 'Parameter #%d $%s of method %s::%s() is not optional. ' ,
329+ $ j + 1 ,
330+ $ methodParameter ->getName (),
331+ $ method ->getDeclaringClass ()->getDisplayName (),
332+ $ method ->getName ()
333+ ))->nonIgnorable ()->build ();
334+ continue ;
335+ }
299336 }
300337
301338 $ methodReturnType = $ methodVariant ->getNativeReturnType ();
0 commit comments