diff -r 000000000000 -r 7f95f8617b0b vendor/doctrine-common/lib/Doctrine/Common/Annotations/PhpParser.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/doctrine-common/lib/Doctrine/Common/Annotations/PhpParser.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,152 @@ +. + */ + +namespace Doctrine\Common\Annotations; + +/** + * Parses a file for namespaces/use/class declarations. + * + * @author Fabien Potencier + */ +final class PhpParser +{ + private $tokens; + + /** + * Parses a class. + * + * @param \ReflectionClass $class + */ + public function parseClass(\ReflectionClass $class) + { + if (false === $filename = $class->getFilename()) { + return array(); + } + $src = file_get_contents($filename); + $name = $class->getName(); + + // This is a short-cut for code that follows some conventions: + // - namespaced + // - one class per file + if (preg_match_all('#\bnamespace\s+'.str_replace('\\', '\\\\', $class->getNamespaceName()).'\s*;.*?\b(?:class|interface)\s+'.$class->getShortName().'\b#s', $src, $matches)) { + foreach ($matches[0] as $match) { + $classes = $this->parse('parse($src, $name); + + return $classes[$name]; + } + + private function parse($src, $interestedClass = null) + { + $this->tokens = token_get_all($src); + $classes = $uses = array(); + $namespace = ''; + while ($token = $this->next()) { + if (T_NAMESPACE === $token[0]) { + $namespace = $this->parseNamespace(); + $uses = array(); + } elseif (T_CLASS === $token[0] || T_INTERFACE === $token[0]) { + if ('' !== $namespace) { + $class = $namespace.'\\'.$this->nextValue(); + } else { + $class = $this->nextValue(); + } + $classes[$class] = $uses; + + if (null !== $interestedClass && $interestedClass === $class) { + return $classes; + } + } elseif (T_USE === $token[0]) { + foreach ($this->parseUseStatement() as $useStatement) { + list($alias, $class) = $useStatement; + $uses[strtolower($alias)] = $class; + } + } + } + + return $classes; + } + + private function parseNamespace() + { + $namespace = ''; + while ($token = $this->next()) { + if (T_NS_SEPARATOR === $token[0] || T_STRING === $token[0]) { + $namespace .= $token[1]; + } elseif (is_string($token) && in_array($token, array(';', '{'))) { + return $namespace; + } + } + } + + private function parseUseStatement() + { + $statements = $class = array(); + $alias = ''; + while ($token = $this->next()) { + if (T_NS_SEPARATOR === $token[0] || T_STRING === $token[0]) { + $class[] = $token[1]; + } else if (T_AS === $token[0]) { + $alias = $this->nextValue(); + } else if (is_string($token)) { + if (',' === $token || ';' === $token) { + $statements[] = array( + $alias ? $alias : $class[count($class) - 1], + implode('', $class) + ); + } + + if (';' === $token) { + return $statements; + } + if (',' === $token) { + $class = array(); + $alias = ''; + + continue; + } + } + } + } + + private function next() + { + while ($token = array_shift($this->tokens)) { + if (in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT))) { + continue; + } + + return $token; + } + } + + private function nextValue() + { + $token = $this->next(); + + return is_array($token) ? $token[1] : $token; + } +}