gluon-web-remote

Web remote Administration for big size of gluon routers
git clone git://archive.git.mtrnord.blog/MTRNord/gluon-web-remote.git
Log | Files | Refs | README

Token.php (23573B)


      1 <?php
      2 /**
      3  * php-token-stream
      4  *
      5  * Copyright (c) 2009-2013, Sebastian Bergmann <sebastian@phpunit.de>.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  *   * Redistributions of source code must retain the above copyright
     13  *     notice, this list of conditions and the following disclaimer.
     14  *
     15  *   * Redistributions in binary form must reproduce the above copyright
     16  *     notice, this list of conditions and the following disclaimer in
     17  *     the documentation and/or other materials provided with the
     18  *     distribution.
     19  *
     20  *   * Neither the name of Sebastian Bergmann nor the names of his
     21  *     contributors may be used to endorse or promote products derived
     22  *     from this software without specific prior written permission.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  *
     37  * @package   PHP_TokenStream
     38  * @author    Sebastian Bergmann <sebastian@phpunit.de>
     39  * @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
     40  * @license   http://www.opensource.org/licenses/BSD-3-Clause  The BSD 3-Clause License
     41  * @since     File available since Release 1.0.0
     42  */
     43 
     44 /**
     45  * A PHP token.
     46  *
     47  * @author    Sebastian Bergmann <sebastian@phpunit.de>
     48  * @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de>
     49  * @license   http://www.opensource.org/licenses/BSD-3-Clause  The BSD 3-Clause License
     50  * @version   Release: @package_version@
     51  * @link      http://github.com/sebastianbergmann/php-token-stream/tree
     52  * @since     Class available since Release 1.0.0
     53  */
     54 abstract class PHP_Token
     55 {
     56     /**
     57      * @var string
     58      */
     59     protected $text;
     60 
     61     /**
     62      * @var integer
     63      */
     64     protected $line;
     65 
     66     /**
     67      * @var PHP_Token_Stream
     68      */
     69     protected $tokenStream;
     70 
     71     /**
     72      * @var integer
     73      */
     74     protected $id;
     75 
     76     /**
     77      * Constructor.
     78      *
     79      * @param string           $text
     80      * @param integer          $line
     81      * @param PHP_Token_Stream $tokenStream
     82      * @param integer          $id
     83      */
     84     public function __construct($text, $line, PHP_Token_Stream $tokenStream, $id)
     85     {
     86         $this->text        = $text;
     87         $this->line        = $line;
     88         $this->tokenStream = $tokenStream;
     89         $this->id          = $id;
     90     }
     91 
     92     /**
     93      * @return string
     94      */
     95     public function __toString()
     96     {
     97         return $this->text;
     98     }
     99 
    100     /**
    101      * @return integer
    102      */
    103     public function getLine()
    104     {
    105         return $this->line;
    106     }
    107 }
    108 
    109 abstract class PHP_TokenWithScope extends PHP_Token
    110 {
    111     protected $endTokenId;
    112 
    113     /**
    114      * Get the docblock for this token
    115      *
    116      * This method will fetch the docblock belonging to the current token. The
    117      * docblock must be placed on the line directly above the token to be
    118      * recognized.
    119      *
    120      * @return string|null Returns the docblock as a string if found
    121      */
    122     public function getDocblock()
    123     {
    124         $tokens            = $this->tokenStream->tokens();
    125         $currentLineNumber = $tokens[$this->id]->getLine();
    126         $prevLineNumber    = $currentLineNumber - 1;
    127 
    128         for ($i = $this->id - 1; $i; $i--) {
    129             if (!isset($tokens[$i])) {
    130                 return;
    131             }
    132 
    133             if ($tokens[$i] instanceof PHP_Token_FUNCTION ||
    134                 $tokens[$i] instanceof PHP_Token_CLASS ||
    135                 $tokens[$i] instanceof PHP_Token_TRAIT) {
    136                 // Some other trait, class or function, no docblock can be
    137                 // used for the current token
    138                 break;
    139             }
    140 
    141             $line = $tokens[$i]->getLine();
    142 
    143             if ($line == $currentLineNumber ||
    144                 ($line == $prevLineNumber &&
    145                  $tokens[$i] instanceof PHP_Token_WHITESPACE)) {
    146                 continue;
    147             }
    148 
    149             if ($line < $currentLineNumber &&
    150                 !$tokens[$i] instanceof PHP_Token_DOC_COMMENT) {
    151                 break;
    152             }
    153 
    154             return (string)$tokens[$i];
    155         }
    156     }
    157 
    158     public function getEndTokenId()
    159     {
    160         $block  = 0;
    161         $i      = $this->id;
    162         $tokens = $this->tokenStream->tokens();
    163 
    164         while ($this->endTokenId === NULL && isset($tokens[$i])) {
    165             if ($tokens[$i] instanceof PHP_Token_OPEN_CURLY ||
    166                 $tokens[$i] instanceof PHP_Token_CURLY_OPEN) {
    167                 $block++;
    168             }
    169 
    170             else if ($tokens[$i] instanceof PHP_Token_CLOSE_CURLY) {
    171                 $block--;
    172 
    173                 if ($block === 0) {
    174                     $this->endTokenId = $i;
    175                 }
    176             }
    177 
    178             else if (($this instanceof PHP_Token_FUNCTION ||
    179                 $this instanceof PHP_Token_NAMESPACE) &&
    180                 $tokens[$i] instanceof PHP_Token_SEMICOLON) {
    181                 if ($block === 0) {
    182                     $this->endTokenId = $i;
    183                 }
    184             }
    185 
    186             $i++;
    187         }
    188 
    189         if ($this->endTokenId === NULL) {
    190             $this->endTokenId = $this->id;
    191         }
    192 
    193         return $this->endTokenId;
    194     }
    195 
    196     public function getEndLine()
    197     {
    198         return $this->tokenStream[$this->getEndTokenId()]->getLine();
    199     }
    200 
    201 }
    202 
    203 abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope {
    204 
    205     public function getVisibility()
    206     {
    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                 return strtolower(
    215                   str_replace('PHP_Token_', '', get_class($tokens[$i]))
    216                 );
    217             }
    218             if (isset($tokens[$i]) &&
    219               !($tokens[$i] instanceof PHP_Token_STATIC ||
    220                 $tokens[$i] instanceof PHP_Token_FINAL ||
    221                 $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
    222                 // no keywords; stop visibility search
    223                 break;
    224             }
    225         }
    226     }
    227 
    228     public function getKeywords()
    229     {
    230         $keywords = array();
    231         $tokens = $this->tokenStream->tokens();
    232 
    233         for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
    234             if (isset($tokens[$i]) &&
    235                ($tokens[$i] instanceof PHP_Token_PRIVATE ||
    236                 $tokens[$i] instanceof PHP_Token_PROTECTED ||
    237                 $tokens[$i] instanceof PHP_Token_PUBLIC)) {
    238                 continue;
    239             }
    240 
    241             if (isset($tokens[$i]) &&
    242                ($tokens[$i] instanceof PHP_Token_STATIC ||
    243                 $tokens[$i] instanceof PHP_Token_FINAL ||
    244                 $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
    245                 $keywords[] = strtolower(
    246                   str_replace('PHP_Token_', '', get_class($tokens[$i]))
    247                 );
    248             }
    249         }
    250 
    251         return implode(',', $keywords);
    252     }
    253 
    254 }
    255 
    256 abstract class PHP_Token_Includes extends PHP_Token
    257 {
    258     protected $name;
    259     protected $type;
    260 
    261     public function getName()
    262     {
    263         if ($this->name !== NULL) {
    264             return $this->name;
    265         }
    266 
    267         $tokens = $this->tokenStream->tokens();
    268 
    269         if ($tokens[$this->id+2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) {
    270             $this->name = trim($tokens[$this->id+2], "'\"");
    271             $this->type = strtolower(
    272               str_replace('PHP_Token_', '', get_class($tokens[$this->id]))
    273             );
    274         }
    275 
    276         return $this->name;
    277     }
    278 
    279     public function getType()
    280     {
    281         $this->getName();
    282         return $this->type;
    283     }
    284 }
    285 
    286 class PHP_Token_REQUIRE_ONCE extends PHP_Token_Includes {}
    287 class PHP_Token_REQUIRE extends PHP_Token_Includes {}
    288 class PHP_Token_EVAL extends PHP_Token {}
    289 class PHP_Token_INCLUDE_ONCE extends PHP_Token_Includes {}
    290 class PHP_Token_INCLUDE extends PHP_Token_Includes {}
    291 class PHP_Token_LOGICAL_OR extends PHP_Token {}
    292 class PHP_Token_LOGICAL_XOR extends PHP_Token {}
    293 class PHP_Token_LOGICAL_AND extends PHP_Token {}
    294 class PHP_Token_PRINT extends PHP_Token {}
    295 class PHP_Token_SR_EQUAL extends PHP_Token {}
    296 class PHP_Token_SL_EQUAL extends PHP_Token {}
    297 class PHP_Token_XOR_EQUAL extends PHP_Token {}
    298 class PHP_Token_OR_EQUAL extends PHP_Token {}
    299 class PHP_Token_AND_EQUAL extends PHP_Token {}
    300 class PHP_Token_MOD_EQUAL extends PHP_Token {}
    301 class PHP_Token_CONCAT_EQUAL extends PHP_Token {}
    302 class PHP_Token_DIV_EQUAL extends PHP_Token {}
    303 class PHP_Token_MUL_EQUAL extends PHP_Token {}
    304 class PHP_Token_MINUS_EQUAL extends PHP_Token {}
    305 class PHP_Token_PLUS_EQUAL extends PHP_Token {}
    306 class PHP_Token_BOOLEAN_OR extends PHP_Token {}
    307 class PHP_Token_BOOLEAN_AND extends PHP_Token {}
    308 class PHP_Token_IS_NOT_IDENTICAL extends PHP_Token {}
    309 class PHP_Token_IS_IDENTICAL extends PHP_Token {}
    310 class PHP_Token_IS_NOT_EQUAL extends PHP_Token {}
    311 class PHP_Token_IS_EQUAL extends PHP_Token {}
    312 class PHP_Token_IS_GREATER_OR_EQUAL extends PHP_Token {}
    313 class PHP_Token_IS_SMALLER_OR_EQUAL extends PHP_Token {}
    314 class PHP_Token_SR extends PHP_Token {}
    315 class PHP_Token_SL extends PHP_Token {}
    316 class PHP_Token_INSTANCEOF extends PHP_Token {}
    317 class PHP_Token_UNSET_CAST extends PHP_Token {}
    318 class PHP_Token_BOOL_CAST extends PHP_Token {}
    319 class PHP_Token_OBJECT_CAST extends PHP_Token {}
    320 class PHP_Token_ARRAY_CAST extends PHP_Token {}
    321 class PHP_Token_STRING_CAST extends PHP_Token {}
    322 class PHP_Token_DOUBLE_CAST extends PHP_Token {}
    323 class PHP_Token_INT_CAST extends PHP_Token {}
    324 class PHP_Token_DEC extends PHP_Token {}
    325 class PHP_Token_INC extends PHP_Token {}
    326 class PHP_Token_CLONE extends PHP_Token {}
    327 class PHP_Token_NEW extends PHP_Token {}
    328 class PHP_Token_EXIT extends PHP_Token {}
    329 class PHP_Token_IF extends PHP_Token {}
    330 class PHP_Token_ELSEIF extends PHP_Token {}
    331 class PHP_Token_ELSE extends PHP_Token {}
    332 class PHP_Token_ENDIF extends PHP_Token {}
    333 class PHP_Token_LNUMBER extends PHP_Token {}
    334 class PHP_Token_DNUMBER extends PHP_Token {}
    335 class PHP_Token_STRING extends PHP_Token {}
    336 class PHP_Token_STRING_VARNAME extends PHP_Token {}
    337 class PHP_Token_VARIABLE extends PHP_Token {}
    338 class PHP_Token_NUM_STRING extends PHP_Token {}
    339 class PHP_Token_INLINE_HTML extends PHP_Token {}
    340 class PHP_Token_CHARACTER extends PHP_Token {}
    341 class PHP_Token_BAD_CHARACTER extends PHP_Token {}
    342 class PHP_Token_ENCAPSED_AND_WHITESPACE extends PHP_Token {}
    343 class PHP_Token_CONSTANT_ENCAPSED_STRING extends PHP_Token {}
    344 class PHP_Token_ECHO extends PHP_Token {}
    345 class PHP_Token_DO extends PHP_Token {}
    346 class PHP_Token_WHILE extends PHP_Token {}
    347 class PHP_Token_ENDWHILE extends PHP_Token {}
    348 class PHP_Token_FOR extends PHP_Token {}
    349 class PHP_Token_ENDFOR extends PHP_Token {}
    350 class PHP_Token_FOREACH extends PHP_Token {}
    351 class PHP_Token_ENDFOREACH extends PHP_Token {}
    352 class PHP_Token_DECLARE extends PHP_Token {}
    353 class PHP_Token_ENDDECLARE extends PHP_Token {}
    354 class PHP_Token_AS extends PHP_Token {}
    355 class PHP_Token_SWITCH extends PHP_Token {}
    356 class PHP_Token_ENDSWITCH extends PHP_Token {}
    357 class PHP_Token_CASE extends PHP_Token {}
    358 class PHP_Token_DEFAULT extends PHP_Token {}
    359 class PHP_Token_BREAK extends PHP_Token {}
    360 class PHP_Token_CONTINUE extends PHP_Token {}
    361 class PHP_Token_GOTO extends PHP_Token {}
    362 class PHP_Token_CALLABLE extends PHP_Token {}
    363 class PHP_Token_INSTEADOF extends PHP_Token {}
    364 
    365 class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility
    366 {
    367     protected $arguments;
    368     protected $ccn;
    369     protected $name;
    370     protected $signature;
    371 
    372     public function getArguments()
    373     {
    374         if ($this->arguments !== NULL) {
    375             return $this->arguments;
    376         }
    377 
    378         $this->arguments = array();
    379         $tokens          = $this->tokenStream->tokens();
    380         $typeHint        = NULL;
    381 
    382         // Search for first token inside brackets
    383         $i = $this->id + 2;
    384         while (!$tokens[$i-1] instanceof PHP_Token_OPEN_BRACKET) {
    385             $i++;
    386         }
    387 
    388         while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) {
    389             if ($tokens[$i] instanceof PHP_Token_STRING) {
    390                 $typeHint = (string)$tokens[$i];
    391             }
    392 
    393             else if ($tokens[$i] instanceof PHP_Token_VARIABLE) {
    394                 $this->arguments[(string)$tokens[$i]] = $typeHint;
    395                 $typeHint                             = NULL;
    396             }
    397 
    398             $i++;
    399         }
    400 
    401         return $this->arguments;
    402     }
    403 
    404     public function getName()
    405     {
    406         if ($this->name !== NULL) {
    407             return $this->name;
    408         }
    409 
    410         $tokens = $this->tokenStream->tokens();
    411 
    412         for ($i = $this->id + 1; $i < count($tokens); $i++) {
    413             if ($tokens[$i] instanceof PHP_Token_STRING) {
    414                 $this->name = (string)$tokens[$i];
    415                 break;
    416             }
    417 
    418             else if ($tokens[$i] instanceof PHP_Token_AMPERSAND &&
    419                      $tokens[$i+1] instanceof PHP_Token_STRING) {
    420                 $this->name = (string)$tokens[$i+1];
    421                 break;
    422             }
    423 
    424             else if ($tokens[$i] instanceof PHP_Token_OPEN_BRACKET) {
    425                 $this->name = 'anonymous function';
    426                 break;
    427             }
    428         }
    429 
    430         if ($this->name != 'anonymous function') {
    431             for ($i = $this->id; $i; --$i) {
    432                 if ($tokens[$i] instanceof PHP_Token_NAMESPACE) {
    433                     $this->name = $tokens[$i]->getName() . '\\' . $this->name;
    434                     break;
    435                 }
    436 
    437                 if ($tokens[$i] instanceof PHP_Token_INTERFACE) {
    438                     break;
    439                 }
    440             }
    441         }
    442 
    443         return $this->name;
    444     }
    445 
    446     public function getCCN()
    447     {
    448         if ($this->ccn !== NULL) {
    449             return $this->ccn;
    450         }
    451 
    452         $this->ccn = 1;
    453         $end       = $this->getEndTokenId();
    454         $tokens    = $this->tokenStream->tokens();
    455 
    456         for ($i = $this->id; $i <= $end; $i++) {
    457             switch (get_class($tokens[$i])) {
    458                 case 'PHP_Token_IF':
    459                 case 'PHP_Token_ELSEIF':
    460                 case 'PHP_Token_FOR':
    461                 case 'PHP_Token_FOREACH':
    462                 case 'PHP_Token_WHILE':
    463                 case 'PHP_Token_CASE':
    464                 case 'PHP_Token_CATCH':
    465                 case 'PHP_Token_BOOLEAN_AND':
    466                 case 'PHP_Token_LOGICAL_AND':
    467                 case 'PHP_Token_BOOLEAN_OR':
    468                 case 'PHP_Token_LOGICAL_OR':
    469                 case 'PHP_Token_QUESTION_MARK': {
    470                     $this->ccn++;
    471                 }
    472                 break;
    473             }
    474         }
    475 
    476         return $this->ccn;
    477     }
    478 
    479     public function getSignature()
    480     {
    481         if ($this->signature !== NULL) {
    482             return $this->signature;
    483         }
    484 
    485         if ($this->getName() == 'anonymous function') {
    486             $this->signature = 'anonymous function';
    487             $i               = $this->id + 1;
    488         } else {
    489             $this->signature = '';
    490             $i               = $this->id + 2;
    491         }
    492 
    493         $tokens = $this->tokenStream->tokens();
    494 
    495         while (isset($tokens[$i]) &&
    496                !$tokens[$i] instanceof PHP_Token_OPEN_CURLY &&
    497                !$tokens[$i] instanceof PHP_Token_SEMICOLON) {
    498             $this->signature .= $tokens[$i++];
    499         }
    500 
    501         $this->signature = trim($this->signature);
    502 
    503         return $this->signature;
    504     }
    505 }
    506 
    507 class PHP_Token_CONST extends PHP_Token {}
    508 class PHP_Token_RETURN extends PHP_Token {}
    509 class PHP_Token_YIELD extends PHP_Token {}
    510 class PHP_Token_TRY extends PHP_Token {}
    511 class PHP_Token_CATCH extends PHP_Token {}
    512 class PHP_Token_FINALLY extends PHP_Token {}
    513 class PHP_Token_THROW extends PHP_Token {}
    514 class PHP_Token_USE extends PHP_Token {}
    515 class PHP_Token_GLOBAL extends PHP_Token {}
    516 class PHP_Token_PUBLIC extends PHP_Token {}
    517 class PHP_Token_PROTECTED extends PHP_Token {}
    518 class PHP_Token_PRIVATE extends PHP_Token {}
    519 class PHP_Token_FINAL extends PHP_Token {}
    520 class PHP_Token_ABSTRACT extends PHP_Token {}
    521 class PHP_Token_STATIC extends PHP_Token {}
    522 class PHP_Token_VAR extends PHP_Token {}
    523 class PHP_Token_UNSET extends PHP_Token {}
    524 class PHP_Token_ISSET extends PHP_Token {}
    525 class PHP_Token_EMPTY extends PHP_Token {}
    526 class PHP_Token_HALT_COMPILER extends PHP_Token {}
    527 
    528 class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility
    529 {
    530     protected $interfaces;
    531 
    532     public function getName()
    533     {
    534         return (string)$this->tokenStream[$this->id + 2];
    535     }
    536 
    537     public function hasParent()
    538     {
    539         return $this->tokenStream[$this->id + 4] instanceof PHP_Token_EXTENDS;
    540     }
    541 
    542     public function getPackage()
    543     {
    544         $className  = $this->getName();
    545         $docComment = $this->getDocblock();
    546 
    547         $result = array(
    548           'namespace'   => '',
    549           'fullPackage' => '',
    550           'category'    => '',
    551           'package'     => '',
    552           'subpackage'  => ''
    553         );
    554 
    555         for ($i = $this->id; $i; --$i) {
    556             if ($this->tokenStream[$i] instanceof PHP_Token_NAMESPACE) {
    557                 $result['namespace'] = $this->tokenStream[$i]->getName();
    558                 break;
    559             }
    560         }
    561 
    562         if (preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) {
    563             $result['category'] = $matches[1];
    564         }
    565 
    566         if (preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) {
    567             $result['package']     = $matches[1];
    568             $result['fullPackage'] = $matches[1];
    569         }
    570 
    571         if (preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) {
    572             $result['subpackage']   = $matches[1];
    573             $result['fullPackage'] .= '.' . $matches[1];
    574         }
    575 
    576         if (empty($result['fullPackage'])) {
    577             $result['fullPackage'] = $this->arrayToName(
    578               explode('_', str_replace('\\', '_', $className)), '.'
    579             );
    580         }
    581 
    582         return $result;
    583     }
    584 
    585     protected function arrayToName(array $parts, $join = '\\')
    586     {
    587         $result = '';
    588 
    589         if (count($parts) > 1) {
    590             array_pop($parts);
    591 
    592             $result = join($join, $parts);
    593         }
    594 
    595         return $result;
    596     }
    597 
    598     public function getParent()
    599     {
    600         if (!$this->hasParent()) {
    601             return FALSE;
    602         }
    603 
    604         $i         = $this->id + 6;
    605         $tokens    = $this->tokenStream->tokens();
    606         $className = (string)$tokens[$i];
    607 
    608         while (isset($tokens[$i+1]) &&
    609                !$tokens[$i+1] instanceof PHP_Token_WHITESPACE) {
    610             $className .= (string)$tokens[++$i];
    611         }
    612 
    613         return $className;
    614     }
    615 
    616     public function hasInterfaces()
    617     {
    618         return (isset($this->tokenStream[$this->id + 4]) &&
    619                 $this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) ||
    620                (isset($this->tokenStream[$this->id + 8]) &&
    621                 $this->tokenStream[$this->id + 8] instanceof PHP_Token_IMPLEMENTS);
    622     }
    623 
    624     public function getInterfaces()
    625     {
    626         if ($this->interfaces !== NULL) {
    627             return $this->interfaces;
    628         }
    629 
    630         if (!$this->hasInterfaces()) {
    631             return ($this->interfaces = FALSE);
    632         }
    633 
    634         if ($this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) {
    635             $i = $this->id + 3;
    636         } else {
    637             $i = $this->id + 7;
    638         }
    639 
    640         $tokens = $this->tokenStream->tokens();
    641 
    642         while (!$tokens[$i+1] instanceof PHP_Token_OPEN_CURLY) {
    643             $i++;
    644 
    645             if ($tokens[$i] instanceof PHP_Token_STRING) {
    646                 $this->interfaces[] = (string)$tokens[$i];
    647             }
    648         }
    649 
    650         return $this->interfaces;
    651     }
    652 }
    653 
    654 class PHP_Token_CLASS extends PHP_Token_INTERFACE {}
    655 class PHP_Token_CLASS_NAME_CONSTANT extends PHP_Token {}
    656 class PHP_Token_TRAIT extends PHP_Token_INTERFACE {}
    657 class PHP_Token_EXTENDS extends PHP_Token {}
    658 class PHP_Token_IMPLEMENTS extends PHP_Token {}
    659 class PHP_Token_OBJECT_OPERATOR extends PHP_Token {}
    660 class PHP_Token_DOUBLE_ARROW extends PHP_Token {}
    661 class PHP_Token_LIST extends PHP_Token {}
    662 class PHP_Token_ARRAY extends PHP_Token {}
    663 class PHP_Token_CLASS_C extends PHP_Token {}
    664 class PHP_Token_TRAIT_C extends PHP_Token {}
    665 class PHP_Token_METHOD_C extends PHP_Token {}
    666 class PHP_Token_FUNC_C extends PHP_Token {}
    667 class PHP_Token_LINE extends PHP_Token {}
    668 class PHP_Token_FILE extends PHP_Token {}
    669 class PHP_Token_COMMENT extends PHP_Token {}
    670 class PHP_Token_DOC_COMMENT extends PHP_Token {}
    671 class PHP_Token_OPEN_TAG extends PHP_Token {}
    672 class PHP_Token_OPEN_TAG_WITH_ECHO extends PHP_Token {}
    673 class PHP_Token_CLOSE_TAG extends PHP_Token {}
    674 class PHP_Token_WHITESPACE extends PHP_Token {}
    675 class PHP_Token_START_HEREDOC extends PHP_Token {}
    676 class PHP_Token_END_HEREDOC extends PHP_Token {}
    677 class PHP_Token_DOLLAR_OPEN_CURLY_BRACES extends PHP_Token {}
    678 class PHP_Token_CURLY_OPEN extends PHP_Token {}
    679 class PHP_Token_PAAMAYIM_NEKUDOTAYIM extends PHP_Token {}
    680 
    681 class PHP_Token_NAMESPACE extends PHP_TokenWithScope
    682 {
    683     public function getName()
    684     {
    685         $tokens    = $this->tokenStream->tokens();
    686         $namespace = (string)$tokens[$this->id+2];
    687 
    688         for ($i = $this->id + 3; ; $i += 2) {
    689             if (isset($tokens[$i]) &&
    690                 $tokens[$i] instanceof PHP_Token_NS_SEPARATOR) {
    691                 $namespace .= '\\' . $tokens[$i+1];
    692             } else {
    693                 break;
    694             }
    695         }
    696 
    697         return $namespace;
    698     }
    699 }
    700 
    701 class PHP_Token_NS_C extends PHP_Token {}
    702 class PHP_Token_DIR extends PHP_Token {}
    703 class PHP_Token_NS_SEPARATOR extends PHP_Token {}
    704 class PHP_Token_DOUBLE_COLON extends PHP_Token {}
    705 class PHP_Token_OPEN_BRACKET extends PHP_Token {}
    706 class PHP_Token_CLOSE_BRACKET extends PHP_Token {}
    707 class PHP_Token_OPEN_SQUARE extends PHP_Token {}
    708 class PHP_Token_CLOSE_SQUARE extends PHP_Token {}
    709 class PHP_Token_OPEN_CURLY extends PHP_Token {}
    710 class PHP_Token_CLOSE_CURLY extends PHP_Token {}
    711 class PHP_Token_SEMICOLON extends PHP_Token {}
    712 class PHP_Token_DOT extends PHP_Token {}
    713 class PHP_Token_COMMA extends PHP_Token {}
    714 class PHP_Token_EQUAL extends PHP_Token {}
    715 class PHP_Token_LT extends PHP_Token {}
    716 class PHP_Token_GT extends PHP_Token {}
    717 class PHP_Token_PLUS extends PHP_Token {}
    718 class PHP_Token_MINUS extends PHP_Token {}
    719 class PHP_Token_MULT extends PHP_Token {}
    720 class PHP_Token_DIV extends PHP_Token {}
    721 class PHP_Token_QUESTION_MARK extends PHP_Token {}
    722 class PHP_Token_EXCLAMATION_MARK extends PHP_Token {}
    723 class PHP_Token_COLON extends PHP_Token {}
    724 class PHP_Token_DOUBLE_QUOTES extends PHP_Token {}
    725 class PHP_Token_AT extends PHP_Token {}
    726 class PHP_Token_AMPERSAND extends PHP_Token {}
    727 class PHP_Token_PERCENT extends PHP_Token {}
    728 class PHP_Token_PIPE extends PHP_Token {}
    729 class PHP_Token_DOLLAR extends PHP_Token {}
    730 class PHP_Token_CARET extends PHP_Token {}
    731 class PHP_Token_TILDE extends PHP_Token {}
    732 class PHP_Token_BACKTICK extends PHP_Token {}