[ 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\AnnotationCollection; 13 use Zend\Code\Annotation\AnnotationManager; 14 use Zend\Code\NameInformation; 15 16 class AnnotationScanner extends AnnotationCollection 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 NameInformation 30 */ 31 protected $nameInformation = null; 32 33 /** 34 * @var AnnotationManager 35 */ 36 protected $annotationManager = null; 37 38 /** 39 * @var array 40 */ 41 protected $annotations = array(); 42 43 /** 44 * @param AnnotationManager $annotationManager 45 * @param string $docComment 46 * @param NameInformation $nameInformation 47 * @return AnnotationScanner 48 */ 49 public function __construct( 50 AnnotationManager $annotationManager, 51 $docComment, 52 NameInformation $nameInformation = null 53 ) { 54 $this->annotationManager = $annotationManager; 55 $this->docComment = $docComment; 56 $this->nameInformation = $nameInformation; 57 $this->scan($this->tokenize()); 58 } 59 60 /** 61 * @param NameInformation $nameInformation 62 */ 63 public function setNameInformation(NameInformation $nameInformation) 64 { 65 $this->nameInformation = $nameInformation; 66 } 67 68 /** 69 * @param array $tokens 70 */ 71 protected function scan(array $tokens) 72 { 73 $annotations = array(); 74 $annotationIndex = -1; 75 $contentEnd = false; 76 77 reset($tokens); 78 79 SCANNER_TOP: 80 $token = current($tokens); 81 82 switch ($token[0]) { 83 84 case 'ANNOTATION_CLASS': 85 86 $contentEnd = false; 87 $annotationIndex++; 88 $class = substr($token[1], 1); 89 $class = $this->nameInformation->resolveName($class); 90 $annotations[$annotationIndex] = array($class, null); 91 goto SCANNER_CONTINUE; 92 // goto no break needed 93 94 case 'ANNOTATION_CONTENT_START': 95 96 $annotations[$annotationIndex][1] = ''; 97 //fall-through 98 99 case 'ANNOTATION_CONTENT_END': 100 case 'ANNOTATION_CONTENT': 101 case 'ANNOTATION_WHITESPACE': 102 case 'ANNOTATION_NEWLINE': 103 104 if (!$contentEnd && isset($annotations[$annotationIndex]) && is_string($annotations[$annotationIndex][1])) { 105 $annotations[$annotationIndex][1] .= $token[1]; 106 } 107 108 if ($token[0] === 'ANNOTATION_CONTENT_END') { 109 $contentEnd = true; 110 } 111 112 goto SCANNER_CONTINUE; 113 } 114 115 SCANNER_CONTINUE: 116 if (next($tokens) === false) { 117 goto SCANNER_END; 118 } 119 goto SCANNER_TOP; 120 121 SCANNER_END: 122 123 foreach ($annotations as $annotation) { 124 $annotation[] = '@' . $annotation[0] . $annotation[1]; 125 $annotationObject = $this->annotationManager->createAnnotation($annotation); 126 if ($annotationObject) { 127 $this->append($annotationObject); 128 } 129 } 130 } 131 132 /** 133 * @return array 134 */ 135 protected function tokenize() 136 { 137 static $CONTEXT_DOCBLOCK = 0x01; 138 static $CONTEXT_ASTERISK = 0x02; 139 static $CONTEXT_CLASS = 0x04; 140 static $CONTEXT_CONTENT = 0x08; 141 142 $context = 0x00; 143 $stream = $this->docComment; 144 $streamIndex = null; 145 $tokens = array(); 146 $tokenIndex = null; 147 $currentChar = null; 148 $currentWord = null; 149 $currentLine = null; 150 151 $annotationParentCount = 0; 152 153 $MACRO_STREAM_ADVANCE_CHAR = function ($positionsForward = 1) use (&$stream, &$streamIndex, &$currentChar, &$currentWord, &$currentLine) { 154 $positionsForward = ($positionsForward > 0) ? $positionsForward : 1; 155 $streamIndex = ($streamIndex === null) ? 0 : $streamIndex + $positionsForward; 156 if (!isset($stream[$streamIndex])) { 157 $currentChar = false; 158 159 return false; 160 } 161 $currentChar = $stream[$streamIndex]; 162 $matches = array(); 163 $currentLine = (preg_match('#(.*?)(?:\n|\r\n?)#', $stream, $matches, null, $streamIndex) === 1) ? $matches[1] : substr($stream, $streamIndex); 164 if ($currentChar === ' ') { 165 $currentWord = (preg_match('#( +)#', $currentLine, $matches) === 1) ? $matches[1] : $currentLine; 166 } else { 167 $currentWord = (($matches = strpos($currentLine, ' ')) !== false) ? substr($currentLine, 0, $matches) : $currentLine; 168 } 169 170 return $currentChar; 171 }; 172 $MACRO_STREAM_ADVANCE_WORD = function () use (&$currentWord, &$MACRO_STREAM_ADVANCE_CHAR) { 173 return $MACRO_STREAM_ADVANCE_CHAR(strlen($currentWord)); 174 }; 175 $MACRO_STREAM_ADVANCE_LINE = function () use (&$currentLine, &$MACRO_STREAM_ADVANCE_CHAR) { 176 return $MACRO_STREAM_ADVANCE_CHAR(strlen($currentLine)); 177 }; 178 $MACRO_TOKEN_ADVANCE = function () use (&$tokenIndex, &$tokens) { 179 $tokenIndex = ($tokenIndex === null) ? 0 : $tokenIndex + 1; 180 $tokens[$tokenIndex] = array('ANNOTATION_UNKNOWN', ''); 181 }; 182 $MACRO_TOKEN_SET_TYPE = function ($type) use (&$tokenIndex, &$tokens) { 183 $tokens[$tokenIndex][0] = $type; 184 }; 185 $MACRO_TOKEN_APPEND_CHAR = function () use (&$currentChar, &$tokens, &$tokenIndex) { 186 $tokens[$tokenIndex][1] .= $currentChar; 187 }; 188 $MACRO_TOKEN_APPEND_WORD = function () use (&$currentWord, &$tokens, &$tokenIndex) { 189 $tokens[$tokenIndex][1] .= $currentWord; 190 }; 191 $MACRO_TOKEN_APPEND_LINE = function () use (&$currentLine, &$tokens, &$tokenIndex) { 192 $tokens[$tokenIndex][1] .= $currentLine; 193 }; 194 $MACRO_HAS_CONTEXT = function ($which) use (&$context) { 195 return (($context & $which) === $which); 196 }; 197 198 $MACRO_STREAM_ADVANCE_CHAR(); 199 $MACRO_TOKEN_ADVANCE(); 200 201 TOKENIZER_TOP: 202 203 if ($context === 0x00 && $currentChar === '/' && $currentWord === '/**') { 204 $MACRO_TOKEN_SET_TYPE('ANNOTATION_COMMENTSTART'); 205 $MACRO_TOKEN_APPEND_WORD(); 206 $MACRO_TOKEN_ADVANCE(); 207 $context |= $CONTEXT_DOCBLOCK; 208 $context |= $CONTEXT_ASTERISK; 209 if ($MACRO_STREAM_ADVANCE_WORD() === false) { 210 goto TOKENIZER_END; 211 } 212 goto TOKENIZER_TOP; 213 } 214 215 if ($MACRO_HAS_CONTEXT($CONTEXT_CLASS)) { 216 if (in_array($currentChar, array(' ', '(', "\n", "\r"))) { 217 $context &= ~$CONTEXT_CLASS; 218 $MACRO_TOKEN_ADVANCE(); 219 } else { 220 $MACRO_TOKEN_APPEND_CHAR(); 221 if ($MACRO_STREAM_ADVANCE_CHAR() === false) { 222 goto TOKENIZER_END; 223 } 224 goto TOKENIZER_TOP; 225 } 226 } 227 228 // Since we don't know what line endings are used in the file, we check for all scenarios. If we find a 229 // cariage return (\r), we check the next character for a line feed (\n). If so we consume it and act as 230 // if the cariage return was a line feed. 231 $lineEnded = $currentChar === "\n"; 232 if ($currentChar === "\r") { 233 $lineEnded = true; 234 235 $nextChar = $MACRO_STREAM_ADVANCE_CHAR(); 236 if ($nextChar !== "\n") { 237 $streamIndex--; 238 } 239 240 $currentChar = "\n"; 241 } 242 243 if ($lineEnded) { 244 $MACRO_TOKEN_SET_TYPE('ANNOTATION_NEWLINE'); 245 $MACRO_TOKEN_APPEND_CHAR(); 246 $MACRO_TOKEN_ADVANCE(); 247 $context &= ~$CONTEXT_ASTERISK; 248 $context &= ~$CONTEXT_CLASS; 249 if ($MACRO_STREAM_ADVANCE_CHAR() === false) { 250 goto TOKENIZER_END; 251 } 252 goto TOKENIZER_TOP; 253 } 254 255 if ($currentChar === ' ') { 256 $MACRO_TOKEN_SET_TYPE(($MACRO_HAS_CONTEXT($CONTEXT_ASTERISK)) ? 'ANNOTATION_WHITESPACE' : 'ANNOTATION_WHITESPACE_INDENT'); 257 $MACRO_TOKEN_APPEND_WORD(); 258 $MACRO_TOKEN_ADVANCE(); 259 if ($MACRO_STREAM_ADVANCE_WORD() === false) { 260 goto TOKENIZER_END; 261 } 262 goto TOKENIZER_TOP; 263 } 264 265 if ($MACRO_HAS_CONTEXT($CONTEXT_CONTENT) && $MACRO_HAS_CONTEXT($CONTEXT_ASTERISK)) { 266 $MACRO_TOKEN_SET_TYPE('ANNOTATION_CONTENT'); 267 $annotationParentCount += substr_count($currentWord, '('); 268 $annotationParentCount -= substr_count($currentWord, ')'); 269 270 if ($annotationParentCount === 0) { 271 $context &= ~$CONTEXT_CONTENT; 272 $MACRO_TOKEN_SET_TYPE('ANNOTATION_CONTENT_END'); 273 } 274 $MACRO_TOKEN_APPEND_WORD(); 275 $MACRO_TOKEN_ADVANCE(); 276 if ($MACRO_STREAM_ADVANCE_WORD() === false) { 277 goto TOKENIZER_END; 278 } 279 goto TOKENIZER_TOP; 280 } 281 282 if ($currentChar === '(' && $tokens[$tokenIndex - 1][0] === 'ANNOTATION_CLASS') { 283 $context |= $CONTEXT_CONTENT; 284 $annotationParentCount = 1; 285 $MACRO_TOKEN_SET_TYPE('ANNOTATION_CONTENT_START'); 286 $MACRO_TOKEN_APPEND_CHAR(); 287 $MACRO_TOKEN_ADVANCE(); 288 if ($MACRO_STREAM_ADVANCE_CHAR() === false) { 289 goto TOKENIZER_END; 290 } 291 goto TOKENIZER_TOP; 292 } 293 294 if ($MACRO_HAS_CONTEXT($CONTEXT_DOCBLOCK) && $currentWord === '*/') { 295 $MACRO_TOKEN_SET_TYPE('ANNOTATION_COMMENTEND'); 296 $MACRO_TOKEN_APPEND_WORD(); 297 $MACRO_TOKEN_ADVANCE(); 298 $context &= ~$CONTEXT_DOCBLOCK; 299 if ($MACRO_STREAM_ADVANCE_WORD() === false) { 300 goto TOKENIZER_END; 301 } 302 goto TOKENIZER_TOP; 303 } 304 305 if ($currentChar === '*') { 306 if ($MACRO_HAS_CONTEXT($CONTEXT_DOCBLOCK) && ($MACRO_HAS_CONTEXT($CONTEXT_ASTERISK))) { 307 $MACRO_TOKEN_SET_TYPE('ANNOTATION_IGNORE'); 308 } else { 309 $MACRO_TOKEN_SET_TYPE('ANNOTATION_ASTERISK'); 310 $context |= $CONTEXT_ASTERISK; 311 } 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 ($currentChar === '@') { 321 $MACRO_TOKEN_SET_TYPE('ANNOTATION_CLASS'); 322 $context |= $CONTEXT_CLASS; 323 $MACRO_TOKEN_APPEND_CHAR(); 324 if ($MACRO_STREAM_ADVANCE_CHAR() === false) { 325 goto TOKENIZER_END; 326 } 327 goto TOKENIZER_TOP; 328 } 329 330 TOKENIZER_CONTINUE: 331 332 if ($context && $CONTEXT_CONTENT) { 333 $MACRO_TOKEN_APPEND_CHAR(); 334 if ($MACRO_STREAM_ADVANCE_CHAR() === false) { 335 goto TOKENIZER_END; 336 } 337 } else { 338 $MACRO_TOKEN_SET_TYPE('ANNOTATION_IGNORE'); 339 $MACRO_TOKEN_APPEND_LINE(); 340 $MACRO_TOKEN_ADVANCE(); 341 if ($MACRO_STREAM_ADVANCE_LINE() === false) { 342 goto TOKENIZER_END; 343 } 344 } 345 goto TOKENIZER_TOP; 346 347 TOKENIZER_END: 348 349 array_pop($tokens); 350 351 return $tokens; 352 } 353 }
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 |