public function __construct(\ReflectionClass $intf) { $this->intf = $intf; $classParser = new PhpParser(); $uses = array_merge($classParser->parseClass($this->intf), [$this->intf->getNamespaceName()]); $this->reader = new AnnotationReader($this->intf); $this->converter = new AnnotationConverter($uses); }
/** * @param $string * @param ReflectionClass $class * @return string */ public function resolveClassMapping($string, ReflectionClass $class) { $regex = '/\\:\\:class$/'; if (preg_match($regex, $string) !== 1) { return $string; } $alias = strtolower(preg_replace($regex, '', $string)); $parser = new PhpParser(); $imports = $parser->parseClass($class); if (isset($imports[$alias])) { return $imports[$alias]; } else { return $string; } }
/** * @param ReflectionClass $reflectionClass * @return string[] */ public function getUseStatements(ReflectionClass $reflectionClass) { if (!isset($this->cachedUseStatements[$reflectionClass->getName()])) { $this->cachedUseStatements[$reflectionClass->getName()] = $this->phpParser->parseClass($reflectionClass); } return $this->cachedUseStatements[$reflectionClass->getName()]; }
/** * Collects parsing metadata for a given class. * * @param \ReflectionClass $class */ private function collectParsingMetadata(ReflectionClass $class) { $ignoredAnnotationNames = self::$globalIgnoredNames; $annotations = $this->preParser->parse($class->getDocComment(), 'class ' . $class->name); foreach ($annotations as $annotation) { if ($annotation instanceof IgnoreAnnotation) { foreach ($annotation->names as $annot) { $ignoredAnnotationNames[$annot] = true; } } } $name = $class->getName(); $this->imports[$name] = array_merge(self::$globalImports, $this->phpParser->parseClass($class), array('__NAMESPACE__' => $class->getNamespaceName())); $this->ignoredAnnotationNames[$name] = $ignoredAnnotationNames; }
/** * Retrieves imports for methods. * * @param \ReflectionMethod $method * * @return array */ private function getMethodImports(ReflectionMethod $method) { $class = $method->getDeclaringClass(); $classImports = $this->getClassImports($class); if (!method_exists($class, 'getTraits')) { return $classImports; } $traitImports = array(); foreach ($class->getTraits() as $trait) { if ($trait->hasMethod($method->getName()) && $trait->getFileName() === $method->getFileName()) { $traitImports = array_merge($traitImports, $this->phpParser->parseClass($trait)); } } return array_merge($classImports, $traitImports); }
private function resolveClassName($type, \ReflectionClass $usingClass) { if (strpos($type, '\\') === 0 && class_exists($type)) { return $type; } if (strpos($type, '\\') === 0) { $type = substr($type, 1); } $aliases = $this->phpParser->parseClass($usingClass); $alias = strtolower($type); if (!isset($aliases[$alias])) { return $usingClass->getNamespaceName() . '\\' . $type; } return $aliases[$alias]; }
/** * @group DCOM-97 * @group regression */ public function testClassWithClosure() { $parser = new PhpParser(); $class = new ReflectionClass(__NAMESPACE__ . '\\Fixtures\\ClassWithClosure'); $this->assertEquals(array('annotationtargetall' => __NAMESPACE__ . '\\Fixtures\\AnnotationTargetAll', 'annotationtargetannotation' => __NAMESPACE__ . '\\Fixtures\\AnnotationTargetAnnotation'), $parser->parseClass($class)); }
/** * @param \Reflector|Nette\Reflection\ClassType|Nette\Reflection\Method $refl * @param $annotation */ private static function findRenamed(\Reflector $refl, $annotation) { $parser = new Doctrine\Common\Annotations\PhpParser(); $imports = $parser->parseClass($refl instanceof \ReflectionClass ? $refl : $refl->getDeclaringClass()); $annotationClass = ltrim($annotation, '@'); foreach ($imports as $alias => $import) { if (!Strings::startsWith($annotationClass, $import)) { continue; } $aliased = str_replace(Strings::lower($import), $alias, Strings::lower($annotationClass)); $searchFor = preg_quote(Strings::lower($aliased)); if (!($m = Strings::match($refl->getDocComment(), "~(?P<usage>@?{$searchFor})~i"))) { continue; } return $m['usage']; } return $annotation; }
/** * @group performance */ public function testPhpParserPerformanceWithoutShortCut() { $class = new \ReflectionClass('SingleClassLOC1000'); $time = microtime(true); for ($i = 0, $c = 500; $i < $c; $i++) { $parser = new PhpParser(); $parser->parseClass($class); } $time = microtime(true) - $time; $this->printResults('doc-parser-without-short-cut', $time, $c); }
/** * @param \ReflectionProperty $property * @param string $fullClassName * @return string */ public function getFullClassNameBecauseOfImports($property, $fullClassName) { // only process names which are not fully qualified, yet // fully qualified names must start with a \ if ('\\' !== $fullClassName[0]) { $parser = new PhpParser(); $useStatements = $parser->parseClass($property->getDeclaringClass()); if ($property->getDeclaringClass()->inNamespace()) { $parentNamespace = $property->getDeclaringClass()->getNamespaceName(); } $alias = false === ($pos = strpos($fullClassName, '\\')) ? $fullClassName : substr($fullClassName, 0, $pos); if (isset($useStatements[$loweredAlias = strtolower($alias)])) { if (false !== $pos) { $fullClassName = $useStatements[$loweredAlias] . substr($fullClassName, $pos); } else { $fullClassName = $useStatements[$loweredAlias]; } } elseif (isset($parentNamespace)) { $fullClassName = $parentNamespace . '\\' . $fullClassName; } } return trim($fullClassName, '\\'); }
public function testParseClassWhenClassIsInterface() { $parser = new PhpParser(); $class = new \ReflectionClass('Doctrine\\Tests\\Common\\Annotations\\Fixtures\\TestInterface'); $this->assertEquals(array('secure' => 'Doctrine\\Tests\\Common\\Annotations\\Fixtures\\Annotation\\Secure'), $parser->parseClass($class)); }
/** * 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->phpParser->parseClass($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; }
public static function fromReflection(ReflectionClass $reflection = NULL) { if (!defined('PHP_VERSION_ID')) { $v = explode('.', PHP_VERSION); define('PHP_VERSION_ID', $v[0] * 10000 + $v[1] * 100 + $v[2]); } if ($reflection === null) { return null; } if (func_num_args() > 1) { $stack = func_get_arg(1); } else { $stack = new \ArrayObject(); } $stackExpression = $reflection->getName(); if (isset($stack[$stackExpression])) { return $stack[$stackExpression]; } $stack[$stackExpression] = $instance = new Type($reflection); if (func_num_args() > 2) { $reader = func_get_arg(2); } else { $reader = new AnnotationReader(); } if (func_num_args() > 3) { $phpParser = func_get_arg(3); } else { $phpParser = new PhpParser(); } $instance->name = $reflection->getName(); $instance->internal = $reflection->isInternal(); $instance->userDefined = $reflection->isUserDefined(); $instance->instantiable = $reflection->isInstantiable(); $instance->fileName = $reflection->getFileName(); $instance->startLine = $reflection->getStartLine(); $instance->endLine = $reflection->getEndLine(); $instance->docComment = $reflection->getDocComment(); $instance->constants = $reflection->getConstants(); $instance->interfaceNames = $reflection->getInterfaceNames(); $instance->interface = $reflection->isInterface(); $instance->traitNames = PHP_VERSION_ID >= 50400 ? $reflection->getTraitNames() : null; $instance->trait = PHP_VERSION_ID >= 50400 ? $reflection->isTrait() : null; $instance->abstract = $reflection->isAbstract(); $instance->final = $reflection->isFinal(); $instance->modifiers = $reflection->getModifiers(); $instance->defaultProperties = $reflection->getDefaultProperties(); $instance->iterateable = $reflection->isIterateable(); $instance->extensionName = $reflection->getExtensionName(); $instance->namespaceName = $reflection->getNamespaceName(); $instance->shortName = $reflection->getShortName(); $instance->annotations = $reader->getClassAnnotations($reflection); $instance->useStatements = $phpParser->parseClass($reflection); $instance->useStatements[strtolower($reflection->getShortName())] = $reflection->getName(); return $instance; }
public function testIfPointerResetsOnMultipleParsingTries() { $parser = new PhpParser(); $class = new ReflectionClass(__NAMESPACE__ . '\\Fixtures\\NamespaceWithClosureDeclaration'); $this->assertEquals(array('secure' => __NAMESPACE__ . '\\Fixtures\\Annotation\\Secure', 'route' => __NAMESPACE__ . '\\Fixtures\\Annotation\\Route', 'template' => __NAMESPACE__ . '\\Fixtures\\Annotation\\Template'), $parser->parseClass($class)); $this->assertEquals(array('secure' => __NAMESPACE__ . '\\Fixtures\\Annotation\\Secure', 'route' => __NAMESPACE__ . '\\Fixtures\\Annotation\\Route', 'template' => __NAMESPACE__ . '\\Fixtures\\Annotation\\Template'), $parser->parseClass($class)); }