[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Zend Framework (http://framework.zend.com/) 4 * 5 * @link http://github.com/zendframework/zf2 for the canonical source repository 6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 7 * @license http://framework.zend.com/license/new-bsd New BSD License 8 */ 9 10 namespace Zend\Code\Scanner; 11 12 use Zend\Code\Annotation\AnnotationManager; 13 use Zend\Code\Exception; 14 use Zend\Code\NameInformation; 15 16 class MethodScanner implements ScannerInterface 17 { 18 /** 19 * @var bool 20 */ 21 protected $isScanned = false; 22 23 /** 24 * @var string 25 */ 26 protected $docComment = null; 27 28 /** 29 * @var ClassScanner 30 */ 31 protected $scannerClass = null; 32 33 /** 34 * @var string 35 */ 36 protected $class = null; 37 38 /** 39 * @var string 40 */ 41 protected $name = null; 42 43 /** 44 * @var int 45 */ 46 protected $lineStart = null; 47 48 /** 49 * @var int 50 */ 51 protected $lineEnd = null; 52 53 /** 54 * @var bool 55 */ 56 protected $isFinal = false; 57 58 /** 59 * @var bool 60 */ 61 protected $isAbstract = false; 62 63 /** 64 * @var bool 65 */ 66 protected $isPublic = true; 67 68 /** 69 * @var bool 70 */ 71 protected $isProtected = false; 72 73 /** 74 * @var bool 75 */ 76 protected $isPrivate = false; 77 78 /** 79 * @var bool 80 */ 81 protected $isStatic = false; 82 83 /** 84 * @var string 85 */ 86 protected $body = ''; 87 88 /** 89 * @var array 90 */ 91 protected $tokens = array(); 92 93 /** 94 * @var NameInformation 95 */ 96 protected $nameInformation = null; 97 98 /** 99 * @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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |