Completed
Push — master ( e278ac...454097 )
by Edward
05:17
created

AstBuilder::aggregate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 6
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 8
ccs 0
cts 6
cp 0
crap 2
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace Remorhaz\JSON\Path\Query;
5
6
use Remorhaz\UniLex\AST\Tree;
7
use Remorhaz\UniLex\Exception as UniLexException;
8
9
final class AstBuilder implements AstBuilderInterface
10
{
11
12
    private $inputId;
13
14
    private $tree;
15
16
    public function __construct(Tree $tree)
17
    {
18
        $this->tree = $tree;
19
    }
20
21
    /**
22
     * @return int
23
     */
24
    public function getInput(): int
25
    {
26
        if (!isset($this->inputId)) {
27
            $this->inputId = $this
28
                ->tree
29
                ->createNode(AstNodeType::GET_INPUT)
30
                ->getId();
31
        }
32
33
        return $this->inputId;
34
    }
35
36
    /**
37
     * @param int $id
38
     * @param bool $isDefinite
39
     * @param bool $isAddressable
40
     * @throws UniLexException
41
     */
42
    public function setOutput(int $id, bool $isDefinite, bool $isAddressable): void
43
    {
44
        $setOutputNode = $this
45
            ->tree
46
            ->createNode(AstNodeType::SET_OUTPUT)
47
            ->addChild($this->tree->getNode($id))
48
            ->setAttribute('is_definite', $isDefinite)
49
            ->setAttribute('is_addressable', $isAddressable);
50
        $this
51
            ->tree
52
            ->setRootNode($setOutputNode);
53
    }
54
55
    /**
56
     * @param int $id
57
     * @return int
58
     * @throws UniLexException
59
     */
60
    public function fetchFilterContext(int $id): int
61
    {
62
        return $this
63
            ->tree
64
            ->createNode(AstNodeType::FETCH_FILTER_CONTEXT)
65
            ->addChild($this->tree->getNode($id))
66
            ->getId();
67
    }
68
69
    /**
70
     * @param int $id
71
     * @return int
72
     * @throws UniLexException
73
     */
74
    public function splitFilterContext(int $id): int
75
    {
76
        return $this
77
            ->tree
78
            ->createNode(AstNodeType::SPLIT_FILTER_CONTEXT)
79
            ->addChild($this->tree->getNode($id))
80
            ->getId();
81
    }
82
83
    /**
84
     * @param int $evaluatedId
85
     * @param int $contextId
86
     * @return int
87
     * @throws UniLexException
88
     */
89
    public function joinFilterResults(int $evaluatedId, int $contextId): int
90
    {
91
        return $this
92
            ->tree
93
            ->createNode(AstNodeType::JOIN_FILTER_RESULTS)
94
            ->addChild($this->tree->getNode($evaluatedId))
95
            ->addChild($this->tree->getNode($contextId))
96
            ->getId();
97
    }
98
99
    /**
100
     * @param int $sourceId
101
     * @param int $id
102
     * @return int
103
     * @throws UniLexException
104
     */
105
    public function evaluate(int $sourceId, int $id): int
106
    {
107
        return $this
108
            ->tree
109
            ->createNode(AstNodeType::EVALUATE)
110
            ->addChild($this->tree->getNode($sourceId))
111
            ->addChild($this->tree->getNode($id))
112
            ->getId();
113
    }
114
115
    /**
116
     * @param int $contextId
117
     * @param int $evaluatedId
118
     * @return int
119
     * @throws UniLexException
120
     */
121
    public function filter(int $contextId, int $evaluatedId): int
122
    {
123
        return $this
124
            ->tree
125
            ->createNode(AstNodeType::FILTER)
126
            ->addChild($this->tree->getNode($contextId))
127
            ->addChild($this->tree->getNode($evaluatedId))
128
            ->getId();
129
    }
130
131
    /**
132
     * @param int $leftEvaluatedId
133
     * @param int $rightEvaluatedId
134
     * @return int
135
     * @throws UniLexException
136
     */
137
    public function evaluateLogicalOr(int $leftEvaluatedId, int $rightEvaluatedId): int
138
    {
139
        return $this
140
            ->tree
141
            ->createNode(AstNodeType::EVALUATE_LOGICAL_OR)
142
            ->addChild($this->tree->getNode($leftEvaluatedId))
143
            ->addChild($this->tree->getNode($rightEvaluatedId))
144
            ->getId();
145
    }
146
147
    /**
148
     * @param int $leftEvaluatedId
149
     * @param int $rightEvaluatedId
150
     * @return int
151
     * @throws UniLexException
152
     */
153
    public function evaluateLogicalAnd(int $leftEvaluatedId, int $rightEvaluatedId): int
154
    {
155
        return $this
156
            ->tree
157
            ->createNode(AstNodeType::EVALUATE_LOGICAL_AND)
158
            ->addChild($this->tree->getNode($leftEvaluatedId))
159
            ->addChild($this->tree->getNode($rightEvaluatedId))
160
            ->getId();
161
    }
162
163
    /**
164
     * @param int $evaluatedId
165
     * @return int
166
     * @throws UniLexException
167
     */
168
    public function evaluateLogicalNot(int $evaluatedId): int
169
    {
170
        return $this
171
            ->tree
172
            ->createNode(AstNodeType::EVALUATE_LOGICAL_NOT)
173
            ->addChild($this->tree->getNode($evaluatedId))
174
            ->getId();
175
    }
176
177
    /**
178
     * @param int $leftId
179
     * @param int $rightId
180
     * @return int
181
     * @throws UniLexException
182
     */
183
    public function calculateIsEqual(int $leftId, int $rightId): int
184
    {
185
        return $this
186
            ->tree
187
            ->createNode(AstNodeType::CALCULATE_IS_EQUAL)
188
            ->addChild($this->tree->getNode($leftId))
189
            ->addChild($this->tree->getNode($rightId))
190
            ->getId();
191
    }
192
193
    /**
194
     * @param int $leftId
195
     * @param int $rightId
196
     * @return int
197
     * @throws UniLexException
198
     */
199
    public function calculateIsGreater(int $leftId, int $rightId): int
200
    {
201
        return $this
202
            ->tree
203
            ->createNode(AstNodeType::CALCULATE_IS_GREATER)
204
            ->addChild($this->tree->getNode($leftId))
205
            ->addChild($this->tree->getNode($rightId))
206
            ->getId();
207
    }
208
209
    /**
210
     * @param string $pattern
211
     * @param int $id
212
     * @return int
213
     * @throws UniLexException
214
     */
215
    public function calculateIsRegExp(string $pattern, int $id): int
216
    {
217
        return $this
218
            ->tree
219
            ->createNode(AstNodeType::CALCULATE_IS_REGEXP)
220
            ->addChild($this->tree->getNode($id))
221
            ->setAttribute('pattern', $pattern)
222
            ->getId();
223
    }
224
225
    /**
226
     * @param int $id
227
     * @param int $matcherId
228
     * @return int
229
     * @throws UniLexException
230
     */
231
    public function fetchChildren(int $id, int $matcherId): int
232
    {
233
        return $this
234
            ->tree
235
            ->createNode(AstNodeType::FETCH_CHILDREN)
236
            ->addChild($this->tree->getNode($id))
237
            ->addChild($this->tree->getNode($matcherId))
238
            ->getId();
239
    }
240
241
    /**
242
     * @param int $id
243
     * @param int $matcherId
244
     * @return int
245
     * @throws UniLexException
246
     */
247
    public function fetchChildrenDeep(int $id, int $matcherId): int
248
    {
249
        return $this
250
            ->tree
251
            ->createNode(AstNodeType::FETCH_CHILDREN_DEEP)
252
            ->addChild($this->tree->getNode($id))
253
            ->addChild($this->tree->getNode($matcherId))
254
            ->getId();
255
    }
256
257
    /**
258
     * @param int ...$idList
259
     * @return int
260
     * @throws UniLexException
261
     */
262
    public function merge(int ...$idList): int
263
    {
264
        $node = $this
265
            ->tree
266
            ->createNode(AstNodeType::MERGE);
267
        foreach ($idList as $id) {
268
            $node->addChild($this->tree->getNode($id));
269
        }
270
271
        return $node->getId();
272
    }
273
274
    /**
275
     * @return int
276
     */
277
    public function matchAnyChild(): int
278
    {
279
        return $this
280
            ->tree
281
            ->createNode(AstNodeType::MATCH_ANY_CHILD)
282
            ->getId();
283
    }
284
285
    /**
286
     * @param string ...$names
287
     * @return int
288
     * @throws UniLexException
289
     */
290
    public function matchPropertyStrictly(string ...$names): int
291
    {
292
        return $this
293
            ->tree
294
            ->createNode(AstNodeType::MATCH_PROPERTY_STRICTLY)
295
            ->setAttribute('names', $names)
296
            ->getId();
297
    }
298
299
    /**
300
     * @param int ...$indexes
301
     * @return int
302
     * @throws UniLexException
303
     */
304
    public function matchElementStrictly(int ...$indexes): int
305
    {
306
        return $this
307
            ->tree
308
            ->createNode(AstNodeType::MATCH_ELEMENT_STRICTLY)
309
            ->setAttribute('indexes', $indexes)
310
            ->getId();
311
    }
312
313
    /**
314
     * @param int|null $start
315
     * @param int|null $end
316
     * @param int|null $step
317
     * @return int
318
     * @throws UniLexException
319
     */
320
    public function matchElementSlice(?int $start, ?int $end, ?int $step): int
321
    {
322
        return $this
323
            ->tree
324
            ->createNode(AstNodeType::MATCH_ELEMENT_SLICE)
325
            ->setAttribute('hasStart', isset($start))
326
            ->setAttribute('start', $start)
327
            ->setAttribute('hasEnd', isset($end))
328
            ->setAttribute('end', $end)
329
            ->setAttribute('step', $step ?? 1)
330
            ->getId();
331
    }
332
333
    /**
334
     * @param string $name
335
     * @param int $id
336
     * @return int
337
     * @throws UniLexException
338
     */
339
    public function aggregate(string $name, int $id): int
340
    {
341
        return $this
342
            ->tree
343
            ->createNode(AstNodeType::AGGREGATE)
344
            ->addChild($this->tree->getNode($id))
345
            ->setAttribute('name', $name)
346
            ->getId();
347
    }
348
349
    /**
350
     * @param int $sourceId
351
     * @param mixed $value
352
     * @return int
353
     * @throws UniLexException
354
     */
355
    public function createScalar(int $sourceId, $value): int
356
    {
357
        return $this
358
            ->tree
359
            ->createNode(AstNodeType::CREATE_LITERAL_SCALAR)
360
            ->setAttribute('value', $value)
361
            ->addChild($this->tree->getNode($sourceId))
362
            ->getId();
363
    }
364
365
    /**
366
     * @param int $sourceId
367
     * @param int $arrayId
368
     * @return int
369
     * @throws UniLexException
370
     */
371
    public function createLiteralArray(int $sourceId, int $arrayId): int
372
    {
373
        return $this
374
            ->tree
375
            ->createNode(AstNodeType::CREATE_LITERAL_ARRAY)
376
            ->addChild($this->tree->getNode($sourceId))
377
            ->addChild($this->tree->getNode($arrayId))
378
            ->getId();
379
    }
380
381
    public function createArray(): int
382
    {
383
        return $this
384
            ->tree
385
            ->createNode(AstNodeType::CREATE_ARRAY)
386
            ->getId();
387
    }
388
389
    /**
390
     * @param int $arrayId
391
     * @param int $valueId
392
     * @return int
393
     * @throws UniLexException
394
     */
395
    public function appendToArray(int $arrayId, int $valueId): int
396
    {
397
        $appendNode = $this
398
            ->tree
399
            ->createNode(AstNodeType::APPEND_TO_ARRAY)
400
            ->addChild($this->tree->getNode($valueId));
401
402
        return $this
403
            ->tree
404
            ->getNode($arrayId)
405
            ->addChild($appendNode)
406
            ->getId();
407
    }
408
}
409