1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace Roave\BackwardCompatibility; |
||
6 | |||
7 | use Generator; |
||
8 | use Roave\BackwardCompatibility\DetectChanges\BCBreak\ClassBased\ClassBased; |
||
9 | use Roave\BackwardCompatibility\DetectChanges\BCBreak\InterfaceBased\InterfaceBased; |
||
10 | use Roave\BackwardCompatibility\DetectChanges\BCBreak\TraitBased\TraitBased; |
||
11 | use Roave\BetterReflection\Reflection\ReflectionClass; |
||
12 | use Roave\BetterReflection\Reflector\ClassReflector; |
||
13 | use Roave\BetterReflection\Reflector\Exception\IdentifierNotFound; |
||
14 | use function array_filter; |
||
15 | use function array_map; |
||
16 | use function Safe\preg_match; |
||
17 | use function Safe\sprintf; |
||
18 | |||
19 | final class CompareClasses implements CompareApi |
||
20 | { |
||
21 | /** @var ClassBased */ |
||
22 | private $classBasedComparisons; |
||
23 | |||
24 | /** @var InterfaceBased */ |
||
25 | private $interfaceBasedComparisons; |
||
26 | |||
27 | /** @var TraitBased */ |
||
28 | private $traitBasedComparisons; |
||
29 | |||
30 | public function __construct( |
||
31 | ClassBased $classBasedComparisons, |
||
32 | InterfaceBased $interfaceBasedComparisons, |
||
33 | TraitBased $traitBasedComparisons |
||
34 | ) { |
||
35 | $this->classBasedComparisons = $classBasedComparisons; |
||
36 | $this->interfaceBasedComparisons = $interfaceBasedComparisons; |
||
37 | $this->traitBasedComparisons = $traitBasedComparisons; |
||
38 | } |
||
39 | |||
40 | public function __invoke( |
||
41 | ClassReflector $definedSymbols, |
||
42 | ClassReflector $pastSourcesWithDependencies, |
||
43 | ClassReflector $newSourcesWithDependencies |
||
44 | ) : Changes { |
||
45 | $definedApiClassNames = array_map( |
||
46 | static function (ReflectionClass $class) : string { |
||
47 | return $class->getName(); |
||
48 | }, |
||
49 | array_filter( |
||
50 | $definedSymbols->getAllClasses(), |
||
51 | function (ReflectionClass $class) : bool { |
||
52 | return ! ($class->isAnonymous() || $this->isInternalDocComment($class->getDocComment())); |
||
53 | } |
||
54 | ) |
||
55 | ); |
||
56 | |||
57 | return Changes::fromIterator($this->makeSymbolsIterator( |
||
58 | $definedApiClassNames, |
||
59 | $pastSourcesWithDependencies, |
||
60 | $newSourcesWithDependencies |
||
61 | )); |
||
62 | } |
||
63 | |||
64 | /** |
||
65 | * @param string[] $definedApiClassNames |
||
66 | * |
||
67 | * @return iterable|Change[] |
||
68 | */ |
||
69 | private function makeSymbolsIterator( |
||
70 | array $definedApiClassNames, |
||
71 | ClassReflector $pastSourcesWithDependencies, |
||
72 | ClassReflector $newSourcesWithDependencies |
||
73 | ) : iterable { |
||
74 | foreach ($definedApiClassNames as $apiClassName) { |
||
75 | $oldSymbol = $pastSourcesWithDependencies->reflect($apiClassName); |
||
76 | |||
77 | yield from $this->examineSymbol($oldSymbol, $newSourcesWithDependencies); |
||
0 ignored issues
–
show
Bug
Best Practice
introduced
by
![]() |
|||
78 | } |
||
79 | } |
||
80 | |||
81 | private function examineSymbol( |
||
82 | ReflectionClass $oldSymbol, |
||
83 | ClassReflector $newSourcesWithDependencies |
||
84 | ) : Generator { |
||
85 | try { |
||
86 | $newClass = $newSourcesWithDependencies->reflect($oldSymbol->getName()); |
||
87 | } catch (IdentifierNotFound $exception) { |
||
88 | yield Change::removed(sprintf('Class %s has been deleted', $oldSymbol->getName()), true); |
||
89 | |||
90 | return; |
||
91 | } |
||
92 | |||
93 | if ($oldSymbol->isInterface()) { |
||
94 | yield from $this->interfaceBasedComparisons->__invoke($oldSymbol, $newClass); |
||
95 | |||
96 | return; |
||
97 | } |
||
98 | |||
99 | if ($oldSymbol->isTrait()) { |
||
100 | yield from $this->traitBasedComparisons->__invoke($oldSymbol, $newClass); |
||
101 | |||
102 | return; |
||
103 | } |
||
104 | |||
105 | yield from $this->classBasedComparisons->__invoke($oldSymbol, $newClass); |
||
106 | } |
||
107 | |||
108 | private function isInternalDocComment(string $comment) : bool |
||
109 | { |
||
110 | return preg_match('/\s+@internal\s+/', $comment) === 1; |
||
111 | } |
||
112 | } |
||
113 |