Passed
Push — master ( 2dfc84...94e87c )
by Edward
05:17
created

Node::getIntAttribute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 8
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Remorhaz\UniLex\AST;
6
7
use Remorhaz\UniLex\Exception as UniLexException;
8
use Remorhaz\UniLex\Stack\StackableSymbolInterface;
9
10
use function chr;
11
use function is_array;
12
use function is_int;
13
14
class Node implements StackableSymbolInterface
15
{
16
17
    private $id;
18
19
    private $name;
20
21
    private $attributeMap = [];
22
23
    private $childMap = [];
24
25
    public function __construct(int $id, string $name)
26
    {
27
        $this->id = $id;
28
        $this->name = $name;
29
    }
30
31
    public function getId(): int
32
    {
33
        return $this->id;
34
    }
35
36
    public function getName(): string
37
    {
38
        return $this->name;
39
    }
40
41
    public function getClone(): self
42
    {
43
        $clone = clone $this;
44
        $clone->childMap = [];
45
        foreach ($this->getChildList() as $childNode) {
46
            $clone->addChild($childNode->getClone());
47
        }
48
49
        return $clone;
50
    }
51
52
    /**
53
     * @param string $name
54
     * @param        $value
55
     * @return Node
56
     * @throws UniLexException
57
     */
58
    public function setAttribute(string $name, $value): self
59
    {
60
        if (isset($this->attributeMap[$name])) {
61
            throw new UniLexException("Attribute '{$name}' is already defined in syntax tree node {$this->getId()}");
62
        }
63
        $this->attributeMap[$name] = $value;
64
65
        return $this;
66
    }
67
68
    /**
69
     * @param string $name
70
     * @return mixed
71
     * @throws UniLexException
72
     */
73
    public function getAttribute(string $name)
74
    {
75
        if (!isset($this->attributeMap[$name])) {
76
            throw new UniLexException("Attribute '{$name}' is not defined in syntax tree node {$this->getId()}");
77
        }
78
79
        return $this->attributeMap[$name];
80
    }
81
82
    /**
83
     * @param string $name
84
     * @return int
85
     * @throws UniLexException
86
     */
87
    public function getIntAttribute(string $name): int
88
    {
89
        $attribute = $this->getAttribute($name);
90
        if (is_int($attribute)) {
91
            return $attribute;
92
        }
93
94
        throw new Exception\InvalidAttributeException($name, $attribute, 'integer');
95
    }
96
97
    /**
98
     * @param string $name
99
     * @return string
100
     * @throws UniLexException
101
     */
102
    public function getStringAttribute(string $name): string
103
    {
104
        $attribute = $this->getAttribute($name);
105
        if (is_array($attribute)) {
106
            $string = '';
107
            foreach ($attribute as $symbol) {
108
                if (!is_int($symbol) || $symbol > 0xFF) {
109
                    throw new Exception\InvalidAttributeException($name, $attribute, 'integer[]');
110
                }
111
112
                $string .= chr($symbol);
113
            }
114
115
            return $string;
116
        }
117
118
        throw new Exception\InvalidAttributeException($name, $attribute, 'integer[]');
119
    }
120
121
    public function addChild(Node $node): self
122
    {
123
        $this->childMap[] = $node;
124
125
        return $this;
126
    }
127
128
    /**
129
     * @param int $index
130
     * @return Node
131
     * @throws UniLexException
132
     */
133
    public function getChild(int $index): Node
134
    {
135
        if (!isset($this->childMap[$index])) {
136
            throw new UniLexException("Child node at index {$index} in node {$this->getId()} is not defined");
137
        }
138
139
        return $this->childMap[$index];
140
    }
141
142
    /**
143
     * @return Node[]
144
     */
145
    public function getChildList(): array
146
    {
147
        return $this->childMap;
148
    }
149
150
    /**
151
     * @return int[]
152
     */
153
    public function getChildIndexList(): array
154
    {
155
        return array_keys($this->childMap);
156
    }
157
158
    public function getAttributeList(): array
159
    {
160
        return $this->attributeMap;
161
    }
162
}
163