Skip to content

Commit 2e70574

Browse files
committed
Check whether function has return typehint
1 parent dd2b885 commit 2e70574

File tree

4 files changed

+133
-1
lines changed

4 files changed

+133
-1
lines changed

Diff for: composer.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"autoload-dev": {
3131
"classmap": ["tests/"],
3232
"files": [
33-
"tests/Rules/Functions/data/missing-function-parameter-typehint.php"
33+
"tests/Rules/Functions/data/missing-function-parameter-typehint.php",
34+
"tests/Rules/Functions/data/missing-function-return-typehint.php"
3435
]
3536
}
3637
}
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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\Broker\Broker;
8+
use PHPStan\Reflection\BrokerAwareExtension;
9+
use PHPStan\Type\MixedType;
10+
11+
final class MissingFunctionReturnTypehintRule implements \PHPStan\Rules\Rule, BrokerAwareExtension
12+
{
13+
14+
/**
15+
* @var Broker
16+
*/
17+
private $broker;
18+
19+
/**
20+
* @return string Class implementing \PhpParser\Node
21+
*/
22+
public function getNodeType(): string
23+
{
24+
return \PhpParser\Node\Stmt\Function_::class;
25+
}
26+
27+
/**
28+
* @param \PhpParser\Node\Stmt\Function_ $node
29+
* @param \PHPStan\Analyser\Scope $scope
30+
*
31+
* @return string[] errors
32+
*/
33+
public function processNode(Node $node, Scope $scope): array
34+
{
35+
if ($scope->isInClass()) {
36+
throw new \PHPStan\ShouldNotHappenException();
37+
}
38+
39+
$functionReflection = $this->broker->getCustomFunction(new Node\Name($node->name, $node->getAttributes()), $scope);
40+
$returnType = $functionReflection->getReturnType();
41+
42+
if ($returnType instanceof MixedType && !$returnType->isExplicitMixed()) {
43+
return [
44+
sprintf(
45+
'Function %s() has no return typehint specified',
46+
$functionReflection->getName()
47+
),
48+
];
49+
}
50+
51+
return [];
52+
}
53+
54+
public function setBroker(Broker $broker): void
55+
{
56+
$this->broker = $broker;
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Functions;
4+
5+
class MissingFunctionReturnTypehintRuleTest extends \PHPStan\Testing\RuleTestCase
6+
{
7+
8+
protected function getRule(): \PHPStan\Rules\Rule
9+
{
10+
$rule = new MissingFunctionReturnTypehintRule();
11+
$rule->setBroker($this->createBroker([], []));
12+
13+
return $rule;
14+
}
15+
16+
public function testRule(): void
17+
{
18+
$this->analyse([__DIR__ . '/data/missing-function-return-typehint.php'], [
19+
[
20+
'Function globalFunction1() has no return typehint specified',
21+
5,
22+
],
23+
[
24+
'Function MissingFunctionReturnTypehint\namespacedFunction1() has no return typehint specified',
25+
26,
26+
],
27+
]);
28+
}
29+
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace
4+
{
5+
function globalFunction1($a, $b, $c)
6+
{
7+
return false;
8+
}
9+
10+
function globalFunction2($a, $b, $c): bool
11+
{
12+
return false;
13+
}
14+
15+
/**
16+
* @return bool
17+
*/
18+
function globalFunction3($a, $b, $c)
19+
{
20+
return false;
21+
}
22+
}
23+
24+
namespace MissingFunctionReturnTypehint
25+
{
26+
function namespacedFunction1($d, $e)
27+
{
28+
return 9;
29+
};
30+
31+
function namespacedFunction2($d, $e): int
32+
{
33+
return 9;
34+
};
35+
36+
/**
37+
* @return int
38+
*/
39+
function namespacedFunction3($d, $e)
40+
{
41+
return 9;
42+
};
43+
}

0 commit comments

Comments
 (0)