Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 322de33

Browse files
authored
Fix param castable to string rule
1 parent 7d9800c commit 322de33

21 files changed

+940
-375
lines changed

‎conf/config.level5.neon‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ conditionalTags:
1212
phpstan.rules.rule: %featureToggles.arrayValues%
1313
PHPStan\Rules\Functions\CallUserFuncRule:
1414
phpstan.rules.rule: %featureToggles.callUserFunc%
15-
PHPStan\Rules\Functions\ParameterCastableToStringFunctionRule:
15+
PHPStan\Rules\Functions\ParameterCastableToStringRule:
16+
phpstan.rules.rule: %featureToggles.checkParameterCastableToStringFunctions%
17+
PHPStan\Rules\Functions\ImplodeParameterCastableToStringRule:
18+
phpstan.rules.rule: %featureToggles.checkParameterCastableToStringFunctions%
19+
PHPStan\Rules\Functions\SortParameterCastableToStringRule:
1620
phpstan.rules.rule: %featureToggles.checkParameterCastableToStringFunctions%
1721

1822
rules:
@@ -45,4 +49,8 @@ services:
4549
tags:
4650
- phpstan.rules.rule
4751
-
48-
class: PHPStan\Rules\Functions\ParameterCastableToStringFunctionRule
52+
class: PHPStan\Rules\Functions\ParameterCastableToStringRule
53+
-
54+
class: PHPStan\Rules\Functions\ImplodeParameterCastableToStringRule
55+
-
56+
class: PHPStan\Rules\Functions\SortParameterCastableToStringRule

‎conf/config.neon‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,8 @@ services:
948948

949949
-
950950
class: PHPStan\Rules\FunctionReturnTypeCheck
951+
-
952+
class: PHPStan\Rules\ParameterCastableToStringCheck
951953

952954
-
953955
class: PHPStan\Rules\Generics\CrossCheckInterfacesHelper

‎phpstan-baseline.neon‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,15 +1823,15 @@ parameters:
18231823
-
18241824
message: """
18251825
#^Instantiation of deprecated class PHPStan\\\\Rules\\\\Functions\\\\ImplodeFunctionRule\\:
1826-
Replaced by PHPStan\\\\Rules\\\\Functions\\\\ParameterCastableToStringFunctionRule$#
1826+
Replaced by PHPStan\\\\Rules\\\\Functions\\\\ImplodeParameterCastableToStringRuleTest$#
18271827
"""
18281828
count: 1
18291829
path: tests/PHPStan/Rules/Functions/ImplodeFunctionRuleTest.php
18301830

18311831
-
18321832
message: """
18331833
#^Return type of method PHPStan\\\\Rules\\\\Functions\\\\ImplodeFunctionRuleTest\\:\\:getRule\\(\\) has typehint with deprecated class PHPStan\\\\Rules\\\\Functions\\\\ImplodeFunctionRule\\:
1834-
Replaced by PHPStan\\\\Rules\\\\Functions\\\\ParameterCastableToStringFunctionRule$#
1834+
Replaced by PHPStan\\\\Rules\\\\Functions\\\\ImplodeParameterCastableToStringRuleTest$#
18351835
"""
18361836
count: 1
18371837
path: tests/PHPStan/Rules/Functions/ImplodeFunctionRuleTest.php

‎src/Rules/Functions/ImplodeFunctionRule.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use function sprintf;
1818

