Passed
Pull Request — master (#58)
by James
04:45
created

CompareClasses::examineSymbol()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 4
nop 3
dl 0
loc 23
rs 8.7972
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Roave\BackwardCompatibility;
6
7
use Roave\BackwardCompatibility\DetectChanges\BCBreak\ClassBased\ClassBased;
8
use Roave\BackwardCompatibility\DetectChanges\BCBreak\InterfaceBased\InterfaceBased;
9
use Roave\BackwardCompatibility\DetectChanges\BCBreak\TraitBased\TraitBased;
10
use Roave\BetterReflection\Reflection\ReflectionClass;
11
use Roave\BetterReflection\Reflector\ClassReflector;
12
use Roave\BetterReflection\Reflector\Exception\IdentifierNotFound;
13
use function array_map;
14
use function sprintf;
15
16
final class CompareClasses implements CompareApi
17
{
18
    /** @var ClassBased */
19
    private $classBasedComparisons;
20
21
    /** @var InterfaceBased */
22
    private $interfaceBasedComparisons;
23
24
    /** @var TraitBased */
25
    private $traitBasedComparisons;
26
27
    public function __construct(
28
        ClassBased $classBasedComparisons,
29
        InterfaceBased $interfaceBasedComparisons,
30
        TraitBased $traitBasedComparisons
31
    ) {
32
        $this->classBasedComparisons     = $classBasedComparisons;
33
        $this->interfaceBasedComparisons = $interfaceBasedComparisons;
34
        $this->traitBasedComparisons     = $traitBasedComparisons;
35
    }
36
37
    /**
38
     * {@inheritDoc}
39
     */
40
    public function __invoke(
41
        ClassReflector $definedSymbols,
42
        ClassReflector $pastSourcesWithDependencies,
43
        ClassReflector $newSourcesWithDependencies
44
    ) : Changes {
45
        $changelog = Changes::empty();
46
47
        $definedApiClassNames = array_map(function (ReflectionClass $class) : string {
48
            return $class->getName();
49
        }, $definedSymbols->getAllClasses());
50
51
        foreach ($definedApiClassNames as $apiClassName) {
52
            /** @var ReflectionClass $oldSymbol */
53
            $oldSymbol = $pastSourcesWithDependencies->reflect($apiClassName);
54
            $changelog = $this->examineSymbol($changelog, $oldSymbol, $newSourcesWithDependencies);
55
        }
56
57
        return $changelog;
58
    }
59
60
    private function examineSymbol(
61
        Changes $changelog,
62
        ReflectionClass $oldSymbol,
63
        ClassReflector $newSourcesWithDependencies
64
    ) : Changes {
65
        try {
66
            /** @var ReflectionClass $newClass */
67
            $newClass = $newSourcesWithDependencies->reflect($oldSymbol->getName());
68
        } catch (IdentifierNotFound $exception) {
69
            return $changelog->mergeWith(Changes::fromList(
70
                Change::removed(sprintf('Class %s has been deleted', $oldSymbol->getName()), true)
71
            ));
72
        }
73
74
        if ($oldSymbol->isInterface()) {
75
            return $changelog->mergeWith($this->interfaceBasedComparisons->__invoke($oldSymbol, $newClass));
76
        }
77
78
        if ($oldSymbol->isTrait()) {
79
            return $changelog->mergeWith($this->traitBasedComparisons->__invoke($oldSymbol, $newClass));
80
        }
81
82
        return $changelog->mergeWith($this->classBasedComparisons->__invoke($oldSymbol, $newClass));
83
    }
84
}
85