44
55namespace Rector \TypeDeclaration \Rector \ClassMethod ;
66
7+ use PhpParser \Node \Stmt \TryCatch ;
8+ use PHPStan \Type \Type ;
9+ use PhpParser \Node \Stmt \Catch_ ;
10+ use PhpParser \Node \Stmt \Return_ ;
11+ use PhpParser \Node \Expr ;
712use PhpParser \Node ;
813use PhpParser \Node \Stmt \ClassMethod ;
9- use PHPStan \Reflection \ClassReflection ;
1014use Rector \NodeTypeResolver \TypeComparator \TypeComparator ;
1115use Rector \PHPStan \ScopeFetcher ;
1216use Rector \PHPStanStaticTypeMapper \Enum \TypeKind ;
1317use Rector \Rector \AbstractRector ;
1418use Rector \StaticTypeMapper \StaticTypeMapper ;
19+ use Rector \VendorLocker \NodeVendorLocker \ClassMethodReturnTypeOverrideGuard ;
1520use Symplify \RuleDocGenerator \ValueObject \CodeSample \CodeSample ;
1621use Symplify \RuleDocGenerator \ValueObject \RuleDefinition ;
1722
2126final class AddReturnTypeFromTryCatchTypeRector extends AbstractRector
2227{
2328 public function __construct (
24- private TypeComparator $ typeComparator ,
25- private StaticTypeMapper $ staticTypeMapper ,
29+ private readonly TypeComparator $ typeComparator ,
30+ private readonly StaticTypeMapper $ staticTypeMapper ,
31+ private readonly ClassMethodReturnTypeOverrideGuard $ classMethodReturnTypeOverrideGuard ,
2632 ) {
2733
2834 }
@@ -78,32 +84,26 @@ public function getNodeTypes(): array
7884 */
7985 public function refactor (Node $ node ): ?Node
8086 {
81- // better nothing to do
82- if ($ node ->isAbstract ()) {
83- return null ;
84- }
85-
86- // already known type
87- if ($ node ->returnType instanceof \PhpParser \Node) {
88- return null ;
89- }
90-
9187 $ scope = ScopeFetcher::fetch ($ node );
92- $ classReflection = $ scope ->getClassReflection ();
93- if (! $ classReflection instanceof ClassReflection) {
88+ if ($ this ->classMethodReturnTypeOverrideGuard ->shouldSkipClassMethod ($ node , $ scope )) {
9489 return null ;
9590 }
9691
97- // skip interfaces and traits
98- if (! $ classReflection -> isClass () ) {
92+ // already known type
93+ if ($ node -> returnType instanceof Node ) {
9994 return null ;
10095 }
10196
10297 $ tryReturnType = null ;
10398 $ catchReturnTypes = [];
10499
105100 foreach ((array ) $ node ->stmts as $ classMethodStmt ) {
106- if (! $ classMethodStmt instanceof Node \Stmt \TryCatch) {
101+ if (! $ classMethodStmt instanceof TryCatch) {
102+ continue ;
103+ }
104+
105+ // skip if there is no catch
106+ if ($ classMethodStmt ->catches === []) {
107107 continue ;
108108 }
109109
@@ -114,15 +114,15 @@ public function refactor(Node $node): ?Node
114114 $ currentCatchType = $ this ->matchReturnType ($ catch );
115115
116116 // each catch must have type
117- if (! $ currentCatchType instanceof \ PHPStan \ Type \ Type) {
117+ if (! $ currentCatchType instanceof Type) {
118118 return null ;
119119 }
120120
121121 $ catchReturnTypes [] = $ currentCatchType ;
122122 }
123123 }
124124
125- if (! $ tryReturnType instanceof \ PHPStan \ Type \ Type) {
125+ if (! $ tryReturnType instanceof Type) {
126126 return null ;
127127 }
128128
@@ -133,22 +133,22 @@ public function refactor(Node $node): ?Node
133133 }
134134
135135 $ returnType = $ this ->staticTypeMapper ->mapPHPStanTypeToPhpParserNode ($ tryReturnType , TypeKind::RETURN );
136- if (! $ returnType instanceof \ PhpParser \ Node) {
136+ if (! $ returnType instanceof Node) {
137137 return null ;
138138 }
139139
140140 $ node ->returnType = $ returnType ;
141141 return $ node ;
142142 }
143143
144- private function matchReturnType (Node \ Stmt \ TryCatch |Node \ Stmt \ Catch_ $ tryOrCatch ): ?\ PHPStan \ Type \ Type
144+ private function matchReturnType (TryCatch |Catch_ $ tryOrCatch ): ?Type
145145 {
146146 foreach ($ tryOrCatch ->stmts as $ stmt ) {
147- if (! $ stmt instanceof Node \ Stmt \ Return_) {
147+ if (! $ stmt instanceof Return_) {
148148 continue ;
149149 }
150150
151- if (! $ stmt ->expr instanceof Node \ Expr) {
151+ if (! $ stmt ->expr instanceof Expr) {
152152 continue ;
153153 }
154154
0 commit comments