[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/zendframework/zend-code/src/Scanner/ -> MethodScanner.php (source)

   1  <?php
   2  /**
   3   * Zend Framework (http://framework.zend.com/)
   4   *
   5   * @link      http://github.com/zendframework/zf2 for the canonical source repository
   6   * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
   7   * @license   http://framework.zend.com/license/new-bsd New BSD License
   8   */
   9  
  10  namespace Zend\Code\Scanner;
  11  
  12  use Zend\Code\Annotation\AnnotationManager;
  13  use Zend\Code\Exception;
  14  use Zend\Code\NameInformation;
  15  
  16  class MethodScanner implements ScannerInterface
  17  {
  18      /**
  19       * @var bool
  20       */
  21      protected $isScanned    = false;
  22  
  23      /**
  24       * @var string
  25       */
  26      protected $docComment   = null;
  27  
  28      /**
  29       * @var ClassScanner
  30       */
  31      protected $scannerClass = null;
  32  
  33      /**
  34       * @var string
  35       */
  36      protected $class        = null;
  37  
  38      /**
  39       * @var string
  40       */
  41      protected $name         = null;
  42  
  43      /**
  44       * @var int
  45       */
  46      protected $lineStart    = null;
  47  
  48      /**
  49       * @var int
  50       */
  51      protected $lineEnd      = null;
  52  
  53      /**
  54       * @var bool
  55       */
  56      protected $isFinal = false;
  57  
  58      /**
  59       * @var bool
  60       */
  61      protected $isAbstract = false;
  62  
  63      /**
  64       * @var bool
  65       */
  66      protected $isPublic = true;
  67  
  68      /**
  69       * @var bool
  70       */
  71      protected $isProtected = false;
  72  
  73      /**
  74       * @var bool
  75       */
  76      protected $isPrivate = false;
  77  
  78      /**
  79       * @var bool
  80       */
  81      protected $isStatic = false;
  82  
  83      /**
  84       * @var string
  85       */
  86      protected $body = '';
  87  
  88      /**
  89       * @var array
  90       */
  91      protected $tokens = array();
  92  
  93      /**
  94       * @var NameInformation
  95       */
  96      protected $nameInformation = null;
  97  
  98      /**
  99       * @var array
 100       */
 101      protected $infos = array();
 102  
 103      /**
 104       * @param  array $methodTokens
 105       * @param NameInformation $nameInformation
 106       */
 107      public function __construct(array $methodTokens, NameInformation $nameInformation = null)
 108      {
 109          $this->tokens          = $methodTokens;
 110          $this->nameInformation = $nameInformation;
 111      }
 112  
 113      /**
 114       * @param  string $class
 115       * @return MethodScanner
 116       */
 117      public function setClass($class)
 118      {
 119          $this->class = (string) $class;
 120          return $this;
 121      }
 122  
 123      /**
 124       * @param  ClassScanner  $scannerClass
 125       * @return MethodScanner
 126       */
 127      public function setScannerClass(ClassScanner $scannerClass)
 128      {
 129          $this->scannerClass = $scannerClass;
 130          return $this;
 131      }
 132  
 133      /**
 134       * @return MethodScanner
 135       */
 136      public function getClassScanner()
 137      {
 138          return $this->scannerClass;
 139      }
 140  
 141      /**
 142       * @return string
 143       */
 144      public function getName()
 145      {
 146          $this->scan();
 147  
 148          return $this->name;
 149      }
 150  
 151      /**
 152       * @return int
 153       */
 154      public function getLineStart()
 155      {
 156          $this->scan();
 157  
 158          return $this->lineStart;
 159      }
 160  
 161      /**
 162       * @return int
 163       */
 164      public function getLineEnd()
 165      {
 166          $this->scan();
 167  
 168          return $this->lineEnd;
 169      }
 170  
 171      /**
 172       * @return string
 173       */
 174      public function getDocComment()
 175      {
 176          $this->scan();
 177  
 178          return $this->docComment;
 179      }
 180  
 181      /**
 182       * @param  AnnotationManager $annotationManager
 183       * @return AnnotationScanner
 184       */
 185      public function getAnnotations(AnnotationManager $annotationManager)
 186      {
 187          if (($docComment = $this->getDocComment()) == '') {
 188              return false;
 189          }
 190  
 191          return new AnnotationScanner($annotationManager, $docComment, $this->nameInformation);
 192      }
 193  
 194      /**
 195       * @return bool
 196       */
 197      public function isFinal()
 198      {
 199          $this->scan();
 200  
 201          return $this->isFinal;
 202      }
 203  
 204      /**
 205       * @return bool
 206       */
 207      public function isAbstract()
 208      {
 209          $this->scan();
 210  
 211          return $this->isAbstract;
 212      }
 213  
 214      /**
 215       * @return bool
 216       */
 217      public function isPublic()
 218      {
 219          $this->scan();
 220  
 221          return $this->isPublic;
 222      }
 223  
 224      /**
 225       * @return bool
 226       */
 227      public function isProtected()
 228      {
 229          $this->scan();
 230  
 231          return $this->isProtected;
 232      }
 233  
 234      /**
 235       * @return bool
 236       */
 237      public function isPrivate()
 238      {
 239          $this->scan();
 240  
 241          return $this->isPrivate;
 242      }
 243  
 244      /**
 245       * @return bool
 246       */
 247      public function isStatic()
 248      {
 249          $this->scan();
 250  
 251          return $this->isStatic;
 252      }
 253  
 254      /**
 255       * Override the given name for a method, this is necessary to
 256       * support traits.
 257       *
 258       * @param $name
 259       * @return self
 260       */
 261      public function setName($name)
 262      {
 263          $this->name = $name;
 264          return $this;
 265      }
 266  
 267      /**
 268       * Visibility must be of T_PUBLIC, T_PRIVATE or T_PROTECTED
 269       * Needed to support traits
 270       *
 271       * @param $visibility   T_PUBLIC | T_PRIVATE | T_PROTECTED
 272       * @return self
 273       * @throws \Zend\Code\Exception
 274       */
 275      public function setVisibility($visibility)
 276      {
 277          switch (strtolower($visibility)) {
 278              case T_PUBLIC:
 279                  $this->isPublic = true;
 280                  $this->isPrivate = false;
 281                  $this->isProtected = false;
 282                  break;
 283  
 284              case T_PRIVATE:
 285                  $this->isPublic = false;
 286                  $this->isPrivate = true;
 287                  $this->isProtected = false;
 288                  break;
 289  
 290              case T_PROTECTED:
 291                  $this->isPublic = false;
 292                  $this->isPrivate = false;
 293                  $this->isProtected = true;
 294                  break;
 295  
 296              default:
 297                  throw new Exception("Invalid visibility argument passed to setVisibility.");
 298          }
 299  
 300          return $this;
 301      }
 302  
 303      /**
 304       * @return int
 305       */
 306      public function getNumberOfParameters()
 307      {
 308          return count($this->getParameters());
 309      }
 310  
 311      /**
 312       * @param  bool $returnScanner
 313       * @return array
 314       */
 315      public function getParameters($returnScanner = false)
 316      {
 317          $this->scan();
 318  
 319          $return = array();
 320  
 321          foreach ($this->infos as $info) {
 322              if ($info['type'] != 'parameter') {
 323                  continue;
 324              }
 325  
 326              if (!$returnScanner) {
 327                  $return[] = $info['name'];
 328              } else {
 329                  $return[] = $this->getParameter($info['name']);
 330              }
 331          }
 332  
 333          return $return;
 334      }
 335  
 336      /**
 337       * @param  int|string $parameterNameOrInfoIndex
 338       * @return ParameterScanner
 339       * @throws Exception\InvalidArgumentException
 340       */
 341      public function getParameter($parameterNameOrInfoIndex)
 342      {
 343          $this->scan();
 344  
 345          if (is_int($parameterNameOrInfoIndex)) {
 346              $info = $this->infos[$parameterNameOrInfoIndex];
 347              if ($info['type'] != 'parameter') {
 348                  throw new Exception\InvalidArgumentException('Index of info offset is not about a parameter');
 349              }
 350          } elseif (is_string($parameterNameOrInfoIndex)) {
 351              foreach ($this->infos as $info) {
 352                  if ($info['type'] === 'parameter' && $info['name'] === $parameterNameOrInfoIndex) {
 353                      break;
 354                  }
 355                  unset($info);
 356              }
 357              if (!isset($info)) {
 358                  throw new Exception\InvalidArgumentException('Index of info offset is not about a parameter');
 359              }
 360          }
 361  
 362          $p = new ParameterScanner(
 363              array_slice($this->tokens, $info['tokenStart'], $info['tokenEnd'] - $info['tokenStart']),
 364              $this->nameInformation
 365          );
 366          $p->setDeclaringFunction($this->name);
 367          $p->setDeclaringScannerFunction($this);
 368          $p->setDeclaringClass($this->class);
 369          $p->setDeclaringScannerClass($this->scannerClass);
 370          $p->setPosition($info['position']);
 371  
 372          return $p;
 373      }
 374  
 375      /**
 376       * @return string
 377       */
 378      public function getBody()
 379      {
 380          $this->scan();
 381  
 382          return $this->body;
 383      }
 384  
 385      public static function export()
 386      {
 387          // @todo
 388      }
 389  
 390      public function __toString()
 391      {
 392          $this->scan();
 393  
 394          return var_export($this, true);
 395      }
 396  
 397      protected function scan()
 398      {
 399          if ($this->isScanned) {
 400              return;
 401          }
 402  
 403          if (!$this->tokens) {
 404              throw new Exception\RuntimeException('No tokens were provided');
 405          }
 406  
 407          /**
 408           * Variables & Setup
 409           */
 410  
 411          $tokens       = &$this->tokens; // localize
 412          $infos        = &$this->infos; // localize
 413          $tokenIndex   = null;
 414          $token        = null;
 415          $tokenType    = null;
 416          $tokenContent = null;
 417          $tokenLine    = null;
 418          $infoIndex    = 0;
 419          $parentCount  = 0;
 420  
 421          /*
 422           * MACRO creation
 423           */
 424          $MACRO_TOKEN_ADVANCE = function () use (
 425              &$tokens,
 426              &$tokenIndex,
 427              &$token,
 428              &$tokenType,
 429              &$tokenContent,
 430              &$tokenLine
 431          ) {
 432              static $lastTokenArray = null;
 433              $tokenIndex = ($tokenIndex === null) ? 0 : $tokenIndex + 1;
 434              if (!isset($tokens[$tokenIndex])) {
 435                  $token        = false;
 436                  $tokenContent = false;
 437                  $tokenType    = false;
 438                  $tokenLine    = false;
 439  
 440                  return false;
 441              }
 442              $token = $tokens[$tokenIndex];
 443              if (is_string($token)) {
 444                  $tokenType    = null;
 445                  $tokenContent = $token;
 446                  $tokenLine    = $tokenLine + substr_count(
 447                      $lastTokenArray[1],
 448                      "\n"
 449                  ); // adjust token line by last known newline count
 450              } else {
 451                  list($tokenType, $tokenContent, $tokenLine) = $token;
 452              }
 453  
 454              return $tokenIndex;
 455          };
 456          $MACRO_INFO_START    = function () use (&$infoIndex, &$infos, &$tokenIndex, &$tokenLine) {
 457              $infos[$infoIndex] = array(
 458                  'type'        => 'parameter',
 459                  'tokenStart'  => $tokenIndex,
 460                  'tokenEnd'    => null,
 461                  'lineStart'   => $tokenLine,
 462                  'lineEnd'     => $tokenLine,
 463                  'name'        => null,
 464                  'position'    => $infoIndex + 1, // position is +1 of infoIndex
 465              );
 466          };
 467          $MACRO_INFO_ADVANCE  = function () use (&$infoIndex, &$infos, &$tokenIndex, &$tokenLine) {
 468              $infos[$infoIndex]['tokenEnd'] = $tokenIndex;
 469              $infos[$infoIndex]['lineEnd']  = $tokenLine;
 470              $infoIndex++;
 471  
 472              return $infoIndex;
 473          };
 474  
 475          /**
 476           * START FINITE STATE MACHINE FOR SCANNING TOKENS
 477           */
 478  
 479          // Initialize token
 480          $MACRO_TOKEN_ADVANCE();
 481  
 482          SCANNER_TOP:
 483  
 484          $this->lineStart = ($this->lineStart) ? : $tokenLine;
 485  
 486          switch ($tokenType) {
 487              case T_DOC_COMMENT:
 488                  $this->lineStart = null;
 489                  if ($this->docComment === null && $this->name === null) {
 490                      $this->docComment = $tokenContent;
 491                  }
 492                  goto SCANNER_CONTINUE_SIGNATURE;
 493                  //goto (no break needed);
 494  
 495              case T_FINAL:
 496                  $this->isFinal = true;
 497                  goto SCANNER_CONTINUE_SIGNATURE;
 498                  //goto (no break needed);
 499  
 500              case T_ABSTRACT:
 501                  $this->isAbstract = true;
 502                  goto SCANNER_CONTINUE_SIGNATURE;
 503                  //goto (no break needed);
 504  
 505              case T_PUBLIC:
 506                  // use defaults
 507                  goto SCANNER_CONTINUE_SIGNATURE;
 508                  //goto (no break needed);
 509  
 510              case T_PROTECTED:
 511                  $this->setVisibility(T_PROTECTED);
 512                  goto SCANNER_CONTINUE_SIGNATURE;
 513                  //goto (no break needed);
 514  
 515              case T_PRIVATE:
 516                  $this->setVisibility(T_PRIVATE);
 517                  goto SCANNER_CONTINUE_SIGNATURE;
 518                  //goto (no break needed);
 519  
 520              case T_STATIC:
 521                  $this->isStatic = true;
 522                  goto SCANNER_CONTINUE_SIGNATURE;
 523                  //goto (no break needed);
 524  
 525              case T_VARIABLE:
 526              case T_STRING:
 527  
 528                  if ($tokenType === T_STRING && $parentCount === 0) {
 529                      $this->name = $tokenContent;
 530                  }
 531  
 532                  if ($parentCount === 1) {
 533                      if (!isset($infos[$infoIndex])) {
 534                          $MACRO_INFO_START();
 535                      }
 536                      if ($tokenType === T_VARIABLE) {
 537                          $infos[$infoIndex]['name'] = ltrim($tokenContent, '$');
 538                      }
 539                  }
 540  
 541                  goto SCANNER_CONTINUE_SIGNATURE;
 542                  //goto (no break needed);
 543  
 544              case null:
 545  
 546                  switch ($tokenContent) {
 547                      case '&':
 548                          if (!isset($infos[$infoIndex])) {
 549                              $MACRO_INFO_START();
 550                          }
 551                          goto SCANNER_CONTINUE_SIGNATURE;
 552                          //goto (no break needed);
 553                      case '(':
 554                          $parentCount++;
 555                          goto SCANNER_CONTINUE_SIGNATURE;
 556                          //goto (no break needed);
 557                      case ')':
 558                          $parentCount--;
 559                          if ($parentCount > 0) {
 560                              goto SCANNER_CONTINUE_SIGNATURE;
 561                          }
 562                          if ($parentCount === 0) {
 563                              if ($infos) {
 564                                  $MACRO_INFO_ADVANCE();
 565                              }
 566                              $context = 'body';
 567                          }
 568                          goto SCANNER_CONTINUE_BODY;
 569                          //goto (no break needed);
 570                      case ',':
 571                          if ($parentCount === 1) {
 572                              $MACRO_INFO_ADVANCE();
 573                          }
 574                          goto SCANNER_CONTINUE_SIGNATURE;
 575                  }
 576          }
 577  
 578          SCANNER_CONTINUE_SIGNATURE:
 579  
 580          if ($MACRO_TOKEN_ADVANCE() === false) {
 581              goto SCANNER_END;
 582          }
 583          goto SCANNER_TOP;
 584  
 585          SCANNER_CONTINUE_BODY:
 586  
 587          $braceCount = 0;
 588          while ($MACRO_TOKEN_ADVANCE() !== false) {
 589              if ($tokenContent == '}') {
 590                  $braceCount--;
 591              }
 592              if ($braceCount > 0) {
 593                  $this->body .= $tokenContent;
 594              }
 595              if ($tokenContent == '{') {
 596                  $braceCount++;
 597              }
 598              $this->lineEnd = $tokenLine;
 599          }
 600  
 601          SCANNER_END:
 602  
 603          $this->isScanned = true;
 604  
 605          return;
 606      }
 607  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1