Completed
Push — 2.0 ( b09486...6b5a44 )
by Peter
07:34 queued 13s
created

Spec   C

Complexity

Total Complexity 56

Size/Duplication

Total Lines 611
Duplicated Lines 4.26 %

Coupling/Cohesion

Components 0
Dependencies 47

Importance

Changes 0
Metric Value
wmc 56
lcom 0
cbo 47
dl 26
loc 611
rs 5.509
c 0
b 0
f 0

51 Methods

Rating   Name   Duplication   Size   Complexity  
A __callStatic() 0 12 3
A not() 0 4 1
A andX() 13 14 2
A orX() 13 14 2
A join() 0 4 1
A leftJoin() 0 4 1
A innerJoin() 0 4 1
A indexBy() 0 4 1
A limit() 0 4 1
A offset() 0 4 1
A slice() 0 4 1
A orderBy() 0 4 1
A groupBy() 0 4 1
A distinct() 0 4 1
A select() 0 5 1
A addSelect() 0 5 1
A selectEntity() 0 4 1
A selectAs() 0 4 1
A selectHiddenAs() 0 4 1
A asArray() 0 4 1
A asSingleScalar() 0 4 1
A asScalar() 0 4 1
A cache() 0 4 1
A roundDateTimeParams() 0 4 1
A isNull() 0 4 1
A isNotNull() 0 4 1
A in() 0 4 1
A notIn() 0 4 1
A eq() 0 4 1
A neq() 0 4 1
A lt() 0 4 1
A lte() 0 4 1
A gt() 0 4 1
A gte() 0 4 1
A like() 0 4 1
A instanceOfX() 0 4 1
A memberOfX() 0 4 1
A countOf() 0 4 1
A having() 0 4 1
A field() 0 4 1
A value() 0 4 1
A values() 0 4 1
A likePattern() 0 4 1
A countDistinct() 0 4 1
A add() 0 4 1
A sub() 0 4 1
A mul() 0 4 1
A div() 0 4 1
A mod() 0 4 1
A fun() 0 12 2
A alias() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Spec often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Spec, and based on these observations, apply Extract Interface, too.

1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of the Happyr Doctrine Specification package.
6
 *
7
 * (c) Tobias Nyholm <[email protected]>
8
 *     Kacper Gunia <[email protected]>
9
 *     Peter Gribanov <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Happyr\DoctrineSpecification;
