Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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: 09.10.2024, 12:57 - Dateigröße: 14.27 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-2015 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  class MethodScanner implements ScannerInterface
017  {
018      /**
019       * @var bool
020       */
021      protected $isScanned    = false;
022   
023      /**
024       * @var string
025       */
026      protected $docComment   = null;
027   
028      /**
029       * @var ClassScanner
030       */
031      protected $scannerClass = null;
032   
033      /**
034       * @var string
035       */
036      protected $class        = null;
037   
038      /**
039       * @var string
040       */
041      protected $name         = null;
042   
043      /**
044       * @var int
045       */
046      protected $lineStart    = null;
047   
048      /**
049       * @var int
050       */
051      protected $lineEnd      = null;
052   
053      /**
054       * @var bool
055       */
056      protected $isFinal = false;
057   
058      /**
059       * @var bool
060       */
061      protected $isAbstract = false;
062   
063      /**
064       * @var bool
065       */
066      protected $isPublic = true;
067   
068      /**
069       * @var bool
070       */
071      protected $isProtected = false;
072   
073      /**
074       * @var bool
075       */
076      protected $isPrivate = false;
077   
078      /**
079       * @var bool
080       */
081      protected $isStatic = false;
082   
083      /**
084       * @var string
085       */
086      protected $body = '';
087   
088      /**
089       * @var array
090       */
091      protected $tokens = array();
092   
093      /**
094       * @var NameInformation
095       */
096      protected $nameInformation = null;
097   
098      /**
099       * @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  }
608