Completed
Pull Request — master (#1)
by James
01:44
created

Comparator::examineParameter()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 27
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 2
nop 6
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Roave\ApiCompare;
5
6
use Roave\BetterReflection\Reflection\ReflectionClass;
7
use Roave\BetterReflection\Reflection\ReflectionMethod;
8
use Roave\BetterReflection\Reflection\ReflectionParameter;
9
use Roave\BetterReflection\Reflector\ClassReflector;
10
use Roave\BetterReflection\Reflector\Exception\IdentifierNotFound;
11
12
final class Comparator
13
{
14
    public function compare(ClassReflector $oldApi, ClassReflector $newApi): array
15
    {
16
        $changelog = [];
17
18
        foreach ($oldApi->getAllClasses() as $oldClass) {
19
            $changelog = $this->examineClass($changelog, $oldClass, $newApi);
20
        }
21
22
        return $changelog;
23
    }
24
25
    private function examineClass(array $changelog, ReflectionClass $oldClass, ClassReflector $newApi): array
26
    {
27
        try {
28
            $newClass = $newApi->reflect($oldClass->getName());
29
        } catch (IdentifierNotFound $exception) {
30
            $changelog[] = sprintf('[BC] Class %s has been deleted', $oldClass->getName());
31
            return $changelog;
32
        }
33
34
        foreach ($oldClass->getMethods() as $oldMethod) {
35
            $changelog = $this->examineMethod($changelog, $oldClass, $oldMethod, $newClass);
36
        }
37
38
        return $changelog;
39
    }
40
41
    private function examineMethod(
42
        array $changelog,
43
        ReflectionClass $oldClass,
44
        ReflectionMethod $oldMethod,
45
        ReflectionClass $newClass
46
    ): array {
47
        // @todo ignore private methods
48
        try {
49
            $newMethod = $newClass->getMethod($oldMethod->getName());
50
        } catch (\OutOfBoundsException $exception) {
51
            $changelog[] = sprintf(
52
                '[BC] Method %s in class %s has been deleted',
53
                $oldMethod->getName(),
54
                $oldClass->getName()
55
            );
56
            return $changelog;
57
        }
58
59
        foreach ($oldMethod->getParameters() as $parameterPosition => $oldParameter) {
60
            $changelog = $this->examineParameter(
61
                $changelog,
62
                $parameterPosition,
63
                $oldClass,
64
                $oldMethod,
65
                $oldParameter,
66
                $newMethod
67
            );
68
        }
69
70
        return $changelog;
71
    }
72
73
    private function examineParameter(
74
        array $changelog,
75
        int $parameterPosition,
76
        ReflectionClass $oldClass,
77
        ReflectionMethod $oldMethod,
78
        ReflectionParameter $oldParameter,
79
        ReflectionMethod $newMethod
80
    ): array {
81
        $newParameters = $newMethod->getParameters();
82
        if (!array_key_exists($parameterPosition, $newParameters)) {
83
            $changelog[] = sprintf(
84
                '[BC] Parameter %s (position %d) in %s%s%s has been deleted',
85
                $oldParameter->getName(),
86
                $parameterPosition,
87
                $oldClass->getName(),
88
                $oldMethod->isStatic() ? '#' : '::',
89
                $oldMethod->getName()
90
            );
91
            return $changelog;
92
        }
93
94
        $newParameter = $newParameters[$parameterPosition];
0 ignored issues
show
Unused Code introduced by
The assignment to $newParameter is dead and can be removed.
Loading history...
95
96
        // @todo check if types changed, or becoming default
97
        // @todo check if a new param (without a default) was added
98
99
        return $changelog;
100
    }
101
}
102