From dc35bb56bcff52ada6cb9ee033984093a1aa59ed Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 25 Jul 2026 12:38:30 +0300 Subject: [PATCH 01/15] rector --- CHANGELOG.md | 1 + README.md | 49 +++++++++++- composer.json | 4 +- rector.php | 10 +-- .../Rules/RemoveOverrideAttributeRector.php | 74 +++++++++++++++++++ src/Rector/SetList.php | 10 +++ src/Rector/Sets/yii-core.php | 23 ++++++ .../Fixture/aliased_import.php.inc | 32 ++++++++ .../Fixture/fully_qualified.php.inc | 28 +++++++ .../grouped_with_other_attribute.php.inc | 29 ++++++++ .../Fixture/no_change_no_attribute.php.inc | 9 +++ .../Fixture/no_change_other_attribute.php.inc | 10 +++ .../Fixture/separate_attribute_groups.php.inc | 30 ++++++++ .../Fixture/simple.php.inc | 28 +++++++ .../RemoveOverrideAttributeRectorTest.php | 29 ++++++++ .../config/configured_rule.php | 11 +++ tests/Rector/SetListTest.php | 25 +++++++ 17 files changed, 391 insertions(+), 11 deletions(-) create mode 100644 src/Rector/Rules/RemoveOverrideAttributeRector.php create mode 100644 src/Rector/SetList.php create mode 100644 src/Rector/Sets/yii-core.php create mode 100644 tests/Rector/Rules/RemoveOverrideAttributeRector/Fixture/aliased_import.php.inc create mode 100644 tests/Rector/Rules/RemoveOverrideAttributeRector/Fixture/fully_qualified.php.inc create mode 100644 tests/Rector/Rules/RemoveOverrideAttributeRector/Fixture/grouped_with_other_attribute.php.inc create mode 100644 tests/Rector/Rules/RemoveOverrideAttributeRector/Fixture/no_change_no_attribute.php.inc create mode 100644 tests/Rector/Rules/RemoveOverrideAttributeRector/Fixture/no_change_other_attribute.php.inc create mode 100644 tests/Rector/Rules/RemoveOverrideAttributeRector/Fixture/separate_attribute_groups.php.inc create mode 100644 tests/Rector/Rules/RemoveOverrideAttributeRector/Fixture/simple.php.inc create mode 100644 tests/Rector/Rules/RemoveOverrideAttributeRector/RemoveOverrideAttributeRectorTest.php create mode 100644 tests/Rector/Rules/RemoveOverrideAttributeRector/config/configured_rule.php create mode 100644 tests/Rector/SetListTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index d7be0e5..331746a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 1.0.1 under development - Enh #4: Add the `no_empty_statement` rule to `@Yiisoft/Core` (@mspirkov) +- Enh #10: Add `RemoveOverrideAttributeRector` rule (@vjik) ## 1.0.0 January 23, 2026 diff --git a/README.md b/README.md index a954489..1aa392c 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ [![type-coverage](https://shepherd.dev/github/yiisoft/code-style/coverage.svg)](https://shepherd.dev/github/yiisoft/code-style) [![psalm-level](https://shepherd.dev/github/yiisoft/code-style/level.svg)](https://shepherd.dev/github/yiisoft/code-style) -A package that provides [PHP CS Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) rule sets for enforcing code style -in Yii packages. +A package that provides [PHP CS Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) rule sets and +[Rector](https://github.com/rectorphp/rector) rules for enforcing code style in Yii packages. ## Requirements @@ -61,6 +61,51 @@ return ConfigBuilder::build() ``` +The package also provides [Rector](https://github.com/rectorphp/rector) rules: + +- `Yiisoft\CodeStyle\Rector\Rules\RemoveOverrideAttributeRector` — removes the `#[Override]` attribute from methods. + Useful for packages that support PHP versions lower than 8.3, where the attribute is not available. + +An example configuration using this rule: + +```php +withPaths([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]) + ->withRules([ + RemoveOverrideAttributeRector::class, + ]); +``` + +The rules are also bundled into a ready-to-use `Yiisoft\CodeStyle\Rector\SetList::YII_CORE` set: + +```php +withPaths([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]) + ->withSets([ + SetList::YII_CORE, + ]); +``` + ## Documentation - [Internals](docs/internals.md) diff --git a/composer.json b/composer.json index eccb75b..f45066d 100644 --- a/composer.json +++ b/composer.json @@ -28,12 +28,12 @@ ], "require": { "php": "^7.4 || ^8.0", - "friendsofphp/php-cs-fixer": "^3.92.5" + "friendsofphp/php-cs-fixer": "^3.92.5", + "rector/rector": "^2.0" }, "require-dev": { "maglnet/composer-require-checker": "^3.8.0 || ^4.7.1", "phpunit/phpunit": "^9.6.31", - "rector/rector": "^2.3.4", "vimeo/psalm": "^5.26.1 || ^6.10.3" }, "autoload": { diff --git a/rector.php b/rector.php index d545deb..3aa0ecd 100644 --- a/rector.php +++ b/rector.php @@ -2,9 +2,8 @@ declare(strict_types=1); -use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector; use Rector\Config\RectorConfig; -use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector; +use Yiisoft\CodeStyle\Rector\SetList; return RectorConfig::configure() ->withPaths([ @@ -12,9 +11,6 @@ __DIR__ . '/tests', ]) ->withPhp74Sets() - ->withRules([ - InlineConstructorDefaultToPropertyRector::class, - ]) - ->withSkip([ - ClosureToArrowFunctionRector::class, + ->withSets([ + SetList::YII_CORE, ]); diff --git a/src/Rector/Rules/RemoveOverrideAttributeRector.php b/src/Rector/Rules/RemoveOverrideAttributeRector.php new file mode 100644 index 0000000..48c4f60 --- /dev/null +++ b/src/Rector/Rules/RemoveOverrideAttributeRector.php @@ -0,0 +1,74 @@ +attrGroups as $groupKey => $attrGroup) { + foreach ($attrGroup->attrs as $attrKey => $attr) { + if ($this->getName($attr->name) === 'Override') { + unset($attrGroup->attrs[$attrKey]); + $changed = true; + break; + } + } + + if ($attrGroup->attrs === []) { + unset($node->attrGroups[$groupKey]); + } + } + + if (!$changed) { + return null; + } + + $node->attrGroups = array_values($node->attrGroups); + + return $node; + } +} diff --git a/src/Rector/SetList.php b/src/Rector/SetList.php new file mode 100644 index 0000000..186ab01 --- /dev/null +++ b/src/Rector/SetList.php @@ -0,0 +1,10 @@ +rules([ + InlineConstructorDefaultToPropertyRector::class, + RemoveOverrideAttributeRector::class, + ]); + + $rectorConfig->skip([ + ClosureToArrowFunctionRector::class, + ReadOnlyPropertyRector::class, + NullToStrictStringFuncCallArgRector::class, + ]); +}; diff --git a/tests/Rector/Rules/RemoveOverrideAttributeRector/Fixture/aliased_import.php.inc b/tests/Rector/Rules/RemoveOverrideAttributeRector/Fixture/aliased_import.php.inc new file mode 100644 index 0000000..7c4ea5a --- /dev/null +++ b/tests/Rector/Rules/RemoveOverrideAttributeRector/Fixture/aliased_import.php.inc @@ -0,0 +1,32 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/tests/Rector/Rules/RemoveOverrideAttributeRector/config/configured_rule.php b/tests/Rector/Rules/RemoveOverrideAttributeRector/config/configured_rule.php new file mode 100644 index 0000000..bd802af --- /dev/null +++ b/tests/Rector/Rules/RemoveOverrideAttributeRector/config/configured_rule.php @@ -0,0 +1,11 @@ +withRules([ + RemoveOverrideAttributeRector::class, + ]); diff --git a/tests/Rector/SetListTest.php b/tests/Rector/SetListTest.php new file mode 100644 index 0000000..cbcfe99 --- /dev/null +++ b/tests/Rector/SetListTest.php @@ -0,0 +1,25 @@ +assertFileExists(SetList::YII_CORE); + + $callable = require SetList::YII_CORE; + + $this->assertIsCallable($callable); + + $callable(new RectorConfig()); + + $this->addToAssertionCount(1); + } +} From c97f92c15798b3b0520d81094f14d0597979ace7 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 25 Jul 2026 12:47:26 +0300 Subject: [PATCH 02/15] improve --- README.md | 4 ++++ src/Rector/SetList.php | 2 +- src/Rector/{Sets => sets}/yii-core.php | 0 3 files changed, 5 insertions(+), 1 deletion(-) rename src/Rector/{Sets => sets}/yii-core.php (100%) diff --git a/README.md b/README.md index 1aa392c..2119acf 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ composer require --dev yiisoft/code-style ## General usage +### PHP CS Fixer + The package contains the following sets of rules: 1. `@Yiisoft/Core` @@ -61,6 +63,8 @@ return ConfigBuilder::build() ``` +### Rector + The package also provides [Rector](https://github.com/rectorphp/rector) rules: - `Yiisoft\CodeStyle\Rector\Rules\RemoveOverrideAttributeRector` — removes the `#[Override]` attribute from methods. diff --git a/src/Rector/SetList.php b/src/Rector/SetList.php index 186ab01..af70196 100644 --- a/src/Rector/SetList.php +++ b/src/Rector/SetList.php @@ -6,5 +6,5 @@ final class SetList { - public const YII_CORE = __DIR__ . '/Sets/yii-core.php'; + public const YII_CORE = __DIR__ . '/sets/yii-core.php'; } diff --git a/src/Rector/Sets/yii-core.php b/src/Rector/sets/yii-core.php similarity index 100% rename from src/Rector/Sets/yii-core.php rename to src/Rector/sets/yii-core.php From 02cce239fcca5b41db2c54be0b6aa7ea155e3b4b Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 25 Jul 2026 12:48:55 +0300 Subject: [PATCH 03/15] changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 331746a..e21c1a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ ## 1.0.1 under development -- Enh #4: Add the `no_empty_statement` rule to `@Yiisoft/Core` (@mspirkov) -- Enh #10: Add `RemoveOverrideAttributeRector` rule (@vjik) +- New #4: Add the `no_empty_statement` rule to `@Yiisoft/Core` (@mspirkov) +- New #11: Add `RemoveOverrideAttributeRector` Rector rule (@vjik) +- New #11: Add `SetList::YII_CORE` Rector set (@vjik) ## 1.0.0 January 23, 2026 From 8af7867a3ed284dc7abeef857d904328fd0fbdd2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 25 Jul 2026 09:49:59 +0000 Subject: [PATCH 04/15] Apply PHP CS Fixer and Rector changes (CI) --- src/Rector/Rules/RemoveOverrideAttributeRector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Rector/Rules/RemoveOverrideAttributeRector.php b/src/Rector/Rules/RemoveOverrideAttributeRector.php index 48c4f60..63dbfab 100644 --- a/src/Rector/Rules/RemoveOverrideAttributeRector.php +++ b/src/Rector/Rules/RemoveOverrideAttributeRector.php @@ -33,7 +33,7 @@ public function foo(): void {} } CODE_SAMPLE, ), - ] + ], ); } From 011f983748f3887f822f1d0d1e82d7cb66f19eac Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 25 Jul 2026 12:54:35 +0300 Subject: [PATCH 05/15] readme --- README.md | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 2119acf..0c73609 100644 --- a/README.md +++ b/README.md @@ -65,32 +65,12 @@ return ConfigBuilder::build() ### Rector -The package also provides [Rector](https://github.com/rectorphp/rector) rules: +The package provides [Rector](https://github.com/rectorphp/rector) rules: -- `Yiisoft\CodeStyle\Rector\Rules\RemoveOverrideAttributeRector` — removes the `#[Override]` attribute from methods. - Useful for packages that support PHP versions lower than 8.3, where the attribute is not available. +- `RemoveOverrideAttributeRector` — removes the `#[Override]` attribute from methods. Yii convention is not to use + this attribute. -An example configuration using this rule: - -```php -withPaths([ - __DIR__ . '/src', - __DIR__ . '/tests', - ]) - ->withRules([ - RemoveOverrideAttributeRector::class, - ]); -``` - -The rules are also bundled into a ready-to-use `Yiisoft\CodeStyle\Rector\SetList::YII_CORE` set: +A ready-to-use `SetList::YII_CORE` set with rules recommended for Yii packages is also provided: ```php Date: Sat, 25 Jul 2026 13:08:01 +0300 Subject: [PATCH 06/15] fix --- .github/workflows/composer-require-checker.yml | 1 + composer-require-checker.json | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 composer-require-checker.json diff --git a/.github/workflows/composer-require-checker.yml b/.github/workflows/composer-require-checker.yml index 99dfb1c..d4b5ea5 100644 --- a/.github/workflows/composer-require-checker.yml +++ b/.github/workflows/composer-require-checker.yml @@ -7,6 +7,7 @@ on: - 'tests/**' - 'composer.json' - '.github/workflows/composer-require-checker.yml' + - 'composer-require-checker.json' push: branches: ['master'] paths: *paths diff --git a/composer-require-checker.json b/composer-require-checker.json new file mode 100644 index 0000000..97cd4a1 --- /dev/null +++ b/composer-require-checker.json @@ -0,0 +1,14 @@ +{ + "symbol-whitelist": [ + "PhpParser\\Node", + "PhpParser\\Node\\Stmt\\ClassMethod", + "Rector\\CodeQuality\\Rector\\Class_\\InlineConstructorDefaultToPropertyRector", + "Rector\\Php74\\Rector\\Closure\\ClosureToArrowFunctionRector", + "Rector\\Php81\\Rector\\FuncCall\\NullToStrictStringFuncCallArgRector", + "Rector\\Php81\\Rector\\Property\\ReadOnlyPropertyRector", + "Rector\\Rector\\AbstractRector", + "Symplify\\RuleDocGenerator\\Contract\\DocumentedRuleInterface", + "Symplify\\RuleDocGenerator\\ValueObject\\CodeSample\\CodeSample", + "Symplify\\RuleDocGenerator\\ValueObject\\RuleDefinition" + ] +} From aca0cb706bedbc06da014564b4a32cfa67a1ab0f Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 25 Jul 2026 13:21:01 +0300 Subject: [PATCH 07/15] fix --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 16df22d..b88c650 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,6 +25,7 @@ jobs: secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: + coverage: xdebug os: >- ['ubuntu-latest', 'windows-latest'] php: >- From 5af3fddb48755d6e90ca0b256bde97023b68efbc Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 25 Jul 2026 13:26:29 +0300 Subject: [PATCH 08/15] fix --- .github/workflows/build.yml | 1 - phpunit.xml.dist | 2 +- tests/bootstrap.php | 17 +++++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 tests/bootstrap.php diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b88c650..16df22d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,6 @@ jobs: secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: - coverage: xdebug os: >- ['ubuntu-latest', 'windows-latest'] php: >- diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8f2359e..e2562c2 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -4,7 +4,7 @@ backupGlobals="false" colors="true" verbose="true" - bootstrap="vendor/autoload.php" + bootstrap="tests/bootstrap.php" failOnRisky="true" failOnWarning="true" convertErrorsToExceptions="true" diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..beb8ccd --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,17 @@ + Date: Sat, 25 Jul 2026 13:29:48 +0300 Subject: [PATCH 09/15] fix --- phpunit.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e2562c2..8f2359e 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -4,7 +4,7 @@ backupGlobals="false" colors="true" verbose="true" - bootstrap="tests/bootstrap.php" + bootstrap="vendor/autoload.php" failOnRisky="true" failOnWarning="true" convertErrorsToExceptions="true" From b5715c5651c5af45f5871d2685634d7a40d7ae82 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 25 Jul 2026 13:30:18 +0300 Subject: [PATCH 10/15] fix --- .../RemoveOverrideAttributeRectorTest.php | 3 +++ tests/bootstrap.php | 17 ----------------- 2 files changed, 3 insertions(+), 17 deletions(-) delete mode 100644 tests/bootstrap.php diff --git a/tests/Rector/Rules/RemoveOverrideAttributeRector/RemoveOverrideAttributeRectorTest.php b/tests/Rector/Rules/RemoveOverrideAttributeRector/RemoveOverrideAttributeRectorTest.php index e2ed595..1c36a35 100644 --- a/tests/Rector/Rules/RemoveOverrideAttributeRector/RemoveOverrideAttributeRectorTest.php +++ b/tests/Rector/Rules/RemoveOverrideAttributeRector/RemoveOverrideAttributeRectorTest.php @@ -7,6 +7,9 @@ use Iterator; use Rector\Testing\PHPUnit\AbstractRectorTestCase; +/** + * @requires PHP >= 8.3 + */ final class RemoveOverrideAttributeRectorTest extends AbstractRectorTestCase { /** diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100644 index beb8ccd..0000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,17 +0,0 @@ - Date: Sat, 25 Jul 2026 13:31:51 +0300 Subject: [PATCH 11/15] fix --- phpunit.xml.dist | 2 +- tests/bootstrap.php | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/bootstrap.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8f2359e..e2562c2 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -4,7 +4,7 @@ backupGlobals="false" colors="true" verbose="true" - bootstrap="vendor/autoload.php" + bootstrap="tests/bootstrap.php" failOnRisky="true" failOnWarning="true" convertErrorsToExceptions="true" diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..beb8ccd --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,17 @@ + Date: Sat, 25 Jul 2026 13:33:33 +0300 Subject: [PATCH 12/15] fix --- .github/workflows/composer-require-checker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/composer-require-checker.yml b/.github/workflows/composer-require-checker.yml index d4b5ea5..df3e5d9 100644 --- a/.github/workflows/composer-require-checker.yml +++ b/.github/workflows/composer-require-checker.yml @@ -23,6 +23,7 @@ jobs: composer-require-checker: uses: yiisoft/actions/.github/workflows/composer-require-checker.yml@master with: + config: composer-require-checker.json os: >- ['ubuntu-latest'] php: >- From 28ab45619736c3b1824cf76db48689bda81ca25b Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 25 Jul 2026 13:35:43 +0300 Subject: [PATCH 13/15] fix --- composer-require-checker.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/composer-require-checker.json b/composer-require-checker.json index 97cd4a1..64239f0 100644 --- a/composer-require-checker.json +++ b/composer-require-checker.json @@ -10,5 +10,18 @@ "Symplify\\RuleDocGenerator\\Contract\\DocumentedRuleInterface", "Symplify\\RuleDocGenerator\\ValueObject\\CodeSample\\CodeSample", "Symplify\\RuleDocGenerator\\ValueObject\\RuleDefinition" - ] + ], + "php-core-extensions": [ + "Core", + "date", + "json", + "hash", + "pcre", + "Phar", + "Reflection", + "SPL", + "random", + "standard" + ], + "scan-files": [] } From 54df0ff85f835121d1296254da0df502a9d57e09 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 25 Jul 2026 13:39:59 +0300 Subject: [PATCH 14/15] fix --- composer-require-checker.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer-require-checker.json b/composer-require-checker.json index 64239f0..71536f8 100644 --- a/composer-require-checker.json +++ b/composer-require-checker.json @@ -20,7 +20,6 @@ "Phar", "Reflection", "SPL", - "random", "standard" ], "scan-files": [] From f19654c1a155b0f27592c5b425e57497a791ddae Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sat, 25 Jul 2026 13:43:30 +0300 Subject: [PATCH 15/15] fix --- composer-require-checker.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/composer-require-checker.json b/composer-require-checker.json index 71536f8..2b17420 100644 --- a/composer-require-checker.json +++ b/composer-require-checker.json @@ -9,7 +9,10 @@ "Rector\\Rector\\AbstractRector", "Symplify\\RuleDocGenerator\\Contract\\DocumentedRuleInterface", "Symplify\\RuleDocGenerator\\ValueObject\\CodeSample\\CodeSample", - "Symplify\\RuleDocGenerator\\ValueObject\\RuleDefinition" + "Symplify\\RuleDocGenerator\\ValueObject\\RuleDefinition", + "null", "true", "false", + "static", "self", "parent", + "array", "string", "int", "float", "bool", "iterable", "callable", "void", "object", "mixed", "never" ], "php-core-extensions": [ "Core",