Skip to content

Commit ae5279f

Browse files
Merge pull request rectorphp#3279 from rectorphp/php80-get-debug-type
[PHP 8.0] Add get_debug_type()
2 parents f0d9340 + 993550c commit ae5279f

File tree

5 files changed

+193
-1
lines changed

5 files changed

+193
-1
lines changed

config/set/php/php80.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ services:
66
Rector\Php80\Rector\Class_\StringableForToStringRector: null
77
Rector\Php80\Rector\Class_\AnnotationToAttributeRector: null
88
Rector\Php80\Rector\FuncCall\ClassOnObjectRector: null
9+
Rector\Php80\Rector\Ternary\GetDebugTypeRector: null

docs/AllRectorsOverview.md

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# All 506 Rectors Overview
1+
# All 507 Rectors Overview
22

33
- [Projects](#projects)
44
- [General](#general)
@@ -7940,6 +7940,26 @@ Change get_class($object) to faster $object::class
79407940

79417941
<br>
79427942

7943+
### `GetDebugTypeRector`
7944+
7945+
- class: [`Rector\Php80\Rector\Ternary\GetDebugTypeRector`](/../master/rules/php80/src/Rector/Ternary/GetDebugTypeRector.php)
7946+
- [test fixtures](/../master/rules/php80/tests/Rector/Ternary/GetDebugTypeRector/Fixture)
7947+
7948+
Change ternary type resolve to get_debug_type()
7949+
7950+
```diff
7951+
class SomeClass
7952+
{
7953+
public function run($value)
7954+
{
7955+
- return is_object($value) ? get_class($value) : gettype($value);
7956+
+ return get_debug_type($value);
7957+
}
7958+
}
7959+
```
7960+
7961+
<br>
7962+
79437963
### `StrContainsRector`
79447964

79457965
- class: [`Rector\Php80\Rector\NotIdentical\StrContainsRector`](/../master/rules/php80/src/Rector/NotIdentical/StrContainsRector.php)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Php80\Rector\Ternary;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Expr\FuncCall;
9+
use PhpParser\Node\Expr\Ternary;
10+
use Rector\Core\Rector\AbstractRector;
11+
use Rector\Core\RectorDefinition\CodeSample;
12+
use Rector\Core\RectorDefinition\RectorDefinition;
13+
14+
/**
15+
* @see https://wiki.php.net/rfc/get_debug_type
16+
*
17+
* @see \Rector\Php80\Tests\Rector\Ternary\GetDebugTypeRector\GetDebugTypeRectorTest
18+
*/
19+
final class GetDebugTypeRector extends AbstractRector
20+
{
21+
public function getDefinition(): RectorDefinition
22+
{
23+
return new RectorDefinition('Change ternary type resolve to get_debug_type()', [
24+
new CodeSample(
25+
<<<'PHP'
26+
class SomeClass
27+
{
28+
public function run($value)
29+
{
30+
return is_object($value) ? get_class($value) : gettype($value);
31+
}
32+
}
33+
PHP
34+
,
35+
<<<'PHP'
36+
class SomeClass
37+
{
38+
public function run($value)
39+
{
40+
return get_debug_type($value);
41+
}
42+
}
43+
PHP
44+
45+
),
46+
]);
47+
}
48+
49+
/**
50+
* @return string[]
51+
*/
52+
public function getNodeTypes(): array
53+
{
54+
return [Ternary::class];
55+
}
56+
57+
/**
58+
* @param Ternary $node
59+
*/
60+
public function refactor(Node $node): ?Node
61+
{
62+
if ($this->shouldSkip($node)) {
63+
return null;
64+
}
65+
66+
if (! $this->areValuesIdentical($node)) {
67+
return null;
68+
}
69+
70+
/** @var FuncCall $funcCall */
71+
$funcCall = $node->if;
72+
$firstExpr = $funcCall->args[0]->value;
73+
74+
return $this->createFuncCall('get_debug_type', [$firstExpr]);
75+
}
76+
77+
private function shouldSkip(Ternary $ternary): bool
78+
{
79+
if (! $this->isFuncCallName($ternary->cond, 'is_object')) {
80+
return true;
81+
}
82+
83+
if ($ternary->if === null) {
84+
return true;
85+
}
86+
87+
if (! $this->isFuncCallName($ternary->if, 'get_class')) {
88+
return true;
89+
}
90+
91+
return ! $this->isFuncCallName($ternary->else, 'gettype');
92+
}
93+
94+
private function areValuesIdentical(Ternary $ternary): bool
95+
{
96+
/** @var FuncCall $isObjectFuncCall */
97+
$isObjectFuncCall = $ternary->cond;
98+
$firstExpr = $isObjectFuncCall->args[0]->value;
99+
100+
/** @var FuncCall $getClassFuncCall */
101+
$getClassFuncCall = $ternary->if;
102+
$secondExpr = $getClassFuncCall->args[0]->value;
103+
104+
/** @var FuncCall $gettypeFuncCall */
105+
$gettypeFuncCall = $ternary->else;
106+
$thirdExpr = $gettypeFuncCall->args[0]->value;
107+
108+
if (! $this->areNodesEqual($firstExpr, $secondExpr)) {
109+
return false;
110+
}
111+
112+
return $this->areNodesEqual($firstExpr, $thirdExpr);
113+
}
114+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Rector\Php80\Tests\Rector\Ternary\GetDebugTypeRector\Fixture;
4+
5+
class SomeClass
6+
{
7+
public function run($value)
8+
{
9+
return is_object($value) ? get_class($value) : gettype($value);
10+
}
11+
}
12+
13+
?>
14+
-----
15+
<?php
16+
17+
namespace Rector\Php80\Tests\Rector\Ternary\GetDebugTypeRector\Fixture;
18+
19+
class SomeClass
20+
{
21+
public function run($value)
22+
{
23+
return get_debug_type($value);
24+
}
25+
}
26+
27+
?>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Php80\Tests\Rector\Ternary\GetDebugTypeRector;
6+
7+
use Iterator;
8+
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
9+
use Rector\Php80\Rector\Ternary\GetDebugTypeRector;
10+
11+
final class GetDebugTypeRectorTest extends AbstractRectorTestCase
12+
{
13+
/**
14+
* @dataProvider provideData()
15+
*/
16+
public function test(string $file): void
17+
{
18+
$this->doTestFile($file);
19+
}
20+
21+
public function provideData(): Iterator
22+
{
23+
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
24+
}
25+
26+
protected function getRectorClass(): string
27+
{
28+
return GetDebugTypeRector::class;
29+
}
30+
}

0 commit comments

Comments
 (0)