示例#1
0
 private function getUseImports(ReflectionClass $class)
 {
     if (isset($this->useImports[$class->class])) {
         return $this->useImports[$class->class];
     }
     $content = file_get_contents($class->path);
     $tokenizer = new TokenParser('<?php ' . $content);
     $useImports = $tokenizer->parseUseStatements($class->namespace);
     $this->useImports[$class->class] = $useImports;
     return $useImports;
 }
示例#2
0
 /**
  * {@inheritdoc}
  */
 public function process($context, Result $result, Collection $collection)
 {
     $this->result = $result;
     $this->collection = $collection;
     $this->docParser = new DocParser();
     $this->docParser->setIgnoreNotImportedAnnotations(true);
     $phpdoc = $namespace = false;
     $tokenParser = new TokenParser($context->getFileContent());
     while ($token = $tokenParser->next(false)) {
         if (false === is_array($token)) {
             continue;
         }
         switch ($token[0]) {
             case T_DOC_COMMENT:
                 if ($phpdoc !== false) {
                     $this->processDocComment($phpdoc);
                     $phpdoc = false;
                 }
                 $phpdoc = $token[1];
                 break;
             case T_NAMESPACE:
                 $namespace = $tokenParser->parseNamespace();
                 break;
             case T_USE:
                 // add imports to doc parser to be able to use annotation without FQCN.
                 foreach ($tokenParser->parseUseStatement() as $alias => $target) {
                     if ($target[0] === '\\') {
                         $target = substr($target, 1);
                     }
                     $imports[$alias] = $target;
                 }
                 $this->docParser->setImports($imports);
                 break;
             case T_CLASS:
                 $token = $tokenParser->next(false);
                 $class = $namespace ? $namespace . '\\' . $token[1] : $token[1];
                 $this->dispatchEvent(Events::TOKEN_PHP_CLASS, new Context\PHP\PHPClass($class, $phpdoc), $phpdoc);
                 break;
             case T_VARIABLE:
                 $this->dispatchEvent(Events::TOKEN_PHP_VARIABLE, new Context\PHP\PHPVariable(substr($token[1], 1), isset($class) ? $class : null, $phpdoc), $phpdoc);
                 break;
             case T_FUNCTION:
                 $token = $tokenParser->next(false);
                 if (!is_array($token)) {
                     continue;
                 }
                 $this->dispatchEvent(Events::TOKEN_PHP_FUNCTION, new Context\PHP\PHPFunction($token[1], isset($class) ? $class : null, $phpdoc), $phpdoc);
                 break;
         }
     }
 }
示例#3
0
 /**
  * Parses a class.
  *
  * @param  \ReflectionClass $class A <code>ReflectionClass</code> object.
  * @return array            A list with use statements in the form (Alias => FQN).
  */
 public function parseClass(\ReflectionClass $class)
 {
     if (method_exists($class, 'getUseStatements')) {
         return $class->getUseStatements();
     }
     if (false === ($filename = $class->getFilename())) {
         return array();
     }
     $content = $this->getFileContent($filename, $class->getStartLine());
     $namespace = str_replace('\\', '\\\\', $class->getNamespaceName());
     $content = preg_replace('/^.*?(\\bnamespace\\s+' . $namespace . '\\s*[;{].*)$/s', '\\1', $content);
     $tokenizer = new TokenParser('<?php ' . $content);
     $statements = $tokenizer->parseUseStatements($class->getNamespaceName());
     return $statements;
 }
示例#4
0
 /**
  * Class constructor.
  *
  * @param \Reflector $context A reflection of the context in which the types will be resolved.
  *                            The context can be a class, property, method or parameter.
  *
  * @throws \InvalidArgumentException If the class or file name cannot be inferred from the context.
  */
 public function __construct(\Reflector $context)
 {
     $class = $this->getDeclaringClass($context);
     if ($class === null) {
         throw $this->invalidArgumentException('declaring class', $context);
     }
     $fileName = $class->getFileName();
     if ($fileName === false) {
         throw $this->invalidArgumentException('file name', $context);
     }
     $source = @file_get_contents($fileName);
     if ($source === false) {
         throw new \RuntimeException('Could not read ' . $fileName);
     }
     $parser = new TokenParser($source);
     $this->namespace = $class->getNamespaceName();
     $this->aliases = $parser->parseUseStatements($this->namespace);
 }
