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

DirectedEdgesBuilder::fromProperties()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
b 0
f 0
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