Passed
Pull Request — master (#315)
by Théo
02:54
created

AnnotationDumper::dump()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 11
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the box project.
7
 *
8
 * (c) Kevin Herrera <[email protected]>
9
 *     Théo Fidry <[email protected]>
10
 *
11
 * This source file is subject to the MIT license that is bundled
12
 * with this source code in the file LICENSE.
13
 */
14
15
namespace KevinGH\Box\Annotation;
16
17
use Assert\Assertion;
18
use Hoa\Compiler\Llk\TreeNode;
19
use InvalidArgumentException;
20
use function array_map;
21
use function array_shift;
22
use function array_values;
23
use function implode;
24
use function in_array;
25
use function sprintf;
26
27
final class AnnotationDumper
28
{
29
    /**
30
     * Dumps the list of annotations from the given tree.
31
     *
32
     * @return string[]
33
     */
34
    public function dump(TreeNode $node): array
35
    {
36
        if ('#annotations' !== $node->getId()) {
37
            return [];
38
        }
39
40
        return array_map(
41
            function (TreeNode $node): string {
42
                return $this->transformDataToString($node);
43
            },
44
            $node->getChildren()
45
        );
46
    }
47
48
    private function transformDataToString(TreeNode $node): string
49
    {
50
        if ('token' === $node->getId()) {
51
            if (in_array($node->getValueToken(), ['identifier', 'simple_identifier', 'integer', 'float', 'boolean', 'identifier_ns'], true)) {
52
                return $node->getValueValue();
53
            }
54
55
            if ('string' === $node->getValueToken()) {
56
                return sprintf('"%s"', $node->getValueValue());
57
            }
58
59
            if ('valued_identifier' === $node->getValueToken()) {
60
                return sprintf('%s()', $node->getValueValue());
61
            }
62
63
            throw new InvalidArgumentException(
64
                sprintf(
65
                    'Unknown token type "%s"',
66
                    $node->getValueToken()
67
                )
68
            );
69
        }
70
71
        if ('#parameters' === $node->getId()) {
72
            $transformedChildren = array_map(
73
                function (TreeNode $parameter): string {
74
                    return $this->transformDataToString($parameter);
75
                },
76
                $node->getChildren()
77
            );
78
79
            return implode(',', $transformedChildren);
80
        }
81
82
        if ('#named_parameter' === $node->getId() || '#pair' === $node->getId()) {
83
            Assertion::same($node->getChildrenNumber(), 2);
84
85
            $name = $node->getChild(0);
86
            $parameter = $node->getChild(1);
87
88
            return sprintf(
89
                '%s=%s',
90
                $this->transformDataToString($name),
91
                $this->transformDataToString($parameter)
92
            );
93
        }
94
95
        if ('#value' === $node->getId()) {
96
            Assertion::same($node->getChildrenNumber(), 1);
97
98
            return $this->transformDataToString($node->getChild(0));
99
        }
100
101
        if ('#string' === $node->getId()) {
102
            Assertion::lessOrEqualThan($node->getChildrenNumber(), 1);
103
104
            return 1 === $node->getChildrenNumber() ? $this->transformDataToString($node->getChild(0)) : '""';
105
        }
106
107
        if ('#list' === $node->getId() || '#map' === $node->getId()) {
108
            $transformedChildren = array_map(
109
                function (TreeNode $parameter): string {
110
                    return $this->transformDataToString($parameter);
111
                },
112
                $node->getChildren()
113
            );
114
115
            return sprintf(
116
                '{%s}',
117
                implode(
118
                    ',',
119
                    $transformedChildren
120
                )
121
            );
122
        }
123
124
        if ('#annotation' === $node->getId()) {
125
            Assertion::greaterOrEqualThan($node->getChildrenNumber(), 1);
126
127
            $children = $node->getChildren();
128
129
            /** @var TreeNode $token */
130
            $token = array_shift($children);
131
            $parameters = array_values($children);
132
133
            if ('simple_identifier' === $token->getValueToken()) {
134
                Assertion::count($parameters, 0);
135
136
                return '@'.$token->getValueValue();
137
            }
138
139
            if ('valued_identifier' === $token->getValueToken()) {
140
                $transformedChildren = array_map(
141
                    function (TreeNode $parameter): string {
142
                        return $this->transformDataToString($parameter);
143
                    },
144
                    $parameters
145
                );
146
147
                return sprintf(
148
                    '@%s(%s)',
149
                    $token->getValueValue(),
150
                    implode(
151
                        '',
152
                        $transformedChildren
153
                    )
154
                );
155
            }
156
        }
157
158
        if ('#unnamed_parameter' === $node->getId()) {
159
            Assertion::same($node->getChildrenNumber(), 1);
160
161
            return $this->transformDataToString($node->getChild(0));
162
        }
163
164
        if ('#reference' === $node->getId()) {
165
            Assertion::same($node->getChildrenNumber(), 1);
166
167
            return $this->transformDataToString($node->getChild(0));
168
        }
169
170
        if ('#constant' === $node->getId()) {
171
            Assertion::same($node->getChildrenNumber(), 2);
172
173
            return sprintf(
174
                '%s::%s',
175
                $this->transformDataToString($node->getChild(0)),
176
                $this->transformDataToString($node->getChild(1))
177
            );
178
        }
179
180
        $x = '';
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return string. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
Unused Code introduced by
The assignment to $x is dead and can be removed.
Loading history...
181
    }
182
}
183