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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
MethodScanner.php
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