Skip to content

Commit 595ef0d

Browse files
paxalondrejmirtes
authored andcommitted
Format errors to comply with PHPStan pattern
1 parent 263d66c commit 595ef0d

File tree

4 files changed

+76
-39
lines changed

4 files changed

+76
-39
lines changed

src/Rules/Deprecations/TypeHintDeprecatedInClassMethodSignatureRule.php

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Broker\Broker;
88
use PHPStan\Node\InClassMethodNode;
9+
use PHPStan\Reflection\ClassReflection;
910
use PHPStan\Reflection\MethodReflection;
1011
use PHPStan\Reflection\ParameterReflection;
1112
use PHPStan\Reflection\ParametersAcceptorSelector;
@@ -40,31 +41,68 @@ public function processNode(Node $node, Scope $scope): array
4041
}
4142
$methodSignature = ParametersAcceptorSelector::selectSingle($method->getVariants());
4243

43-
$errorLists = [];
44+
$errors = [];
4445
foreach ($methodSignature->getParameters() as $i => $parameter) {
4546
/** @var ParameterReflection $parameter */
46-
$errorLists[] = $this->checkClasses(
47-
$parameter->getType()->getReferencedClasses(),
48-
'argument #' . $i
47+
$deprecatedClasses = $this->filterDeprecatedClasses($parameter->getType()->getReferencedClasses());
48+
foreach ($deprecatedClasses as $deprecatedClass) {
49+
$errors[] = sprintf(
50+
'Parameter $%s of method %s::%s() has typehint with deprecated %s %s%s',
51+
$parameter->getName(),
52+
$method->getDeclaringClass()->getName(),
53+
$method->getName(),
54+
$this->getClassType($deprecatedClass),
55+
$deprecatedClass->getName(),
56+
$this->getClassDeprecationDescription($deprecatedClass)
57+
);
58+
}
59+
}
60+
61+
$deprecatedClasses = $this->filterDeprecatedClasses($methodSignature->getReturnType()->getReferencedClasses());
62+
foreach ($deprecatedClasses as $deprecatedClass) {
63+
$errors[] = sprintf(
64+
'Return type of method %s::%s() has typehint with deprecated %s %s%s',
65+
$method->getDeclaringClass()->getName(),
66+
$method->getName(),
67+
$this->getClassType($deprecatedClass),
68+
$deprecatedClass->getName(),
69+
$this->getClassDeprecationDescription($deprecatedClass)
4970
);
5071
}
5172

52-
$errorLists[] = $this->checkClasses(
53-
$methodSignature->getReturnType()->getReferencedClasses(),
54-
'return type'
55-
);
73+
return $errors;
74+
}
75+
76+
private function getClassType(ClassReflection $class): string
77+
{
78+
if ($class->isInterface()) {
79+
return 'interface';
80+
}
5681

57-
return array_merge(...$errorLists);
82+
return 'class';
83+
}
84+
85+
private function getClassDeprecationDescription(ClassReflection $class): string
86+
{
87+
$description = null;
88+
if (method_exists($class, 'getDeprecatedDescription')) {
89+
$description = $class->getDeprecatedDescription();
90+
}
91+
92+
if ($description === null) {
93+
return '.';
94+
}
95+
96+
return sprintf(":\n%s", $description);
5897
}
5998

6099
/**
61100
* @param string[] $referencedClasses
62-
* @param string $where
63-
* @return string[]
101+
* @return ClassReflection[]
64102
*/
65-
private function checkClasses(array $referencedClasses, string $where): array
103+
private function filterDeprecatedClasses(array $referencedClasses): array
66104
{
67-
$errors = [];
105+
$deprecatedClasses = [];
68106
foreach ($referencedClasses as $referencedClass) {
69107
try {
70108
$class = $this->broker->getClass($referencedClass);
@@ -76,28 +114,10 @@ private function checkClasses(array $referencedClasses, string $where): array
76114
continue;
77115
}
78116

79-
$classDescription = null;
80-
if (method_exists($class, 'getDeprecatedDescription')) {
81-
$classDescription = $class->getDeprecatedDescription();
82-
}
83-
84-
if ($classDescription === null) {
85-
$errors[] = sprintf(
86-
'Usage of deprecated class %s in %s.',
87-
$referencedClass,
88-
$where
89-
);
90-
} else {
91-
$errors[] = sprintf(
92-
"Usage of deprecated class %s in %s:\n%s",
93-
$referencedClass,
94-
$where,
95-
$classDescription
96-
);
97-
}
117+
$deprecatedClasses[] = $class;
98118
}
99119

100-
return $errors;
120+
return $deprecatedClasses;
101121
}
102122

103123
}

tests/Rules/Deprecations/TypeHintDeprecatedInClassMethodSignatureRuleTest.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ public function test(): void
1818
$this->analyse(
1919
[__DIR__ . '/data/typehint-deprecated-class.php'],
2020
[
21-
['Usage of deprecated class TypeHintDeprecatedInFunctionSignature\DeprecatedProperty in argument #0.', 13],
22-
['Usage of deprecated class TypeHintDeprecatedInFunctionSignature\DeprecatedProperty in argument #1.', 13],
23-
['Usage of deprecated class TypeHintDeprecatedInFunctionSignature\DeprecatedProperty in argument #5.', 13],
24-
['Usage of deprecated class TypeHintDeprecatedInFunctionSignature\DeprecatedProperty in return type.', 13],
21+
['Parameter $property of method TypeHintDeprecatedInFunctionSignature\Foo::setProperties() has typehint with deprecated class TypeHintDeprecatedInFunctionSignature\DeprecatedProperty.', 13],
22+
['Parameter $property2 of method TypeHintDeprecatedInFunctionSignature\Foo::setProperties() has typehint with deprecated interface TypeHintDeprecatedInFunctionSignature\DeprecatedInterface.', 13],
23+
["Parameter \$property4 of method TypeHintDeprecatedInFunctionSignature\Foo::setProperties() has typehint with deprecated class TypeHintDeprecatedInFunctionSignature\VerboseDeprecatedProperty:\nI'll be back", 13],
24+
['Parameter $property6 of method TypeHintDeprecatedInFunctionSignature\Foo::setProperties() has typehint with deprecated class TypeHintDeprecatedInFunctionSignature\DeprecatedProperty.', 13],
25+
['Return type of method TypeHintDeprecatedInFunctionSignature\Foo::setProperties() has typehint with deprecated class TypeHintDeprecatedInFunctionSignature\DeprecatedProperty.', 13],
2526
]
2627
);
2728
}

tests/Rules/Deprecations/data/typehint-deprecated-class-definition.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ class DeprecatedProperty
1010

1111
}
1212

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+
1329
class Property
1430
{
1531

tests/Rules/Deprecations/data/typehint-deprecated-class.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ class Foo
1212
*/
1313
public function setProperties(
1414
DeprecatedProperty $property,
15-
?DeprecatedProperty $property2,
15+
?DeprecatedInterface $property2,
1616
$property3,
17-
Property $property4,
17+
VerboseDeprecatedProperty $property4,
1818
string $property5,
1919
$property6
2020
): DeprecatedProperty {

0 commit comments

Comments
 (0)