1<?php
2/*
3 * This file is part of php-token-stream.
4 *
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11/**
12 * A PHP token.
13 */
14abstract class PHP_Token
15{
16    /**
17     * @var string
18     */
19    protected $text;
20
21    /**
22     * @var int
23     */
24    protected $line;
25
26    /**
27     * @var PHP_Token_Stream
28     */
29    protected $tokenStream;
30
31    /**
32     * @var int
33     */
34    protected $id;
35
36    /**
37     * @param string           $text
38     * @param int              $line
39     * @param PHP_Token_Stream $tokenStream
40     * @param int              $id
41     */
42    public function __construct($text, $line, PHP_Token_Stream $tokenStream, $id)
43    {
44        $this->text        = $text;
45        $this->line        = $line;
46        $this->tokenStream = $tokenStream;
47        $this->id          = $id;
48    }
49
50    /**
51     * @return string
52     */
53    public function __toString()
54    {
55        return $this->text;
56    }
57
58    /**
59     * @return int
60     */
61    public function getLine()
62    {
63        return $this->line;
64    }
65
66    /**
67     * @return int
68     */
69    public function getId()
70    {
71        return $this->id;
72    }
73}
74
75abstract class PHP_TokenWithScope extends PHP_Token
76{
77    /**
78     * @var int
79     */
80    protected $endTokenId;
81
82    /**
83     * Get the docblock for this token
84     *
85     * This method will fetch the docblock belonging to the current token. The
86     * docblock must be placed on the line directly above the token to be
87     * recognized.
88     *
89     * @return string|null Returns the docblock as a string if found
90     */
91    public function getDocblock()
92    {
93        $tokens            = $this->tokenStream->tokens();
94        $currentLineNumber = $tokens[$this->id]->getLine();
95        $prevLineNumber    = $currentLineNumber - 1;
96
97        for ($i = $this->id - 1; $i; $i--) {
98            if (!isset($tokens[$i])) {
99                return;
100            }
101
102            if ($tokens[$i] instanceof PHP_Token_FUNCTION ||
103                $tokens[$i] instanceof PHP_Token_CLASS ||
104                $tokens[$i] instanceof PHP_Token_TRAIT) {
105                // Some other trait, class or function, no docblock can be
106                // used for the current token
107                break;
108            }
109
110            $line = $tokens[$i]->getLine();
111
112            if ($line == $currentLineNumber ||
113                ($line == $prevLineNumber &&
114                 $tokens[$i] instanceof PHP_Token_WHITESPACE)) {
115                continue;
116            }
117
118            if ($line < $currentLineNumber &&
119                !$tokens[$i] instanceof PHP_Token_DOC_COMMENT) {
120                break;
121            }
122
123            return (string) $tokens[$i];
124        }
125    }
126
127    /**
128     * @return int
129     */
130    public function getEndTokenId()
131    {
132        $block  = 0;
133        $i      = $this->id;
134        $tokens = $this->tokenStream->tokens();
135
136        while ($this->endTokenId === null && isset($tokens[$i])) {
137            if ($tokens[$i] instanceof PHP_Token_OPEN_CURLY ||
138                $tokens[$i] instanceof PHP_Token_CURLY_OPEN) {
139                $block++;
140            } elseif ($tokens[$i] instanceof PHP_Token_CLOSE_CURLY) {
141                $block--;
142
143                if ($block === 0) {
144                    $this->endTokenId = $i;
145                }
146            } elseif (($this instanceof PHP_Token_FUNCTION ||
147                $this instanceof PHP_Token_NAMESPACE) &&
148                $tokens[$i] instanceof PHP_Token_SEMICOLON) {
149                if ($block === 0) {
150                    $this->endTokenId = $i;
151                }
152            }
153
154            $i++;
155        }
156
157        if ($this->endTokenId === null) {
158            $this->endTokenId = $this->id;
159        }
160
161        return $this->endTokenId;
162    }
163
164    /**
165     * @return int
166     */
167    public function getEndLine()
168    {
169        return $this->tokenStream[$this->getEndTokenId()]->getLine();
170    }
171}
172
173abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope
174{
175    /**
176     * @return string
177     */
178    public function getVisibility()
179    {
180        $tokens = $this->tokenStream->tokens();
181
182        for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
183            if (isset($tokens[$i]) &&
184               ($tokens[$i] instanceof PHP_Token_PRIVATE ||
185                $tokens[$i] instanceof PHP_Token_PROTECTED ||
186                $tokens[$i] instanceof PHP_Token_PUBLIC)) {
187                return strtolower(
188                    str_replace('PHP_Token_', '', get_class($tokens[$i]))
189                );
190            }
191            if (isset($tokens[$i]) &&
192              !($tokens[$i] instanceof PHP_Token_STATIC ||
193                $tokens[$i] instanceof PHP_Token_FINAL ||
194                $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
195                // no keywords; stop visibility search
196                break;
197            }
198        }
199    }
200
201    /**
202     * @return string
203     */
204    public function getKeywords()
205    {
206        $keywords = [];
207        $tokens   = $this->tokenStream->tokens();
208
209        for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
210            if (isset($tokens[$i]) &&
211               ($tokens[$i] instanceof PHP_Token_PRIVATE ||
212                $tokens[$i] instanceof PHP_Token_PROTECTED ||
213                $tokens[$i] instanceof PHP_Token_PUBLIC)) {
214                continue;
215            }
216
217            if (isset($tokens[$i]) &&
218               ($tokens[$i] instanceof PHP_Token_STATIC ||
219                $tokens[$i] instanceof PHP_Token_FINAL ||
220                $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
221                $keywords[] = strtolower(
222                    str_replace('PHP_Token_', '', get_class($tokens[$i]))
223                );
224            }
225        }
226
227        return implode(',', $keywords);
228    }
229}
230
231abstract class PHP_Token_Includes extends PHP_Token
232{
233    /**
234     * @var string
235     */
236    protected $name;
237
238    /**
239     * @var string
240     */
241    protected $type;
242
243    /**
244     * @return string
245     */
246    public function getName()
247    {
248        if ($this->name === null) {
249            $this->process();
250        }
251
252        return $this->name;
253    }
254
255    /**
256     * @return string
257     */
258    public function getType()
259    {
260        if ($this->type === null) {
261            $this->process();
262        }
263
264        return $this->type;
265    }
266
267    private function process()
268    {
269        $tokens = $this->tokenStream->tokens();
270
271        if ($tokens[$this->id + 2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) {
272            $this->name = trim($tokens[$this->id + 2], "'\"");
273            $this->type = strtolower(
274                str_replace('PHP_Token_', '', get_class($tokens[$this->id]))
275            );
276        }
277    }
278}
279
280class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility
281{
282    /**
283     * @var array
284     */
285    protected $arguments;
286
287    /**
288     * @var int
289     */
290    protected $ccn;
291
292    /**
293     * @var string
294     */
295    protected $name;
296
297    /**
298     * @var string
299     */
300    protected $signature;
301
302    /**
303     * @var bool
304     */
305    private $anonymous = false;
306
307    /**
308     * @return array
309     */
310    public function getArguments()
311    {
312        if ($this->arguments !== null) {
313            return $this->arguments;
314        }
315
316        $this->arguments = [];
317        $tokens          = $this->tokenStream->tokens();
318        $typeDeclaration = null;
319
320        // Search for first token inside brackets
321        $i = $this->id + 2;
322
323        while (!$tokens[$i - 1] instanceof PHP_Token_OPEN_BRACKET) {
324            $i++;
325        }
326
327        while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) {
328            if ($tokens[$i] instanceof PHP_Token_STRING) {
329                $typeDeclaration = (string) $tokens[$i];
330            } elseif ($tokens[$i] instanceof PHP_Token_VARIABLE) {
331                $this->arguments[(string) $tokens[$i]] = $typeDeclaration;
332                $typeDeclaration                       = null;
333            }
334
335            $i++;
336        }
337
338        return $this->arguments;
339    }
340
341    /**
342     * @return string
343     */
344    public function getName()
345    {
346        if ($this->name !== null) {
347            return $this->name;
348        }
349
350        $tokens = $this->tokenStream->tokens();
351
352        $i = $this->id + 1;
353
354        if ($tokens[$i] instanceof PHP_Token_WHITESPACE) {
355            $i++;
356        }
357
358        if ($tokens[$i] instanceof PHP_Token_AMPERSAND) {
359            $i++;
360        }
361
362        if ($tokens[$i + 1] instanceof PHP_Token_OPEN_BRACKET) {
363            $this->name = (string) $tokens[$i];
364        } elseif ($tokens[$i + 1] instanceof PHP_Token_WHITESPACE && $tokens[$i + 2] instanceof PHP_Token_OPEN_BRACKET) {
365            $this->name = (string) $tokens[$i];
366        } else {
367            $this->anonymous = true;
368
369            $this->name = sprintf(
370                'anonymousFunction:%s#%s',
371                $this->getLine(),
372                $this->getId()
373            );
374        }
375
376        if (!$this->isAnonymous()) {
377            for ($i = $this->id; $i; --$i) {
378                if ($tokens[$i] instanceof PHP_Token_NAMESPACE) {
379                    $this->name = $tokens[$i]->getName() . '\\' . $this->name;
380
381                    break;
382                }
383
384                if ($tokens[$i] instanceof PHP_Token_INTERFACE) {
385                    break;
386                }
387            }
388        }
389
390        return $this->name;
391    }
392
393    /**
394     * @return int
395     */
396    public function getCCN()
397    {
398        if ($this->ccn !== null) {
399            return $this->ccn;
400        }
401
402        $this->ccn = 1;
403        $end       = $this->getEndTokenId();
404        $tokens    = $this->tokenStream->tokens();
405
406        for ($i = $this->id; $i <= $end; $i++) {
407            switch (get_class($tokens[$i])) {
408                case 'PHP_Token_IF':
409                case 'PHP_Token_ELSEIF':
410                case 'PHP_Token_FOR':
411                case 'PHP_Token_FOREACH':
412                case 'PHP_Token_WHILE':
413                case 'PHP_Token_CASE':
414                case 'PHP_Token_CATCH':
415                case 'PHP_Token_BOOLEAN_AND':
416                case 'PHP_Token_LOGICAL_AND':
417                case 'PHP_Token_BOOLEAN_OR':
418                case 'PHP_Token_LOGICAL_OR':
419                case 'PHP_Token_QUESTION_MARK':
420                    $this->ccn++;
421                    break;
422            }
423        }
424
425        return $this->ccn;
426    }
427
428    /**
429     * @return string
430     */
431    public function getSignature()
432    {
433        if ($this->signature !== null) {
434            return $this->signature;
435        }
436
437        if ($this->isAnonymous()) {
438            $this->signature = 'anonymousFunction';
439            $i               = $this->id + 1;
440        } else {
441            $this->signature = '';
442            $i               = $this->id + 2;
443        }
444
445        $tokens = $this->tokenStream->tokens();
446
447        while (isset($tokens[$i]) &&
448               !$tokens[$i] instanceof PHP_Token_OPEN_CURLY &&
449               !$tokens[$i] instanceof PHP_Token_SEMICOLON) {
450            $this->signature .= $tokens[$i++];
451        }
452
453        $this->signature = trim($this->signature);
454
455        return $this->signature;
456    }
457
458    /**
459     * @return bool
460     */
461    public function isAnonymous()
462    {
463        return $this->anonymous;
464    }
465}
466
467class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility
468{
469    /**
470     * @var array
471     */
472    protected $interfaces;
473
474    /**
475     * @return string
476     */
477    public function getName()
478    {
479        return (string) $this->tokenStream[$this->id + 2];
480    }
481
482    /**
483     * @return bool
484     */
485    public function hasParent()
486    {
487        return $this->tokenStream[$this->id + 4] instanceof PHP_Token_EXTENDS;
488    }
489
490    /**
491     * @return array
492     */
493    public function getPackage()
494    {
495        $className  = $this->getName();
496        $docComment = $this->getDocblock();
497
498        $result = [
499            'namespace'   => '',
500            'fullPackage' => '',
501            'category'    => '',
502            'package'     => '',
503            'subpackage'  => ''
504        ];
505
506        for ($i = $this->id; $i; --$i) {
507            if ($this->tokenStream[$i] instanceof PHP_Token_NAMESPACE) {
508                $result['namespace'] = $this->tokenStream[$i]->getName();
509                break;
510            }
511        }
512
513        if (preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) {
514            $result['category'] = $matches[1];
515        }
516
517        if (preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) {
518            $result['package']     = $matches[1];
519            $result['fullPackage'] = $matches[1];
520        }
521
522        if (preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) {
523            $result['subpackage']   = $matches[1];
524            $result['fullPackage'] .= '.' . $matches[1];
525        }
526
527        if (empty($result['fullPackage'])) {
528            $result['fullPackage'] = $this->arrayToName(
529                explode('_', str_replace('\\', '_', $className)),
530                '.'
531            );
532        }
533
534        return $result;
535    }
536
537    /**
538     * @param array  $parts
539     * @param string $join
540     *
541     * @return string
542     */
543    protected function arrayToName(array $parts, $join = '\\')
544    {
545        $result = '';
546
547        if (count($parts) > 1) {
548            array_pop($parts);
549
550            $result = implode($join, $parts);
551        }
552
553        return $result;
554    }
555
556    /**
557     * @return bool|string
558     */
559    public function getParent()
560    {
561        if (!$this->hasParent()) {
562            return false;
563        }
564
565        $i         = $this->id + 6;
566        $tokens    = $this->tokenStream->tokens();
567        $className = (string) $tokens[$i];
568
569        while (isset($tokens[$i + 1]) &&
570               !$tokens[$i + 1] instanceof PHP_Token_WHITESPACE) {
571            $className .= (string) $tokens[++$i];
572        }
573
574        return $className;
575    }
576
577    /**
578     * @return bool
579     */
580    public function hasInterfaces()
581    {
582        return (isset($this->tokenStream[$this->id + 4]) &&
583                $this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) ||
584               (isset($this->tokenStream[$this->id + 8]) &&
585                $this->tokenStream[$this->id + 8] instanceof PHP_Token_IMPLEMENTS);
586    }
587
588    /**
589     * @return array|bool
590     */
591    public function getInterfaces()
592    {
593        if ($this->interfaces !== null) {
594            return $this->interfaces;
595        }
596
597        if (!$this->hasInterfaces()) {
598            return ($this->interfaces = false);
599        }
600
601        if ($this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) {
602            $i = $this->id + 3;
603        } else {
604            $i = $this->id + 7;
605        }
606
607        $tokens = $this->tokenStream->tokens();
608
609        while (!$tokens[$i + 1] instanceof PHP_Token_OPEN_CURLY) {
610            $i++;
611
612            if ($tokens[$i] instanceof PHP_Token_STRING) {
613                $this->interfaces[] = (string) $tokens[$i];
614            }
615        }
616
617        return $this->interfaces;
618    }
619}
620
621class PHP_Token_ABSTRACT extends PHP_Token
622{
623}
624
625class PHP_Token_AMPERSAND extends PHP_Token
626{
627}
628
629class PHP_Token_AND_EQUAL extends PHP_Token
630{
631}
632
633class PHP_Token_ARRAY extends PHP_Token
634{
635}
636
637class PHP_Token_ARRAY_CAST extends PHP_Token
638{
639}
640
641class PHP_Token_AS extends PHP_Token
642{
643}
644
645class PHP_Token_AT extends PHP_Token
646{
647}
648
649class PHP_Token_BACKTICK extends PHP_Token
650{
651}
652
653class PHP_Token_BAD_CHARACTER extends PHP_Token
654{
655}
656
657class PHP_Token_BOOLEAN_AND extends PHP_Token
658{
659}
660
661class PHP_Token_BOOLEAN_OR extends PHP_Token
662{
663}
664
665class PHP_Token_BOOL_CAST extends PHP_Token
666{
667}
668
669class PHP_Token_BREAK extends PHP_Token
670{
671}
672
673class PHP_Token_CARET extends PHP_Token
674{
675}
676
677class PHP_Token_CASE extends PHP_Token
678{
679}
680
681class PHP_Token_CATCH extends PHP_Token
682{
683}
684
685class PHP_Token_CHARACTER extends PHP_Token
686{
687}
688
689class PHP_Token_CLASS extends PHP_Token_INTERFACE
690{
691    /**
692     * @var bool
693     */
694    private $anonymous = false;
695
696    /**
697     * @var string
698     */
699    private $name;
700
701    /**
702     * @return string
703     */
704    public function getName()
705    {
706        if ($this->name !== null) {
707            return $this->name;
708        }
709
710        $next = $this->tokenStream[$this->id + 1];
711
712        if ($next instanceof PHP_Token_WHITESPACE) {
713            $next = $this->tokenStream[$this->id + 2];
714        }
715
716        if ($next instanceof PHP_Token_STRING) {
717            $this->name =(string) $next;
718
719            return $this->name;
720        }
721
722        if ($next instanceof PHP_Token_OPEN_CURLY ||
723            $next instanceof PHP_Token_EXTENDS ||
724            $next instanceof PHP_Token_IMPLEMENTS) {
725
726            $this->name = sprintf(
727                'AnonymousClass:%s#%s',
728                $this->getLine(),
729                $this->getId()
730            );
731
732            $this->anonymous = true;
733
734            return $this->name;
735        }
736    }
737
738    public function isAnonymous()
739    {
740        return $this->anonymous;
741    }
742}
743
744class PHP_Token_CLASS_C extends PHP_Token
745{
746}
747
748class PHP_Token_CLASS_NAME_CONSTANT extends PHP_Token
749{
750}
751
752class PHP_Token_CLONE extends PHP_Token
753{
754}
755
756class PHP_Token_CLOSE_BRACKET extends PHP_Token
757{
758}
759
760class PHP_Token_CLOSE_CURLY extends PHP_Token
761{
762}
763
764class PHP_Token_CLOSE_SQUARE extends PHP_Token
765{
766}
767
768class PHP_Token_CLOSE_TAG extends PHP_Token
769{
770}
771
772class PHP_Token_COLON extends PHP_Token
773{
774}
775
776class PHP_Token_COMMA extends PHP_Token
777{
778}
779
780class PHP_Token_COMMENT extends PHP_Token
781{
782}
783
784class PHP_Token_CONCAT_EQUAL extends PHP_Token
785{
786}
787
788class PHP_Token_CONST extends PHP_Token
789{
790}
791
792class PHP_Token_CONSTANT_ENCAPSED_STRING extends PHP_Token
793{
794}
795
796class PHP_Token_CONTINUE extends PHP_Token
797{
798}
799
800class PHP_Token_CURLY_OPEN extends PHP_Token
801{
802}
803
804class PHP_Token_DEC extends PHP_Token
805{
806}
807
808class PHP_Token_DECLARE extends PHP_Token
809{
810}
811
812class PHP_Token_DEFAULT extends PHP_Token
813{
814}
815
816class PHP_Token_DIV extends PHP_Token
817{
818}
819
820class PHP_Token_DIV_EQUAL extends PHP_Token
821{
822}
823
824class PHP_Token_DNUMBER extends PHP_Token
825{
826}
827
828class PHP_Token_DO extends PHP_Token
829{
830}
831
832class PHP_Token_DOC_COMMENT extends PHP_Token
833{
834}
835
836class PHP_Token_DOLLAR extends PHP_Token
837{
838}
839
840class PHP_Token_DOLLAR_OPEN_CURLY_BRACES extends PHP_Token
841{
842}
843
844class PHP_Token_DOT extends PHP_Token
845{
846}
847
848class PHP_Token_DOUBLE_ARROW extends PHP_Token
849{
850}
851
852class PHP_Token_DOUBLE_CAST extends PHP_Token
853{
854}
855
856class PHP_Token_DOUBLE_COLON extends PHP_Token
857{
858}
859
860class PHP_Token_DOUBLE_QUOTES extends PHP_Token
861{
862}
863
864class PHP_Token_ECHO extends PHP_Token
865{
866}
867
868class PHP_Token_ELSE extends PHP_Token
869{
870}
871
872class PHP_Token_ELSEIF extends PHP_Token
873{
874}
875
876class PHP_Token_EMPTY extends PHP_Token
877{
878}
879
880class PHP_Token_ENCAPSED_AND_WHITESPACE extends PHP_Token
881{
882}
883
884class PHP_Token_ENDDECLARE extends PHP_Token
885{
886}
887
888class PHP_Token_ENDFOR extends PHP_Token
889{
890}
891
892class PHP_Token_ENDFOREACH extends PHP_Token
893{
894}
895
896class PHP_Token_ENDIF extends PHP_Token
897{
898}
899
900class PHP_Token_ENDSWITCH extends PHP_Token
901{
902}
903
904class PHP_Token_ENDWHILE extends PHP_Token
905{
906}
907
908class PHP_Token_END_HEREDOC extends PHP_Token
909{
910}
911
912class PHP_Token_EQUAL extends PHP_Token
913{
914}
915
916class PHP_Token_EVAL extends PHP_Token
917{
918}
919
920class PHP_Token_EXCLAMATION_MARK extends PHP_Token
921{
922}
923
924class PHP_Token_EXIT extends PHP_Token
925{
926}
927
928class PHP_Token_EXTENDS extends PHP_Token
929{
930}
931
932class PHP_Token_FILE extends PHP_Token
933{
934}
935
936class PHP_Token_FINAL extends PHP_Token
937{
938}
939
940class PHP_Token_FOR extends PHP_Token
941{
942}
943
944class PHP_Token_FOREACH extends PHP_Token
945{
946}
947
948class PHP_Token_FUNC_C extends PHP_Token
949{
950}
951
952class PHP_Token_GLOBAL extends PHP_Token
953{
954}
955
956class PHP_Token_GT extends PHP_Token
957{
958}
959
960class PHP_Token_IF extends PHP_Token
961{
962}
963
964class PHP_Token_IMPLEMENTS extends PHP_Token
965{
966}
967
968class PHP_Token_INC extends PHP_Token
969{
970}
971
972class PHP_Token_INCLUDE extends PHP_Token_Includes
973{
974}
975
976class PHP_Token_INCLUDE_ONCE extends PHP_Token_Includes
977{
978}
979
980class PHP_Token_INLINE_HTML extends PHP_Token
981{
982}
983
984class PHP_Token_INSTANCEOF extends PHP_Token
985{
986}
987
988class PHP_Token_INT_CAST extends PHP_Token
989{
990}
991
992class PHP_Token_ISSET extends PHP_Token
993{
994}
995
996class PHP_Token_IS_EQUAL extends PHP_Token
997{
998}
999
1000class PHP_Token_IS_GREATER_OR_EQUAL extends PHP_Token
1001{
1002}
1003
1004class PHP_Token_IS_IDENTICAL extends PHP_Token
1005{
1006}
1007
1008class PHP_Token_IS_NOT_EQUAL extends PHP_Token
1009{
1010}
1011
1012class PHP_Token_IS_NOT_IDENTICAL extends PHP_Token
1013{
1014}
1015
1016class PHP_Token_IS_SMALLER_OR_EQUAL extends PHP_Token
1017{
1018}
1019
1020class PHP_Token_LINE extends PHP_Token
1021{
1022}
1023
1024class PHP_Token_LIST extends PHP_Token
1025{
1026}
1027
1028class PHP_Token_LNUMBER extends PHP_Token
1029{
1030}
1031
1032class PHP_Token_LOGICAL_AND extends PHP_Token
1033{
1034}
1035
1036class PHP_Token_LOGICAL_OR extends PHP_Token
1037{
1038}
1039
1040class PHP_Token_LOGICAL_XOR extends PHP_Token
1041{
1042}
1043
1044class PHP_Token_LT extends PHP_Token
1045{
1046}
1047
1048class PHP_Token_METHOD_C extends PHP_Token
1049{
1050}
1051
1052class PHP_Token_MINUS extends PHP_Token
1053{
1054}
1055
1056class PHP_Token_MINUS_EQUAL extends PHP_Token
1057{
1058}
1059
1060class PHP_Token_MOD_EQUAL extends PHP_Token
1061{
1062}
1063
1064class PHP_Token_MULT extends PHP_Token
1065{
1066}
1067
1068class PHP_Token_MUL_EQUAL extends PHP_Token
1069{
1070}
1071
1072class PHP_Token_NEW extends PHP_Token
1073{
1074}
1075
1076class PHP_Token_NUM_STRING extends PHP_Token
1077{
1078}
1079
1080class PHP_Token_OBJECT_CAST extends PHP_Token
1081{
1082}
1083
1084class PHP_Token_OBJECT_OPERATOR extends PHP_Token
1085{
1086}
1087
1088class PHP_Token_OPEN_BRACKET extends PHP_Token
1089{
1090}
1091
1092class PHP_Token_OPEN_CURLY extends PHP_Token
1093{
1094}
1095
1096class PHP_Token_OPEN_SQUARE extends PHP_Token
1097{
1098}
1099
1100class PHP_Token_OPEN_TAG extends PHP_Token
1101{
1102}
1103
1104class PHP_Token_OPEN_TAG_WITH_ECHO extends PHP_Token
1105{
1106}
1107
1108class PHP_Token_OR_EQUAL extends PHP_Token
1109{
1110}
1111
1112class PHP_Token_PAAMAYIM_NEKUDOTAYIM extends PHP_Token
1113{
1114}
1115
1116class PHP_Token_PERCENT extends PHP_Token
1117{
1118}
1119
1120class PHP_Token_PIPE extends PHP_Token
1121{
1122}
1123
1124class PHP_Token_PLUS extends PHP_Token
1125{
1126}
1127
1128class PHP_Token_PLUS_EQUAL extends PHP_Token
1129{
1130}
1131
1132class PHP_Token_PRINT extends PHP_Token
1133{
1134}
1135
1136class PHP_Token_PRIVATE extends PHP_Token
1137{
1138}
1139
1140class PHP_Token_PROTECTED extends PHP_Token
1141{
1142}
1143
1144class PHP_Token_PUBLIC extends PHP_Token
1145{
1146}
1147
1148class PHP_Token_QUESTION_MARK extends PHP_Token
1149{
1150}
1151
1152class PHP_Token_REQUIRE extends PHP_Token_Includes
1153{
1154}
1155
1156class PHP_Token_REQUIRE_ONCE extends PHP_Token_Includes
1157{
1158}
1159
1160class PHP_Token_RETURN extends PHP_Token
1161{
1162}
1163
1164class PHP_Token_SEMICOLON extends PHP_Token
1165{
1166}
1167
1168class PHP_Token_SL extends PHP_Token
1169{
1170}
1171
1172class PHP_Token_SL_EQUAL extends PHP_Token
1173{
1174}
1175
1176class PHP_Token_SR extends PHP_Token
1177{
1178}
1179
1180class PHP_Token_SR_EQUAL extends PHP_Token
1181{
1182}
1183
1184class PHP_Token_START_HEREDOC extends PHP_Token
1185{
1186}
1187
1188class PHP_Token_STATIC extends PHP_Token
1189{
1190}
1191
1192class PHP_Token_STRING extends PHP_Token
1193{
1194}
1195
1196class PHP_Token_STRING_CAST extends PHP_Token
1197{
1198}
1199
1200class PHP_Token_STRING_VARNAME extends PHP_Token
1201{
1202}
1203
1204class PHP_Token_SWITCH extends PHP_Token
1205{
1206}
1207
1208class PHP_Token_THROW extends PHP_Token
1209{
1210}
1211
1212class PHP_Token_TILDE extends PHP_Token
1213{
1214}
1215
1216class PHP_Token_TRY extends PHP_Token
1217{
1218}
1219
1220class PHP_Token_UNSET extends PHP_Token
1221{
1222}
1223
1224class PHP_Token_UNSET_CAST extends PHP_Token
1225{
1226}
1227
1228class PHP_Token_USE extends PHP_Token
1229{
1230}
1231
1232class PHP_Token_USE_FUNCTION extends PHP_Token
1233{
1234}
1235
1236class PHP_Token_VAR extends PHP_Token
1237{
1238}
1239
1240class PHP_Token_VARIABLE extends PHP_Token
1241{
1242}
1243
1244class PHP_Token_WHILE extends PHP_Token
1245{
1246}
1247
1248class PHP_Token_WHITESPACE extends PHP_Token
1249{
1250}
1251
1252class PHP_Token_XOR_EQUAL extends PHP_Token
1253{
1254}
1255
1256// Tokens introduced in PHP 5.1
1257class PHP_Token_HALT_COMPILER extends PHP_Token
1258{
1259}
1260
1261// Tokens introduced in PHP 5.3
1262class PHP_Token_DIR extends PHP_Token
1263{
1264}
1265
1266class PHP_Token_GOTO extends PHP_Token
1267{
1268}
1269
1270class PHP_Token_NAMESPACE extends PHP_TokenWithScope
1271{
1272    /**
1273     * @return string
1274     */
1275    public function getName()
1276    {
1277        $tokens    = $this->tokenStream->tokens();
1278        $namespace = (string) $tokens[$this->id + 2];
1279
1280        for ($i = $this->id + 3;; $i += 2) {
1281            if (isset($tokens[$i]) &&
1282                $tokens[$i] instanceof PHP_Token_NS_SEPARATOR) {
1283                $namespace .= '\\' . $tokens[$i + 1];
1284            } else {
1285                break;
1286            }
1287        }
1288
1289        return $namespace;
1290    }
1291}
1292
1293class PHP_Token_NS_C extends PHP_Token
1294{
1295}
1296
1297class PHP_Token_NS_SEPARATOR extends PHP_Token
1298{
1299}
1300
1301// Tokens introduced in PHP 5.4
1302class PHP_Token_CALLABLE extends PHP_Token
1303{
1304}
1305
1306class PHP_Token_INSTEADOF extends PHP_Token
1307{
1308}
1309
1310class PHP_Token_TRAIT extends PHP_Token_INTERFACE
1311{
1312}
1313
1314class PHP_Token_TRAIT_C extends PHP_Token
1315{
1316}
1317
1318// Tokens introduced in PHP 5.5
1319class PHP_Token_FINALLY extends PHP_Token
1320{
1321}
1322
1323class PHP_Token_YIELD extends PHP_Token
1324{
1325}
1326
1327// Tokens introduced in PHP 5.6
1328class PHP_Token_ELLIPSIS extends PHP_Token
1329{
1330}
1331
1332class PHP_Token_POW extends PHP_Token
1333{
1334}
1335
1336class PHP_Token_POW_EQUAL extends PHP_Token
1337{
1338}
1339
1340// Tokens introduced in PHP 7.0
1341class PHP_Token_COALESCE extends PHP_Token
1342{
1343}
1344
1345class PHP_Token_SPACESHIP extends PHP_Token
1346{
1347}
1348
1349class PHP_Token_YIELD_FROM extends PHP_Token
1350{
1351}
1352
1353// Tokens introduced in HackLang / HHVM
1354class PHP_Token_ASYNC extends PHP_Token
1355{
1356}
1357
1358class PHP_Token_AWAIT extends PHP_Token
1359{
1360}
1361
1362class PHP_Token_COMPILER_HALT_OFFSET extends PHP_Token
1363{
1364}
1365
1366class PHP_Token_ENUM extends PHP_Token
1367{
1368}
1369
1370class PHP_Token_EQUALS extends PHP_Token
1371{
1372}
1373
1374class PHP_Token_IN extends PHP_Token
1375{
1376}
1377
1378class PHP_Token_JOIN extends PHP_Token
1379{
1380}
1381
1382class PHP_Token_LAMBDA_ARROW extends PHP_Token
1383{
1384}
1385
1386class PHP_Token_LAMBDA_CP extends PHP_Token
1387{
1388}
1389
1390class PHP_Token_LAMBDA_OP extends PHP_Token
1391{
1392}
1393
1394class PHP_Token_ONUMBER extends PHP_Token
1395{
1396}
1397
1398class PHP_Token_NULLSAFE_OBJECT_OPERATOR extends PHP_Token
1399{
1400}
1401
1402class PHP_Token_SHAPE extends PHP_Token
1403{
1404}
1405
1406class PHP_Token_SUPER extends PHP_Token
1407{
1408}
1409
1410class PHP_Token_TYPE extends PHP_Token
1411{
1412}
1413
1414class PHP_Token_TYPELIST_GT extends PHP_Token
1415{
1416}
1417
1418class PHP_Token_TYPELIST_LT extends PHP_Token
1419{
1420}
1421
1422class PHP_Token_WHERE extends PHP_Token
1423{
1424}
1425
1426class PHP_Token_XHP_ATTRIBUTE extends PHP_Token
1427{
1428}
1429
1430class PHP_Token_XHP_CATEGORY extends PHP_Token
1431{
1432}
1433
1434class PHP_Token_XHP_CATEGORY_LABEL extends PHP_Token
1435{
1436}
1437
1438class PHP_Token_XHP_CHILDREN extends PHP_Token
1439{
1440}
1441
1442class PHP_Token_XHP_LABEL extends PHP_Token
1443{
1444}
1445
1446class PHP_Token_XHP_REQUIRED extends PHP_Token
1447{
1448}
1449
1450class PHP_Token_XHP_TAG_GT extends PHP_Token
1451{
1452}
1453
1454class PHP_Token_XHP_TAG_LT extends PHP_Token
1455{
1456}
1457
1458class PHP_Token_XHP_TEXT extends PHP_Token
1459{
1460}
1461