Skip to content

Commit 0fa7412

Browse files
committed
[typed-collections] Add CollectionDocblockGenericTypeRector
1 parent 787002f commit 0fa7412

5 files changed

Lines changed: 194 additions & 0 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Doctrine\Tests\TypedCollections\Rector\ClassMethod\CollectionDocblockGenericTypeRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
10+
11+
final class CollectionDocblockGenericTypeRectorTest extends AbstractRectorTestCase
12+
{
13+
#[DataProvider('provideData')]
14+
public function test(string $filePath): void
15+
{
16+
$this->doTestFile($filePath);
17+
}
18+
19+
public static function provideData(): Iterator
20+
{
21+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22+
}
23+
24+
public function provideConfigFilePath(): string
25+
{
26+
return __DIR__ . '/config/configured_rule.php';
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Doctrine\Tests\TypedCollections\Rector\ClassMethod\CollectionDocblockGenericTypeRector\Fixture;
6+
7+
use Doctrine\Common\Collections\Collection;
8+
use Doctrine\Common\Collections\ArrayCollection;
9+
use Rector\Doctrine\Tests\TypedCollections\Rector\ClassMethod\CollectionDocblockGenericTypeRector\Source\RandomHouse;
10+
11+
final class SomeMethodWithReturnCollection
12+
{
13+
public function getItems(): Collection
14+
{
15+
$collection = new ArrayCollection();
16+
$collection->add(new RandomHouse());
17+
18+
return $collection;
19+
}
20+
}
21+
22+
?>
23+
-----
24+
<?php
25+
26+
declare(strict_types=1);
27+
28+
namespace Rector\Doctrine\Tests\TypedCollections\Rector\ClassMethod\CollectionDocblockGenericTypeRector\Fixture;
29+
30+
use Doctrine\Common\Collections\Collection;
31+
use Doctrine\Common\Collections\ArrayCollection;
32+
use Rector\Doctrine\Tests\TypedCollections\Rector\ClassMethod\CollectionDocblockGenericTypeRector\Source\RandomHouse;
33+
34+
final class SomeMethodWithReturnCollection
35+
{
36+
/**
37+
* @return Collection<int, RandomHouse>
38+
*/
39+
public function getItems(): Collection
40+
{
41+
$collection = new ArrayCollection();
42+
$collection->add(new RandomHouse());
43+
44+
return $collection;
45+
}
46+
}
47+
48+
?>
49+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Rector\Doctrine\Tests\TypedCollections\Rector\ClassMethod\CollectionDocblockGenericTypeRector\Source;
4+
5+
class RandomHouse
6+
{
7+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
use Rector\Doctrine\TypedCollections\Rector\ClassMethod\CollectionGetterNativeTypeRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig->rule(\Rector\Doctrine\TypedCollections\Rector\ClassMethod\CollectionDocblockGenericTypeRector::class);
10+
};
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Doctrine\TypedCollections\Rector\ClassMethod;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Expr\PropertyFetch;
9+
use PhpParser\Node\Name\FullyQualified;
10+
use PhpParser\Node\Stmt\ClassMethod;
11+
use PhpParser\Node\Stmt\Return_;
12+
use Rector\Doctrine\Enum\DoctrineClass;
13+
use Rector\Doctrine\TypedCollections\TypeAnalyzer\CollectionTypeDetector;
14+
use Rector\Rector\AbstractRector;
15+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
16+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
17+
18+
/**
19+
* @see \Rector\Doctrine\Tests\TypedCollections\Rector\ClassMethod\CollectionDocblockGenericTypeRector\CollectionDocblockGenericTypeRectorTest
20+
*/
21+
final class CollectionDocblockGenericTypeRector extends AbstractRector
22+
{
23+
public function getRuleDefinition(): RuleDefinition
24+
{
25+
return new RuleDefinition(
26+
'Add more precise generics type to method that returns Collection',
27+
[
28+
new CodeSample(
29+
<<<'CODE_SAMPLE'
30+
use Doctrine\Common\Collections\Collection;
31+
use Doctrine\Common\Collections\ArrayCollection;
32+
33+
final class SomeClass
34+
{
35+
public function getItems(): Collection
36+
{
37+
$collection = new ArrayCollection();
38+
$collection->add(new SomeClass());
39+
40+
return $collection;
41+
}
42+
}
43+
CODE_SAMPLE
44+
,
45+
<<<'CODE_SAMPLE'
46+
use Doctrine\Common\Collections\Collection;
47+
use Doctrine\Common\Collections\ArrayCollection;
48+
49+
final class SomeClass
50+
{
51+
/**
52+
* @return Collection<int, SomeClass>
53+
*/
54+
public function getItems(): Collection
55+
{
56+
$collection = new ArrayCollection();
57+
$collection->add(new SomeClass());
58+
59+
return $collection;
60+
}
61+
}
62+
CODE_SAMPLE
63+
)]
64+
);
65+
}
66+
67+
public function getNodeTypes(): array
68+
{
69+
return [ClassMethod::class];
70+
}
71+
72+
/**
73+
* @param ClassMethod $node
74+
*/
75+
public function refactor(Node $node): ?ClassMethod
76+
{
77+
if ($node->stmts === null) {
78+
return null;
79+
}
80+
81+
// already different type
82+
if ($node->returnType instanceof \PhpParser\Node) {
83+
return null;
84+
}
85+
86+
if ($node->returnType === null) {
87+
return null;
88+
}
89+
90+
if (! $this->isName($node->returnType, DoctrineClass::COLLECTION)) {
91+
return null;
92+
}
93+
94+
// find return
95+
// find new ArrayCollection()
96+
// improve return type
97+
98+
return null;
99+
}
100+
}

0 commit comments

Comments
 (0)