/vendor/zendframework/zend-code/src/Scanner/DocBlockScanner.php
https://gitlab.com/yousafsyed/easternglamor · PHP · 326 lines · 223 code · 47 blank · 56 comment · 35 complexity · 011b3b1271b053f30d809a704c801110 MD5 · raw file
- <?php
- /**
- * Zend Framework (http://framework.zend.com/)
- *
- * @link http://github.com/zendframework/zf2 for the canonical source repository
- * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
- namespace Zend\Code\Scanner;
- use Zend\Code\Annotation\AnnotationManager;
- use Zend\Code\NameInformation;
- class DocBlockScanner implements ScannerInterface
- {
- /**
- * @var bool
- */
- protected $isScanned = false;
- /**
- * @var string
- */
- protected $docComment = null;
- /**
- * @var NameInformation
- */
- protected $nameInformation = null;
- /**
- * @var AnnotationManager
- */
- protected $annotationManager = null;
- /**
- * @var string
- */
- protected $shortDescription = null;
- /**
- * @var string
- */
- protected $longDescription = '';
- /**
- * @var array
- */
- protected $tags = array();
- /**
- * @var array
- */
- protected $annotations = array();
- /**
- * @param string $docComment
- * @param null|NameInformation $nameInformation
- */
- public function __construct($docComment, NameInformation $nameInformation = null)
- {
- $this->docComment = $docComment;
- $this->nameInformation = $nameInformation;
- }
- /**
- * @return string
- */
- public function getShortDescription()
- {
- $this->scan();
- return $this->shortDescription;
- }
- /**
- * @return string
- */
- public function getLongDescription()
- {
- $this->scan();
- return $this->longDescription;
- }
- /**
- * @return array
- */
- public function getTags()
- {
- $this->scan();
- return $this->tags;
- }
- /**
- * @return array
- */
- public function getAnnotations()
- {
- $this->scan();
- return $this->annotations;
- }
- /**
- * @return void
- */
- protected function scan()
- {
- if ($this->isScanned) {
- return;
- }
- $mode = 1;
- $tokens = $this->tokenize();
- $tagIndex = null;
- reset($tokens);
- SCANNER_TOP:
- $token = current($tokens);
- switch ($token[0]) {
- case 'DOCBLOCK_NEWLINE':
- if ($this->shortDescription != '' && $tagIndex === null) {
- $mode = 2;
- } else {
- $this->longDescription .= $token[1];
- }
- goto SCANNER_CONTINUE;
- //goto no break needed
- case 'DOCBLOCK_WHITESPACE':
- case 'DOCBLOCK_TEXT':
- if ($tagIndex !== null) {
- $this->tags[$tagIndex]['value'] .= ($this->tags[$tagIndex]['value'] == '') ? $token[1] : ' ' . $token[1];
- goto SCANNER_CONTINUE;
- } elseif ($mode <= 2) {
- if ($mode == 1) {
- $this->shortDescription .= $token[1];
- } else {
- $this->longDescription .= $token[1];
- }
- goto SCANNER_CONTINUE;
- }
- //gotos no break needed
- case 'DOCBLOCK_TAG':
- array_push($this->tags, array('name' => $token[1],
- 'value' => ''));
- end($this->tags);
- $tagIndex = key($this->tags);
- $mode = 3;
- goto SCANNER_CONTINUE;
- //goto no break needed
- case 'DOCBLOCK_COMMENTEND':
- goto SCANNER_END;
- }
- SCANNER_CONTINUE:
- if (next($tokens) === false) {
- goto SCANNER_END;
- }
- goto SCANNER_TOP;
- SCANNER_END:
- $this->shortDescription = trim($this->shortDescription);
- $this->longDescription = trim($this->longDescription);
- $this->isScanned = true;
- }
- /**
- * @return array
- */
- protected function tokenize()
- {
- static $CONTEXT_INSIDE_DOCBLOCK = 0x01;
- static $CONTEXT_INSIDE_ASTERISK = 0x02;
- $context = 0x00;
- $stream = $this->docComment;
- $streamIndex = null;
- $tokens = array();
- $tokenIndex = null;
- $currentChar = null;
- $currentWord = null;
- $currentLine = null;
- $MACRO_STREAM_ADVANCE_CHAR = function ($positionsForward = 1) use (&$stream, &$streamIndex, &$currentChar, &$currentWord, &$currentLine) {
- $positionsForward = ($positionsForward > 0) ? $positionsForward : 1;
- $streamIndex = ($streamIndex === null) ? 0 : $streamIndex + $positionsForward;
- if (!isset($stream[$streamIndex])) {
- $currentChar = false;
- return false;
- }
- $currentChar = $stream[$streamIndex];
- $matches = array();
- $currentLine = (preg_match('#(.*?)\r?\n#', $stream, $matches, null, $streamIndex) === 1) ? $matches[1] : substr($stream, $streamIndex);
- if ($currentChar === ' ') {
- $currentWord = (preg_match('#( +)#', $currentLine, $matches) === 1) ? $matches[1] : $currentLine;
- } else {
- $currentWord = (($matches = strpos($currentLine, ' ')) !== false) ? substr($currentLine, 0, $matches) : $currentLine;
- }
- return $currentChar;
- };
- $MACRO_STREAM_ADVANCE_WORD = function () use (&$currentWord, &$MACRO_STREAM_ADVANCE_CHAR) {
- return $MACRO_STREAM_ADVANCE_CHAR(strlen($currentWord));
- };
- $MACRO_STREAM_ADVANCE_LINE = function () use (&$currentLine, &$MACRO_STREAM_ADVANCE_CHAR) {
- return $MACRO_STREAM_ADVANCE_CHAR(strlen($currentLine));
- };
- $MACRO_TOKEN_ADVANCE = function () use (&$tokenIndex, &$tokens) {
- $tokenIndex = ($tokenIndex === null) ? 0 : $tokenIndex + 1;
- $tokens[$tokenIndex] = array('DOCBLOCK_UNKNOWN', '');
- };
- $MACRO_TOKEN_SET_TYPE = function ($type) use (&$tokenIndex, &$tokens) {
- $tokens[$tokenIndex][0] = $type;
- };
- $MACRO_TOKEN_APPEND_CHAR = function () use (&$currentChar, &$tokens, &$tokenIndex) {
- $tokens[$tokenIndex][1] .= $currentChar;
- };
- $MACRO_TOKEN_APPEND_WORD = function () use (&$currentWord, &$tokens, &$tokenIndex) {
- $tokens[$tokenIndex][1] .= $currentWord;
- };
- $MACRO_TOKEN_APPEND_WORD_PARTIAL = function ($length) use (&$currentWord, &$tokens, &$tokenIndex) {
- $tokens[$tokenIndex][1] .= substr($currentWord, 0, $length);
- };
- $MACRO_TOKEN_APPEND_LINE = function () use (&$currentLine, &$tokens, &$tokenIndex) {
- $tokens[$tokenIndex][1] .= $currentLine;
- };
- $MACRO_STREAM_ADVANCE_CHAR();
- $MACRO_TOKEN_ADVANCE();
- TOKENIZER_TOP:
- if ($context === 0x00 && $currentChar === '/' && $currentWord === '/**') {
- $MACRO_TOKEN_SET_TYPE('DOCBLOCK_COMMENTSTART');
- $MACRO_TOKEN_APPEND_WORD();
- $MACRO_TOKEN_ADVANCE();
- $context |= $CONTEXT_INSIDE_DOCBLOCK;
- $context |= $CONTEXT_INSIDE_ASTERISK;
- if ($MACRO_STREAM_ADVANCE_WORD() === false) {
- goto TOKENIZER_END;
- }
- goto TOKENIZER_TOP;
- }
- if ($context & $CONTEXT_INSIDE_DOCBLOCK && $currentWord === '*/') {
- $MACRO_TOKEN_SET_TYPE('DOCBLOCK_COMMENTEND');
- $MACRO_TOKEN_APPEND_WORD();
- $MACRO_TOKEN_ADVANCE();
- $context &= ~$CONTEXT_INSIDE_DOCBLOCK;
- if ($MACRO_STREAM_ADVANCE_WORD() === false) {
- goto TOKENIZER_END;
- }
- goto TOKENIZER_TOP;
- }
- if ($currentChar === ' ' || $currentChar === "\t") {
- $MACRO_TOKEN_SET_TYPE(($context & $CONTEXT_INSIDE_ASTERISK) ? 'DOCBLOCK_WHITESPACE' : 'DOCBLOCK_WHITESPACE_INDENT');
- $MACRO_TOKEN_APPEND_WORD();
- $MACRO_TOKEN_ADVANCE();
- if ($MACRO_STREAM_ADVANCE_WORD() === false) {
- goto TOKENIZER_END;
- }
- goto TOKENIZER_TOP;
- }
- if ($currentChar === '*') {
- if (($context & $CONTEXT_INSIDE_DOCBLOCK) && ($context & $CONTEXT_INSIDE_ASTERISK)) {
- $MACRO_TOKEN_SET_TYPE('DOCBLOCK_TEXT');
- } else {
- $MACRO_TOKEN_SET_TYPE('DOCBLOCK_ASTERISK');
- $context |= $CONTEXT_INSIDE_ASTERISK;
- }
- $MACRO_TOKEN_APPEND_CHAR();
- $MACRO_TOKEN_ADVANCE();
- if ($MACRO_STREAM_ADVANCE_CHAR() === false) {
- goto TOKENIZER_END;
- }
- goto TOKENIZER_TOP;
- }
- if ($currentChar === '@') {
- $MACRO_TOKEN_SET_TYPE('DOCBLOCK_TAG');
- $MACRO_TOKEN_APPEND_WORD();
- $MACRO_TOKEN_ADVANCE();
- if ($MACRO_STREAM_ADVANCE_WORD() === false) {
- goto TOKENIZER_END;
- }
- goto TOKENIZER_TOP;
- }
- if ($currentChar === "\n") {
- $MACRO_TOKEN_SET_TYPE('DOCBLOCK_NEWLINE');
- $MACRO_TOKEN_APPEND_CHAR();
- $MACRO_TOKEN_ADVANCE();
- $context &= ~$CONTEXT_INSIDE_ASTERISK;
- if ($MACRO_STREAM_ADVANCE_CHAR() === false) {
- goto TOKENIZER_END;
- }
- goto TOKENIZER_TOP;
- }
- $MACRO_TOKEN_SET_TYPE('DOCBLOCK_TEXT');
- $MACRO_TOKEN_APPEND_LINE();
- $MACRO_TOKEN_ADVANCE();
- if ($MACRO_STREAM_ADVANCE_LINE() === false) {
- goto TOKENIZER_END;
- }
- goto TOKENIZER_TOP;
- TOKENIZER_END:
- array_pop($tokens);
- return $tokens;
- }
- }