Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

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: 02.04.2025, 15:03 - 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