|
12 | 12 | use PhpParser\Node\Scalar\String_; |
13 | 13 | use PhpParser\Node\Stmt\Class_; |
14 | 14 | use PhpParser\Node\Stmt\ClassMethod; |
| 15 | +use PhpParser\Node\Stmt\Expression; |
15 | 16 | use PhpParser\Node\Stmt\Function_; |
16 | 17 | use PhpParser\Node\Stmt\Return_; |
17 | 18 | use PhpParser\NodeVisitor; |
18 | 19 | use Rector\FamilyTree\Reflection\FamilyRelationsAnalyzer; |
19 | 20 | use Rector\NodeAnalyzer\ClassAnalyzer; |
| 21 | +use Rector\NodeAnalyzer\TerminatedNodeAnalyzer; |
20 | 22 | use Rector\PhpParser\Node\BetterNodeFinder; |
21 | 23 | use Rector\Rector\AbstractRector; |
22 | 24 | use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer; |
@@ -46,17 +48,22 @@ final class StringableForToStringRector extends AbstractRector implements MinPhp |
46 | 48 | * @readonly |
47 | 49 | */ |
48 | 50 | private BetterNodeFinder $betterNodeFinder; |
| 51 | + /** |
| 52 | + * @readonly |
| 53 | + */ |
| 54 | + private TerminatedNodeAnalyzer $terminatedNodeAnalyzer; |
49 | 55 | /** |
50 | 56 | * @var string |
51 | 57 | */ |
52 | 58 | private const STRINGABLE = 'Stringable'; |
53 | 59 | private bool $hasChanged = \false; |
54 | | - public function __construct(FamilyRelationsAnalyzer $familyRelationsAnalyzer, ReturnTypeInferer $returnTypeInferer, ClassAnalyzer $classAnalyzer, BetterNodeFinder $betterNodeFinder) |
| 60 | + public function __construct(FamilyRelationsAnalyzer $familyRelationsAnalyzer, ReturnTypeInferer $returnTypeInferer, ClassAnalyzer $classAnalyzer, BetterNodeFinder $betterNodeFinder, TerminatedNodeAnalyzer $terminatedNodeAnalyzer) |
55 | 61 | { |
56 | 62 | $this->familyRelationsAnalyzer = $familyRelationsAnalyzer; |
57 | 63 | $this->returnTypeInferer = $returnTypeInferer; |
58 | 64 | $this->classAnalyzer = $classAnalyzer; |
59 | 65 | $this->betterNodeFinder = $betterNodeFinder; |
| 66 | + $this->terminatedNodeAnalyzer = $terminatedNodeAnalyzer; |
60 | 67 | } |
61 | 68 | public function provideMinPhpVersion() : int |
62 | 69 | { |
@@ -135,6 +142,10 @@ private function processNotStringType(ClassMethod $toStringClassMethod) : void |
135 | 142 | $hasReturn = $this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($toStringClassMethod, Return_::class); |
136 | 143 | if (!$hasReturn) { |
137 | 144 | $emptyStringReturn = new Return_(new String_('')); |
| 145 | + $lastStmt = $toStringClassMethod->stmts[\count($toStringClassMethod->stmts) - 1] ?? null; |
| 146 | + if ($lastStmt instanceof Expression && $this->terminatedNodeAnalyzer->isAlwaysTerminated($toStringClassMethod, $lastStmt, $emptyStringReturn)) { |
| 147 | + return; |
| 148 | + } |
138 | 149 | $toStringClassMethod->stmts[] = $emptyStringReturn; |
139 | 150 | $this->hasChanged = \true; |
140 | 151 | return; |
|
0 commit comments