Passed
Push — master ( c57dde...29e061 )
by Satoshi
02:16
created

DependencyGraphBuilder::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace DependencyAnalyzer;
5
6
use DependencyAnalyzer\DependencyGraphBuilder\UnknownClassReflection;
7
use DependencyAnalyzer\DependencyGraph;
8
use DependencyAnalyzer\DependencyGraph\ExtraPhpDocTagResolver;
9
use Fhaculty\Graph\Graph;
10
use PHPStan\Reflection\ClassReflection;
11
12
class DependencyGraphBuilder
13
{
14
    /**
15
     * @var ClassReflection[]|UnknownClassReflection[] $classReflections
16
     */
17
    protected $classes = [];
18
19
    /**
20
     * @var array $dependencyMap
21
     */
22
    protected $dependencyMap = [];
23
24
    /**
25
     * @var ExtraPhpDocTagResolver
26
     */
27
    protected $extraPhpDocTagResolver;
28
29
    public function __construct(ExtraPhpDocTagResolver $extraPhpDocTagResolver)
30
    {
31
        $this->extraPhpDocTagResolver = $extraPhpDocTagResolver;
32
    }
33
34
    /**
35
     * @param ClassReflection $depender
36
     * @param ClassReflection $dependee
37
     */
38
    public function addDependency(ClassReflection $depender, ClassReflection $dependee)
39
    {
40
        $this->addDependencyMap($this->getClassReflectionId($depender), $this->getClassReflectionId($dependee));
41
    }
42
43
    public function addUnknownDependency(ClassReflection $depender, string $dependeeName)
44
    {
45
        $unknownClassReflection = new UnknownClassReflection($dependeeName);
46
        $unknownClassReflection->addDepender($depender->getDisplayName());
47
        $this->addDependencyMap($this->getClassReflectionId($depender), $this->getClassReflectionId($unknownClassReflection));
48
    }
49
50
    protected function addDependencyMap(int $dependerId, int $dependeeId)
51
    {
52
        if (!isset($this->dependencyMap[$dependerId])) {
53
            $this->dependencyMap[$dependerId] = [$dependeeId];
54
        } elseif (!in_array($dependeeId, $this->dependencyMap[$dependerId])) {
55
            $this->dependencyMap[$dependerId][] = $dependeeId;
56
        }
57
    }
58
59
    /**
60
     * @param ClassReflection|UnknownClassReflection $classReflection
61
     * @return int
62
     */
63
    protected function getClassReflectionId($classReflection): int
64
    {
65
        foreach ($this->classes as $id => $reflection) {
66
            if ($reflection->getDisplayName() === $classReflection->getDisplayName()) {
67
                if ($reflection instanceof UnknownClassReflection) {
68
                    $reflection->mergeDepender($classReflection);
0 ignored issues
show
Bug introduced by
It seems like $classReflection can also be of type PHPStan\Reflection\ClassReflection; however, parameter $that of DependencyAnalyzer\Depen...ection::mergeDepender() does only seem to accept DependencyAnalyzer\Depen...\UnknownClassReflection, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

68
                    $reflection->mergeDepender(/** @scrutinizer ignore-type */ $classReflection);
Loading history...
69
                }
70
71
                return $id;
72
            }
73
        }
74
75
        $this->classes[] = $classReflection;
76
        return count($this->classes) - 1;
77
    }
78
79
    public function build(): DependencyGraph
80
    {
81
        $graph = new Graph();
82
83
        foreach ($this->classes as $class) {
84
            $vertex = $graph->createVertex($class->getDisplayName());
85
            $vertex->setAttribute('reflection', $class);
86
            $canOnlyUsedByTags = ($class instanceof ClassReflection) ? $this->extraPhpDocTagResolver->resolveCanOnlyUsedByTag($class) : [];
87
            $vertex->setAttribute(ExtraPhpDocTagResolver::ONLY_USED_BY_TAGS, $canOnlyUsedByTags);
88
        }
89
90
        foreach ($this->dependencyMap as $dependerId => $dependeeIds) {
91
            $depender = $graph->getVertex($this->classes[$dependerId]->getDisplayName());
92
            foreach ($dependeeIds as $dependeeId) {
93
                $dependee = $graph->getVertex($this->classes[$dependeeId]->getDisplayName());
94
                $depender->createEdgeTo($dependee);
95
            }
96
        }
97
98
        return new DependencyGraph($graph);
99
    }
100
}
101