From 92749f6927d6aabf42ce3918e2a4f331d6a60050 Mon Sep 17 00:00:00 2001 From: Owen Voke Date: Mon, 27 Oct 2025 09:52:54 +0000 Subject: [PATCH] feat: JIRA-16089 Add legacy Collection Rector This adds a new Rector rule to refactor the legacy `Collection|Type[]` syntax. --- ...lowedLegacyCollectionArraySyntaxRector.php | 72 +++++++++++++++++++ .../DisallowedAttributesRectorTest.php | 0 .../class_with_allowed_attribute.php.inc | 0 .../class_with_disallowed_attribute.php.inc | 0 ...with_disallowed_attribute_in_group.php.inc | 0 .../config/configured_rule.php | 0 ...dLegacyCollectionArraySyntaxRectorTest.php | 13 ++++ ...ass_with_allowed_collection_syntax.php.inc | 11 +++ ..._with_disallowed_collection_syntax.php.inc | 35 +++++++++ .../config/configured_rule.php | 11 +++ 10 files changed, 142 insertions(+) create mode 100644 src/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector.php rename tests/Rector/{ => Generic}/DisallowedAttributesRector/DisallowedAttributesRectorTest.php (100%) rename tests/Rector/{ => Generic}/DisallowedAttributesRector/Fixture/class_with_allowed_attribute.php.inc (100%) rename tests/Rector/{ => Generic}/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute.php.inc (100%) rename tests/Rector/{ => Generic}/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute_in_group.php.inc (100%) rename tests/Rector/{ => Generic}/DisallowedAttributesRector/config/configured_rule.php (100%) create mode 100644 tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/DisallowedLegacyCollectionArraySyntaxRectorTest.php create mode 100644 tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/Fixture/class_with_allowed_collection_syntax.php.inc create mode 100644 tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/Fixture/class_with_disallowed_collection_syntax.php.inc create mode 100644 tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/config/configured_rule.php diff --git a/src/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector.php b/src/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector.php new file mode 100644 index 0000000..12d5a86 --- /dev/null +++ b/src/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector.php @@ -0,0 +1,72 @@ + \$models */ + class MyClass {} + PHP, + ), + ] + ); + } + + /** {@inheritdoc} */ + public function getNodeTypes(): array + { + return [Property::class, ClassMethod::class, Class_::class]; + } + + /** {@inheritdoc} */ + public function refactor(Node $node): Node|null + { + $docComment = $node->getDocComment(); + + if (null === $docComment) { + return null; + } + + $originalText = $docComment->getText(); + $transformedText = $this->transformDocComment($originalText); + + if ($originalText === $transformedText) { + return null; + } + + $node->setDocComment(new Doc($transformedText)); + + return $node; + } + + protected function transformDocComment(string $docComment): string + { + return preg_replace( + pattern: '#(\\\\?(?:Illuminate\\\\Database\\\\Eloquent\\\\)?Collection)\|([^\s\[\]]+)\[]#', + replacement: '$1', + subject: $docComment + ); + } +} diff --git a/tests/Rector/DisallowedAttributesRector/DisallowedAttributesRectorTest.php b/tests/Rector/Generic/DisallowedAttributesRector/DisallowedAttributesRectorTest.php similarity index 100% rename from tests/Rector/DisallowedAttributesRector/DisallowedAttributesRectorTest.php rename to tests/Rector/Generic/DisallowedAttributesRector/DisallowedAttributesRectorTest.php diff --git a/tests/Rector/DisallowedAttributesRector/Fixture/class_with_allowed_attribute.php.inc b/tests/Rector/Generic/DisallowedAttributesRector/Fixture/class_with_allowed_attribute.php.inc similarity index 100% rename from tests/Rector/DisallowedAttributesRector/Fixture/class_with_allowed_attribute.php.inc rename to tests/Rector/Generic/DisallowedAttributesRector/Fixture/class_with_allowed_attribute.php.inc diff --git a/tests/Rector/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute.php.inc b/tests/Rector/Generic/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute.php.inc similarity index 100% rename from tests/Rector/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute.php.inc rename to tests/Rector/Generic/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute.php.inc diff --git a/tests/Rector/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute_in_group.php.inc b/tests/Rector/Generic/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute_in_group.php.inc similarity index 100% rename from tests/Rector/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute_in_group.php.inc rename to tests/Rector/Generic/DisallowedAttributesRector/Fixture/class_with_disallowed_attribute_in_group.php.inc diff --git a/tests/Rector/DisallowedAttributesRector/config/configured_rule.php b/tests/Rector/Generic/DisallowedAttributesRector/config/configured_rule.php similarity index 100% rename from tests/Rector/DisallowedAttributesRector/config/configured_rule.php rename to tests/Rector/Generic/DisallowedAttributesRector/config/configured_rule.php diff --git a/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/DisallowedLegacyCollectionArraySyntaxRectorTest.php b/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/DisallowedLegacyCollectionArraySyntaxRectorTest.php new file mode 100644 index 0000000..9209899 --- /dev/null +++ b/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/DisallowedLegacyCollectionArraySyntaxRectorTest.php @@ -0,0 +1,13 @@ +doTestFile( + __DIR__ . '/Fixture/class_with_disallowed_collection_syntax.php.inc' + ); +}); + +it('does not replace allowed Collection syntax', function () { + $this->doTestFile( + __DIR__ . '/Fixture/class_with_allowed_collection_syntax.php.inc' + ); +}); diff --git a/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/Fixture/class_with_allowed_collection_syntax.php.inc b/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/Fixture/class_with_allowed_collection_syntax.php.inc new file mode 100644 index 0000000..bdf8638 --- /dev/null +++ b/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/Fixture/class_with_allowed_collection_syntax.php.inc @@ -0,0 +1,11 @@ + $models */ +class ClassWithAllowedCollectionSyntax {} + +?> diff --git a/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/Fixture/class_with_disallowed_collection_syntax.php.inc b/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/Fixture/class_with_disallowed_collection_syntax.php.inc new file mode 100644 index 0000000..d1fd025 --- /dev/null +++ b/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/Fixture/class_with_disallowed_collection_syntax.php.inc @@ -0,0 +1,35 @@ + $models_valid (ensures valid syntax is not touched) + * @property Collection|Model[] $models_invalid_a + * @property \Illuminate\Database\Eloquent\Collection|Model[] $models_invalid_b + * @property EloquentCollection|Model[] $models_invalid_c + */ +class ClassWithAllowedCollectionSyntax {} + +?> +----- + $models_valid (ensures valid syntax is not touched) + * @property Collection $models_invalid_a + * @property \Illuminate\Database\Eloquent\Collection $models_invalid_b + * @property EloquentCollection $models_invalid_c + */ +class ClassWithAllowedCollectionSyntax {} + +?> diff --git a/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/config/configured_rule.php b/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/config/configured_rule.php new file mode 100644 index 0000000..10ab21a --- /dev/null +++ b/tests/Rector/Laravel/DisallowedLegacyCollectionArraySyntaxRector/config/configured_rule.php @@ -0,0 +1,11 @@ +rule(DisallowedLegacyCollectionArraySyntaxRector::class); +};