16
17
use Happyr\DoctrineSpecification\Filter\Equals;
18
use Happyr\DoctrineSpecification\Filter\Filter;
19
use Happyr\DoctrineSpecification\Filter\GreaterOrEqualThan;
20
use Happyr\DoctrineSpecification\Filter\GreaterThan;
21
use Happyr\DoctrineSpecification\Filter\In;
22
use Happyr\DoctrineSpecification\Filter\InstanceOfX;
23
use Happyr\DoctrineSpecification\Filter\IsNotNull;
24
use Happyr\DoctrineSpecification\Filter\IsNull;
25
use Happyr\DoctrineSpecification\Filter\LessOrEqualThan;
26
use Happyr\DoctrineSpecification\Filter\LessThan;
27
use Happyr\DoctrineSpecification\Filter\Like;
28
use Happyr\DoctrineSpecification\Filter\MemberOfX;
29
use Happyr\DoctrineSpecification\Filter\NotEquals;
30
use Happyr\DoctrineSpecification\Logic\AndX;
31
use Happyr\DoctrineSpecification\Logic\Not;
32
use Happyr\DoctrineSpecification\Logic\OrX;
33
use Happyr\DoctrineSpecification\Operand\Addition;
34
use Happyr\DoctrineSpecification\Operand\Alias;
35
use Happyr\DoctrineSpecification\Operand\CountDistinct;
36
use Happyr\DoctrineSpecification\Operand\Division;
37
use Happyr\DoctrineSpecification\Operand\Field;
38
use Happyr\DoctrineSpecification\Operand\LikePattern;
39
use Happyr\DoctrineSpecification\Operand\Modulo;
40
use Happyr\DoctrineSpecification\Operand\Multiplication;
41
use Happyr\DoctrineSpecification\Operand\Operand;
42
use Happyr\DoctrineSpecification\Operand\PlatformFunction;
43
use Happyr\DoctrineSpecification\Operand\Subtraction;
44
use Happyr\DoctrineSpecification\Operand\Value;
45
use Happyr\DoctrineSpecification\Operand\Values;
46
use Happyr\DoctrineSpecification\Query\AddSelect;
47
use Happyr\DoctrineSpecification\Query\Distinct;
48
use Happyr\DoctrineSpecification\Query\GroupBy;
49
use Happyr\DoctrineSpecification\Query\Having;
50
use Happyr\DoctrineSpecification\Query\IndexBy;
51
use Happyr\DoctrineSpecification\Query\InnerJoin;
52
use Happyr\DoctrineSpecification\Query\Join;
53
use Happyr\DoctrineSpecification\Query\LeftJoin;
54
use Happyr\DoctrineSpecification\Query\Limit;
55
use Happyr\DoctrineSpecification\Query\Offset;
56
use Happyr\DoctrineSpecification\Query\OrderBy;
57
use Happyr\DoctrineSpecification\Query\QueryModifier;
58
use Happyr\DoctrineSpecification\Query\Select;
59
use Happyr\DoctrineSpecification\Query\Selection\SelectAs;
60
use Happyr\DoctrineSpecification\Query\Selection\SelectEntity;
61
use Happyr\DoctrineSpecification\Query\Selection\SelectHiddenAs;
62
use Happyr\DoctrineSpecification\Query\Slice;
63
use Happyr\DoctrineSpecification\Result\AsArray;
64
use Happyr\DoctrineSpecification\Result\AsScalar;
65
use Happyr\DoctrineSpecification\Result\AsSingleScalar;
66
use Happyr\DoctrineSpecification\Result\Cache;
67
use Happyr\DoctrineSpecification\Result\RoundDateTime;
68
use Happyr\DoctrineSpecification\Specification\CountOf;
69
70
/**
71
 * Factory class for the specifications.
72
 *
73
 * @method static PlatformFunction CONCAT($str1, $str2)
74
 * @method static PlatformFunction SUBSTRING($str, $start, $length = null) Return substring of given string.
75
 * @method static PlatformFunction TRIM($str) Trim the string by the given trim char, defaults to whitespaces.
76
 * @method static PlatformFunction LOWER($str) Returns the string lowercased.
77
 * @method static PlatformFunction UPPER($str) Return the upper-case of the given string.
78
 * @method static PlatformFunction IDENTITY($expression, $fieldMapping = null) Retrieve the foreign key column of association of the owning side
79
 * @method static PlatformFunction LENGTH($str) Returns the length of the given string
80
 * @method static PlatformFunction LOCATE($needle, $haystack, $offset = 0) Locate the first occurrence of the substring in the string.
81
 * @method static PlatformFunction ABS($expression)
82
 * @method static PlatformFunction SQRT($q) Return the square-root of q.
83
 * @method static PlatformFunction MOD($a, $b) Return a MOD b.
84
 * @method static PlatformFunction SIZE($collection) Return the number of elements in the specified collection
85
 * @method static PlatformFunction DATE_DIFF($date1, $date2) Calculate the difference in days between date1-date2.
86
 * @method static PlatformFunction BIT_AND($a, $b)
87
 * @method static PlatformFunction BIT_OR($a, $b)
88
 * @method static PlatformFunction MIN($a)
89
 * @method static PlatformFunction MAX($a)
90
 * @method static PlatformFunction AVG($a)
91
 * @method static PlatformFunction SUM($a)
92
 * @method static PlatformFunction COUNT($a)
93
 * @method static PlatformFunction CURRENT_DATE() Return the current date
94
 * @method static PlatformFunction CURRENT_TIME() Returns the current time
95
 * @method static PlatformFunction CURRENT_TIMESTAMP() Returns a timestamp of the current date and time.
96
 * @method static PlatformFunction DATE_ADD($date, $days, $unit) Add the number of days to a given date. (Supported units are DAY, MONTH)
97
 * @method static PlatformFunction DATE_SUB($date, $days, $unit) Substract the number of days from a given date. (Supported units are DAY, MONTH)
98
 */
