77use PHPStan \Node \MethodReturnStatementsNode ;
88use PHPStan \Rules \Rule ;
99use PHPStan \Rules \RuleErrorBuilder ;
10- use PHPStan \Type \FileTypeMapper ;
1110use function sprintf ;
1211
1312/**
1615final class TooWideMethodThrowTypeRule implements Rule
1716{
1817
19- public function __construct (private FileTypeMapper $ fileTypeMapper , private TooWideThrowTypeCheck $ check )
18+ public function __construct (
19+ private TooWideThrowTypeCheck $ check ,
20+ private bool $ checkProtectedAndPublicMethods ,
21+ )
2022 {
2123 }
2224
@@ -27,34 +29,32 @@ public function getNodeType(): string
2729
2830 public function processNode (Node $ node , Scope $ scope ): array
2931 {
30- $ docComment = $ node ->getDocComment ();
31- if ($ docComment === null ) {
32- return [];
33- }
34-
3532 $ statementResult = $ node ->getStatementResult ();
36- $ methodReflection = $ node ->getMethodReflection ();
37- $ classReflection = $ node ->getClassReflection ();
38- $ resolvedPhpDoc = $ this ->fileTypeMapper ->getResolvedPhpDoc (
39- $ scope ->getFile (),
40- $ classReflection ->getName (),
41- $ scope ->isInTrait () ? $ scope ->getTraitReflection ()->getName () : null ,
42- $ methodReflection ->getName (),
43- $ docComment ->getText (),
44- );
33+ $ method = $ node ->getMethodReflection ();
34+ $ isFirstDeclaration = $ method ->getPrototype ()->getDeclaringClass () === $ method ->getDeclaringClass ();
35+ if (!$ method ->isPrivate ()) {
36+ if (!$ method ->getDeclaringClass ()->isFinal () && !$ method ->isFinal ()->yes ()) {
37+ if (!$ this ->checkProtectedAndPublicMethods ) {
38+ return [];
39+ }
4540
46- if ($ resolvedPhpDoc ->getThrowsTag () === null ) {
47- return [];
41+ if ($ isFirstDeclaration ) {
42+ return [];
43+ }
44+ }
4845 }
4946
50- $ throwType = $ resolvedPhpDoc ->getThrowsTag ()->getType ();
47+ $ throwType = $ method ->getThrowType ();
48+ if ($ throwType === null ) {
49+ return [];
50+ }
5151
5252 $ errors = [];
5353 foreach ($ this ->check ->check ($ throwType , $ statementResult ->getThrowPoints ()) as $ throwClass ) {
5454 $ errors [] = RuleErrorBuilder::message (sprintf (
5555 'Method %s::%s() has %s in PHPDoc @throws tag but it \'s not thrown. ' ,
56- $ methodReflection ->getDeclaringClass ()->getDisplayName (),
57- $ methodReflection ->getName (),
56+ $ method ->getDeclaringClass ()->getDisplayName (),
57+ $ method ->getName (),
5858 $ throwClass ,
5959 ))
6060 ->identifier ('throws.unusedType ' )
0 commit comments