[CodingStyle] Add CamelCaseFunctionNamingToUnderscoreRector

This commit is contained in:
TomasVotruba 2020-02-21 02:06:13 +01:00
parent f0a8a527fe
commit 0e61d7e96f
7 changed files with 184 additions and 2 deletions

View File

@ -34,3 +34,4 @@ services:
$functionsToConstants:
php_sapi_name: PHP_SAPI
pi: M_PI
Rector\CodingStyle\Rector\Function_\CamelCaseFunctionNamingToUnderscoreRector: null

View File

@ -1,4 +1,4 @@
# All 454 Rectors Overview
# All 455 Rectors Overview
- [Projects](#projects)
- [General](#general)
@ -1779,6 +1779,24 @@ Replace call_user_func_call with variadic
<br>
### `CamelCaseFunctionNamingToUnderscoreRector`
- class: `Rector\CodingStyle\Rector\Function_\CamelCaseFunctionNamingToUnderscoreRector`
Change CamelCase naming of functions to under_score naming
```diff
-function someCamelCaseFunction()
+function some_camel_case_function()
{
}
-someCamelCaseFunction();
+some_camel_case_function();
```
<br>
### `CatchExceptionNameMatchingTypeRector`
- class: `Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector`

View File

@ -0,0 +1,96 @@
<?php
declare(strict_types=1);
namespace Rector\CodingStyle\Rector\Function_;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Function_;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\Core\Util\RectorStrings;
/**
* @see \Rector\CodingStyle\Tests\Rector\Function_\CamelCaseFunctionNamingToUnderscoreRector\CamelCaseFunctionNamingToUnderscoreRectorTest
*/
final class CamelCaseFunctionNamingToUnderscoreRector extends AbstractRector
{
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Change CamelCase naming of functions to under_score naming', [
new CodeSample(
<<<'PHP'
function someCamelCaseFunction()
{
}
someCamelCaseFunction();
PHP
,
<<<'PHP'
function some_camel_case_function()
{
}
some_camel_case_function();
PHP
),
]);
}
/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [Function_::class, FuncCall::class];
}
/**
* @param Function_|FuncCall $node
*/
public function refactor(Node $node): ?Node
{
$shortName = $this->resolveShortName($node);
if ($shortName === null) {
return null;
}
$underscoredName = RectorStrings::camelCaseToUnderscore($shortName);
if ($underscoredName === $shortName) {
return null;
}
if ($node instanceof FuncCall) {
$node->name = new Name($underscoredName);
} elseif ($node instanceof Function_) {
$node->name = new Identifier($underscoredName);
}
return $node;
}
/**
* @param Function_|FuncCall $node
*/
private function resolveShortName(Node $node): ?string
{
$functionOrFuncCallName = $this->getName($node);
if ($functionOrFuncCallName === null) {
return null;
}
$shortName = Strings::after($functionOrFuncCallName, '\\', -1);
if ($shortName === null) {
return $functionOrFuncCallName;
}
return $shortName;
}
}

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace Rector\CodingStyle\Tests\Rector\Function_\CamelCaseFunctionNamingToUnderscoreRector;
use Iterator;
use Rector\CodingStyle\Rector\Function_\CamelCaseFunctionNamingToUnderscoreRector;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
final class CamelCaseFunctionNamingToUnderscoreRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(string $file): void
{
$this->doTestFile($file);
}
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
protected function getRectorClass(): string
{
return CamelCaseFunctionNamingToUnderscoreRector::class;
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Rector\CodingStyle\Tests\Rector\Function_\CamelCaseFunctionNamingToUnderscoreRector\Fixture;
function someCamelCaseFunction()
{
}
someCamelCaseFunction();
?>
-----
<?php
namespace Rector\CodingStyle\Tests\Rector\Function_\CamelCaseFunctionNamingToUnderscoreRector\Fixture;
function some_camel_case_function()
{
}
some_camel_case_function();
?>

View File

@ -0,0 +1,11 @@
<?php
namespace Rector\CodingStyle\Tests\Rector\Function_\CamelCaseFunctionNamingToUnderscoreRector\Fixture;
class SkipIsA
{
public function run()
{
return is_a($this, self::class);
}
}

View File

@ -82,8 +82,11 @@ final class RectorStrings
private static function camelCaseToGlue(string $input, string $glue): string
{
$matches = Strings::matchAll($input, '#([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)#');
if ($input === strtolower($input)) {
return $input;
}
$matches = Strings::matchAll($input, '#([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)#');
$parts = [];
foreach ($matches as $match) {
$parts[] = $match[0] === strtoupper($match[0]) ? strtolower($match[0]) : lcfirst($match[0]);