Skip to content

Commit b77f894

Browse files
paulbalandanondrejmirtes
authored andcommitted
Add RedefinedParametersRule
1 parent 78aab76 commit b77f894

File tree

4 files changed

+127
-0
lines changed

4 files changed

+127
-0
lines changed

conf/config.level0.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ rules:
7575
- PHPStan\Rules\Functions\InnerFunctionRule
7676
- PHPStan\Rules\Functions\ParamAttributesRule
7777
- PHPStan\Rules\Functions\PrintfParametersRule
78+
- PHPStan\Rules\Functions\RedefinedParametersRule
7879
- PHPStan\Rules\Functions\ReturnNullsafeByRefRule
7980
- PHPStan\Rules\Functions\VariadicParametersDeclarationRule
8081
- PHPStan\Rules\Keywords\ContinueBreakInLoopRule
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Functions;
4+
5+
use PhpParser\Node;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Rules\Rule;
8+
use PHPStan\Rules\RuleErrorBuilder;
9+
use function count;
10+
use function is_string;
11+
use function sprintf;
12+
13+
/**
14+
* @implements Rule<Node\FunctionLike>
15+
*/
16+
class RedefinedParametersRule implements Rule
17+
{
18+
19+
public function getNodeType(): string
20+
{
21+
return Node\FunctionLike::class;
22+
}
23+
24+
public function processNode(Node $node, Scope $scope): array
25+
{
26+
$params = $node->getParams();
27+
28+
if (count($params) <= 1) {
29+
return [];
30+
}
31+
32+
$vars = [];
33+
$errors = [];
34+
35+
foreach ($params as $param) {
36+
if (!$param->var instanceof Node\Expr\Variable) {
37+
continue;
38+
}
39+
40+
if (!is_string($param->var->name)) {
41+
continue;
42+
}
43+
44+
$var = $param->var->name;
45+
46+
if (!isset($vars[$var])) {
47+
$vars[$var] = true;
48+
continue;
49+
}
50+
51+
$errors[] = RuleErrorBuilder::message(sprintf('Redefinition of parameter $%s.', $var))->nonIgnorable()->build();
52+
}
53+
54+
return $errors;
55+
}
56+
57+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Functions;
4+
5+
use PHPStan\Rules\Rule;
6+
use PHPStan\Testing\RuleTestCase;
7+
8+
/**
9+
* @extends RuleTestCase<RedefinedParametersRule>
10+
*/
11+
class RedefinedParametersRuleTest extends RuleTestCase
12+
{
13+
14+
protected function getRule(): Rule
15+
{
16+
return new RedefinedParametersRule();
17+
}
18+
19+
public function testRule(): void
20+
{
21+
$this->analyse([__DIR__ . '/data/redefined-parameters.php'], [
22+
[
23+
'Redefinition of parameter $foo.',
24+
11,
25+
],
26+
[
27+
'Redefinition of parameter $bar.',
28+
13,
29+
],
30+
[
31+
'Redefinition of parameter $baz.',
32+
15,
33+
],
34+
]);
35+
}
36+
37+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace RedefinedParameters;
4+
5+
class HelloWorld
6+
{
7+
8+
/**
9+
* @return \Closure(string, int): int
10+
*/
11+
public function foo(string $foo, string $foo): \Closure
12+
{
13+
$callback = static fn (int $bar, array $bar): int => (int) $bar;
14+
15+
return function (string $baz, int $baz) use ($callback): int {
16+
return $callback($baz, []);
17+
};
18+
}
19+
20+
/**
21+
* @return \Closure(string, bool): int
22+
*/
23+
public function bar(string $pipe, int $count): \Closure
24+
{
25+
$cb = fn (int $a, string $b): int => $a + (int) $b;
26+
27+
return function (string $c, bool $d) use ($cb, $pipe, $count): int {
28+
return $cb((int) $d, $c) + $cb($count, $pipe);
29+
};
30+
}
31+
32+
}

0 commit comments

Comments
 (0)