MethodRemoved::accessibleMethods()   A
last analyzed

Complexity

Conditions 3
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 13
rs 9.9666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Roave\BackwardCompatibility\DetectChanges\BCBreak\ClassBased;
6
7
use Roave\BackwardCompatibility\Change;
8
use Roave\BackwardCompatibility\Changes;
9
use Roave\BackwardCompatibility\Formatter\ReflectionFunctionAbstractName;
10
use Roave\BetterReflection\Reflection\ReflectionClass;
11
use Roave\BetterReflection\Reflection\ReflectionMethod;
12
use function array_change_key_case;
13
use function array_diff_key;
14
use function array_filter;
15
use function array_map;
16
use function array_values;
17
use function Safe\array_combine;
18
use function Safe\preg_match;
19
use function Safe\sprintf;
20
use const CASE_UPPER;
21
22
final class MethodRemoved implements ClassBased
23
{
24
    /** @var ReflectionFunctionAbstractName */
25
    private $formatFunction;
26
27
    public function __construct()
28
    {
29
        $this->formatFunction = new ReflectionFunctionAbstractName();
30
    }
31
32
    public function __invoke(ReflectionClass $fromClass, ReflectionClass $toClass) : Changes
33
    {
34
        $removedMethods = array_diff_key(
35
            array_change_key_case($this->accessibleMethods($fromClass), CASE_UPPER),
36
            array_change_key_case($this->accessibleMethods($toClass), CASE_UPPER)
37
        );
38
39
        return Changes::fromList(...array_values(array_map(function (ReflectionMethod $method) : Change {
40
            return Change::removed(
41
                sprintf('Method %s was removed', $this->formatFunction->__invoke($method)),
42
                true
43
            );
44
        }, $removedMethods)));
45
    }
46
47
    /** @return ReflectionMethod[] */
48
    private function accessibleMethods(ReflectionClass $class) : array
49
    {
50
        $methods = array_filter($class->getMethods(), function (ReflectionMethod $method) : bool {
51
            return ($method->isPublic()
52
                || $method->isProtected())
53
                && ! $this->isInternalDocComment($method->getDocComment());
54
        });
55
56
        return array_combine(
57
            array_map(static function (ReflectionMethod $method) : string {
58
                return $method->getName();
59
            }, $methods),
60
            $methods
61
        );
62
    }
63
64
    private function isInternalDocComment(string $comment) : bool
65
    {
66
        return preg_match('/\s+@internal\s+/', $comment) === 1;
67
    }
68
}
69