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

AnnotationScanner.php

Zuletzt modifiziert: 01.05.2026, 11:27 - Dateigröße: 12.12 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\AnnotationCollection;
 013  use Zend\Code\Annotation\AnnotationManager;
 014  use Zend\Code\NameInformation;
 015   
 016  use function array_pop;
 017  use function current;
 018  use function in_array;
 019  use function is_string;
 020  use function next;
 021  use function preg_match;
 022  use function reset;
 023  use function strlen;
 024  use function strpos;
 025  use function substr;
 026  use function substr_count;
 027   
 028  class AnnotationScanner extends AnnotationCollection implements ScannerInterface
 029  {
 030      /**
 031       * @var bool
 032       */
 033      protected $isScanned = false;
 034   
 035      /**
 036       * @var string
 037       */
 038      protected $docComment;
 039   
 040      /**
 041       * @var NameInformation
 042       */
 043      protected $nameInformation;
 044   
 045      /**
 046       * @var AnnotationManager
 047       */
 048      protected $annotationManager;
 049   
 050      /**
 051       * @var array
 052       */
 053      protected $annotations = [];
 054   
 055      /**
 056       * @param  AnnotationManager $annotationManager
 057       * @param  string $docComment
 058       * @param  NameInformation $nameInformation
 059       * @return AnnotationScanner
 060       */
 061      public function __construct(
 062          AnnotationManager $annotationManager,
 063          $docComment,
 064          NameInformation $nameInformation = null
 065      ) {
 066          $this->annotationManager = $annotationManager;
 067          $this->docComment        = $docComment;
 068          $this->nameInformation   = $nameInformation;
 069          $this->scan($this->tokenize());
 070      }
 071   
 072      /**
 073       * @param NameInformation $nameInformation
 074       */
 075      public function setNameInformation(NameInformation $nameInformation)
 076      {
 077          $this->nameInformation = $nameInformation;
 078      }
 079   
 080      /**
 081       * @param  array $tokens
 082       */
 083      protected function scan(array $tokens)
 084      {
 085          $annotations     = [];
 086          $annotationIndex = -1;
 087          $contentEnd      = false;
 088   
 089          reset($tokens);
 090   
 091          SCANNER_TOP:
 092          $token = current($tokens);
 093   
 094          switch ($token[0]) {
 095              case 'ANNOTATION_CLASS':
 096                  $contentEnd = false;
 097                  $annotationIndex++;
 098                  $class                         = substr($token[1], 1);
 099                  $class                         = $this->nameInformation->resolveName($class);
 100                  $annotations[$annotationIndex] = [$class, null];
 101                  goto SCANNER_CONTINUE;
 102                  // goto no break needed
 103   
 104              case 'ANNOTATION_CONTENT_START':
 105                  $annotations[$annotationIndex][1] = '';
 106                  // fall-through
 107   
 108              case 'ANNOTATION_CONTENT_END':
 109              case 'ANNOTATION_CONTENT':
 110              case 'ANNOTATION_WHITESPACE':
 111              case 'ANNOTATION_NEWLINE':
 112                  if (! $contentEnd
 113                      && isset($annotations[$annotationIndex])
 114                      && is_string($annotations[$annotationIndex][1])
 115                  ) {
 116                      $annotations[$annotationIndex][1] .= $token[1];
 117                  }
 118   
 119                  if ($token[0] === 'ANNOTATION_CONTENT_END') {
 120                      $contentEnd = true;
 121                  }
 122   
 123                  goto SCANNER_CONTINUE;
 124                  // goto no break needed
 125          }
 126   
 127          SCANNER_CONTINUE:
 128          if (next($tokens) === false) {
 129              goto SCANNER_END;
 130          }
 131          goto SCANNER_TOP;
 132   
 133          SCANNER_END:
 134   
 135          foreach ($annotations as $annotation) {
 136              $annotation[]     = '@' . $annotation[0] . $annotation[1];
 137              $annotationObject = $this->annotationManager->createAnnotation($annotation);
 138              if ($annotationObject) {
 139                  $this->append($annotationObject);
 140              }
 141          }
 142      }
 143   
 144      /**
 145       * @return array
 146       */
 147      protected function tokenize()
 148      {
 149          static $CONTEXT_DOCBLOCK = 0x01;
 150          static $CONTEXT_ASTERISK = 0x02;
 151          static $CONTEXT_CLASS = 0x04;
 152          static $CONTEXT_CONTENT = 0x08;
 153   
 154          $context     = 0x00;
 155          $stream      = $this->docComment;
 156          $streamIndex = null;
 157          $tokens      = [];
 158          $tokenIndex  = null;
 159          $currentChar = null;
 160          $currentWord = null;
 161          $currentLine = null;
 162   
 163          $annotationParentCount = 0;
 164   
 165          $MACRO_STREAM_ADVANCE_CHAR = function ($positionsForward = 1) use (
 166              &$stream,
 167              &$streamIndex,
 168              &$currentChar,
 169              &$currentWord,
 170              &$currentLine
 171          ) {
 172              $positionsForward = $positionsForward > 0 ? $positionsForward : 1;
 173              $streamIndex      = $streamIndex === null ? 0 : $streamIndex + $positionsForward;
 174              if (! isset($stream[$streamIndex])) {
 175                  $currentChar = false;
 176   
 177                  return false;
 178              }
 179              $currentChar = $stream[$streamIndex];
 180              $matches     = [];
 181              $currentLine = preg_match('#(.*?)(?:\n|\r\n?)#', $stream, $matches, null, $streamIndex) === 1
 182                  ? $matches[1]
 183                  : substr($stream, $streamIndex);
 184              if ($currentChar === ' ') {
 185                  $currentWord = preg_match('#( +)#', $currentLine, $matches) === 1 ? $matches[1] : $currentLine;
 186              } else {
 187                  $currentWord = ($matches = strpos($currentLine, ' ')) !== false
 188                      ? substr($currentLine, 0, $matches)
 189                      : $currentLine;
 190              }
 191   
 192              return $currentChar;
 193          };
 194          $MACRO_STREAM_ADVANCE_WORD = function () use (&$currentWord, &$MACRO_STREAM_ADVANCE_CHAR) {
 195              return $MACRO_STREAM_ADVANCE_CHAR(strlen($currentWord));
 196          };
 197          $MACRO_STREAM_ADVANCE_LINE = function () use (&$currentLine, &$MACRO_STREAM_ADVANCE_CHAR) {
 198              return $MACRO_STREAM_ADVANCE_CHAR(strlen($currentLine));
 199          };
 200          $MACRO_TOKEN_ADVANCE       = function () use (&$tokenIndex, &$tokens) {
 201              $tokenIndex          = $tokenIndex === null ? 0 : $tokenIndex + 1;
 202              $tokens[$tokenIndex] = ['ANNOTATION_UNKNOWN', ''];
 203          };
 204          $MACRO_TOKEN_SET_TYPE      = function ($type) use (&$tokenIndex, &$tokens) {
 205              $tokens[$tokenIndex][0] = $type;
 206          };
 207          $MACRO_TOKEN_APPEND_CHAR   = function () use (&$currentChar, &$tokens, &$tokenIndex) {
 208              $tokens[$tokenIndex][1] .= $currentChar;
 209          };
 210          $MACRO_TOKEN_APPEND_WORD   = function () use (&$currentWord, &$tokens, &$tokenIndex) {
 211              $tokens[$tokenIndex][1] .= $currentWord;
 212          };
 213          $MACRO_TOKEN_APPEND_LINE   = function () use (&$currentLine, &$tokens, &$tokenIndex) {
 214              $tokens[$tokenIndex][1] .= $currentLine;
 215          };
 216          $MACRO_HAS_CONTEXT         = function ($which) use (&$context) {
 217              return ($context & $which) === $which;
 218          };
 219   
 220          $MACRO_STREAM_ADVANCE_CHAR();
 221          $MACRO_TOKEN_ADVANCE();
 222   
 223          TOKENIZER_TOP:
 224   
 225          if ($context === 0x00 && $currentChar === '/' && $currentWord === '/**') {
 226              $MACRO_TOKEN_SET_TYPE('ANNOTATION_COMMENTSTART');
 227              $MACRO_TOKEN_APPEND_WORD();
 228              $MACRO_TOKEN_ADVANCE();
 229              $context |= $CONTEXT_DOCBLOCK;
 230              $context |= $CONTEXT_ASTERISK;
 231              if ($MACRO_STREAM_ADVANCE_WORD() === false) {
 232                  goto TOKENIZER_END;
 233              }
 234              goto TOKENIZER_TOP;
 235          }
 236   
 237          if ($MACRO_HAS_CONTEXT($CONTEXT_CLASS)) {
 238              if (in_array($currentChar, [' ', '(', "\n", "\r"])) {
 239                  $context &= ~$CONTEXT_CLASS;
 240                  $MACRO_TOKEN_ADVANCE();
 241              } else {
 242                  $MACRO_TOKEN_APPEND_CHAR();
 243                  if ($MACRO_STREAM_ADVANCE_CHAR() === false) {
 244                      goto TOKENIZER_END;
 245                  }
 246                  goto TOKENIZER_TOP;
 247              }
 248          }
 249   
 250          // Since we don't know what line endings are used in the file, we check for all scenarios. If we find a
 251          // carriage return (\r), we check the next character for a line feed (\n). If so we consume it and act as
 252          // if the carriage return was a line feed.
 253          $lineEnded = $currentChar === "\n";
 254          if ($currentChar === "\r") {
 255              $lineEnded = true;
 256   
 257              $nextChar = $MACRO_STREAM_ADVANCE_CHAR();
 258              if ($nextChar !== "\n") {
 259                  $streamIndex--;
 260              }
 261   
 262              $currentChar = "\n";
 263          }
 264   
 265          if ($lineEnded) {
 266              $MACRO_TOKEN_SET_TYPE('ANNOTATION_NEWLINE');
 267              $MACRO_TOKEN_APPEND_CHAR();
 268              $MACRO_TOKEN_ADVANCE();
 269              $context &= ~$CONTEXT_ASTERISK;
 270              $context &= ~$CONTEXT_CLASS;
 271              if ($MACRO_STREAM_ADVANCE_CHAR() === false) {
 272                  goto TOKENIZER_END;
 273              }
 274              goto TOKENIZER_TOP;
 275          }
 276   
 277          if ($currentChar === ' ') {
 278              $MACRO_TOKEN_SET_TYPE(
 279                  $MACRO_HAS_CONTEXT($CONTEXT_ASTERISK)
 280                  ? 'ANNOTATION_WHITESPACE'
 281                  : 'ANNOTATION_WHITESPACE_INDENT'
 282              );
 283              $MACRO_TOKEN_APPEND_WORD();
 284              $MACRO_TOKEN_ADVANCE();
 285              if ($MACRO_STREAM_ADVANCE_WORD() === false) {
 286                  goto TOKENIZER_END;
 287              }
 288              goto TOKENIZER_TOP;
 289          }
 290   
 291          if ($MACRO_HAS_CONTEXT($CONTEXT_CONTENT) && $MACRO_HAS_CONTEXT($CONTEXT_ASTERISK)) {
 292              $MACRO_TOKEN_SET_TYPE('ANNOTATION_CONTENT');
 293              $annotationParentCount += substr_count($currentWord, '(');
 294              $annotationParentCount -= substr_count($currentWord, ')');
 295   
 296              if ($annotationParentCount === 0) {
 297                  $context &= ~$CONTEXT_CONTENT;
 298                  $MACRO_TOKEN_SET_TYPE('ANNOTATION_CONTENT_END');
 299              }
 300              $MACRO_TOKEN_APPEND_WORD();
 301              $MACRO_TOKEN_ADVANCE();
 302              if ($MACRO_STREAM_ADVANCE_WORD() === false) {
 303                  goto TOKENIZER_END;
 304              }
 305              goto TOKENIZER_TOP;
 306          }
 307   
 308          if ($currentChar === '(' && $tokens[$tokenIndex - 1][0] === 'ANNOTATION_CLASS') {
 309              $context |= $CONTEXT_CONTENT;
 310              $annotationParentCount = 1;
 311              $MACRO_TOKEN_SET_TYPE('ANNOTATION_CONTENT_START');
 312              $MACRO_TOKEN_APPEND_CHAR();
 313              $MACRO_TOKEN_ADVANCE();
 314              if ($MACRO_STREAM_ADVANCE_CHAR() === false) {
 315                  goto TOKENIZER_END;
 316              }
 317              goto TOKENIZER_TOP;
 318          }
 319   
 320          if ($MACRO_HAS_CONTEXT($CONTEXT_DOCBLOCK) && $currentWord === '*/') {
 321              $MACRO_TOKEN_SET_TYPE('ANNOTATION_COMMENTEND');
 322              $MACRO_TOKEN_APPEND_WORD();
 323              $MACRO_TOKEN_ADVANCE();
 324              $context &= ~$CONTEXT_DOCBLOCK;
 325              if ($MACRO_STREAM_ADVANCE_WORD() === false) {
 326                  goto TOKENIZER_END;
 327              }
 328              goto TOKENIZER_TOP;
 329          }
 330   
 331          if ($currentChar === '*') {
 332              if ($MACRO_HAS_CONTEXT($CONTEXT_DOCBLOCK) && ($MACRO_HAS_CONTEXT($CONTEXT_ASTERISK))) {
 333                  $MACRO_TOKEN_SET_TYPE('ANNOTATION_IGNORE');
 334              } else {
 335                  $MACRO_TOKEN_SET_TYPE('ANNOTATION_ASTERISK');
 336                  $context |= $CONTEXT_ASTERISK;
 337              }
 338              $MACRO_TOKEN_APPEND_CHAR();
 339              $MACRO_TOKEN_ADVANCE();
 340              if ($MACRO_STREAM_ADVANCE_CHAR() === false) {
 341                  goto TOKENIZER_END;
 342              }
 343              goto TOKENIZER_TOP;
 344          }
 345   
 346          if ($currentChar === '@') {
 347              $MACRO_TOKEN_SET_TYPE('ANNOTATION_CLASS');
 348              $context |= $CONTEXT_CLASS;
 349              $MACRO_TOKEN_APPEND_CHAR();
 350              if ($MACRO_STREAM_ADVANCE_CHAR() === false) {
 351                  goto TOKENIZER_END;
 352              }
 353              goto TOKENIZER_TOP;
 354          }
 355   
 356          TOKENIZER_CONTINUE:
 357   
 358          if ($context && $CONTEXT_CONTENT) {
 359              $MACRO_TOKEN_APPEND_CHAR();
 360              if ($MACRO_STREAM_ADVANCE_CHAR() === false) {
 361                  goto TOKENIZER_END;
 362              }
 363          } else {
 364              $MACRO_TOKEN_SET_TYPE('ANNOTATION_IGNORE');
 365              $MACRO_TOKEN_APPEND_LINE();
 366              $MACRO_TOKEN_ADVANCE();
 367              if ($MACRO_STREAM_ADVANCE_LINE() === false) {
 368                  goto TOKENIZER_END;
 369              }
 370          }
 371          goto TOKENIZER_TOP;
 372   
 373          TOKENIZER_END:
 374   
 375          array_pop($tokens);
 376   
 377          return $tokens;
 378      }
 379  }
 380