Completed
Push — master ( 389baa...c7c5a4 )
by Luis
14:17 queued 08:06
created

CodebaseBuilder::buildFrom()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 8
nc 5
nop 1
dl 0
loc 13
ccs 9
cts 9
cp 1
crap 5
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * PHP version 7.1
4
 *
5
 * This source file is subject to the license that is bundled with this package in the file LICENSE.
6
 */
7
8
namespace PhUml\Parser;
9
10
use PhUml\Code\ClassDefinition;
11
use PhUml\Code\Definition;
12
use PhUml\Code\InterfaceDefinition;
13
use PhUml\Code\Codebase;
14
use PhUml\Parser\Raw\RawDefinition;
15
use PhUml\Parser\Raw\RawDefinitions;
16
17
/**
18
 * It builds a `Codebase` from a `RawDefinitions`
19
 */
20
class CodebaseBuilder
21
{
22
    /** @var Codebase */
23
    private $codebase;
24
25
    /** @var DefinitionMembersBuilder */
26
    protected $builder;
27
28 120
    public function __construct(Codebase $codebase = null, DefinitionMembersBuilder $builder = null)
29
    {
30 120
        $this->codebase = $codebase ?? new Codebase();
31 120
        $this->builder = $builder ?? new DefinitionMembersBuilder();
32 120
    }
33
34 102
    public function buildFrom(RawDefinitions $definitions): Codebase
35
    {
36 102
        foreach ($definitions->all() as $definition) {
37 99
            if ($this->codebase->has($definition->name())) {
38 45
                continue;
39
            }
40 99
            if ($definition->isClass()) {
41 90
                $this->codebase->addClass($this->buildClass($definitions, $definition));
42 18
            } elseif ($definition->isInterface()) {
43 99
                $this->codebase->addInterface($this->buildInterface($definitions, $definition));
44
            }
45
        }
46 102
        return $this->codebase;
47
    }
48
49 57
    protected function buildInterface(RawDefinitions $definitions, RawDefinition $interface): InterfaceDefinition
50
    {
51 57
        return new InterfaceDefinition(
52 57
            $interface->name(),
53 57
            $this->builder->constants($interface),
54 57
            $this->builder->methods($interface),
55 57
            $this->resolveRelatedInterface($definitions, $interface->parent())
56
        );
57
    }
58
59 84
    protected function buildClass(RawDefinitions $definitions, RawDefinition $class): ClassDefinition
60
    {
61 84
        return new ClassDefinition(
62 84
            $class->name(),
63 84
            $this->builder->constants($class),
64 84
            $this->builder->methods($class),
65 84
            $this->resolveParentClass($definitions, $class->parent()),
66 84
            $this->builder->attributes($class),
67 84
            $this->buildInterfaces($definitions, $class->interfaces())
68
        );
69
    }
70
71
    /**
72
     * @param string[] $implements
73
     * @return Definition[]
74
     */
75
    protected function buildInterfaces(RawDefinitions $definitions, array $implements): array
76
    {
77 90
        return array_map(function (string $interface) use ($definitions) {
78 48
            return $this->resolveRelatedInterface($definitions, $interface);
79 90
        }, $implements);
80
    }
81
82 57
    protected function resolveRelatedInterface(RawDefinitions $definitions, ?string $interface): ?Definition
83
    {
84 57
        if ($interface === null) {
85 57
            return null;
86
        }
87 54
        if (!$this->codebase->has($interface)) {
88 39
            $this->codebase->addInterface($this->buildInterface(
89 39
                $definitions,
90 39
                $definitions->get($interface)
91
            ));
92
        }
93 54
        return $this->codebase->get($interface);
94
    }
95
96 90
    protected function resolveParentClass(RawDefinitions $definitions, ?string $parent): ?Definition
97
    {
98 90
        if ($parent === null) {
99 90
            return null;
100
        }
101 54
        if (!$this->codebase->has($parent)) {
102 45
            $this->codebase->addClass($this->buildClass($definitions, $definitions->get($parent)));
103
        }
104 54
        return $this->codebase->get($parent);
105
    }
106
}
107