Skip to content

Commit f45fbbd

Browse files
committed
Report useless return values of function calls
1 parent 892eb2e commit f45fbbd

File tree

5 files changed

+155
-1
lines changed

5 files changed

+155
-1
lines changed

src/Rules/FunctionCallParametersCheck.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PhpParser\Node;
66
use PhpParser\Node\Expr;
7+
use PHPStan\Analyser\ArgumentsNormalizer;
78
use PHPStan\Analyser\MutatingScope;
89
use PHPStan\Analyser\Scope;
910
use PHPStan\Php\PhpVersion;
@@ -29,6 +30,7 @@
2930
use function array_key_exists;
3031
use function count;
3132
use function implode;
33+
use function in_array;
3234
use function is_string;
3335
use function max;
3436
use function sprintf;
@@ -53,7 +55,7 @@ public function __construct(
5355

5456
/**
5557
* @param Node\Expr\FuncCall|Node\Expr\MethodCall|Node\Expr\StaticCall|Node\Expr\New_ $funcCall
56-
* @param array{0: string, 1: string, 2: string, 3: string, 4: string, 5: string, 6: string, 7: string, 8: string, 9: string, 10: string, 11: string, 12: string, 13?: string} $messages
58+
* @param array{0: string, 1: string, 2: string, 3: string, 4: string, 5: string, 6: string, 7: string, 8: string, 9: string, 10: string, 11: string, 12: string, 13?: string, 14?: string} $messages
5759
* @param 'attribute'|'callable'|'method'|'staticMethod'|'function'|'new' $nodeType
5860
* @return list<IdentifierRuleError>
5961
*/
@@ -244,6 +246,30 @@ public function check(
244246
->build();
245247
}
246248

249+
if (
250+
$funcCall instanceof Expr\FuncCall
251+
&& isset($messages[14])
252+
&& !$scope->isInFirstLevelStatement()
253+
&& $funcCall->name instanceof Node\Name
254+
&& in_array($funcCall->name->toString(), ['var_export', 'print_r', 'highlight_string', 'highlight_file'], true)
255+
) {
256+
$reorderedFuncCall = ArgumentsNormalizer::reorderFuncArguments(
257+
$parametersAcceptor,
258+
$funcCall,
259+
);
260+
261+
if ($reorderedFuncCall !== null) {
262+
$reorderedArgs = $reorderedFuncCall->getArgs();
263+
264+
if (count($reorderedArgs) === 1 || (count($reorderedArgs) >= 2 && $scope->getType($reorderedArgs[1]->value)->isFalse()->yes())) {
265+
$errors[] = RuleErrorBuilder::message($messages[14])
266+
->identifier(sprintf('%s.uselessReturn', $nodeType))
267+
->line($funcCall->getStartLine())
268+
->build();
269+
}
270+
}
271+
}
272+
247273
[$addedErrors, $argumentsWithParameters] = $this->processArguments($parametersAcceptor, $funcCall->getStartLine(), $isBuiltin, $arguments, $hasNamedArguments, $messages[10], $messages[11]);
248274
foreach ($addedErrors as $error) {
249275
$errors[] = $error;

src/Rules/Functions/CallToFunctionParametersRule.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public function processNode(Node $node, Scope $scope): array
6464
'Unknown parameter $%s in call to function ' . $functionName . '.',
6565
'Return type of call to function ' . $functionName . ' contains unresolvable type.',
6666
'Parameter %s of function ' . $functionName . ' contains unresolvable type.',
67+
'Return value of call to function ' . $functionName . ' is useless.',
6768
],
6869
'function',
6970
);

tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,4 +1716,36 @@ public function testCountArrayShift(): void
17161716
$this->analyse([__DIR__ . '/data/count-array-shift.php'], $errors);
17171717
}
17181718

1719+
public function testUselessReturnValue(): void
1720+
{
1721+
$this->analyse([__DIR__ . '/data/useless-fn-return.php'], [
1722+
[
1723+
'Return value of call to function print_r is useless.',
1724+
47,
1725+
],
1726+
[
1727+
'Return value of call to function var_export is useless.',
1728+
56,
1729+
],
1730+
[
1731+
'Return value of call to function print_r is useless.',
1732+
64,
1733+
],
1734+
]);
1735+
}
1736+
1737+
public function testUselessReturnValuePhp8(): void
1738+
{
1739+
if (PHP_VERSION_ID < 80000) {
1740+
return;
1741+
}
1742+
1743+
$this->analyse([__DIR__ . '/data/useless-fn-return-php8.php'], [
1744+
[
1745+
'Return value of call to function print_r is useless.',
1746+
18,
1747+
],
1748+
]);
1749+
}
1750+
17191751
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php // lint >= 8.0
2+
3+
namespace UselessFunctionReturnPhp8;
4+
5+
class FooClass
6+
{
7+
public function explicitReturnNamed(): void
8+
{
9+
error_log("Email-Template couldn't be found by parameters:" . print_r(return: true, value: [
10+
'template' => 1,
11+
'spracheid' => 2,
12+
])
13+
);
14+
}
15+
16+
public function explicitNoReturnNamed(): void
17+
{
18+
error_log("Email-Template couldn't be found by parameters:" . print_r(return: false, value: [
19+
'template' => 1,
20+
'spracheid' => 2,
21+
])
22+
);
23+
}
24+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
namespace UselessFunctionReturn;
4+
5+
class FooClass
6+
{
7+
public function fine(bool $bool): void
8+
{
9+
error_log(
10+
"Email-Template couldn't be found by parameters:" . print_r([
11+
'template' => 1,
12+
'spracheid' => 2,
13+
], true)
14+
);
15+
16+
$x = print_r([
17+
'template' => 1,
18+
'spracheid' => 2,
19+
], true);
20+
21+
print_r([
22+
'template' => 1,
23+
'spracheid' => 2,
24+
]);
25+
26+
error_log(
27+
"Email-Template couldn't be found by parameters:" . print_r([
28+
'template' => 1,
29+
'spracheid' => 2,
30+
], $bool)
31+
);
32+
33+
print_r([
34+
'template' => 1,
35+
'spracheid' => 2,
36+
], $bool);
37+
38+
$x = print_r([
39+
'template' => 1,
40+
'spracheid' => 2,
41+
], $bool);
42+
}
43+
44+
public function missesReturn(): void
45+
{
46+
error_log(
47+
"Email-Template couldn't be found by parameters:" . print_r([
48+
'template' => 1,
49+
'spracheid' => 2,
50+
])
51+
);
52+
}
53+
54+
public function missesReturnVarDump(): string
55+
{
56+
return "Email-Template couldn't be found by parameters:" . var_export([
57+
'template' => 1,
58+
'spracheid' => 2,
59+
]);
60+
}
61+
62+
public function explicitNoReturn(): void
63+
{
64+
error_log("Email-Template couldn't be found by parameters:" . print_r([
65+
'template' => 1,
66+
'spracheid' => 2,
67+
], false)
68+
);
69+
}
70+
71+
}

0 commit comments

Comments
 (0)