示例#5
0
 /**
  * @return void
  */
 protected function parse()
 {
     if ($this->parsed || !($fileName = $this->finder->findFile($this->className))) {
         return;
     }
     $this->parsed = true;
     $contents = file_get_contents($fileName);
     if ($this->classAnnotationOptimize) {
         if (preg_match("/\\A.*^\\s*((abstract|final)\\s+)?class\\s+{$this->shortClassName}\\s+/sm", $contents, $matches)) {
             $contents = $matches[0];
         }
     }
     $tokenParser = new TokenParser($contents);
     $docComment = '';
     while ($token = $tokenParser->next(false)) {
         if (is_array($token)) {
             switch ($token[0]) {
                 case T_USE:
                     $this->useStatements = array_merge($this->useStatements, $tokenParser->parseUseStatement());
                     break;
                 case T_DOC_COMMENT:
                     $docComment = $token[1];
                     break;
                 case T_CLASS:
                     $this->docComment['class'] = $docComment;
                     $docComment = '';
                     break;
                 case T_VAR:
                 case T_PRIVATE:
                 case T_PROTECTED:
                 case T_PUBLIC:
                     $token = $tokenParser->next();
                     if ($token[0] === T_VARIABLE) {
                         $propertyName = substr($token[1], 1);
                         $this->docComment['property'][$propertyName] = $docComment;
                         continue 2;
                     }
                     if ($token[0] !== T_FUNCTION) {
                         // For example, it can be T_FINAL.
                         continue 2;
                     }
                     // No break.
                 // No break.
                 case T_FUNCTION:
                     // The next string after function is the name, but
                     // there can be & before the function name so find the
                     // string.
                     while (($token = $tokenParser->next()) && $token[0] !== T_STRING) {
                     }
                     $methodName = $token[1];
                     $this->docComment['method'][$methodName] = $docComment;
                     $docComment = '';
                     break;
                 case T_EXTENDS:
                     $this->parentClassName = $tokenParser->parseClass();
                     $nsPos = strpos($this->parentClassName, '\\');
                     $fullySpecified = false;
                     if ($nsPos === 0) {
                         $fullySpecified = true;
                     } else {
                         if ($nsPos) {
                             $prefix = strtolower(substr($this->parentClassName, 0, $nsPos));
                             $postfix = substr($this->parentClassName, $nsPos);
                         } else {
                             $prefix = strtolower($this->parentClassName);
                             $postfix = '';
                         }
                         foreach ($this->useStatements as $alias => $use) {
                             if ($alias == $prefix) {
                                 $this->parentClassName = '\\' . $use . $postfix;
                                 $fullySpecified = true;
                             }
                         }
                     }
                     if (!$fullySpecified) {
                         $this->parentClassName = '\\' . $this->namespace . '\\' . $this->parentClassName;
                     }
                     break;
             }
         }
     }
 }
 /**
  * @param mixed           $value
  * @param array           $annotations
  * @param ReflectionClass $reflection
  *
  * @return object
  */
 protected static function parseAnnotation($value, array $annotations, ReflectionClass $reflection)
 {
     if (null !== $value && !empty($annotations)) {
         $tokenParse = new TokenParser(file_get_contents($reflection->getFileName()));
         $useStatements = $tokenParse->parseUseStatements($reflection->getNamespaceName());
         foreach ($annotations as $annotation) {
             if (false !== strrpos($annotation, 'var')) {
                 $class = trim(str_replace('var ', '', $annotation));
                 if (class_exists($class)) {
                     $value = static::deserializeValue($class, $value);
                 } elseif (class_exists(sprintf('%s\\%s', $reflection->getNamespaceName(), $class))) {
                     $class = sprintf('%s\\%s', $reflection->getNamespaceName(), $class);
                     $value = static::deserializeValue($class, $value);
                 } elseif (isset($useStatements[strtolower($class)])) {
                     $class = $useStatements[strtolower($class)];
                     $value = static::deserializeValue($class, $value);
                 }
                 break;
             }
         }
     }
     return $value;
 }