Skip to content

Commit 5ef04eb

Browse files
arshidkv12Arshidsamsonasik
authored
Php8.5 OrdSingleByteRector (#7219)
* OrdSingleByteRector * OrdSingleByteRector * OrdSingleByteRector * OrdSingleByteRector * OrdSingleByteRector * OrdSingleByteRector * OrdSingleByteRector * OrdSingleByteRector * OrdSingleByteRector * OrdSingleByteRector * Update rules/Php85/Rector/FuncCall/OrdSingleByteRector.php Co-authored-by: Abdul Malik Ikhsan <samsonasik@gmail.com> --------- Co-authored-by: Arshid <arshid@Arshids-MacBook-Air.local> Co-authored-by: Abdul Malik Ikhsan <samsonasik@gmail.com>
1 parent 7fdeb68 commit 5ef04eb

File tree

9 files changed

+189
-0
lines changed

9 files changed

+189
-0
lines changed

config/set/php85.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Rector\Php85\Rector\Const_\DeprecatedAnnotationToDeprecatedAttributeRector;
1313
use Rector\Php85\Rector\FuncCall\ArrayKeyExistsNullToEmptyStringRector;
1414
use Rector\Php85\Rector\FuncCall\ChrArgModuloRector;
15+
use Rector\Php85\Rector\FuncCall\OrdSingleByteRector;
1516
use Rector\Php85\Rector\FuncCall\RemoveFinfoBufferContextArgRector;
1617
use Rector\Php85\Rector\Switch_\ColonAfterSwitchCaseRector;
1718
use Rector\Removing\Rector\FuncCall\RemoveFuncCallArgRector;
@@ -37,6 +38,7 @@
3738
ColonAfterSwitchCaseRector::class,
3839
ArrayKeyExistsNullToEmptyStringRector::class,
3940
ChrArgModuloRector::class,
41+
OrdSingleByteRector::class,
4042
]
4143
);
4244

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
namespace Rector\Tests\Php85\Rector\FuncCall\OrdSingleByteRector\Fixture;
3+
echo ord(123);
4+
?>
5+
-----
6+
<?php
7+
namespace Rector\Tests\Php85\Rector\FuncCall\OrdSingleByteRector\Fixture;
8+
echo ord(1);
9+
?>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
namespace Rector\Tests\Php85\Rector\FuncCall\OrdSingleByteRector\Fixture;
3+
$a = 'abc';
4+
echo ord($a);
5+
?>
6+
-----
7+
<?php
8+
namespace Rector\Tests\Php85\Rector\FuncCall\OrdSingleByteRector\Fixture;
9+
$a = 'abc';
10+
echo ord($a[0]);
11+
?>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
namespace Rector\Tests\Php85\Rector\FuncCall\OrdSingleByteRector\Fixture;
3+
$a = true;
4+
echo ord($a);
5+
?>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
namespace Rector\Tests\Php85\Rector\FuncCall\OrdSingleByteRector\Fixture;
3+
$i = 123;
4+
echo ord($i);
5+
?>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\Php85\Rector\FuncCall\OrdSingleByteRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
10+
11+
final class OrdSingleByteRectorTest extends AbstractRectorTestCase
12+
{
13+
#[DataProvider('provideData')]
14+
public function test(string $filePath): void
15+
{
16+
$this->doTestFile($filePath);
17+
}
18+
19+
public static function provideData(): Iterator
20+
{
21+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22+
}
23+
24+
public function provideConfigFilePath(): string
25+
{
26+
return __DIR__ . '/config/configured_rule.php';
27+
}
28+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
use Rector\Php85\Rector\FuncCall\OrdSingleByteRector;
7+
use Rector\ValueObject\PhpVersion;
8+
9+
return static function (RectorConfig $rectorConfig): void {
10+
$rectorConfig->rule(OrdSingleByteRector::class);
11+
12+
$rectorConfig->phpVersion(PhpVersion::PHP_85);
13+
};
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Php85\Rector\FuncCall;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Expr\ArrayDimFetch;
9+
use PhpParser\Node\Expr\FuncCall;
10+
use PhpParser\Node\Scalar\Int_;
11+
use PhpParser\Node\Scalar\String_;
12+
use Rector\PhpParser\Node\Value\ValueResolver;
13+
use Rector\Rector\AbstractRector;
14+
use Rector\ValueObject\PhpVersionFeature;
15+
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
16+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
17+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
18+
19+
/**
20+
* @see https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_string_which_are_not_one_byte_long_to_ord
21+
* @see \Rector\Tests\Php85\Rector\FuncCall\OrdSingleByteRector\OrdSingleByteRectorTest
22+
*/
23+
final class OrdSingleByteRector extends AbstractRector implements MinPhpVersionInterface
24+
{
25+
public function __construct(
26+
private readonly ValueResolver $valueResolver
27+
) {
28+
29+
}
30+
31+
public function getRuleDefinition(): RuleDefinition
32+
{
33+
return new RuleDefinition(
34+
'Replace ord($str) with ord($str[0])',
35+
[
36+
new CodeSample(
37+
<<<'CODE_SAMPLE'
38+
echo ord('abc');
39+
CODE_SAMPLE
40+
,
41+
<<<'CODE_SAMPLE'
42+
echo ord('a');
43+
CODE_SAMPLE
44+
),
45+
]
46+
);
47+
}
48+
49+
public function getNodeTypes(): array
50+
{
51+
return [FuncCall::class];
52+
}
53+
54+
/**
55+
* @param FuncCall $node
56+
*/
57+
public function refactor(Node $node): ?Node
58+
{
59+
if ($node->isFirstClassCallable()) {
60+
return null;
61+
}
62+
63+
if (! $this->isName($node, 'ord')) {
64+
return null;
65+
}
66+
67+
$args = $node->getArgs();
68+
69+
if (! isset($node->args[0])) {
70+
return null;
71+
}
72+
73+
$argExpr = $args[0]->value;
74+
$type = $this->nodeTypeResolver->getNativeType($argExpr);
75+
76+
if (! $type->isString()->yes() && ! $type->isInteger()->yes()) {
77+
return null;
78+
}
79+
80+
$value = $this->valueResolver->getValue($argExpr);
81+
$isInt = is_int($value);
82+
83+
if (! $argExpr instanceof Int_) {
84+
85+
if ($isInt) {
86+
return null;
87+
}
88+
89+
$args[0]->value = new ArrayDimFetch($argExpr, new Int_(0));
90+
$node->args = $args;
91+
92+
return $node;
93+
}
94+
95+
$value = (string) $value;
96+
$byte = $value[0] ?? '';
97+
98+
$byteValue = $isInt ? new Int_((int) $byte) : new String_($byte);
99+
100+
$args[0]->value = $byteValue;
101+
$node->args = $args;
102+
103+
return $node;
104+
}
105+
106+
public function provideMinPhpVersion(): int
107+
{
108+
return PhpVersionFeature::DEPRECATE_ORD_WITH_MULTIBYTE_STRING;
109+
}
110+
}

src/ValueObject/PhpVersionFeature.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,4 +810,10 @@ final class PhpVersionFeature
810810
* @var int
811811
*/
812812
public const DEPRECATE_OUTSIDE_INTERVEL_VAL_IN_CHR_FUNCTION = PhpVersion::PHP_85;
813+
814+
/**
815+
* @see https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_string_which_are_not_one_byte_long_to_ord
816+
* @var int
817+
*/
818+
public const DEPRECATE_ORD_WITH_MULTIBYTE_STRING = PhpVersion::PHP_85;
813819
}

0 commit comments

Comments
 (0)