Add custom rector rule for yoda conditions

This commit is contained in:
David Stone
2025-02-09 00:21:40 -07:00
parent be0ab98895
commit 07a69d33e5
7 changed files with 167 additions and 29 deletions

View File

@ -17,10 +17,12 @@
"license": [ "license": [
"GPL-3.0-or-later" "GPL-3.0-or-later"
], ],
"autoload": { "autoload": {
"classmap": ["inc"] "classmap": [
}, "inc"
"type": "wordpress-plugin", ]
},
"type": "wordpress-plugin",
"require": { "require": {
"php": ">=7.4.1", "php": ">=7.4.1",
"automattic/jetpack-autoloader": "^5.0.0", "automattic/jetpack-autoloader": "^5.0.0",
@ -62,9 +64,9 @@
"phpstan/extension-installer": "^1.1" "phpstan/extension-installer": "^1.1"
}, },
"config": { "config": {
"platform": { "platform": {
"php": "7.4.1" "php": "7.4.1"
}, },
"allow-plugins": { "allow-plugins": {
"composer/installers": true, "composer/installers": true,
"dealerdirect/phpcodesniffer-composer-installer": true, "dealerdirect/phpcodesniffer-composer-installer": true,
@ -95,7 +97,9 @@
}, },
"extra": { "extra": {
"installer-paths": { "installer-paths": {
"vendor/woocommerce/{$name}/": ["type:wordpress-plugin"] "vendor/woocommerce/{$name}/": [
"type:wordpress-plugin"
]
}, },
"patches": { "patches": {
"jasny/sso": [ "jasny/sso": [
@ -107,7 +111,13 @@
] ]
} }
}, },
"scripts": { "scripts": {
"post-update-cmd": "cd vendor/mpdf/mpdf/ttfonts && rm -f AboriginalSansREGULAR.ttf Aegean.otf Aegyptus.otf Akkadian.otf ayar.ttf damase_v.2.ttf DBSILBR.ttf DejaVuSerif.ttf Dhyana-Regular.ttf DejaVuSansMono-Oblique.ttf DejaVuSerif-BoldItalic.ttf DhyanaOFL.txt DejaVuSerifCondensed-BoldItalic.ttf DejaVuSansMono-Bold.ttf DejaVuSerif-Italic.ttf DejaVuSansMono.ttf DejaVuSansMono-BoldOblique.ttf DejaVuSerif-Bold.ttf Dhyana-Bold.ttf DejaVuSerifCondensed-Italic.ttf DejaVuSansCondensed-BoldOblique.ttf DejaVuSansCondensed-Oblique.ttf DejaVuSans-Oblique.ttf DejaVuSans-BoldOblique.ttf DejaVuSans-Bold.ttf DejaVuSans.ttf FreeMonoBoldOblique.ttf FreeMonoOblique.ttf FreeSans.ttf FreeSansBold.ttf FreeSansBoldOblique.ttf FreeSansOblique.ttf FreeSerif.ttf FreeSerifBold.ttf FreeSerifBoldItalic.ttf FreeSerifItalic.ttf Garuda.ttf Garuda-Bold.ttf Garuda-BoldOblique.ttf Garuda-Oblique.ttf GNUFreeFontinfo.txt Jomolhari.ttf Jomolhari-OFL.txt kaputaunicode.ttf KhmerOFL.txt KhmerOS.ttf lannaalif-v1-03.ttf 'Lateef font OFL.txt' LateefRegOT.ttf Lohit-Kannada.ttf LohitKannadaOFL.txt ocrb10.ttf ocrbinfo.txt Padauk-book.ttf Pothana2000.ttf Quivira.otf Sun-ExtA.ttf Sun-ExtB.ttf SundaneseUnicode-1.0.5.ttf SyrCOMEdessa.otf SyrCOMEdessa_license.txt TaameyDavidCLM-LICENSE.txt TaameyDavidCLM-Medium.ttf TaiHeritagePro.ttf Tharlon-Regular.ttf TharlonOFL.txt UnBatang_0613.ttf Uthman.otf 'XB Riyaz.ttf' 'XB RiyazBd.ttf' 'XB RiyazBdIt.ttf' 'XB RiyazIt.ttf' 'XW Zar Font Info.txt' ZawgyiOne.ttf Abyssinica_SIL.ttf" "post-update-cmd": "cd vendor/mpdf/mpdf/ttfonts && rm -f AboriginalSansREGULAR.ttf Aegean.otf Aegyptus.otf Akkadian.otf ayar.ttf damase_v.2.ttf DBSILBR.ttf DejaVuSerif.ttf Dhyana-Regular.ttf DejaVuSansMono-Oblique.ttf DejaVuSerif-BoldItalic.ttf DhyanaOFL.txt DejaVuSerifCondensed-BoldItalic.ttf DejaVuSansMono-Bold.ttf DejaVuSerif-Italic.ttf DejaVuSansMono.ttf DejaVuSansMono-BoldOblique.ttf DejaVuSerif-Bold.ttf Dhyana-Bold.ttf DejaVuSerifCondensed-Italic.ttf DejaVuSansCondensed-BoldOblique.ttf DejaVuSansCondensed-Oblique.ttf DejaVuSans-Oblique.ttf DejaVuSans-BoldOblique.ttf DejaVuSans-Bold.ttf DejaVuSans.ttf FreeMonoBoldOblique.ttf FreeMonoOblique.ttf FreeSans.ttf FreeSansBold.ttf FreeSansBoldOblique.ttf FreeSansOblique.ttf FreeSerif.ttf FreeSerifBold.ttf FreeSerifBoldItalic.ttf FreeSerifItalic.ttf Garuda.ttf Garuda-Bold.ttf Garuda-BoldOblique.ttf Garuda-Oblique.ttf GNUFreeFontinfo.txt Jomolhari.ttf Jomolhari-OFL.txt kaputaunicode.ttf KhmerOFL.txt KhmerOS.ttf lannaalif-v1-03.ttf 'Lateef font OFL.txt' LateefRegOT.ttf Lohit-Kannada.ttf LohitKannadaOFL.txt ocrb10.ttf ocrbinfo.txt Padauk-book.ttf Pothana2000.ttf Quivira.otf Sun-ExtA.ttf Sun-ExtB.ttf SundaneseUnicode-1.0.5.ttf SyrCOMEdessa.otf SyrCOMEdessa_license.txt TaameyDavidCLM-LICENSE.txt TaameyDavidCLM-Medium.ttf TaiHeritagePro.ttf Tharlon-Regular.ttf TharlonOFL.txt UnBatang_0613.ttf Uthman.otf 'XB Riyaz.ttf' 'XB RiyazBd.ttf' 'XB RiyazBdIt.ttf' 'XB RiyazIt.ttf' 'XW Zar Font Info.txt' ZawgyiOne.ttf Abyssinica_SIL.ttf"
} },
} "autoload-dev": {
"psr-4": {
"Utils\\Rector\\": "utils/rector/src",
"Utils\\Rector\\Tests\\": "utils/rector/tests"
}
}
}

