@@ -360,8 +360,12 @@ public function getExtensionName(): string|null
360360 return $ this ->locatedSource ->getExtensionName ();
361361 }
362362
363- /** @return list<ReflectionMethod> */
364- private function createMethodsFromTrait (ReflectionMethod $ method ): array
363+ /**
364+ * @param array<lowercase-string, ReflectionMethod> $currentMethods
365+ *
366+ * @return list<ReflectionMethod>
367+ */
368+ private function createMethodsFromTrait (ReflectionMethod $ method , array $ currentMethods ): array
365369 {
366370 $ methodModifiers = $ method ->getModifiers ();
367371 $ lowerCasedMethodHash = $ this ->lowerCasedMethodHash ($ method ->getImplementingClass ()->getName (), $ method ->getName ());
@@ -377,17 +381,35 @@ private function createMethodsFromTrait(ReflectionMethod $method): array
377381 }
378382 }
379383
380- $ createMethod = function (string |null $ aliasMethodName ) use ($ method, $ methodModifiers ): ReflectionMethod {
384+ $ createMethod = function (string |null $ aliasMethodName, int $ methodModifiers ) use ($ method ): ReflectionMethod {
381385 assert ($ aliasMethodName === null || $ aliasMethodName !== '' );
382386
383- /** @phpstan-ignore argument.type */
387+ /** @var int-mask-of<ReflectionMethodAdapter::IS_*> $methodModifiers */
388+ $ methodModifiers = $ methodModifiers ;
389+
384390 return $ method ->withImplementingClass ($ this , $ aliasMethodName , $ methodModifiers );
385391 };
386392
387393 $ methods = [];
388394
389- if (! array_key_exists ($ lowerCasedMethodHash , $ this ->traitsData ['precedences ' ])) {
390- $ methods [] = $ createMethod ($ method ->getAliasName ());
395+ if (
396+ ! array_key_exists ($ lowerCasedMethodHash , $ this ->traitsData ['precedences ' ])
397+ && ! array_key_exists ($ lowerCasedMethodHash , $ currentMethods )
398+ ) {
399+ $ modifiersUsedWithAlias = false ;
400+
401+ foreach ($ this ->traitsData ['aliases ' ] as $ traitAliasDefinitions ) {
402+ foreach ($ traitAliasDefinitions as $ traitAliasDefinition ) {
403+ if ($ lowerCasedMethodHash === $ traitAliasDefinition ['hash ' ]) {
404+ $ modifiersUsedWithAlias = true ;
405+ break ;
406+ }
407+ }
408+ }
409+
410+ // Modifiers used with alias -> copy method with original modifiers (will be added later with the alias name and new modifiers)
411+ // Modifiers not used with alias -> add method with new modifiers
412+ $ methods [] = $ createMethod ($ method ->getAliasName (), $ modifiersUsedWithAlias ? $ method ->getModifiers () : $ methodModifiers );
391413 }
392414
393415 if ($ this ->traitsData ['aliases ' ] !== []) {
@@ -403,7 +425,7 @@ private function createMethodsFromTrait(ReflectionMethod $method): array
403425 continue ;
404426 }
405427
406- $ methods [] = $ createMethod ($ traitAliasDefinition ['alias ' ]);
428+ $ methods [] = $ createMethod ($ traitAliasDefinition ['alias ' ], $ methodModifiers );
407429 }
408430 }
409431 }
@@ -455,7 +477,7 @@ private function getMethodsIndexedByLowercasedName(AlreadyVisitedClasses $alread
455477 foreach ($ this ->getTraits () as $ trait ) {
456478 $ alreadyVisitedClassesCopy = clone $ alreadyVisitedClasses ;
457479 foreach ($ trait ->getMethodsIndexedByLowercasedName ($ alreadyVisitedClassesCopy ) as $ method ) {
458- foreach ($ this ->createMethodsFromTrait ($ method ) as $ traitMethod ) {
480+ foreach ($ this ->createMethodsFromTrait ($ method, $ methods ) as $ traitMethod ) {
459481 $ lowercasedMethodName = strtolower ($ traitMethod ->getName ());
460482
461483 if (! array_key_exists ($ lowercasedMethodName , $ methods )) {
0 commit comments