forked from composer/composer
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'beberlei/ClassMaps'
- Loading branch information
Showing
24 changed files
with
426 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
<?php | ||
|
||
/* | ||
* This file is copied from the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
* | ||
* @license MIT | ||
*/ | ||
|
||
namespace Composer\Autoload; | ||
|
||
/** | ||
* ClassMapGenerator | ||
* | ||
* @author Gyula Sallai <salla016@gmail.com> | ||
*/ | ||
class ClassMapGenerator | ||
{ | ||
/** | ||
* Generate a class map file | ||
* | ||
* @param Traversable $dirs Directories or a single path to search in | ||
* @param string $file The name of the class map file | ||
*/ | ||
static public function dump($dirs, $file) | ||
{ | ||
$maps = array(); | ||
|
||
foreach ($dirs as $dir) { | ||
$maps = array_merge($maps, static::createMap($dir)); | ||
} | ||
|
||
file_put_contents($file, sprintf('<?php return %s;', var_export($maps, true))); | ||
} | ||
|
||
/** | ||
* Iterate over all files in the given directory searching for classes | ||
* | ||
* @param Iterator|string $dir The directory to search in or an iterator | ||
* | ||
* @return array A class map array | ||
*/ | ||
static public function createMap($dir) | ||
{ | ||
if (is_string($dir)) { | ||
$dir = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir)); | ||
} | ||
|
||
$map = array(); | ||
|
||
foreach ($dir as $file) { | ||
if (!$file->isFile()) { | ||
continue; | ||
} | ||
|
||
$path = $file->getRealPath(); | ||
|
||
if (pathinfo($path, PATHINFO_EXTENSION) !== 'php') { | ||
continue; | ||
} | ||
|
||
$classes = self::findClasses($path); | ||
|
||
foreach ($classes as $class) { | ||
$map[$class] = $path; | ||
} | ||
|
||
} | ||
|
||
return $map; | ||
} | ||
|
||
/** | ||
* Extract the classes in the given file | ||
* | ||
* @param string $path The file to check | ||
* | ||
* @return array The found classes | ||
*/ | ||
static private function findClasses($path) | ||
{ | ||
$contents = file_get_contents($path); | ||
$tokens = token_get_all($contents); | ||
|
||
$classes = array(); | ||
|
||
$namespace = ''; | ||
for ($i = 0, $max = count($tokens); $i < $max; $i++) { | ||
$token = $tokens[$i]; | ||
|
||
if (is_string($token)) { | ||
continue; | ||
} | ||
|
||
$class = ''; | ||
|
||
switch ($token[0]) { | ||
case T_NAMESPACE: | ||
$namespace = ''; | ||
// If there is a namespace, extract it | ||
while (($t = $tokens[++$i]) && is_array($t)) { | ||
if (in_array($t[0], array(T_STRING, T_NS_SEPARATOR))) { | ||
$namespace .= $t[1]; | ||
} | ||
} | ||
$namespace .= '\\'; | ||
break; | ||
case T_CLASS: | ||
case T_INTERFACE: | ||
// Find the classname | ||
while (($t = $tokens[++$i]) && is_array($t)) { | ||
if (T_STRING === $t[0]) { | ||
$class .= $t[1]; | ||
} elseif ($class !== '' && T_WHITESPACE == $t[0]) { | ||
break; | ||
} | ||
} | ||
|
||
if (empty($namespace)) { | ||
$classes[] = $class; | ||
} else { | ||
$classes[] = $namespace . $class; | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
return $classes; | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<?php | ||
|
||
/* | ||
* This file was copied from the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Composer\Test\Autoload; | ||
|
||
use Composer\Autoload\ClassMapGenerator; | ||
|
||
class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
/** | ||
* @dataProvider getTestCreateMapTests | ||
*/ | ||
public function testCreateMap($directory, $expected) | ||
{ | ||
$this->assertEqualsNormalized($expected, ClassMapGenerator::createMap($directory)); | ||
} | ||
|
||
public function getTestCreateMapTests() | ||
{ | ||
return array( | ||
array(__DIR__.'/Fixtures/Namespaced', array( | ||
'Namespaced\\Bar' => realpath(__DIR__).'/Fixtures/Namespaced/Bar.php', | ||
'Namespaced\\Foo' => realpath(__DIR__).'/Fixtures/Namespaced/Foo.php', | ||
'Namespaced\\Baz' => realpath(__DIR__).'/Fixtures/Namespaced/Baz.php', | ||
) | ||
), | ||
array(__DIR__.'/Fixtures/beta/NamespaceCollision', array( | ||
'NamespaceCollision\\A\\B\\Bar' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Bar.php', | ||
'NamespaceCollision\\A\\B\\Foo' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Foo.php', | ||
)), | ||
array(__DIR__.'/Fixtures/Pearlike', array( | ||
'Pearlike_Foo' => realpath(__DIR__).'/Fixtures/Pearlike/Foo.php', | ||
'Pearlike_Bar' => realpath(__DIR__).'/Fixtures/Pearlike/Bar.php', | ||
'Pearlike_Baz' => realpath(__DIR__).'/Fixtures/Pearlike/Baz.php', | ||
)), | ||
array(__DIR__.'/Fixtures/classmap', array( | ||
'Foo\\Bar\\A' => realpath(__DIR__).'/Fixtures/classmap/sameNsMultipleClasses.php', | ||
'Foo\\Bar\\B' => realpath(__DIR__).'/Fixtures/classmap/sameNsMultipleClasses.php', | ||
'Alpha\\A' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', | ||
'Alpha\\B' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', | ||
'Beta\\A' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', | ||
'Beta\\B' => realpath(__DIR__).'/Fixtures/classmap/multipleNs.php', | ||
'ClassMap\\SomeInterface' => realpath(__DIR__).'/Fixtures/classmap/SomeInterface.php', | ||
'ClassMap\\SomeParent' => realpath(__DIR__).'/Fixtures/classmap/SomeParent.php', | ||
'ClassMap\\SomeClass' => realpath(__DIR__).'/Fixtures/classmap/SomeClass.php', | ||
)), | ||
); | ||
} | ||
|
||
public function testCreateMapFinderSupport() | ||
{ | ||
if (!class_exists('Symfony\\Component\\Finder\\Finder')) { | ||
$this->markTestSkipped('Finder component is not available'); | ||
} | ||
|
||
$finder = new \Symfony\Component\Finder\Finder(); | ||
$finder->files()->in(__DIR__ . '/Fixtures/beta/NamespaceCollision'); | ||
|
||
$this->assertEqualsNormalized(array( | ||
'NamespaceCollision\\A\\B\\Bar' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Bar.php', | ||
'NamespaceCollision\\A\\B\\Foo' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Foo.php', | ||
), ClassMapGenerator::createMap($finder)); | ||
} | ||
|
||
protected function assertEqualsNormalized($expected, $actual, $message = null) | ||
{ | ||
foreach ($expected as $ns => $path) { | ||
$expected[$ns] = strtr($path, '\\', '/'); | ||
} | ||
foreach ($actual as $ns => $path) { | ||
$actual[$ns] = strtr($path, '\\', '/'); | ||
} | ||
$this->assertEquals($expected, $actual, $message); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
|
||
namespace Namespaced; | ||
|
||
class Bar | ||
{ | ||
public static $loaded = true; | ||
} |
Oops, something went wrong.