Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

MethodScanner.php

Zuletzt modifiziert: 01.05.2026, 11:27 - Dateigröße: 14.67 KiB


 001  <?php
 002  /**
 003   * Zend Framework (http://framework.zend.com/)
 004   *
 005   * @link      http://github.com/zendframework/zf2 for the canonical source repository
 006   * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
 007   * @license   http://framework.zend.com/license/new-bsd New BSD License
 008   */
 009   
 010  namespace Zend\Code\Scanner;
 011   
 012  use Zend\Code\Annotation\AnnotationManager;
 013  use Zend\Code\Exception;
 014  use Zend\Code\NameInformation;
 015   
 016  use function array_slice;
 017  use function count;
 018  use function is_int;
 019  use function is_string;
 020  use function ltrim;
 021  use function strtolower;
 022  use function substr_count;
 023  use function var_export;
 024   
 025  class MethodScanner implements ScannerInterface
 026  {
 027      /**
 028       * @var bool
 029       */
 030      protected $isScanned = false;
 031   
 032      /**
 033       * @var string
 034       */
 035      protected $docComment;
 036   
 037      /**
 038       * @var ClassScanner
 039       */
 040      protected $scannerClass;
 041   
 042      /**
 043       * @var string
 044       */
 045      protected $class;
 046   
 047      /**
 048       * @var string
 049       */
 050      protected $name;
 051   
 052      /**
 053       * @var int
 054       */
 055      protected $lineStart;
 056   
 057      /**
 058       * @var int
 059       */
 060      protected $lineEnd;
 061   
 062      /**
 063       * @var bool
 064       */
 065      protected $isFinal = false;
 066   
 067      /**
 068       * @var bool
 069       */
 070      protected $isAbstract = false;
 071   
 072      /**
 073       * @var bool
 074       */
 075      protected $isPublic = true;
 076   
 077      /**
 078       * @var bool
 079       */
 080      protected $isProtected = false;
 081   
 082      /**
 083       * @var bool
 084       */
 085      protected $isPrivate = false;
 086   
 087      /**
 088       * @var bool
 089       */
 090      protected $isStatic = false;
 091   
 092      /**
 093       * @var string
 094       */
 095      protected $body = '';
 096   
 097      /**
 098       * @var array
 099       */
 100      protected $tokens = [];
 101   
 102      /**
 103       * @var NameInformation
 104       */
 105      protected $nameInformation;
 106   
 107      /**
 108       * @var array
 109       */
 110      protected $infos = [];
 111   
 112      /**
 113       * @param  array $methodTokens
 114       * @param NameInformation $nameInformation
 115       */
 116      public function __construct(array $methodTokens, NameInformation $nameInformation = null)
 117      {
 118          $this->tokens          = $methodTokens;
 119          $this->nameInformation = $nameInformation;
 120      }
 121   
 122      /**
 123       * @param  string $class
 124       * @return MethodScanner
 125       */
 126      public function setClass($class)
 127      {
 128          $this->class = (string) $class;
 129          return $this;
 130      }
 131   
 132      /**
 133       * @param  ClassScanner  $scannerClass
 134       * @return MethodScanner
 135       */
 136      public function setScannerClass(ClassScanner $scannerClass)
 137      {
 138          $this->scannerClass = $scannerClass;
 139          return $this;
 140      }
 141   
 142      /**
 143       * @return ClassScanner
 144       */
 145      public function getClassScanner()
 146      {
 147          return $this->scannerClass;
 148      }
 149   
 150      /**
 151       * @return string
 152       */
 153      public function getName()
 154      {
 155          $this->scan();
 156   
 157          return $this->name;
 158      }
 159   
 160      /**
 161       * @return int
 162       */
 163      public function getLineStart()
 164      {
 165          $this->scan();
 166   
 167          return $this->lineStart;
 168      }
 169   
 170      /**
 171       * @return int
 172       */
 173      public function getLineEnd()
 174      {
 175          $this->scan();
 176   
 177          return $this->lineEnd;
 178      }
 179   
 180      /**
 181       * @return string
 182       */
 183      public function getDocComment()
 184      {
 185          $this->scan();
 186   
 187          return $this->docComment;
 188      }
 189   
 190      /**
 191       * @param  AnnotationManager $annotationManager
 192       * @return AnnotationScanner|false
 193       */
 194      public function getAnnotations(AnnotationManager $annotationManager)
 195      {
 196          if (($docComment = $this->getDocComment()) == '') {
 197              return false;
 198          }
 199   
 200          return new AnnotationScanner($annotationManager, $docComment, $this->nameInformation);
 201      }
 202   
 203      /**
 204       * @return bool
 205       */
 206      public function isFinal()
 207      {
 208          $this->scan();
 209   
 210          return $this->isFinal;
 211      }
 212   
 213      /**
 214       * @return bool
 215       */
 216      public function isAbstract()
 217      {
 218          $this->scan();
 219   
 220          return $this->isAbstract;
 221      }
 222   
 223      /**
 224       * @return bool
 225       */
 226      public function isPublic()
 227      {
 228          $this->scan();
 229   
 230          return $this->isPublic;
 231      }
 232   
 233      /**
 234       * @return bool
 235       */
 236      public function isProtected()
 237      {
 238          $this->scan();
 239   
 240          return $this->isProtected;
 241      }
 242   
 243      /**
 244       * @return bool
 245       */
 246      public function isPrivate()
 247      {
 248          $this->scan();
 249   
 250          return $this->isPrivate;
 251      }
 252   
 253      /**
 254       * @return bool
 255       */
 256      public function isStatic()
 257      {
 258          $this->scan();
 259   
 260          return $this->isStatic;
 261      }
 262   
 263      /**
 264       * Override the given name for a method, this is necessary to
 265       * support traits.
 266       *
 267       * @param string $name
 268       * @return self
 269       */
 270      public function setName($name)
 271      {
 272          $this->name = $name;
 273          return $this;
 274      }
 275   
 276      /**
 277       * Visibility must be of T_PUBLIC, T_PRIVATE or T_PROTECTED
 278       * Needed to support traits
 279       *
 280       * @param int $visibility   T_PUBLIC | T_PRIVATE | T_PROTECTED
 281       * @return self
 282       * @throws \Zend\Code\Exception\InvalidArgumentException
 283       */
 284      public function setVisibility($visibility)
 285      {
 286          switch ($visibility) {
 287              case T_PUBLIC:
 288                  $this->isPublic = true;
 289                  $this->isPrivate = false;
 290                  $this->isProtected = false;
 291                  break;
 292   
 293              case T_PRIVATE:
 294                  $this->isPublic = false;
 295                  $this->isPrivate = true;
 296                  $this->isProtected = false;
 297                  break;
 298   
 299              case T_PROTECTED:
 300                  $this->isPublic = false;
 301                  $this->isPrivate = false;
 302                  $this->isProtected = true;
 303                  break;
 304   
 305              default:
 306                  throw new Exception\InvalidArgumentException('Invalid visibility argument passed to setVisibility.');
 307          }
 308   
 309          return $this;
 310      }
 311   
 312      /**
 313       * @return int
 314       */
 315      public function getNumberOfParameters()
 316      {
 317          return count($this->getParameters());
 318      }
 319   
 320      /**
 321       * @param  bool $returnScanner
 322       * @return array
 323       */
 324      public function getParameters($returnScanner = false)
 325      {
 326          $this->scan();
 327   
 328          $return = [];
 329   
 330          foreach ($this->infos as $info) {
 331              if ($info['type'] != 'parameter') {
 332                  continue;
 333              }
 334   
 335              if (! $returnScanner) {
 336                  $return[] = $info['name'];
 337              } else {
 338                  $return[] = $this->getParameter($info['name']);
 339              }
 340          }
 341   
 342          return $return;
 343      }
 344   
 345      /**
 346       * @param  int|string $parameterNameOrInfoIndex
 347       * @return ParameterScanner
 348       * @throws Exception\InvalidArgumentException
 349       */
 350      public function getParameter($parameterNameOrInfoIndex)
 351      {
 352          $this->scan();
 353   
 354          if (is_int($parameterNameOrInfoIndex)) {
 355              $info = $this->infos[$parameterNameOrInfoIndex];
 356              if ($info['type'] != 'parameter') {
 357                  throw new Exception\InvalidArgumentException('Index of info offset is not about a parameter');
 358              }
 359          } elseif (is_string($parameterNameOrInfoIndex)) {
 360              foreach ($this->infos as $info) {
 361                  if ($info['type'] === 'parameter' && $info['name'] === $parameterNameOrInfoIndex) {
 362                      break;
 363                  }
 364                  unset($info);
 365              }
 366              if (! isset($info)) {
 367                  throw new Exception\InvalidArgumentException('Index of info offset is not about a parameter');
 368              }
 369          }
 370   
 371          $p = new ParameterScanner(
 372              array_slice($this->tokens, $info['tokenStart'], $info['tokenEnd'] - $info['tokenStart']),
 373              $this->nameInformation
 374          );
 375          $p->setDeclaringFunction($this->name);
 376          $p->setDeclaringScannerFunction($this);
 377          $p->setDeclaringClass($this->class);
 378          $p->setDeclaringScannerClass($this->scannerClass);
 379          $p->setPosition($info['position']);
 380   
 381          return $p;
 382      }
 383   
 384      /**
 385       * @return string
 386       */
 387      public function getBody()
 388      {
 389          $this->scan();
 390   
 391          return $this->body;
 392      }
 393   
 394      public static function export()
 395      {
 396          // @todo
 397      }
 398   
 399      public function __toString()
 400      {
 401          $this->scan();
 402   
 403          return var_export($this, true);
 404      }
 405   
 406      protected function scan()
 407      {
 408          if ($this->isScanned) {
 409              return;
 410          }
 411   
 412          if (! $this->tokens) {
 413              throw new Exception\RuntimeException('No tokens were provided');
 414          }
 415   
 416          /**
 417           * Variables & Setup
 418           */
 419          $tokens       = &$this->tokens; // localize
 420          $infos        = &$this->infos; // localize
 421          $tokenIndex   = null;
 422          $token        = null;
 423          $tokenType    = null;
 424          $tokenContent = null;
 425          $tokenLine    = null;
 426          $infoIndex    = 0;
 427          $parentCount  = 0;
 428   
 429          /*
 430           * MACRO creation
 431           */
 432          $MACRO_TOKEN_ADVANCE = function () use (
 433              &$tokens,
 434              &$tokenIndex,
 435              &$token,
 436              &$tokenType,
 437              &$tokenContent,
 438              &$tokenLine
 439          ) {
 440              static $lastTokenArray = null;
 441              $tokenIndex = $tokenIndex === null ? 0 : $tokenIndex + 1;
 442              if (! isset($tokens[$tokenIndex])) {
 443                  $token        = false;
 444                  $tokenContent = false;
 445                  $tokenType    = false;
 446                  $tokenLine    = false;
 447   
 448                  return false;
 449              }
 450              $token = $tokens[$tokenIndex];
 451              if (is_string($token)) {
 452                  $tokenType    = null;
 453                  $tokenContent = $token;
 454                  $tokenLine   += substr_count(
 455                      $lastTokenArray[1] ?? '',
 456                      "\n"
 457                  ); // adjust token line by last known newline count
 458              } else {
 459                  $lastTokenArray = $token;
 460                  [$tokenType, $tokenContent, $tokenLine] = $token;
 461              }
 462   
 463              return $tokenIndex;
 464          };
 465          $MACRO_INFO_START    = function () use (&$infoIndex, &$infos, &$tokenIndex, &$tokenLine) {
 466              $infos[$infoIndex] = [
 467                  'type'        => 'parameter',
 468                  'tokenStart'  => $tokenIndex,
 469                  'tokenEnd'    => null,
 470                  'lineStart'   => $tokenLine,
 471                  'lineEnd'     => $tokenLine,
 472                  'name'        => null,
 473                  'position'    => $infoIndex + 1, // position is +1 of infoIndex
 474              ];
 475          };
 476          $MACRO_INFO_ADVANCE  = function () use (&$infoIndex, &$infos, &$tokenIndex, &$tokenLine) {
 477              $infos[$infoIndex]['tokenEnd'] = $tokenIndex;
 478              $infos[$infoIndex]['lineEnd']  = $tokenLine;
 479              $infoIndex++;
 480   
 481              return $infoIndex;
 482          };
 483   
 484          /**
 485           * START FINITE STATE MACHINE FOR SCANNING TOKENS
 486           */
 487          // Initialize token
 488          $MACRO_TOKEN_ADVANCE();
 489   
 490          SCANNER_TOP:
 491   
 492          $this->lineStart = $this->lineStart ? : $tokenLine;
 493   
 494          switch ($tokenType) {
 495              case T_DOC_COMMENT:
 496                  $this->lineStart = null;
 497                  if ($this->docComment === null && $this->name === null) {
 498                      $this->docComment = $tokenContent;
 499                  }
 500                  goto SCANNER_CONTINUE_SIGNATURE;
 501                  // goto (no break needed);
 502   
 503              case T_FINAL:
 504                  $this->isFinal = true;
 505                  goto SCANNER_CONTINUE_SIGNATURE;
 506                  // goto (no break needed);
 507   
 508              case T_ABSTRACT:
 509                  $this->isAbstract = true;
 510                  goto SCANNER_CONTINUE_SIGNATURE;
 511                  // goto (no break needed);
 512   
 513              case T_PUBLIC:
 514                  // use defaults
 515                  goto SCANNER_CONTINUE_SIGNATURE;
 516                  // goto (no break needed);
 517   
 518              case T_PROTECTED:
 519                  $this->setVisibility(T_PROTECTED);
 520                  goto SCANNER_CONTINUE_SIGNATURE;
 521                  // goto (no break needed);
 522   
 523              case T_PRIVATE:
 524                  $this->setVisibility(T_PRIVATE);
 525                  goto SCANNER_CONTINUE_SIGNATURE;
 526                  // goto (no break needed);
 527   
 528              case T_STATIC:
 529                  $this->isStatic = true;
 530                  goto SCANNER_CONTINUE_SIGNATURE;
 531                  // goto (no break needed);
 532   
 533              case T_NS_SEPARATOR:
 534                  if (! isset($infos[$infoIndex])) {
 535                      $MACRO_INFO_START();
 536                  }
 537                  goto SCANNER_CONTINUE_SIGNATURE;
 538                  // goto (no break needed);
 539   
 540              case T_VARIABLE:
 541              case T_STRING:
 542                  if ($tokenType === T_STRING && $parentCount === 0) {
 543                      $this->name = $tokenContent;
 544                  }
 545   
 546                  if ($parentCount === 1) {
 547                      if (! isset($infos[$infoIndex])) {
 548                          $MACRO_INFO_START();
 549                      }
 550                      if ($tokenType === T_VARIABLE) {
 551                          $infos[$infoIndex]['name'] = ltrim($tokenContent, '$');
 552                      }
 553                  }
 554   
 555                  goto SCANNER_CONTINUE_SIGNATURE;
 556                  // goto (no break needed);
 557   
 558              case null:
 559                  switch ($tokenContent) {
 560                      case '&':
 561                          if (! isset($infos[$infoIndex])) {
 562                              $MACRO_INFO_START();
 563                          }
 564                          goto SCANNER_CONTINUE_SIGNATURE;
 565                          // goto (no break needed);
 566                      case '(':
 567                          $parentCount++;
 568                          goto SCANNER_CONTINUE_SIGNATURE;
 569                          // goto (no break needed);
 570                      case ')':
 571                          $parentCount--;
 572                          if ($parentCount > 0) {
 573                              goto SCANNER_CONTINUE_SIGNATURE;
 574                          }
 575                          if ($parentCount === 0) {
 576                              if ($infos) {
 577                                  $MACRO_INFO_ADVANCE();
 578                              }
 579                              $context = 'body';
 580                          }
 581                          goto SCANNER_CONTINUE_BODY;
 582                          // goto (no break needed);
 583                      case ',':
 584                          if ($parentCount === 1) {
 585                              $MACRO_INFO_ADVANCE();
 586                          }
 587                          goto SCANNER_CONTINUE_SIGNATURE;
 588                  }
 589          }
 590   
 591          SCANNER_CONTINUE_SIGNATURE:
 592   
 593          if ($MACRO_TOKEN_ADVANCE() === false) {
 594              goto SCANNER_END;
 595          }
 596          goto SCANNER_TOP;
 597   
 598          SCANNER_CONTINUE_BODY:
 599   
 600          $braceCount = 0;
 601          while ($MACRO_TOKEN_ADVANCE() !== false) {
 602              if ($tokenContent == '}') {
 603                  $braceCount--;
 604              }
 605              if ($braceCount > 0) {
 606                  $this->body .= $tokenContent;
 607              }
 608              if ($tokenContent == '{') {
 609                  $braceCount++;
 610              }
 611              $this->lineEnd = $tokenLine;
 612          }
 613   
 614          SCANNER_END:
 615   
 616          $this->isScanned = true;
 617      }
 618  }
 619