From 0c955fe54fd4d8cec8f5284612feef09f7a2f0c8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 30 Apr 2011 10:42:38 +0200 Subject: [PATCH] Fix namespace/class parsing in the entity generator --- lib/Doctrine/ORM/Tools/EntityGenerator.php | 38 +++++++++++---- .../Tests/ORM/Tools/EntityGeneratorTest.php | 48 +++++++++++++++++++ 2 files changed, 76 insertions(+), 10 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php index 182dd441b..9fbc21780 100644 --- a/lib/Doctrine/ORM/Tools/EntityGenerator.php +++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php @@ -179,7 +179,7 @@ public function () $this->_isNew = !file_exists($path) || (file_exists($path) && $this->_regenerateEntityIfExists); if ( ! $this->_isNew) { - $this->_parseTokensInEntityFile($path); + $this->_parseTokensInEntityFile(file_get_contents($path)); } if ($this->_backupExisting && file_exists($path)) { @@ -400,24 +400,42 @@ public function () /** * @todo this won't work if there is a namespace in brackets and a class outside of it. - * @param string $path + * @param string $src */ - private function _parseTokensInEntityFile($path) + private function _parseTokensInEntityFile($src) { - $tokens = token_get_all(file_get_contents($path)); + $tokens = token_get_all($src); $lastSeenNamespace = ""; $lastSeenClass = false; + $inNamespace = false; + $inClass = false; for ($i = 0; $i < count($tokens); $i++) { $token = $tokens[$i]; - if ($token[0] == T_NAMESPACE) { - $lastSeenNamespace = $tokens[$i+2][1] . "\\"; - } else if ($token[0] == T_NS_SEPARATOR) { - $lastSeenNamespace .= $tokens[$i+1][1] . "\\"; - } else if ($token[0] == T_CLASS) { - $lastSeenClass = $lastSeenNamespace . $tokens[$i+2][1]; + if (in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT))) { + continue; + } + + if ($inNamespace) { + if ($token[0] == T_NS_SEPARATOR || $token[0] == T_STRING) { + $lastSeenNamespace .= $token[1]; + } else if (is_string($token) && in_array($token, array(';', '{'))) { + $inNamespace = false; + } + } + + if ($inClass) { + $inClass = false; + $lastSeenClass = $lastSeenNamespace . '\\' . $token[1]; $this->_staticReflection[$lastSeenClass]['properties'] = array(); $this->_staticReflection[$lastSeenClass]['methods'] = array(); + } + + if ($token[0] == T_NAMESPACE) { + $lastSeenNamespace = ""; + $inNamespace = true; + } else if ($token[0] == T_CLASS) { + $inClass = true; } else if ($token[0] == T_FUNCTION) { if ($tokens[$i+2][0] == T_STRING) { $this->_staticReflection[$lastSeenClass]['methods'][] = $tokens[$i+2][1]; diff --git a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php index c8960f6a7..5a9c5d7eb 100644 --- a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php @@ -200,6 +200,54 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals($cm->idGenerator, $metadata->idGenerator); $this->assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName); } + + /** + * @dataProvider getParseTokensInEntityFileData + */ + public function testParseTokensInEntityFile($php, $classes) + { + $r = new \ReflectionObject($this->_generator); + $m = $r->getMethod('_parseTokensInEntityFile'); + $m->setAccessible(true); + + $p = $r->getProperty('_staticReflection'); + $p->setAccessible(true); + + $ret = $m->invoke($this->_generator, $php); + $this->assertEquals($classes, array_keys($p->getValue($this->_generator))); + } + + public function getParseTokensInEntityFileData() + { + return array( + array( + '