Skip to content

Commit dfb760f

Browse files
[CodingStyle] Add StrictInArrayRector (#7921)
* [CodingStyle] Add StrictInArrayRector * add fixture skip mixed type * [ci-review] Rector Rectify * add fixture both mixed types * fix phpstan --------- Co-authored-by: GitHub Action <actions@github.com>
1 parent 64ba1b3 commit dfb760f

File tree

11 files changed

+237
-1
lines changed

11 files changed

+237
-1
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodingStyle\Rector\FuncCall\StrictInArrayRector\Fixture;
4+
5+
class BothIntegers
6+
{
7+
public function run(int $value)
8+
{
9+
return in_array($value, [1, 2, 3]);
10+
}
11+
}
12+
?>
13+
-----
14+
<?php
15+
16+
namespace Rector\Tests\CodingStyle\Rector\FuncCall\StrictInArrayRector\Fixture;
17+
18+
class BothIntegers
19+
{
20+
public function run(int $value)
21+
{
22+
return in_array($value, [1, 2, 3], true);
23+
}
24+
}
25+
?>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodingStyle\Rector\FuncCall\StrictInArrayRector\Fixture;
4+
5+
class BothStrings
6+
{
7+
public function run(string $value)
8+
{
9+
return in_array($value, ['one', 'two', 'three']);
10+
}
11+
}
12+
?>
13+
-----
14+
<?php
15+
16+
namespace Rector\Tests\CodingStyle\Rector\FuncCall\StrictInArrayRector\Fixture;
17+
18+
class BothStrings
19+
{
20+
public function run(string $value)
21+
{
22+
return in_array($value, ['one', 'two', 'three'], true);
23+
}
24+
}
25+
?>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodingStyle\Rector\FuncCall\StrictInArrayRector\Fixture;
4+
5+
class SkipBothMixedTypes
6+
{
7+
/**
8+
* @param mixed[] $items
9+
*/
10+
public function run(mixed $value, array $items)
11+
{
12+
return in_array($value, $items);
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodingStyle\Rector\FuncCall\StrictInArrayRector\Fixture;
4+
5+
class SkipDifferentTypes
6+
{
7+
public function run()
8+
{
9+
$items = ['10', '20', '30'];
10+
return in_array(10, $items);
11+
}
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodingStyle\Rector\FuncCall\StrictInArrayRector\Fixture;
4+
5+
class SkipDocblockArray
6+
{
7+
/**
8+
* @param string[] $items
9+
*/
10+
public function run(string $value, array $items)
11+
{
12+
return in_array($value, $items);
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodingStyle\Rector\FuncCall\StrictInArrayRector\Fixture;
4+
5+
class SkipMixedType
6+
{
7+
public function run(mixed $value)
8+
{
9+
$items = ['10', '20', '30'];
10+
return in_array($value, $items);
11+
}
12+
}
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\CodingStyle\Rector\FuncCall\StrictInArrayRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
10+
11+
final class StrictInArrayRectorTest 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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\CodingStyle\Rector\FuncCall\StrictInArrayRector;
6+
use Rector\Config\RectorConfig;
7+
8+
return RectorConfig::configure()
9+
->withRules([StrictInArrayRector::class]);
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\CodingStyle\Rector\FuncCall;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Arg;
9+
use PhpParser\Node\Expr\FuncCall;
10+
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
11+
use Rector\Rector\AbstractRector;
12+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
13+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
14+
15+
/**
16+
* @see \Rector\Tests\CodingStyle\Rector\FuncCall\StrictInArrayRector\StrictInArrayRectorTest
17+
*/
18+
final class StrictInArrayRector extends AbstractRector
19+
{
20+
public function __construct(
21+
private readonly TypeComparator $typeComparator
22+
) {
23+
}
24+
25+
public function getRuleDefinition(): RuleDefinition
26+
{
27+
return new RuleDefinition(
28+
'Set in_array strict to true when defined on similar type', [
29+
new CodeSample(
30+
<<<'CODE_SAMPLE'
31+
class BothStrings
32+
{
33+
public function run(string $value)
34+
{
35+
return in_array($value, ['one', 'two', 'three']);
36+
}
37+
}
38+
CODE_SAMPLE
39+
,
40+
<<<'CODE_SAMPLE'
41+
class BothStrings
42+
{
43+
public function run(string $value)
44+
{
45+
return in_array($value, ['one', 'two', 'three'], true);
46+
}
47+
}
48+
CODE_SAMPLE
49+
),
50+
]
51+
);
52+
}
53+
54+
/**
55+
* @return array<class-string<Node>>
56+
*/
57+
public function getNodeTypes(): array
58+
{
59+
return [FuncCall::class];
60+
}
61+
62+
/**
63+
* @param FuncCall $node
64+
*/
65+
public function refactor(Node $node): ?Node
66+
{
67+
if (! $this->isName($node, 'in_array')) {
68+
return null;
69+
}
70+
71+
if ($node->isFirstClassCallable()) {
72+
return null;
73+
}
74+
75+
$args = $node->getArgs();
76+
if (count($args) !== 2) {
77+
return null;
78+
}
79+
80+
$firstArgType = $this->nodeTypeResolver->getNativeType($args[0]->value);
81+
$secondArgType = $this->nodeTypeResolver->getNativeType($args[1]->value);
82+
83+
if (! $secondArgType->isArray()->yes()) {
84+
return null;
85+
}
86+
87+
if ($this->typeComparator->isSubtype($secondArgType->getIterableValueType(), $firstArgType)) {
88+
$node->args[] = new Arg($this->nodeFactory->createTrue());
89+
return $node;
90+
}
91+
92+
return null;
93+
}
94+
}

rules/DeadCode/Rector/FuncCall/RemoveFilterVarOnExactTypeRector.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ public function refactor(Node $node): ?Node
8484

8585
if (in_array(
8686
$constantFilterName,
87-
['FILTER_VALIDATE_BOOLEAN', 'FILTER_VALIDATE_BOOL']
87+
['FILTER_VALIDATE_BOOLEAN', 'FILTER_VALIDATE_BOOL'],
88+
true
8889
) && $valueType->isBoolean()
8990
->yes()) {
9091
return $firstArgValue;

0 commit comments

Comments
 (0)