From 40ff02d6870a759edf83c897e86593843bbdd83f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Wer=C5=82os?= Date: Mon, 14 Apr 2025 23:18:29 +0200 Subject: [PATCH 1/3] # This is a combination of 7 commits. # This is the 1st commit message: Add `NoUselessWriteVisibilityFixer` # The commit message #2 will be skipped: # Update # The commit message #3 will be skipped: # Update # The commit message #4 will be skipped: # Update # The commit message #5 will be skipped: # Update # The commit message #6 will be skipped: # Test # The commit message #7 will be skipped: # Fix linting --- CHANGELOG.md | 1 + README.md | 15 ++- src/Fixer/NoUselessWriteVisibilityFixer.php | 101 +++++++++++++++++ .../NoUselessWriteVisibilityFixerTest.php | 105 ++++++++++++++++++ 4 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 src/Fixer/NoUselessWriteVisibilityFixer.php create mode 100644 tests/Fixer/NoUselessWriteVisibilityFixerTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b7adc43..9ba5ec12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG for PHP CS Fixer: custom fixers ## v3.25.0 +- Add NoUselessWriteVisibilityFixer - ReadonlyPromotedPropertiesFixer - support asymmetric visibility ## v3.24.0 diff --git a/README.md b/README.md index a3dc44cb..af94733d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Latest stable version](https://img.shields.io/packagist/v/kubawerlos/php-cs-fixer-custom-fixers.svg?label=current%20version)](https://packagist.org/packages/kubawerlos/php-cs-fixer-custom-fixers) [![PHP version](https://img.shields.io/packagist/php-v/kubawerlos/php-cs-fixer-custom-fixers.svg)](https://php.net) [![License](https://img.shields.io/github/license/kubawerlos/php-cs-fixer-custom-fixers.svg)](LICENSE) -![Tests](https://img.shields.io/badge/tests-3613-brightgreen.svg) +![Tests](https://img.shields.io/badge/tests-3638-brightgreen.svg) [![Downloads](https://img.shields.io/packagist/dt/kubawerlos/php-cs-fixer-custom-fixers.svg)](https://packagist.org/packages/kubawerlos/php-cs-fixer-custom-fixers) [![CI status](https://github.com/kubawerlos/php-cs-fixer-custom-fixers/actions/workflows/ci.yaml/badge.svg)](https://github.com/kubawerlos/php-cs-fixer-custom-fixers/actions/workflows/ci.yaml) @@ -399,6 +399,19 @@ Functions `strlen` and `mb_strlen` must not be compared to 0. +$isNotEmpty = $string !== ''; ``` +#### NoUselessWriteVisibilityFixer +There must be no useless write visibility. +```diff + > */ + private array $predecessorKindMap; + + public function __construct() + { + if (\defined('T_PUBLIC_SET')) { + $this->predecessorKindMap = [ + \T_PUBLIC_SET => [\T_PUBLIC, CT::T_CONSTRUCTOR_PROPERTY_PROMOTION_PUBLIC], + \T_PROTECTED_SET => [\T_PROTECTED, CT::T_CONSTRUCTOR_PROPERTY_PROMOTION_PROTECTED], + \T_PRIVATE_SET => [\T_PRIVATE, CT::T_CONSTRUCTOR_PROPERTY_PROMOTION_PRIVATE], + ]; + } + } + + public function getDefinition(): FixerDefinitionInterface + { + return new FixerDefinition( + 'There must be no useless write visibility.', + [new CodeSample( + <<<'PHP' + isAnyTokenKindsFound(\array_keys($this->predecessorKindMap)); + } + + public function isRisky(): bool + { + return false; + } + + public function fix(\SplFileInfo $file, Tokens $tokens): void + { + foreach ($tokens->findGivenKind(\array_keys($this->predecessorKindMap)) as $kind => $elements) { + foreach (\array_keys($elements) as $index) { + $this->fixVisibility($tokens, $index, $kind, $kind === \T_PUBLIC_SET); + } + } + } + + private function fixVisibility(Tokens $tokens, int $index, int $kind, bool $makePublicIfNone): void + { + $prevIndex = $tokens->getPrevMeaningfulToken($index); + \assert(\is_int($prevIndex)); + if ($tokens[$prevIndex]->isGivenKind(\T_ABSTRACT)) { + $prevIndex = $tokens->getPrevMeaningfulToken($prevIndex); + \assert(\is_int($prevIndex)); + } + + if (!$tokens[$prevIndex]->isGivenKind($this->predecessorKindMap[$kind])) { + if ($makePublicIfNone) { + $tokens[$index] = new Token([\T_PUBLIC, 'public']); + } + + return; + } + + $tokens->clearAt($index); + + if ($tokens[$index + 1]->isWhitespace()) { + $tokens->clearAt($index + 1); + } + } +} diff --git a/tests/Fixer/NoUselessWriteVisibilityFixerTest.php b/tests/Fixer/NoUselessWriteVisibilityFixerTest.php new file mode 100644 index 00000000..9df7b6a4 --- /dev/null +++ b/tests/Fixer/NoUselessWriteVisibilityFixerTest.php @@ -0,0 +1,105 @@ += 8.4 + */ +final class NoUselessWriteVisibilityFixerTest extends AbstractFixerTestCase +{ + public function testIsRisky(): void + { + self::assertRiskiness(false); + } + + /** + * @dataProvider provideFixCases + */ + public function testFix(string $expected, ?string $input = null): void + { + $this->doTest($expected, $input); + } + + /** + * @return iterable + */ + public static function provideFixCases(): iterable + { + yield 'class properties' => [ + <<<'PHP' + [ + <<<'PHP' + [ + <<<'PHP' + [ + <<<'PHP' + Date: Wed, 23 Apr 2025 22:24:27 +0200 Subject: [PATCH 2/3] Update --- src/Fixer/NoUselessWriteVisibilityFixer.php | 5 +++- .../NoUselessWriteVisibilityFixerTest.php | 26 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/Fixer/NoUselessWriteVisibilityFixer.php b/src/Fixer/NoUselessWriteVisibilityFixer.php index 42c47776..a3400f0e 100644 --- a/src/Fixer/NoUselessWriteVisibilityFixer.php +++ b/src/Fixer/NoUselessWriteVisibilityFixer.php @@ -86,7 +86,10 @@ private function fixVisibility(Tokens $tokens, int $index, int $kind, bool $make if (!$tokens[$prevIndex]->isGivenKind($this->predecessorKindMap[$kind])) { if ($makePublicIfNone) { - $tokens[$index] = new Token([\T_PUBLIC, 'public']); + $prevDeciderIndex = $tokens->getPrevTokenOfKind($index, ['(', ';', '{']); + \assert(\is_int($prevDeciderIndex)); + $kind = $tokens[$prevDeciderIndex]->equals('(') ? CT::T_CONSTRUCTOR_PROPERTY_PROMOTION_PUBLIC : \T_PUBLIC; + $tokens[$index] = new Token([$kind, 'public']); } return; diff --git a/tests/Fixer/NoUselessWriteVisibilityFixerTest.php b/tests/Fixer/NoUselessWriteVisibilityFixerTest.php index 9df7b6a4..4464ef31 100644 --- a/tests/Fixer/NoUselessWriteVisibilityFixerTest.php +++ b/tests/Fixer/NoUselessWriteVisibilityFixerTest.php @@ -58,12 +58,34 @@ public static function provideFixCases(): iterable yield 'only write visibility' => [ <<<'PHP' Date: Thu, 24 Apr 2025 21:21:49 +0200 Subject: [PATCH 3/3] Update `README.md` --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ef13ccad..399ada69 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Latest stable version](https://img.shields.io/packagist/v/kubawerlos/php-cs-fixer-custom-fixers.svg?label=current%20version)](https://packagist.org/packages/kubawerlos/php-cs-fixer-custom-fixers) [![PHP version](https://img.shields.io/packagist/php-v/kubawerlos/php-cs-fixer-custom-fixers.svg)](https://php.net) [![License](https://img.shields.io/github/license/kubawerlos/php-cs-fixer-custom-fixers.svg)](LICENSE) -![Tests](https://img.shields.io/badge/tests-3607-brightgreen.svg) +![Tests](https://img.shields.io/badge/tests-3632-brightgreen.svg) [![Downloads](https://img.shields.io/packagist/dt/kubawerlos/php-cs-fixer-custom-fixers.svg)](https://packagist.org/packages/kubawerlos/php-cs-fixer-custom-fixers) [![CI status](https://github.com/kubawerlos/php-cs-fixer-custom-fixers/actions/workflows/ci.yaml/badge.svg)](https://github.com/kubawerlos/php-cs-fixer-custom-fixers/actions/workflows/ci.yaml) @@ -399,6 +399,19 @@ Functions `strlen` and `mb_strlen` must not be compared to 0. +$isNotEmpty = $string !== ''; ``` +#### NoUselessWriteVisibilityFixer +There must be no useless write visibility. +```diff +