1919
/**
20-
* @deprecated Replaced by PHPStan\Rules\Functions\ParameterCastableToStringFunctionRule
20+
* @deprecated Replaced by PHPStan\Rules\Functions\ImplodeParameterCastableToStringRuleTest
2121
* @implements Rule<Node\Expr\FuncCall>
2222
*/
2323
class ImplodeFunctionRule implements Rule
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Functions;
4+
5+
use PhpParser\Node;
6+
use PhpParser\Node\Expr\FuncCall;
7+
use PHPStan\Analyser\ArgumentsNormalizer;
8+
use PHPStan\Analyser\Scope;
9+
use PHPStan\Reflection\ParametersAcceptorSelector;
10+
use PHPStan\Reflection\ReflectionProvider;
11+
use PHPStan\Rules\ParameterCastableToStringCheck;
12+
use PHPStan\Rules\Rule;
13+
use PHPStan\Type\Type;
14+
use function array_key_exists;
15+
use function count;
16+
use function in_array;
17+
use function sprintf;
18+
19+
/**
20+
* @implements Rule<Node\Expr\FuncCall>
21+
*/
22+
class ImplodeParameterCastableToStringRule implements Rule
23+
{
24+
25+
public function __construct(
26+
private ReflectionProvider $reflectionProvider,
27+
private ParameterCastableToStringCheck $parameterCastableToStringCheck,
28+
)
29+
{
30+
}
31+
32+
public function getNodeType(): string
33+
{
34+
return FuncCall::class;
35+
}
36+
37+
public function processNode(Node $node, Scope $scope): array
38+
{
39+
if (!($node->name instanceof Node\Name)) {
40+
return [];
41+
}
42+
43+
if (!$this->reflectionProvider->hasFunction($node->name, $scope)) {
44+
return [];
45+
}
46+
47+
$functionReflection = $this->reflectionProvider->getFunction($node->name, $scope);
48+
$functionName = $functionReflection->getName();
49+
if (!in_array($functionName, ['implode', 'join'], true)) {
50+
return [];
51+
}
52+
53+
$origArgs = $node->getArgs();
54+
$parametersAcceptor = ParametersAcceptorSelector::selectFromArgs(
55+
$scope,
56+
$origArgs,
57+
$functionReflection->getVariants(),
58+
$functionReflection->getNamedArgumentsVariants(),
59+
);
60+
61+
$normalizedFuncCall = ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $node);
62+
63+
if ($normalizedFuncCall === null) {
64+
return [];
65+
}
66+
67+
$normalizedArgs = $normalizedFuncCall->getArgs();
68+
$errorMessage = 'Parameter %s of function %s expects array<string>, %s given.';
69+
if (count($normalizedArgs) === 1) {
70+
$argsToCheck = [0 => $normalizedArgs[0]];
71+
} elseif (count($normalizedArgs) === 2) {
72+
$argsToCheck = [1 => $normalizedArgs[1]];
73+
} else {
74+
return [];
75+
}
76+
77+
$origNamedArgs = [];
78+
foreach ($origArgs as $arg) {
79+
if ($arg->unpack || $arg->name === null) {
80+
continue;
81+
}
82+
83+
$origNamedArgs[$arg->name->toString()] = $arg;
84+
}
85+
86+
$errors = [];
87+
88+
foreach ($argsToCheck as $argIdx => $arg) {
89+
// implode has weird variants, so $array has to be fixed. It's especially weird with named arguments.
90+
if (array_key_exists('array', $origNamedArgs)) {
91+
$argName = '$array';
92+
} elseif (array_key_exists('separator', $origNamedArgs) && count($origArgs) === 1) {
93+
$argName = '$separator';
94+
} else {
95+
$argName = sprintf('#%d $array', $argIdx + 1);
96+
}
97+
98+
$error = $this->parameterCastableToStringCheck->checkParameter(
99+
$arg,
100+
$scope,
101+
$errorMessage,
102+
static fn (Type $t) => $t->toString(),
103+
$functionName,
104+
$argName,
105+
);
106+
107+
if ($error === null) {
108+
continue;
109+
}
110+
111+
$errors[] = $error;
112+
}
113+
114+
return $errors;
115+
}
116+
117+
}

‎src/Rules/Functions/ParameterCastableToStringFunctionRule.php‎

Lines changed: 0 additions & 170 deletions
This file was deleted.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /