Skip to content

Commit 62e1c8f

Browse files
authored
Keep PhpDocs when migrating to the new casts() method (#198)
* Keep PhpDocs when migrating to the new casts() method * Small Rector fix
1 parent dea1359 commit 62e1c8f

File tree

2 files changed

+79
-4
lines changed

2 files changed

+79
-4
lines changed

Diff for: src/Rector/Class_/ModelCastsPropertyToCastsMethodRector.php

+35-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
use PhpParser\Node\Stmt\ClassMethod;
99
use PhpParser\Node\Stmt\Property;
1010
use PhpParser\Node\Stmt\Return_;
11+
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
12+
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
1113
use PHPStan\Type\ObjectType;
14+
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
15+
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
1216
use Rector\Rector\AbstractRector;
1317
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
1418
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@@ -18,8 +22,11 @@
1822
*/
1923
class ModelCastsPropertyToCastsMethodRector extends AbstractRector
2024
{
21-
public function __construct(protected BuilderFactory $builderFactory)
22-
{
25+
public function __construct(
26+
protected BuilderFactory $builderFactory,
27+
protected PhpDocInfoFactory $phpDocInfoFactory,
28+
protected DocBlockUpdater $docBlockUpdater,
29+
) {
2330
}
2431

2532
public function getRuleDefinition(): RuleDefinition
@@ -82,15 +89,39 @@ public function refactor(Node $node): ?Class_
8289
$method = $this->builderFactory->method('casts')
8390
->setReturnType('array')
8491
->makeProtected();
92+
93+
if ($stmt->getDocComment() !== null) {
94+
$method->setDocComment($stmt->getDocComment());
95+
}
96+
97+
unset($node->stmts[$index]);
98+
8599
// convert the property to a return statement
86100
$method->addStmt(new Return_($stmt->props[0]->default));
87-
unset($node->stmts[$index]);
88-
$node->stmts[] = $method->getNode();
101+
$methodNode = $method->getNode();
102+
$node->stmts[] = $methodNode;
103+
104+
$this->restorePhpDoc($methodNode);
89105

90106
return $node;
91107
}
92108
}
93109

94110
return null;
95111
}
112+
113+
private function restorePhpDoc(ClassMethod|Node $methodNode): void
114+
{
115+
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($methodNode);
116+
117+
$varTagValueNode = $phpDocInfo->getVarTagValueNode();
118+
119+
if (! $varTagValueNode instanceof VarTagValueNode) {
120+
return;
121+
}
122+
123+
$phpDocInfo->addTagValueNode(new ReturnTagValueNode($varTagValueNode->type, $varTagValueNode->description));
124+
$phpDocInfo->removeByType(VarTagValueNode::class);
125+
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($methodNode);
126+
}
96127
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\Class_\ModelCastsPropertyToCastsMethodRector\Fixture;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class CastsPropertyExists extends Model
8+
{
9+
/**
10+
* The attributes that should be cast.
11+
*
12+
* @var array<string, string>
13+
*/
14+
protected $casts = [
15+
'birthday' => 'datetime',
16+
'age' => 'integer',
17+
];
18+
}
19+
20+
?>
21+
-----
22+
<?php
23+
24+
namespace RectorLaravel\Tests\Rector\Class_\ModelCastsPropertyToCastsMethodRector\Fixture;
25+
26+
use Illuminate\Database\Eloquent\Model;
27+
28+
class CastsPropertyExists extends Model
29+
{
30+
/**
31+
* The attributes that should be cast.
32+
*
33+
* @return array<string, string>
34+
*/
35+
protected function casts(): array
36+
{
37+
return [
38+
'birthday' => 'datetime',
39+
'age' => 'integer',
40+
];
41+
}
42+
}
43+
44+
?>

0 commit comments

Comments
 (0)