Skip to content

Commit e932fb5

Browse files
paxalondrejmirtes
authored andcommitted
Add deprecation for function typehints
1 parent 0887096 commit e932fb5

File tree

5 files changed

+153
-0
lines changed

5 files changed

+153
-0
lines changed

rules.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ rules:
1515
- PHPStan\Rules\Deprecations\InstantiationOfDeprecatedClassRule
1616
- PHPStan\Rules\Deprecations\TypeHintDeprecatedInClassMethodSignatureRule
1717
- PHPStan\Rules\Deprecations\TypeHintDeprecatedInClosureSignatureRule
18+
- PHPStan\Rules\Deprecations\TypeHintDeprecatedInFunctionSignatureRule
1819
- PHPStan\Rules\Deprecations\UsageOfDeprecatedTraitRule
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Deprecations;
4+
5+
use PhpParser\Node;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Node\InFunctionNode;
8+
use PHPStan\Reflection\FunctionReflection;
9+
use PHPStan\Reflection\ParametersAcceptorSelector;
10+
11+
class TypeHintDeprecatedInFunctionSignatureRule implements \PHPStan\Rules\Rule
12+
{
13+
14+
/** @var DeprecatedClassHelper */
15+
private $deprecatedClassHelper;
16+
17+
public function __construct(DeprecatedClassHelper $deprecatedClassHelper)
18+
{
19+
$this->deprecatedClassHelper = $deprecatedClassHelper;
20+
}
21+
22+
public function getNodeType(): string
23+
{
24+
return InFunctionNode::class;
25+
}
26+
27+
/**
28+
* @param InFunctionNode $node
29+
* @param \PHPStan\Analyser\Scope $scope
30+
* @return string[] errors
31+
*/
32+
public function processNode(Node $node, Scope $scope): array
33+
{
34+
if (DeprecatedScopeHelper::isScopeDeprecated($scope)) {
35+
return [];
36+
}
37+
38+
$function = $scope->getFunction();
39+
if (!$function instanceof FunctionReflection) {
40+
throw new \PHPStan\ShouldNotHappenException();
41+
}
42+
$functionSignature = ParametersAcceptorSelector::selectSingle($function->getVariants());
43+
44+
$errors = [];
45+
foreach ($functionSignature->getParameters() as $i => $parameter) {
46+
$deprecatedClasses = $this->deprecatedClassHelper->filterDeprecatedClasses($parameter->getType()->getReferencedClasses());
47+
foreach ($deprecatedClasses as $deprecatedClass) {
48+
$errors[] = sprintf(
49+
'Parameter $%s of function %s() has typehint with deprecated %s %s%s',
50+
$parameter->getName(),
51+
$function->getName(),
52+
$this->deprecatedClassHelper->getClassType($deprecatedClass),
53+
$deprecatedClass->getName(),
54+
$this->deprecatedClassHelper->getClassDeprecationDescription($deprecatedClass)
55+
);
56+
}
57+
}
58+
59+
$deprecatedClasses = $this->deprecatedClassHelper->filterDeprecatedClasses($functionSignature->getReturnType()->getReferencedClasses());
60+
foreach ($deprecatedClasses as $deprecatedClass) {
61+
$errors[] = sprintf(
62+
'Return type of function %s() has typehint with deprecated %s %s%s',
63+
$function->getName(),
64+
$this->deprecatedClassHelper->getClassType($deprecatedClass),
65+
$deprecatedClass->getName(),
66+
$this->deprecatedClassHelper->getClassDeprecationDescription($deprecatedClass)
67+
);
68+
}
69+
70+
return $errors;
71+
}
72+
73+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Deprecations;
4+
5+
class TypeHintDeprecatedInFunctionSignatureRuleTest extends \PHPStan\Testing\RuleTestCase
6+
{
7+
8+
protected function getRule(): \PHPStan\Rules\Rule
9+
{
10+
$broker = $this->createBroker();
11+
12+
return new TypeHintDeprecatedInFunctionSignatureRule(new DeprecatedClassHelper($broker));
13+
}
14+
15+
public function test(): void
16+
{
17+
require_once __DIR__ . '/data/typehint-function-deprecated-class-definition.php';
18+
$this->analyse(
19+
[__DIR__ . '/data/typehint-function-deprecated-class.php'],
20+
[
21+
['Parameter $property of function TypeHintDeprecatedInFunctionSignature\setProperties() has typehint with deprecated class TypeHintDeprecatedInFunctionSignature\DeprecatedProperty.', 8],
22+
['Parameter $property2 of function TypeHintDeprecatedInFunctionSignature\setProperties() has typehint with deprecated interface TypeHintDeprecatedInFunctionSignature\DeprecatedInterface.', 8],
23+
["Parameter \$property4 of function TypeHintDeprecatedInFunctionSignature\setProperties() has typehint with deprecated class TypeHintDeprecatedInFunctionSignature\VerboseDeprecatedProperty:\nI'll be back", 8],
24+
['Parameter $property6 of function TypeHintDeprecatedInFunctionSignature\setProperties() has typehint with deprecated class TypeHintDeprecatedInFunctionSignature\DeprecatedProperty.', 8],
25+
['Return type of function TypeHintDeprecatedInFunctionSignature\setProperties() has typehint with deprecated class TypeHintDeprecatedInFunctionSignature\DeprecatedProperty.', 8],
26+
]
27+
);
28+
}
29+
30+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace TypeHintDeprecatedInFunctionSignature;
4+
5+
/**
6+
* @deprecated
7+
*/
8+
class DeprecatedProperty
9+
{
10+
11+
}
12+
13+
/**
14+
* @deprecated I'll be back
15+
*/
16+
class VerboseDeprecatedProperty
17+
{
18+
19+
}
20+
21+
/**
22+
* @deprecated
23+
*/
24+
interface DeprecatedInterface
25+
{
26+
27+
}
28+
29+
class Property
30+
{
31+
32+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace TypeHintDeprecatedInFunctionSignature;
4+
5+
/**
6+
* @param DeprecatedProperty $property6
7+
*/
8+
function setProperties(
9+
DeprecatedProperty $property,
10+
?DeprecatedInterface $property2,
11+
$property3,
12+
VerboseDeprecatedProperty $property4,
13+
string $property5,
14+
$property6
15+
): DeprecatedProperty {
16+
return $property;
17+
}

0 commit comments

Comments
 (0)