예제 #1
0
 /**
  * Attempts to resolve the FQN of the provided $type based on the $class and $member context.
  *
  * @param string $type
  * @param ReflectionClass $class
  * @param Reflector $member
  * 
  * @return string|null Fully qualified name of the type, or null if it could not be resolved
  */
 private function tryResolveFqn($type, ReflectionClass $class, Reflector $member)
 {
     $alias = ($pos = strpos($type, '\\')) === false ? $type : substr($type, 0, $pos);
     $loweredAlias = strtolower($alias);
     // Retrieve "use" statements
     $uses = $this->parser->parseUseStatements($class);
     if (isset($uses[$loweredAlias])) {
         // Imported classes
         if ($pos !== false) {
             return $uses[$loweredAlias] . substr($type, $pos);
         } else {
             return $uses[$loweredAlias];
         }
     } elseif ($this->classExists($class->getNamespaceName() . '\\' . $type)) {
         return $class->getNamespaceName() . '\\' . $type;
     } elseif (isset($uses['__NAMESPACE__']) && $this->classExists($uses['__NAMESPACE__'] . '\\' . $type)) {
         // Class namespace
         return $uses['__NAMESPACE__'] . '\\' . $type;
     } elseif ($this->classExists($type)) {
         // No namespace
         return $type;
     }
     if (version_compare(phpversion(), '5.4.0', '<')) {
         return null;
     } else {
         // If all fail, try resolving through related traits
         return $this->tryResolveFqnInTraits($type, $class, $member);
     }
 }
예제 #2
0
 /**
  * Parse the docblock of the property to get the class of the param annotation.
  *
  * @param ReflectionParameter $parameter
  *
  * @throws AnnotationException
  * @return string|null Type of the property (content of var annotation)
  */
 public function getParameterClass(ReflectionParameter $parameter)
 {
     // Use reflection
     $parameterClass = $parameter->getClass();
     if ($parameterClass !== null) {
         return $parameterClass->name;
     }
     $parameterName = $parameter->name;
     // Get the content of the @param annotation
     $method = $parameter->getDeclaringFunction();
     if (preg_match('/@param\\s+([^\\s]+)\\s+\\$' . $parameterName . '/', $method->getDocComment(), $matches)) {
         list(, $type) = $matches;
     } else {
         return null;
     }
     // Ignore primitive types
     if (in_array($type, $this->ignoredTypes)) {
         return null;
     }
     // Ignore types containing special characters ([], <> ...)
     if (!preg_match('/^[a-zA-Z0-9\\\\_]+$/', $type)) {
         return null;
     }
     $class = $parameter->getDeclaringClass();
     // If the class name is not fully qualified (i.e. doesn't start with a \)
     if ($type[0] !== '\\') {
         $alias = false === ($pos = strpos($type, '\\')) ? $type : substr($type, 0, $pos);
         $loweredAlias = strtolower($alias);
         // Retrieve "use" statements
         $uses = $this->parser->parseUseStatements($class);
         $found = false;
         if (isset($uses[$loweredAlias])) {
             // Imported classes
             if (false !== $pos) {
                 $type = $uses[$loweredAlias] . substr($type, $pos);
             } else {
                 $type = $uses[$loweredAlias];
             }
             $found = true;
         } elseif ($this->classExists($class->getNamespaceName() . '\\' . $type)) {
             $type = $class->getNamespaceName() . '\\' . $type;
             $found = true;
         } elseif (isset($uses['__NAMESPACE__']) && $this->classExists($uses['__NAMESPACE__'] . '\\' . $type)) {
             // Class namespace
             $type = $uses['__NAMESPACE__'] . '\\' . $type;
             $found = true;
         } elseif ($this->classExists($type)) {
             // No namespace
             $found = true;
         }
         if (!$found && !$this->ignorePhpDocErrors) {
             throw new AnnotationException(sprintf('The @param annotation for parameter "%s" of %s::%s contains a non existent class "%s". ' . 'Did you maybe forget to add a "use" statement for this annotation?', $parameterName, $class->name, $method->name, $type));
         }
     }
     if (!$this->classExists($type) && !$this->ignorePhpDocErrors) {
         throw new AnnotationException(sprintf('The @param annotation for parameter "%s" of %s::%s contains a non existent class "%s"', $parameterName, $class->name, $method->name, $type));
     }
     // Remove the leading \ (FQN shouldn't contain it)
     $type = ltrim($type, '\\');
     return $type;
 }