1<?php declare(strict_types=1); 2 3namespace PhpDocReader\PhpParser; 4 5use SplFileObject; 6 7/** 8 * Parses a file for "use" declarations. 9 * 10 * Class taken and adapted from doctrine/annotations to avoid pulling the whole package. 11 * 12 * Authors: Fabien Potencier <fabien@symfony.com> and Christian Kaps <christian.kaps@mohiva.com> 13 */ 14class UseStatementParser 15{ 16 /** 17 * @return array A list with use statements in the form (Alias => FQN). 18 */ 19 public function parseUseStatements(\ReflectionClass $class): array 20 { 21 $filename = $class->getFilename(); 22 if ($filename === false) { 23 return []; 24 } 25 26 $content = $this->getFileContent($filename, $class->getStartLine()); 27 28 if ($content === null) { 29 return []; 30 } 31 32 $namespace = preg_quote($class->getNamespaceName(), '/'); 33 $content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content); 34 $tokenizer = new TokenParser('<?php ' . $content); 35 36 return $tokenizer->parseUseStatements($class->getNamespaceName()); 37 } 38 39 /** 40 * Gets the content of the file right up to the given line number. 41 * 42 * @param string $filename The name of the file to load. 43 * @param int $lineNumber The number of lines to read from file. 44 */ 45 private function getFileContent(string $filename, int $lineNumber): string 46 { 47 if (! is_file($filename)) { 48 throw new \RuntimeException("Unable to read file $filename"); 49 } 50 51 $content = ''; 52 $lineCnt = 0; 53 $file = new SplFileObject($filename); 54 while (! $file->eof()) { 55 if ($lineCnt++ === $lineNumber) { 56 break; 57 } 58 59 $content .= $file->fgets(); 60 } 61 62 return $content; 63 } 64} 65