Passed
Push — master ( 1416ae...b5a8b1 )
by Luis
54s queued 13s
created

TypeBuilder   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 33
dl 0
loc 83
ccs 38
cts 38
cp 1
rs 10
c 0
b 0
f 0
wmc 15
1
<?php declare(strict_types=1);
2
/**
3
 * PHP version 8.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\Code\Builders\Members;
9
10
use PhpParser\Comment\Doc;
11
use PhpParser\Node\ComplexType;
12
use PhpParser\Node\Identifier;
13
use PhpParser\Node\IntersectionType;
14
use PhpParser\Node\Name;
15
use PhpParser\Node\NullableType;
16
use PhpParser\Node\UnionType;
17
use PhUml\Code\UseStatements;
18
use PhUml\Code\Variables\CompositeType;
19
use PhUml\Code\Variables\TypeDeclaration;
20
use PhUml\Parser\Code\TypeResolver;
21
use RuntimeException;
22
23
final class TypeBuilder
24
{
25 59
    public function __construct(private readonly TypeResolver $typeResolver)
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_STRING, expecting T_VARIABLE on line 25 at column 49
Loading history...
26
    {
27
    }
28
29 25
    public function fromMethodParameter(
30
        Identifier|Name|ComplexType|null $type,
31
        ?Doc $docBlock,
32
        string $name,
33
        UseStatements $useStatements
34
    ): TypeDeclaration {
35 25
        $methodComment = $docBlock?->getText();
36 25
        if ($type === null) {
37 18
            return $this->typeResolver->resolveForParameter($methodComment, $name, $useStatements);
38
        }
39
40 22
        $typeDeclaration = $this->fromParsedType($type);
41 22
        if (! $typeDeclaration->isBuiltInArray()) {
42 21
            return $typeDeclaration;
43
        }
44
45 8
        $typeFromDocBlock = $this->typeResolver->resolveForParameter($methodComment, $name, $useStatements);
46
47 8
        return $typeFromDocBlock->isPresent() ? $typeFromDocBlock : $typeDeclaration;
48
    }
49
50 23
    public function fromMethodReturnType(
51
        Identifier|Name|ComplexType|null $type,
52
        ?Doc $docBlock,
53
        UseStatements $useStatements
54
    ): TypeDeclaration {
55 23
        $methodComment = $docBlock?->getText();
56 23
        if ($type === null) {
57 19
            return $this->typeResolver->resolveForReturn($methodComment, $useStatements);
58
        }
59
60 20
        $typeDeclaration = $this->fromParsedType($type);
61 20
        if (! $typeDeclaration->isBuiltInArray()) {
62 19
            return $typeDeclaration;
63
        }
64
65 2
        $typeFromDocBlock = $this->typeResolver->resolveForReturn($methodComment, $useStatements);
66
67 2
        return $typeFromDocBlock->isPresent() ? $typeFromDocBlock : $typeDeclaration;
68
    }
69
70 22
    public function fromPropertyType(
71
        Identifier|Name|ComplexType|null $type,
72
        ?Doc $docBlock,
73
        UseStatements $useStatements
74
    ): TypeDeclaration {
75 22
        $propertyComment = $docBlock?->getText();
76 22
        if ($type === null) {
77 18
            return $this->typeResolver->resolveForProperty($propertyComment, $useStatements);
78
        }
79
80 9
        $typeDeclaration = $this->fromParsedType($type);
81 9
        if (! $typeDeclaration->isBuiltInArray()) {
82 8
            return $typeDeclaration;
83
        }
84
85 2
        $typeFromDocBlock = $this->typeResolver->resolveForProperty($propertyComment, $useStatements);
86
87 2
        return $typeFromDocBlock->isPresent() ? $typeFromDocBlock : $typeDeclaration;
88
    }
89
90 31
    private function fromParsedType(Identifier|Name|ComplexType|null $type): TypeDeclaration
91
    {
92
        return match (true) {
93 31
            $type instanceof NullableType => TypeDeclaration::fromNullable((string) $type->type),
94 31
            $type instanceof Name, $type instanceof Identifier => TypeDeclaration::from((string) $type),
95 17
            $type === null => TypeDeclaration::absent(),
96 17
            $type instanceof UnionType => TypeDeclaration::fromCompositeType(
97 17
                $this->fromCompositeType($type),
98
                CompositeType::UNION
99
            ),
100 1
            $type instanceof IntersectionType => TypeDeclaration::fromCompositeType(
101 1
                $this->fromCompositeType($type),
102
                CompositeType::INTERSECTION
103
            ),
104 31
            default => throw new RuntimeException(sprintf('%s is not supported', $type::class)),
105
        };
106
    }
107
108
    /** @return string[] */
109 17
    private function fromCompositeType(UnionType|IntersectionType $type): array
110
    {
111 17
        return array_map(
112 17
            static fn (Identifier|Name $name): string => (string) $name,
113 17
            $type->types
114
        );
115
    }
116
}
117