CycleDetector::collectConnectedSubGraphs()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 11
nc 8
nop 1
dl 0
loc 20
rs 9.6111
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace DependencyAnalyzer\Inspector;
5
6
use DependencyAnalyzer\DependencyGraph;
7
use DependencyAnalyzer\DependencyGraph\Path;
8
use DependencyAnalyzer\Exceptions\LogicException;
9
use DependencyAnalyzer\Inspector\Responses\CycleDetectorResponse;
10
11
class CycleDetector
12
{
13
    /**
14
     * @var Path[]
15
     */
16
    protected $cycles = [];
17
18
    public function inspect(DependencyGraph $graph): CycleDetectorResponse
19
    {
20
        $subGraphs = $this->collectConnectedSubGraphs($graph);
21
22
        foreach ($subGraphs as $subGraph) {
23
            $subGraph->walkOnPath([$this, 'checkCycle']);
24
        }
25
26
        $response = new CycleDetectorResponse();
27
        foreach ($this->cycles as $cycle) {
28
            $response->addCycle($cycle->toArray());
29
        }
30
31
        return $response;
32
    }
33
34
    public function checkCycle(Path $path): void
35
    {
36
        if ($path->isSimpleCycle()) {
37
            $this->addCycle($path);
38
        }
39
    }
40
41
    protected function addCycle(Path $path): void
42
    {
43
        foreach ($this->cycles as $cycle) {
44
            if ($cycle->isEqual($path)) {
45
                return;
46
            }
47
        }
48
49
        $this->cycles[] = $path;
50
    }
51
52
    /**
53
     * @param DependencyGraph $graph
54
     * @return DependencyGraph[]
55
     */
56
    protected function collectConnectedSubGraphs(DependencyGraph $graph): array
57
    {
58
        $subGraphs = [];
59
60
        $visited = [];
61
        foreach ($graph->getClasses() as $class) {
62
            $id = $class->getName();
63
            if (!isset($visited[$id])) {
64
                $subGraphs[] = $subGraph = $graph->getConnectedSubGraphsStartFrom($class->getVertex());
65
66
                foreach ($subGraph->getClasses() as $subGraphVertex) {
67
                    $visited[$subGraphVertex->getName()] = true;
68
                }
69
            }
70
        }
71
72
        if ($graph->count() !== count($visited)) {
73
            throw new LogicException();
74
        }
75
        return $subGraphs;
76
    }
77
}
78