99
class Spec
100
{
101
    /**
102
     * @param string $name
103
     * @param array  $arguments
104
     *
105
     * @return PlatformFunction
106
     */
107
    public static function __callStatic($name, array $arguments = [])
108
    {
109
        // allow use array in arguments of static function
110
        // Spec::DATE_DIFF([$date1, $date2]);
111
        // is equal
112
        // Spec::DATE_DIFF($date1, $date2);
113
        if (1 === count($arguments) && is_array(current($arguments))) {
114
            $arguments = current($arguments);
115
        }
116
117
        return self::fun($name, $arguments);
118
    }
119
120
    // Logic
121
122
    /**
123
     * @return AndX
124
     */
125 View Code Duplication
    public static function andX()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
    {
127
        // NEXT_MAJOR: use variable-length argument lists (...$specs)
128
        $spec = (new \ReflectionClass(AndX::class))->newInstanceArgs(func_get_args());
129
130
        // hook for PHPStan
131
        if (!($spec instanceof AndX)) {
132
            throw new \RuntimeException(
133
                sprintf('The specification must be an instance of "%s", but got "%s".', AndX::class, get_class($spec))
134
            );
135
        }
136
137
        return $spec;
138
    }
139
140
    /**
141
     * @return OrX
142
     */
143 View Code Duplication
    public static function orX()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
144
    {
145
        // NEXT_MAJOR: use variable-length argument lists (...$specs)
146
        $spec = (new \ReflectionClass(OrX::class))->newInstanceArgs(func_get_args());
147
148
        // hook for PHPStan
149
        if (!($spec instanceof OrX)) {
150
            throw new \RuntimeException(
151
                sprintf('The specification must be an instance of "%s", but got "%s".', OrX::class, get_class($spec))
152
            );
153
        }
154
155
        return $spec;
156
    }
157
158
    /**
159
     * @param Filter $spec
160
     *
161
     * @return Not
162
     */
163
    public static function not(Filter $spec)
164
    {
165
        return new Not($spec);
166
    }
167
168
    // Query modifier
169
170
    /**
171
     * @param string      $field
172
     * @param string      $newAlias
173
     * @param string|null $dqlAlias
174
     *
175
     * @return Join
176
     */
177
    public static function join($field, $newAlias, $dqlAlias = null)
178
    {
179
        return new Join($field, $newAlias, $dqlAlias);
180
    }
181
182
    /**
183
     * @param string      $field
184
     * @param string      $newAlias
185
     * @param string|null $dqlAlias
186
     *
187
     * @return LeftJoin
188
     */
189
    public static function leftJoin($field, $newAlias, $dqlAlias = null)
190
    {
191
        return new LeftJoin($field, $newAlias, $dqlAlias);
192
    }
193
194
    /**
195
     * @param string      $field
196
     * @param string      $newAlias
197
     * @param string|null $dqlAlias
198
     *
199
     * @return InnerJoin
200
     */
201
    public static function innerJoin($field, $newAlias, $dqlAlias = null)
202
    {
203
        return new InnerJoin($field, $newAlias, $dqlAlias);
204
    }
205
206
    /**
207
     * @param Field|string $field
208
     * @param string|null  $dqlAlias
209
     *
210
     * @return IndexBy
211
     */
212
    public static function indexBy($field, $dqlAlias = null)
213
    {
214
        return new IndexBy($field, $dqlAlias);
215
    }
216
217
    /**
218
     * @param int $count
219
     *
220
     * @return Limit
221
     */
222
    public static function limit($count)
223
    {
224
        return new Limit($count);
225
    }
226
227
    /**
228
     * @param int $count
229
     *
230
     * @return Offset
231
     */
232
    public static function offset($count)
233
    {
234
        return new Offset($count);
235
    }
236
237
    /**
238
     * @param int $sliceSize
239
     * @param int $sliceNumber
240
     *
241
     * @return Slice
242
     */
243
    public static function slice($sliceSize, $sliceNumber = 0)
244
    {
245
        return new Slice($sliceSize, $sliceNumber);
246
    }
247
248
    /**
249
     * @param Field|Alias|string $field
250
     * @param string             $order
251
     * @param string|null        $dqlAlias
252
     *
253
     * @return OrderBy
254
     */
255
    public static function orderBy($field, $order = 'ASC', $dqlAlias = null)
256
    {
257
        return new OrderBy($field, $order, $dqlAlias);
258
    }
259
260
    /**
261
     * @param Field|Alias|string $field
262
     * @param string|null        $dqlAlias
263
     *
264
     * @return GroupBy
265
     */
266
    public static function groupBy($field, $dqlAlias = null)
267
    {
268
        return new GroupBy($field, $dqlAlias);
269
    }
270
271
    /**
272
     * @return Distinct
273
     */
274
    public static function distinct()
275
    {
276
        return new Distinct();
277
    }
278
279
    // Selection
280
281
    /**
282
     * @param mixed $field
283
     *
284
     * @return Select
285
     */
286
    public static function select($field)
0 ignored issues
show
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
287
    {
288
        // NEXT_MAJOR: use variable-length argument lists (...$fields)
289
        return new Select(func_get_args());
290
    }
291
292
    /**
293
     * @param mixed $field
294
     *
295
     * @return AddSelect
296
     */
297
    public static function addSelect($field)
0 ignored issues
show
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
298
    {
299
        // NEXT_MAJOR: use variable-length argument lists (...$fields)
300
        return new AddSelect(func_get_args());
301
    }
302
303
    /**
304
     * @param string $dqlAlias
305
     *
306
     * @return SelectEntity
307
     */
308
    public static function selectEntity($dqlAlias)
309
    {
310
        return new SelectEntity($dqlAlias);
311
    }
312
313
    /**
314
     * @param Filter|Operand|string $expression
315
     * @param string                $alias
316
     *
317
     * @return SelectAs
318
     */
319
    public static function selectAs($expression, $alias)
320
    {
321
        return new SelectAs($expression, $alias);
322
    }
323
324
    /**
325
     * @param Filter|Operand|string $expression
326
     * @param string                $alias
327
     *
328
     * @return SelectHiddenAs
329
     */
330
    public static function selectHiddenAs($expression, $alias)
331
    {
332
        return new SelectHiddenAs($expression, $alias);
333
    }
334
335
    // Result modifier
336
337
    /**
338
     * @return AsArray
339
     */
340
    public static function asArray()
341
    {
342
        return new AsArray();
343
    }
344
345
    /**
346
     * @return AsSingleScalar
347
     */
348
    public static function asSingleScalar()
349
    {
350
        return new AsSingleScalar();
351
    }
352
353
    /**
354
     * @return AsScalar
355
     */
356
    public static function asScalar()
357
    {
358
        return new AsScalar();
359
    }
360
361
    /**
362
     * @param int $cacheLifetime How many seconds the cached entry is valid
363
     *
364
     * @return Cache
365
     */
366
    public static function cache($cacheLifetime)
367
    {
368
        return new Cache($cacheLifetime);
369
    }
370
371
    /**
372
     * @param int $roundSeconds How may seconds to round time
373
     *
374
     * @return RoundDateTime
375
     */
376
    public static function roundDateTimeParams($roundSeconds)
377
    {
378
        return new RoundDateTime($roundSeconds);
379
    }
380
381
    // Filters
382
383
    /**
384
     * @param Operand|string $field
385
     * @param string|null    $dqlAlias
386
     *
387
     * @return IsNull
388
     */
389
    public static function isNull($field, $dqlAlias = null)
390
    {
391
        return new IsNull($field, $dqlAlias);
392
    }
393
394
    /**
395
     * @param Operand|string $field
396
     * @param string|null    $dqlAlias
397
     *
398
     * @return IsNotNull
399
     */
400
    public static function isNotNull($field, $dqlAlias = null)
401
    {
402
        return new IsNotNull($field, $dqlAlias);
403
    }
404
405
    /**
406
     * Make sure the $field has a value equals to $value.
407
     *
408
     * @param Operand|string $field
409
     * @param Operand|mixed  $value
410
     * @param string|null    $dqlAlias
411
     *
412
     * @return In
413
     */
414
    public static function in($field, $value, $dqlAlias = null)
415
    {
416
        return new In($field, $value, $dqlAlias);
417
    }
418
419
    /**
420
     * @param Operand|string $field
421
     * @param Operand|mixed  $value
422
     * @param string|null    $dqlAlias
423
     *
424
     * @return Not
425
     */
426
    public static function notIn($field, $value, $dqlAlias = null)
427
    {
428
        return new Not(new In($field, $value, $dqlAlias));
429
    }
430
431
    /**
432
     * @param Operand|string $field
433
     * @param Operand|mixed  $value
434
     * @param string|null    $dqlAlias
435
     *
436
     * @return Equals
437
     */
438
    public static function eq($field, $value, $dqlAlias = null)
439
    {
440
        return new Equals($field, $value, $dqlAlias);
441
    }
442
443
    /**
444
     * @param Operand|string $field
445
     * @param Operand|mixed  $value
446
     * @param string|null    $dqlAlias
447
     *
448
     * @return NotEquals
449
     */
450
    public static function neq($field, $value, $dqlAlias = null)
451
    {
452
        return new NotEquals($field, $value, $dqlAlias);
453
    }
454
455
    /**
456
     * @param Operand|string $field
457
     * @param Operand|mixed  $value
458
     * @param string|null    $dqlAlias
459
     *
460
     * @return LessThan
461
     */
462
    public static function lt($field, $value, $dqlAlias = null)
463
    {
464
        return new LessThan($field, $value, $dqlAlias);
465
    }
466
467
    /**
468
     * @param Operand|string $field
469
     * @param Operand|mixed  $value
470
     * @param string|null    $dqlAlias
471
     *
472
     * @return LessOrEqualThan
473
     */
474
    public static function lte($field, $value, $dqlAlias = null)
475
    {
476
        return new LessOrEqualThan($field, $value, $dqlAlias);
477
    }
478
479
    /**
480
     * @param Operand|string $field
481
     * @param Operand|mixed  $value
482
     * @param string|null    $dqlAlias
483
     *
484
     * @return GreaterThan
485
     */
486
    public static function gt($field, $value, $dqlAlias = null)
487
    {
488
        return new GreaterThan($field, $value, $dqlAlias);
489
    }
490
491
    /**
492
     * @param Operand|string $field
493
     * @param Operand|mixed  $value
494
     * @param string|null    $dqlAlias
495
     *
496
     * @return GreaterOrEqualThan
497
     */
498
    public static function gte($field, $value, $dqlAlias = null)
499
    {
500
        return new GreaterOrEqualThan($field, $value, $dqlAlias);
501
    }
502
503
    /**
504
     * @param Operand|string     $field
505
     * @param LikePattern|string $value
506
     * @param string             $format
507
     * @param string|null        $dqlAlias
508
     *
509
     * @return Like
510
     */
511
    public static function like($field, $value, $format = Like::CONTAINS, $dqlAlias = null)
512
    {
513
        return new Like($field, $value, $format, $dqlAlias);
514
    }
515
516
    /**
517
     * @param string      $value
518
     * @param string|null $dqlAlias
519
     *
520
     * @return InstanceOfX
521
     */
522
    public static function instanceOfX($value, $dqlAlias = null)
523
    {
524
        return new InstanceOfX($value, $dqlAlias);
525
    }
526
527
    /**
528
     * @param Operand|string $value
529
     * @param Operand|string $field
530
     * @param string|null    $dqlAlias
531
     *
532
     * @return MemberOfX
533
     */
534
    public static function memberOfX($value, $field, $dqlAlias = null)
535
    {
536
        return new MemberOfX($value, $field, $dqlAlias);
537
    }
538
539
    // Specifications
540
541
    /**
542
     * @param Filter|QueryModifier $spec
543
     *
544
     * @return CountOf
545
     */
546
    public static function countOf($spec)
547
    {
548
        return new CountOf($spec);
549
    }
550
551
    /**
552
     * @param Filter $spec
553
     *
554
     * @return Having
555
     */
556
    public static function having(Filter $spec)
557
    {
558
        return new Having($spec);
559
    }
560
561
    // Operands
562
563
    /**
564
     * @param string      $fieldName
565
     * @param string|null $dqlAlias
566
     *
567
     * @return Field
568
     */
569
    public static function field($fieldName, $dqlAlias = null)
570
    {
571
        return new Field($fieldName, $dqlAlias);
572
    }
573
574
    /**
575
     * @param mixed           $value
576
     * @param int|string|null $valueType
577
     *
578
     * @return Value
579
     */
580
    public static function value($value, $valueType = null)
581
    {
582
        return new Value($value, $valueType);
583
    }
584
585
    /**
586
     * @param array           $values
587
     * @param int|string|null $valueType
588
     *
589
     * @return Values
590
     */
591
    public static function values($values, $valueType = null)
592
    {
593
        return new Values($values, $valueType);
594
    }
595
596
    /**
597
     * @param string $value
598
     * @param string $format
599
     *
600
     * @return LikePattern
601
     */
602
    public static function likePattern($value, $format = LikePattern::CONTAINS)
603
    {
604
        return new LikePattern($value, $format);
605
    }
606
607
    /**
608
     * @param Operand|string $field
609
     *
610
     * @return CountDistinct
611
     */
612
    public static function countDistinct($field)
613
    {
614
        return new CountDistinct($field);
615
    }
616
617
    // Arithmetic operands
618
619
    /**
620
     * @param Operand|string $field
621
     * @param Operand|mixed  $value
622
     *
623
     * @return Addition
624
     */
625
    public static function add($field, $value)
626
    {
627
        return new Addition($field, $value);
628
    }
629
630
    /**
631
     * @param Operand|string $field
632
     * @param Operand|mixed  $value
633
     *
634
     * @return Subtraction
635
     */
636
    public static function sub($field, $value)
637
    {
638
        return new Subtraction($field, $value);
639
    }
640
641
    /**
642
     * @param Operand|string $field
643
     * @param Operand|mixed  $value
644
     *
645
     * @return Multiplication
646
     */
647
    public static function mul($field, $value)
648
    {
649
        return new Multiplication($field, $value);
650
    }
651
652
    /**
653
     * @param Operand|string $field
654
     * @param Operand|mixed  $value
655
     *
656
     * @return Division
657
     */
658
    public static function div($field, $value)
659
    {
660
        return new Division($field, $value);
661
    }
662
663
    /**
664
     * @param Operand|string $field
665
     * @param Operand|mixed  $value
666
     *
667
     * @return Modulo
668
     */
669
    public static function mod($field, $value)
670
    {
671
        return new Modulo($field, $value);
672
    }
673
674
    /**
675
     * Call DQL function.
676
     *
677
     * Usage:
678
     *  Spec::fun('CURRENT_DATE')
679
     *  Spec::fun('DATE_DIFF', $date1, $date2)
680
     *  Spec::fun('DATE_DIFF', [$date1, $date2])
681
     *
682
     * @param string $functionName
683
     * @param mixed  $arguments
684
     *
685
     * @return PlatformFunction
686
     */
687
    public static function fun($functionName, $arguments = [])
688
    {
689
        // NEXT_MAJOR: use variable-length argument lists ($functionName, ...$arguments)
690
        if (2 === func_num_args()) {
691
            $arguments = (array) $arguments;
692
        } else {
693
            $arguments = func_get_args();
694
            $functionName = array_shift($arguments);
695
        }
696
697
        return new PlatformFunction($functionName, $arguments);
698
    }
699
700
    /**
701
     * @param string $alias
702
     *
703
     * @return Alias
704
     */
705
    public static function alias($alias)
706
    {
707
        return new Alias($alias);
708
    }
709
}
710