Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/composer-require-checker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
- 'tests/**'
- 'composer.json'
- '.github/workflows/composer-require-checker.yml'
- 'composer-require-checker.json'
push:
branches: ['master']
paths: *paths
Expand All @@ -22,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: >-
Expand Down
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

## 1.0.1 under development

- Enh #4: Add the `no_empty_statement` rule to `@Yiisoft/Core` (@mspirkov)
- 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

Expand Down
33 changes: 31 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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`
Expand Down Expand Up @@ -61,6 +63,33 @@ return ConfigBuilder::build()

```

### Rector

The package provides [Rector](https://github.com/rectorphp/rector) rules:

- `RemoveOverrideAttributeRector` — removes the `#[Override]` attribute from methods. Yii convention is not to use
this attribute.

A ready-to-use `SetList::YII_CORE` set with rules recommended for Yii packages is also provided:

```php
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Yiisoft\CodeStyle\Rector\SetList;

return RectorConfig::configure()
->withPaths([
__DIR__ . '/src',
__DIR__ . '/tests',
])
->withSets([
SetList::YII_CORE,
]);
```

## Documentation

- [Internals](docs/internals.md)
Expand Down
29 changes: 29 additions & 0 deletions composer-require-checker.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"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",
"null", "true", "false",
"static", "self", "parent",
"array", "string", "int", "float", "bool", "iterable", "callable", "void", "object", "mixed", "never"
],
"php-core-extensions": [
"Core",
"date",
"json",
"hash",
"pcre",
"Phar",
"Reflection",
"SPL",
"standard"
],
"scan-files": []
}
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
backupGlobals="false"
colors="true"
verbose="true"
bootstrap="vendor/autoload.php"
bootstrap="tests/bootstrap.php"
failOnRisky="true"
failOnWarning="true"
convertErrorsToExceptions="true"
Expand Down
10 changes: 3 additions & 7 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@

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([
__DIR__ . '/src',
__DIR__ . '/tests',
])
->withPhp74Sets()
->withRules([
InlineConstructorDefaultToPropertyRector::class,
])
->withSkip([
ClosureToArrowFunctionRector::class,
->withSets([
SetList::YII_CORE,
]);
74 changes: 74 additions & 0 deletions src/Rector/Rules/RemoveOverrideAttributeRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

declare(strict_types=1);

namespace Yiisoft\CodeStyle\Rector\Rules;

use PhpParser\Node;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\Contract\DocumentedRuleInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

final class RemoveOverrideAttributeRector extends AbstractRector implements DocumentedRuleInterface
{
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Remove #[Override] attribute from methods',
[
new CodeSample(
<<<'CODE_SAMPLE'
class Child extends Parent
{
#[Override]
public function foo(): void {}
}
CODE_SAMPLE,
<<<'CODE_SAMPLE'
class Child extends Parent
{
public function foo(): void {}
}
CODE_SAMPLE,
),
],
);
}

public function getNodeTypes(): array
{
return [ClassMethod::class];
}

public function refactor(Node $node): ?Node
{
if (!$node instanceof ClassMethod) {
return null;
}

$changed = false;
foreach ($node->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;
}
}
10 changes: 10 additions & 0 deletions src/Rector/SetList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Yiisoft\CodeStyle\Rector;

final class SetList
{
public const YII_CORE = __DIR__ . '/sets/yii-core.php';
}
23 changes: 23 additions & 0 deletions src/Rector/sets/yii-core.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use Rector\Config\RectorConfig;
use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector;
use Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector;
use Rector\Php81\Rector\Property\ReadOnlyPropertyRector;
use Yiisoft\CodeStyle\Rector\Rules\RemoveOverrideAttributeRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rules([
InlineConstructorDefaultToPropertyRector::class,
RemoveOverrideAttributeRector::class,
]);

$rectorConfig->skip([
ClosureToArrowFunctionRector::class,
ReadOnlyPropertyRector::class,
NullToStrictStringFuncCallArgRector::class,
]);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Override as Ov;

class AliasedFixtureParent
{
}

class AliasedFixture extends AliasedFixtureParent
{
#[Ov]
public function foo(): void
{
}
}

-----
<?php

use Override as Ov;

class AliasedFixtureParent
{
}

class AliasedFixture extends AliasedFixtureParent
{
public function foo(): void
{
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

class FullyQualifiedFixtureParent
{
}

class FullyQualifiedFixture extends FullyQualifiedFixtureParent
{
#[\Override]
public function foo(): void
{
}
}

-----
<?php

class FullyQualifiedFixtureParent
{
}

class FullyQualifiedFixture extends FullyQualifiedFixtureParent
{
public function foo(): void
{
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

class GroupedFixtureParent
{
}

class GroupedFixture extends GroupedFixtureParent
{
#[Override, SomeAttribute]
public function foo(): void
{
}
}

-----
<?php

class GroupedFixtureParent
{
}

class GroupedFixture extends GroupedFixtureParent
{
#[SomeAttribute]
public function foo(): void
{
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

class NoChangeNoAttributeFixture
{
public function foo(): void
{
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

class NoChangeOtherAttributeFixture
{
#[SomeAttribute]
public function foo(): void
{
}
}

Loading