1010use PHPStan \Reflection \ParameterReflectionWithPhpDocs ;
1111use PHPStan \Reflection \ParametersAcceptorSelector ;
1212use PHPStan \Reflection \ParametersAcceptorWithPhpDocs ;
13+ use PHPStan \Reflection \Php \NativeBuiltinMethodReflection ;
14+ use PHPStan \Reflection \Php \PhpClassReflectionExtension ;
1315use PHPStan \Rules \Rule ;
1416use PHPStan \Rules \RuleErrorBuilder ;
1517use PHPStan \TrinaryLogic ;
2224use PHPStan \Type \TypeTraverser ;
2325use PHPStan \Type \VerbosityLevel ;
2426use function count ;
25- use function is_bool ;
2627use function min ;
2728use function sprintf ;
2829
@@ -33,6 +34,7 @@ class MethodSignatureRule implements Rule
3334{
3435
3536 public function __construct (
37+ private PhpClassReflectionExtension $ phpClassReflectionExtension ,
3638 private bool $ reportMaybes ,
3739 private bool $ reportStatic ,
3840 private bool $ abstractTraitMethod ,
@@ -62,7 +64,7 @@ public function processNode(Node $node, Scope $scope): array
6264
6365 $ errors = [];
6466 $ declaringClass = $ method ->getDeclaringClass ();
65- foreach ($ this ->collectParentMethods ($ methodName , $ method ->getDeclaringClass ()) as $ parentMethod ) {
67+ foreach ($ this ->collectParentMethods ($ methodName , $ method ->getDeclaringClass ()) as [ $ parentMethod, $ parentMethodDeclaringClass ] ) {
6668 $ parentVariants = $ parentMethod ->getVariants ();
6769 if (count ($ parentVariants ) !== 1 ) {
6870 continue ;
@@ -77,7 +79,7 @@ public function processNode(Node $node, Scope $scope): array
7779 $ method ->getName (),
7880 $ returnTypeCompatibility ->no () ? 'compatible ' : 'covariant ' ,
7981 $ parentReturnType ->describe (VerbosityLevel::value ()),
80- $ parentMethod -> getDeclaringClass () ->getDisplayName (),
82+ $ parentMethodDeclaringClass ->getDisplayName (),
8183 $ parentMethod ->getName (),
8284 ))->build ();
8385 }
@@ -102,7 +104,7 @@ public function processNode(Node $node, Scope $scope): array
102104 $ parameterResult ->no () ? 'compatible ' : 'contravariant ' ,
103105 $ parentParameter ->getName (),
104106 $ parentParameterType ->describe (VerbosityLevel::value ()),
105- $ parentMethod -> getDeclaringClass () ->getDisplayName (),
107+ $ parentMethodDeclaringClass ->getDisplayName (),
106108 $ parentMethod ->getName (),
107109 ))->build ();
108110 }
@@ -112,7 +114,7 @@ public function processNode(Node $node, Scope $scope): array
112114 }
113115
114116 /**
115- * @return ExtendedMethodReflection[]
117+ * @return list<array{ ExtendedMethodReflection, ClassReflection}>
116118 */
117119 private function collectParentMethods (string $ methodName , ClassReflection $ class ): array
118120 {
@@ -122,7 +124,7 @@ private function collectParentMethods(string $methodName, ClassReflection $class
122124 if ($ parentClass !== null && $ parentClass ->hasNativeMethod ($ methodName )) {
123125 $ parentMethod = $ parentClass ->getNativeMethod ($ methodName );
124126 if (!$ parentMethod ->isPrivate ()) {
125- $ parentMethods [] = $ parentMethod ;
127+ $ parentMethods [] = [ $ parentMethod, $ parentMethod -> getDeclaringClass ()] ;
126128 }
127129 }
128130
@@ -131,24 +133,31 @@ private function collectParentMethods(string $methodName, ClassReflection $class
131133 continue ;
132134 }
133135
134- $ parentMethods [] = $ interface ->getNativeMethod ($ methodName );
136+ $ method = $ interface ->getNativeMethod ($ methodName );
137+ $ parentMethods [] = [$ method , $ method ->getDeclaringClass ()];
135138 }
136139
137140 if ($ this ->abstractTraitMethod ) {
138141 foreach ($ class ->getTraits (true ) as $ trait ) {
139- if (!$ trait ->hasNativeMethod ($ methodName )) {
142+ $ nativeTraitReflection = $ trait ->getNativeReflection ();
143+ if (!$ nativeTraitReflection ->hasMethod ($ methodName )) {
140144 continue ;
141145 }
142146
143- $ method = $ trait ->getNativeMethod ($ methodName );
144- $ isAbstract = $ method ->isAbstract ();
145- if (is_bool ($ isAbstract )) {
146- if ($ isAbstract ) {
147- $ parentMethods [] = $ method ;
148- }
149- } elseif ($ isAbstract ->yes ()) {
150- $ parentMethods [] = $ method ;
147+ $ methodReflection = $ nativeTraitReflection ->getMethod ($ methodName );
148+ $ isAbstract = $ methodReflection ->isAbstract ();
149+ if (!$ isAbstract ) {
150+ continue ;
151151 }
152+
153+ $ parentMethods [] = [
154+ $ this ->phpClassReflectionExtension ->createUserlandMethodReflection (
155+ $ trait ,
156+ $ class ,
157+ new NativeBuiltinMethodReflection ($ methodReflection ),
158+ ),
159+ $ trait ->getNativeMethod ($ methodName )->getDeclaringClass (),
160+ ];
152161 }
153162 }
154163
0 commit comments