Completed
Pull Request — master (#235)
by Kévin
04:08 queued 20s
created

CompiledExpression   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 284
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 94.59%

Importance

Changes 0
Metric Value
dl 0
loc 284
ccs 35
cts 37
cp 0.9459
rs 10
c 0
b 0
f 0
wmc 25
lcom 1
cbo 1

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getValue() 0 4 1
A isEquals() 0 4 1
A getType() 0 4 1
A getTypeName() 0 4 1
A canBeObject() 0 4 2
A fromZvalValue() 0 4 1
A __debugInfo() 0 7 1
B isCorrectValue() 0 19 7
A getVariable() 0 4 1
A isString() 0 4 1
A isTypeKnown() 0 4 1
A isScalar() 0 4 1
A isArray() 0 4 1
A isObject() 0 4 1
A isCallable() 0 4 1
A hasValue() 0 4 2
1
<?php
2
/**
3
 * @author Patsura Dmitry https://github.com/ovr <[email protected]>
4
 */
5
6
namespace PHPSA;
7
8
use Ovr\PHPReflection\Types;
9
use PHPSA\Compiler\Types as CompilerTypes;
10
use RuntimeException;
11
12
class CompiledExpression
13
{
14
    /**
15
     * Unknown type
16
     */
17
    const UNKNOWN = Types::UNKNOWN_TYPE;
18
19
    /**
20
     * It's not unknown, It's unimplemented
21
     */
22
    const UNIMPLEMENTED = -100;
23
24
    /**
25
     * Void type
26
     */
27
    const VOID = Types::VOID_TYPE;
28
29
    /**
30
     * Integer type
31
     */
32
    const INTEGER = Types::INT_TYPE;
33
34
    /**
35
     * Double/Float type
36
     */
37
    const DOUBLE = Types::DOUBLE_TYPE;
38
39
    /**
40
     * Double/Float type
41
     */
42
    const NUMBER = Types::NUMBER;
43
44
    /**
45
     * String type
46
     */
47
    const STRING = Types::STRING_TYPE;
48
49
    /**
50
     * Boolean type
51
     * true or false
52
     */
53
    const BOOLEAN = Types::BOOLEAN_TYPE;
54
55
    /**
56
     * Array type
57
     */
58
    const ARR = Types::ARRAY_TYPE;
59
60
    /**
61
     * Object type
62
     */
63
    const OBJECT = Types::OBJECT_TYPE;
64
65
    /**
66
     * Resource handler type
67
     */
68
    const RESOURCE = Types::RESOURCE_TYPE;
69
70
    /**
71
     * Callable type
72
     */
73
    const CALLABLE_TYPE = Types::CALLABLE_TYPE;
74
75
    /**
76
     * Value is handled in variable
77
     */
78
    const VARIABLE = 512;
79
80
    /**
81
     * NULL type
82
     */
83
    const NULL = Types::NULL_TYPE;
84
85
    /**
86
     * self::INT_TYPE | self::DOUBLE_TYPE | self::STRING_TYPE | self::BOOLEAN_TYPE | self::ARRAY_TYPE | self::RESOURCE_TYPE | self::OBJECT_TYPE | self::NULL_TYPE
87
     */
88
    const MIXED = Types::MIXED;
89
90
    /**
91
     * I can't explain what it's :D
92
     */
93
    const DYNAMIC = 10000;
94
95
    /**
96
     * By default we don't know what it is
97
     *
98
     * @var int
99
     */
100
    protected $type;
101
102
    /**
103
     * Possible value
104
     *
105
     * @var mixed
106
     */
107
    protected $value;
108
109
    /**
110
     * @var Variable|null
111
     */
112
    protected $variable;
113
114
    /**
115
     * Construct new CompiledExpression to pass result
116
     *
117
     * @param int $type
118
     * @param mixed $value
119
     * @param Variable|null $variable
120
     */
121 887
    public function __construct($type = self::UNKNOWN, $value = null, Variable $variable = null)
122
    {
123 887
        $this->type = $type;
124 887
        $this->value = $value;
125 887
        $this->variable = $variable;
126 887
    }
127
128
    /**
129
     * Returns the value of the expression.
130
     *
131
     * @return mixed
132
     */
133 864
    public function getValue()
134
    {
135 864
        return $this->value;
136
    }
137
138
    /**
139
     * Checks whether the expressions value equals the given value.
140
     *
141
     * @param integer $value
142
     * @return boolean
143
     */
144 72
    public function isEquals($value)
145
    {
146 72
        return $this->value == $value;
147
    }
148
149
    /**
150
     * Returns the type of the expression.
151
     *
152
     * @return int
153
     */
154 863
    public function getType()
155
    {
156 863
        return $this->type;
157
    }
158
159
    /**
160
     * Returns the type of the expression as a string.
161
     *
162
     * @return string
163
     */
164 33
    public function getTypeName()
165
    {
166 33
        return CompilerTypes::getTypeName($this->type);
167
    }
168
169
    /**
170
     * If we don't know $type but know $value
171
     *
172
     * @param $value
173
     * @throws RuntimeException
174
     * @return CompiledExpression
175
     */
176 596
    public static function fromZvalValue($value)
177
    {
178 596
        return new CompiledExpression(CompilerTypes::getTypeByValue($value), $value);
179
    }
180
181
    /**
182
     * This is needed via in feature $this->type can store multiple type(s) by bitmask
183
     *
184
     * @return bool
185
     */
186 1
    public function canBeObject()
187
    {
188 1
        return (boolean) ($this->type == self::OBJECT || $this->type & self::OBJECT);
189
    }
190
191
    /**
192
     * Returns debug info.
193
     *
194
     * @return array
195
     */
196 4
    public function __debugInfo()
197
    {
198
        return [
199 4
            'type' => \PHPSA\Compiler\Types::getTypeName($this->type),
200 4
            'value' => $this->value,
201 4
        ];
202
    }
203
204
    //@codeCoverageIgnoreStart
205
    /**
206
     * Check that $this->value is correct for $this->type
207
     *
208
     * @todo Implement it ;)
209
     * @return boolean
210
     */
211
    public function isCorrectValue()
212
    {
213
        $type = gettype($this->value);
214
215
        switch ($this->type) {
216
            case CompiledExpression::INTEGER:
217
                return $type == 'integer';
218
            case CompiledExpression::NUMBER:
219
                return $type == 'integer' || $type == 'double';
220
            case CompiledExpression::DOUBLE:
221
                return $type == 'double';
222
            case CompiledExpression::BOOLEAN:
223
                return $type == 'boolean';
224
            case CompiledExpression::ARR:
225
                return $type == 'array';
226
        }
227
228
        return true;
229
    }
230
    //@codeCoverageIgnoreEnd
231
232
    /**
233
     * @return Variable|null
234
     */
235
    public function getVariable()
236
    {
237
        return $this->variable;
238
    }
239
240
    /**
241
     * @return bool
242
     */
243 45
    public function isString()
244
    {
245 45
        return $this->type == self::STRING;
246
    }
247
248
    /**
249
     * @return bool
250
     */
251 293
    public function isTypeKnown()
252
    {
253 293
        return $this->type !== self::UNKNOWN;
254
    }
255
256
    /**
257
     * @return bool
258
     */
259 26
    public function isScalar()
260
    {
261 26
        return in_array($this->type, [self::STRING, self::BOOLEAN, self::DOUBLE, self::INTEGER, self::NUMBER], true);
262
    }
263
264
    /**
265
     * @return bool
266
     */
267 54
    public function isArray()
268
    {
269 54
        return $this->type === self::ARR;
270
    }
271
272
    /**
273
     * @return bool
274
     */
275 3
    public function isObject()
276
    {
277 3
        return $this->type == self::OBJECT;
278
    }
279
280
    /**
281
     * @return bool
282
     */
283 10
    public function isCallable()
284
    {
285 10
        return $this->type == self::CALLABLE_TYPE;
286
    }
287
288
    /**
289
     * @return bool
290
     */
291 7
    public function hasValue()
292
    {
293 7
        return $this->value !== null || $this->type === self::NULL;
294
    }
295
}
296