CompiledExpression::toVariable()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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