Passed
Pull Request — master (#50)
by Marco
02:46
created

Comparator   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 7
dl 0
loc 71
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A compare() 0 18 2
B examineSymbol() 0 23 4
A __construct() 0 8 1
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
class Comparator
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
     * @param ClassReflector $definedSymbols              containing only defined symbols in the compared API
39
     * @param ClassReflector $pastSourcesWithDependencies capable of giving us symbols with their dependencies from the
40
     *                                                    old version of the sources
41
     * @param ClassReflector $newSourcesWithDependencies  capable of giving us symbols with their dependencies from the
42
     *                                                    old version of the sources
43
     */
44
    public function compare(
45
        ClassReflector $definedSymbols,
46
        ClassReflector $pastSourcesWithDependencies,
47
        ClassReflector $newSourcesWithDependencies
48
    ) : Changes {
49
        $changelog = Changes::empty();
50
51
        $definedApiClassNames = array_map(function (ReflectionClass $class) : string {
52
            return $class->getName();
53
        }, $definedSymbols->getAllClasses());
54
55
        foreach ($definedApiClassNames as $apiClassName) {
56
            /** @var ReflectionClass $oldSymbol */
57
            $oldSymbol = $pastSourcesWithDependencies->reflect($apiClassName);
58
            $changelog = $this->examineSymbol($changelog, $oldSymbol, $newSourcesWithDependencies);
59
        }
60
61
        return $changelog;
62
    }
63
64
    private function examineSymbol(
65
        Changes $changelog,
66
        ReflectionClass $oldSymbol,
67
        ClassReflector $newSourcesWithDependencies
68
    ) : Changes {
69
        try {
70
            /** @var ReflectionClass $newClass */
71
            $newClass = $newSourcesWithDependencies->reflect($oldSymbol->getName());
72
        } catch (IdentifierNotFound $exception) {
73
            return $changelog->mergeWith(Changes::fromList(
74
                Change::removed(sprintf('Class %s has been deleted', $oldSymbol->getName()), true)
75
            ));
76
        }
77
78
        if ($oldSymbol->isInterface()) {
79
            return $changelog->mergeWith($this->interfaceBasedComparisons->__invoke($oldSymbol, $newClass));
80
        }
81
82
        if ($oldSymbol->isTrait()) {
83
            return $changelog->mergeWith($this->traitBasedComparisons->__invoke($oldSymbol, $newClass));
84
        }
85
86
        return $changelog->mergeWith($this->classBasedComparisons->__invoke($oldSymbol, $newClass));
87
    }
88
}
89