Completed
Pull Request — master (#235)
by Kévin
03:13
created

CompiledExpression::canBeObject()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
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
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 888
    public function __construct($type = self::UNKNOWN, $value = null, Variable $variable = null)
122
    {
123 888
        $this->type = $type;
124 888
        $this->value = $value;
125 888
        $this->variable = $variable;
126 888
    }
127
128
    /**
129
     * Returns the value of the expression.
130
     *
131
     * @return mixed
132
     */
133 865
    public function getValue()
134
    {
135 865
        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 864
    public function getType()
155
    {
156 864
        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 1
     */
176
    public static function fromZvalValue($value)
177 1
    {
178
        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
    public function canBeObject()
187 596
    {
188
        return (boolean) ($this->type == self::OBJECT || $this->type & self::OBJECT);
189 596
    }
190
191
    /**
192
     * Returns debug info.
193
     *
194
     * @return array
195
     */
196
    public function __debugInfo()
197 1
    {
198
        return [
199 1
            'type' => \PHPSA\Compiler\Types::getTypeName($this->type),
200
            'value' => $this->value,
201
        ];
202
    }
203
204
    //@codeCoverageIgnoreStart
205
    /**
206
     * Check that $this->value is correct for $this->type
207 4
     *
208
     * @todo Implement it ;)
209
     * @return boolean
210 4
     */
211 4
    public function isCorrectValue()
212 4
    {
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
    public function isString()
244
    {
245
        return $this->type == self::STRING;
246
    }
247
248
    /**
249
     * @return bool
250
     */
251
    public function isTypeKnown()
252
    {
253
        return $this->type !== self::UNKNOWN;
254 10
    }
255
256 10
    /**
257
     * @return bool
258
     */
259
    public function isScalar()
260
    {
261
        return in_array($this->type, [self::STRING, self::BOOLEAN, self::DOUBLE, self::INTEGER, self::NUMBER], true);
262 293
    }
263
264 293
    /**
265
     * @return bool
266
     */
267
    public function isArray()
268
    {
269
        return $this->type === self::ARR;
270 26
    }
271
272 26
    /**
273
     * @return bool
274
     */
275
    public function isObject()
276
    {
277
        return $this->type == self::OBJECT;
278 54
    }
279
280 54
    /**
281
     * @return bool
282
     */
283
    public function isCallable()
284
    {
285
        return $this->type == self::CALLABLE_TYPE;
286 3
    }
287
288 3
    /**
289
     * @return bool
290
     */
291
    public function hasValue()
292
    {
293
        return $this->value !== null || $this->type === self::NULL;
294 10
    }
295
}
296