View File

@ -1,18 +1,14 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<phpunit <phpunit bootstrap="tests/bootstrap.php" backupGlobals="false" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true">
bootstrap="tests/bootstrap.php" <php>
backupGlobals="false" <const name="WP_TESTS_MULTISITE" value="1"/>
colors="true" </php>
convertErrorsToExceptions="true" <testsuites>
convertNoticesToExceptions="true" <testsuite name="testing">
convertWarningsToExceptions="true" <directory suffix="Test.php">./tests/</directory>
> </testsuite>
<php> <testsuite name="rector">
<const name="WP_TESTS_MULTISITE" value="1" /> <directory>utils/rector/tests</directory>
</php> </testsuite>
<testsuites> </testsuites>
<testsuite name="testing">
<directory suffix="Test.php">./tests/</directory>
</testsuite>
</testsuites>
</phpunit> </phpunit>

View File

@ -19,8 +19,10 @@ return RectorConfig::configure()
->withSkipPath(__DIR__ . '/vendor',) ->withSkipPath(__DIR__ . '/vendor',)
->withImportNames(false) ->withImportNames(false)
->withPhpSets() ->withPhpSets()
->withCodeQualityLevel(15)
->withCodingStyleLevel(5)
->withRules( ->withRules(
[ [
AddVoidReturnTypeWhereNoReturnRector::class, \Utils\Rector\Rector\YodaConditionsRector::class,
] ]
); );

View File

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace Utils\Rector\Rector;
use PhpParser\Node;
use Rector\Rector\AbstractRector;
use PhpParser\Node\Expr\BinaryOp\Equal;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\BinaryOp\NotEqual;
use PhpParser\Node\Scalar;
use PhpParser\Node\Expr\ConstFetch;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
/**
* @see \Rector\Tests\TypeDeclaration\Rector\YodaConditionsRector\YodaConditionsRectorTest
*/
final class YodaConditionsRector extends AbstractRector
{
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Equal::class, NotEqual::class, Identical::class, NotIdentical::class];
}
/**
* @param \PhpParser\Node\Stmt\Class_ $node
*/
public function refactor(Node $node): ?Node
{
// Ensure the left operand is not a constant
if ($node->left instanceof Node\Expr\Variable && (! $node->right instanceof Node\Expr\Variable)) {
// Swap the left and right operands
$this->mirrorComments($node->right, $node->left);
[$node->left, $node->right] = [$node->right, $node->left];
}
return $node;
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace Rector\Tests\TypeDeclaration\Rector\YodaConditionsRector\Fixture;
const A_CONST = 'x';
$a = 'x';
if ($a === 'x') {
$a = 'xx';
}
if ($a === null) {
$a = 'xx';
}
if ($a == false) {
$a = 'xx';
}
if ($a === A_CONST) {
$a = 'xx';
}
if (strlen($a) === 1) {
$a = 'xx';
}
if ($a === 0 || $a === rand()) {
return $a;
}
?>
-----
<?php
namespace Rector\Tests\TypeDeclaration\Rector\YodaConditionsRector\Fixture;
const A_CONST = 'x';
$a = 'x';
if ('x' === $a) {
$a = 'xx';
}
if (null === $a) {
$a = 'xx';
}
if (false == $a) {
$a = 'xx';
}
if (A_CONST === $a) {
$a = 'xx';
}
if (strlen($a) === 1) {
$a = 'xx';
}
if (0 === $a || rand() === $a) {
return $a;
}
?>

View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\TypeDeclaration\Rector\YodaConditionsRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
final class YodaConditionsRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}
public static function provideData(): \Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(\Utils\Rector\Rector\YodaConditionsRector::class);
};