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