Skip to content

Commit 92749f6

Browse files
committed
feat: JIRA-16089 Add legacy Collection Rector
This adds a new Rector rule to refactor the legacy `Collection|Type[]` syntax.
1 parent 83d3f85 commit 92749f6

File tree

10 files changed

+142
-0
lines changed

10 files changed

+142
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Worksome\CodingStyle\Rector\Laravel;
6+
7+
use PhpParser\Comment\Doc;
8+
use PhpParser\Node;
9+
use PhpParser\Node\Stmt\Class_;
10+
use PhpParser\Node\Stmt\ClassMethod;
11+
use PhpParser\Node\Stmt\Property;
12+
use Rector\Rector\AbstractRector;
13+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
14+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
15+
16+
class DisallowedLegacyCollectionArraySyntaxRector extends AbstractRector
17+
{
18+
public function getRuleDefinition(): RuleDefinition
19+
{
20+
return new RuleDefinition(
21+
'PHPDoc `Collection` types must not use the legacy array syntax.',
22+
[
23+
new CodeSample(
24+
<<<PHP
25+
/** @property Collection|Model[] \$models */
26+
class MyClass {}
27+
PHP,
28+
<<<PHP
29+
/** @property Collection<int, Model> \$models */
30+
class MyClass {}
31+
PHP,
32+
),
33+
]
34+
);
35+
}
36+
37+
/** {@inheritdoc} */
38+
public function getNodeTypes(): array
39+
{
40+
return [Property::class, ClassMethod::class, Class_::class];
41+
}
42+
43+
/** {@inheritdoc} */
44+
public function refactor(Node $node): Node|null
45+
{
46+
$docComment = $node->getDocComment();
47+
48+
if (null === $docComment) {
49+
return null;
50+
}
51+
52+
$originalText = $docComment->getText();
53+
$transformedText = $this->transformDocComment($originalText);
54+
55+
if ($originalText === $transformedText) {
56+
return null;
57+
}
58+
59+
$node->setDocComment(new Doc($transformedText));
60+
61+
return $node;
62+
}
63+
64+
protected function transformDocComment(string $docComment): string
65+
{
66+
return preg_replace(
67+
pattern: '#(\\\\?(?:Illuminate\\\\Database\\\\Eloquent\\\\)?Collection)\|([^\s\[\]]+)\[]#',
68+
replacement: '$1<int, $2>',
69+
subject: $docComment
70+
);
71+
}
72+
}

tests/Rector/DisallowedAttributesRector/DisallowedAttributesRectorTest.php renamed to tests/Rector/Generic/DisallowedAttributesRector/DisallowedAttributesRectorTest.php

File renamed without changes.

tests/Rector/DisallowedAttributesRector/Fixture/class_with_allowed_attribute.php.inc renamed to tests/Rector/Generic/DisallowedAttributesRector/Fixture/class_with_allowed_attribute.php.inc

File renamed without changes.

tests/Rector/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute.php.inc renamed to tests/Rector/Generic/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute.php.inc

File renamed without changes.

tests/Rector/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute_in_group.php.inc renamed to tests/Rector/Generic/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute_in_group.php.inc

File renamed without changes.

tests/Rector/DisallowedAttributesRector/config/configured_rule.php renamed to tests/Rector/Generic/DisallowedAttributesRector/config/configured_rule.php

File renamed without changes.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
it('can replace disallowed Collection syntax', function () {
4+
$this->doTestFile(
5+
__DIR__ . '/Fixture/class_with_disallowed_collection_syntax.php.inc'
6+
);
7+
});
8+
9+
it('does not replace allowed Collection syntax', function () {
10+
$this->doTestFile(
11+
__DIR__ . '/Fixture/class_with_allowed_collection_syntax.php.inc'
12+
);
13+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Worksome\CodingStyle\Tests\Rector\DisallowedAttributesRector\Fixture;
4+
5+
use Illuminate\Database\Eloquent\Collection;
6+
use Illuminate\Database\Eloquent\Model;
7+
8+
/** @property Collection<int, Model> $models */
9+
class ClassWithAllowedCollectionSyntax {}
10+
11+
?>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Worksome\CodingStyle\Tests\Rector\DisallowedAttributesRector\Fixture;
4+
5+
use Illuminate\Database\Eloquent\Collection;
6+
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
7+
use Illuminate\Database\Eloquent\Model;
8+
9+
/**
10+
* @property Collection<int, Model> $models_valid (ensures valid syntax is not touched)
11+
* @property Collection|Model[] $models_invalid_a
12+
* @property \Illuminate\Database\Eloquent\Collection|Model[] $models_invalid_b
13+
* @property EloquentCollection|Model[] $models_invalid_c
14+
*/
15+
class ClassWithAllowedCollectionSyntax {}
16+
17+
?>
18+
-----
19+
<?php
20+
21+
namespace Worksome\CodingStyle\Tests\Rector\DisallowedAttributesRector\Fixture;
22+
23+
use Illuminate\Database\Eloquent\Collection;
24+
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
25+
use Illuminate\Database\Eloquent\Model;
26+
27+
/**
28+
* @property Collection<int, Model> $models_valid (ensures valid syntax is not touched)
29+
* @property Collection<int, Model> $models_invalid_a
30+
* @property \Illuminate\Database\Eloquent\Collection<int, Model> $models_invalid_b
31+
* @property EloquentCollection<int, Model> $models_invalid_c
32+
*/
33+
class ClassWithAllowedCollectionSyntax {}
34+
35+
?>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
use Worksome\CodingStyle\Rector\Laravel\DisallowedLegacyCollectionArraySyntaxRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig
10+
->rule(DisallowedLegacyCollectionArraySyntaxRector::class);
11+
};

0 commit comments

Comments
 (0)