Repository navigation
Expand file tree
/
Copy pathDeprecatedMethodCallReplacementResolver.php
More file actions
78 lines (64 loc) · 2.46 KB
/
Copy pathDeprecatedMethodCallReplacementResolver.php
File metadata and controls
78 lines (64 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<?php
declare(strict_types=1);
namespace Rector\Renaming\NodeAnalyzer;
use Nette\Utils\Strings;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MethodReflection;
/**
* @see \Rector\Tests\Renaming\NodeAnalyzer\DeprecatedMethodCallReplacementResolverTest
*/
final class DeprecatedMethodCallReplacementResolver
{
/**
* Matches the new method name suggested inside a "@deprecated" description, e.g.:
* - "use newMethod() instead"
* - "replaced by newMethod()"
* - "{@see newMethod()}"
*
* Cross-class suggestions ("Other::newMethod()") are intentionally skipped for now.
*/
private const string RENAME_SUGGESTION_REGEX = '#(?:\buse\b|\breplaced by\b|\{@see)\s+(?<method>\w+)\(\)#i';
/**
* Resolves a non-deprecated replacement method name suggested by the "@deprecated" docblock
* of the given method, or null when there is no usable suggestion.
*/
public function resolve(MethodReflection $methodReflection): ?string
{
if (! $methodReflection->isDeprecated()->yes()) {
return null;
}
$newMethodName = $this->matchNewMethodName($methodReflection->getDeprecatedDescription());
if ($newMethodName === null) {
return null;
}
// already the suggested name? nothing to do
if (strtolower($methodReflection->getName()) === strtolower($newMethodName)) {
return null;
}
if (! $this->isExistingNonDeprecatedMethod($methodReflection->getDeclaringClass(), $newMethodName)) {
return null;
}
return $newMethodName;
}
private function matchNewMethodName(?string $deprecatedDescription): ?string
{
if ($deprecatedDescription === null || $deprecatedDescription === '') {
return null;
}
$match = Strings::match($deprecatedDescription, self::RENAME_SUGGESTION_REGEX);
if ($match === null) {
return null;
}
return $match['method'];
}
private function isExistingNonDeprecatedMethod(ClassReflection $classReflection, string $newMethodName): bool
{
if (! $classReflection->hasNativeMethod($newMethodName)) {
return false;
}
// do not rename onto another deprecated method, to avoid suggesting a dead end
$extendedMethodReflection = $classReflection->getNativeMethod($newMethodName);
return ! $extendedMethodReflection->isDeprecated()
->yes();
}
}