Passed
Push — master ( 1ba30a...8ac47c )
by Luis
01:05 queued 12s
created

DirectedEdgesBuilder   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 17
dl 0
loc 67
ccs 21
cts 21
cp 1
rs 10
c 1
b 0
f 0
wmc 9

6 Methods

Rating   Name   Duplication   Size   Complexity  
A isAssociationResolved() 0 3 2
A fromConstructor() 0 3 1
A buildEdgesFor() 0 13 3
A markAssociationResolvedFor() 0 3 1
A addAssociations() 0 5 1
A fromProperties() 0 3 1
1
<?php declare(strict_types=1);
2
/**
3
 * This source file is subject to the license that is bundled with this package in the file LICENSE.
4
 */
5
6
namespace PhUml\Graphviz\Builders;
7
8
use PhUml\Code\ClassDefinition;
9
use PhUml\Code\Codebase;
10
use PhUml\Code\Name;
11
use PhUml\Code\Variables\HasType;
12
use PhUml\Graphviz\Edge;
13
14
/**
15
 * It creates directed edges by inspecting a class
16
 *
17
 * 1. It creates edges by inspecting the properties of a class
18
 * 2. It creates edges by inspecting the parameters of the constructor of a class
19
 */
20
final class DirectedEdgesBuilder implements EdgesBuilder
21
{
22
    /** @var bool[] */
23
    private array $edges = [];
24
25
    /**
26
     * It creates an edge if the property
27
     *
28
     * - Has type information, and it's not a PHP's built-in type
29
     * - The association hasn't already been resolved
30
     *
31
     * @return Edge[]
32
     */
33 18
    public function fromProperties(ClassDefinition $class, Codebase $codebase): array
34
    {
35 18
        return $this->buildEdgesFor($class, $class->properties(), $codebase);
36
    }
37
38
    /**
39
     * It creates an edge if the constructor parameter
40
     *
41
     * - Has type information, and it's not a PHP's built-in type
42
     * - The association hasn't already been resolved
43
     *
44
     * @return Edge[]
45
     */
46 18
    public function fromConstructor(ClassDefinition $class, Codebase $codebase): array
47
    {
48 18
        return $this->buildEdgesFor($class, $class->constructorParameters(), $codebase);
49
    }
50
51
    /**
52
     * @param HasType[] $variables
53
     * @return Edge[]
54
     */
55 18
    private function buildEdgesFor(ClassDefinition $class, array $variables, Codebase $codebase): array
56
    {
57 18
        $edges = [];
58 18
        foreach ($variables as $variable) {
59 12
            $key = EdgeKey::from($class->name(), $variable->type());
60 12
            if ($this->isAssociationResolved($key)) {
61 7
                continue;
62
            }
63
64 12
            $this->markAssociationResolvedFor($key);
65 12
            $edges[] = $this->addAssociations($class, $variable, $codebase);
66
        }
67 18
        return array_merge(...$edges);
68
    }
69
70
    /** @return Edge[] */
71 12
    private function addAssociations(ClassDefinition $class, HasType $property, Codebase $codebase): array
72
    {
73 12
        return array_map(
74 12
            static fn (Name $reference): Edge => Edge::association($codebase->get($reference), $class),
75 12
            $property->references()
76
        );
77
    }
78
79 12
    private function isAssociationResolved(EdgeKey $key): bool
80
    {
81 12
        return array_key_exists((string) $key, $this->edges) && $this->edges[(string) $key];
82
    }
83
84 12
    private function markAssociationResolvedFor(EdgeKey $key): void
85
    {
86 12
        $this->edges[(string) $key] = true;
87
    }
88
}
89