Merge pull request #3279 from rectorphp/php80-get-debug-type

[PHP 8.0] Add get_debug_type()
This commit is contained in:
kodiakhq[bot] 2020-04-29 21:39:38 +00:00 committed by GitHub
commit ae5279f01c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 193 additions and 1 deletions

View File

@ -6,3 +6,4 @@ services:
Rector\Php80\Rector\Class_\StringableForToStringRector: null
Rector\Php80\Rector\Class_\AnnotationToAttributeRector: null
Rector\Php80\Rector\FuncCall\ClassOnObjectRector: null
Rector\Php80\Rector\Ternary\GetDebugTypeRector: null

View File

@ -1,4 +1,4 @@
# All 506 Rectors Overview
# All 507 Rectors Overview
- [Projects](#projects)
- [General](#general)
@ -7940,6 +7940,26 @@ Change get_class($object) to faster $object::class
<br>
### `GetDebugTypeRector`
- class: [`Rector\Php80\Rector\Ternary\GetDebugTypeRector`](/../master/rules/php80/src/Rector/Ternary/GetDebugTypeRector.php)
- [test fixtures](/../master/rules/php80/tests/Rector/Ternary/GetDebugTypeRector/Fixture)
Change ternary type resolve to get_debug_type()
```diff
class SomeClass
{
public function run($value)
{
- return is_object($value) ? get_class($value) : gettype($value);
+ return get_debug_type($value);
}
}
```
<br>
### `StrContainsRector`
- class: [`Rector\Php80\Rector\NotIdentical\StrContainsRector`](/../master/rules/php80/src/Rector/NotIdentical/StrContainsRector.php)

View File

@ -0,0 +1,114 @@
<?php
declare(strict_types=1);
namespace Rector\Php80\Rector\Ternary;
use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Ternary;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
/**
* @see https://wiki.php.net/rfc/get_debug_type
*
* @see \Rector\Php80\Tests\Rector\Ternary\GetDebugTypeRector\GetDebugTypeRectorTest
*/
final class GetDebugTypeRector extends AbstractRector
{
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Change ternary type resolve to get_debug_type()', [
new CodeSample(
<<<'PHP'
class SomeClass
{
public function run($value)
{
return is_object($value) ? get_class($value) : gettype($value);
}
}
PHP
,
<<<'PHP'
class SomeClass
{
public function run($value)
{
return get_debug_type($value);
}
}
PHP
),
]);
}
/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [Ternary::class];
}
/**
* @param Ternary $node
*/
public function refactor(Node $node): ?Node
{
if ($this->shouldSkip($node)) {
return null;
}
if (! $this->areValuesIdentical($node)) {
return null;
}
/** @var FuncCall $funcCall */
$funcCall = $node->if;
$firstExpr = $funcCall->args[0]->value;
return $this->createFuncCall('get_debug_type', [$firstExpr]);
}
private function shouldSkip(Ternary $ternary): bool
{
if (! $this->isFuncCallName($ternary->cond, 'is_object')) {
return true;
}
if ($ternary->if === null) {
return true;
}
if (! $this->isFuncCallName($ternary->if, 'get_class')) {
return true;
}
return ! $this->isFuncCallName($ternary->else, 'gettype');
}
private function areValuesIdentical(Ternary $ternary): bool
{
/** @var FuncCall $isObjectFuncCall */
$isObjectFuncCall = $ternary->cond;
$firstExpr = $isObjectFuncCall->args[0]->value;
/** @var FuncCall $getClassFuncCall */
$getClassFuncCall = $ternary->if;
$secondExpr = $getClassFuncCall->args[0]->value;
/** @var FuncCall $gettypeFuncCall */
$gettypeFuncCall = $ternary->else;
$thirdExpr = $gettypeFuncCall->args[0]->value;
if (! $this->areNodesEqual($firstExpr, $secondExpr)) {
return false;
}
return $this->areNodesEqual($firstExpr, $thirdExpr);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Rector\Php80\Tests\Rector\Ternary\GetDebugTypeRector\Fixture;
class SomeClass
{
public function run($value)
{
return is_object($value) ? get_class($value) : gettype($value);
}
}
?>
-----
<?php
namespace Rector\Php80\Tests\Rector\Ternary\GetDebugTypeRector\Fixture;
class SomeClass
{
public function run($value)
{
return get_debug_type($value);
}
}
?>

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace Rector\Php80\Tests\Rector\Ternary\GetDebugTypeRector;
use Iterator;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\Php80\Rector\Ternary\GetDebugTypeRector;
final class GetDebugTypeRectorTest 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 GetDebugTypeRector::class;
}
}