moved ClassLoaderCollection class to the ClassLoader component

This commit is contained in:
Fabien Potencier 2011-01-27 14:11:54 +01:00
parent db818284af
commit 95e10b3ed9
4 changed files with 167 additions and 120 deletions

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpKernel;
namespace Symfony\Component\ClassLoader;
/**
* ClassCollectionLoader.
@ -111,7 +111,7 @@ class ClassCollectionLoader
if (!is_dir(dirname($cache))) {
mkdir(dirname($cache), 0777, true);
}
self::writeCacheFile($cache, Kernel::stripComments('<?php '.$content));
self::writeCacheFile($cache, self::stripComments('<?php '.$content));
if ($autoReload) {
// save the resources
@ -175,4 +175,35 @@ class ClassCollectionLoader
throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
}
/**
* Removes comments from a PHP source string.
*
* We don't use the PHP php_strip_whitespace() function
* as we want the content to be readable and well-formatted.
*
* @param string $source A PHP string
*
* @return string The PHP string with the comments removed
*/
static protected function stripComments($source)
{
if (!function_exists('token_get_all')) {
return $source;
}
$output = '';
foreach (token_get_all($source) as $token) {
if (is_string($token)) {
$output .= $token;
} elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
$output .= $token[1];
}
}
// replace multiple new lines with a single newline
$output = preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $output);
return $output;
}
}

View File

@ -12,7 +12,7 @@ require_once __DIR__.'/../../../ClassLoader/UniversalClassLoader.php';
*/
use Symfony\Component\ClassLoader\UniversalClassLoader;
use Symfony\Component\HttpKernel\ClassCollectionLoader;
use Symfony\Component\ClassLoader\ClassCollectionLoader;
$loader = new UniversalClassLoader();
$loader->registerNamespaces(array('Symfony' => __DIR__.'/../../../../..'));
@ -34,7 +34,6 @@ ClassCollectionLoader::load(array(
'Symfony\\Component\\HttpKernel\\Bundle\\BundleInterface',
'Symfony\\Component\\HttpKernel\\Bundle\\Bundle',
'Symfony\\Component\\HttpKernel\\Debug\\ErrorHandler',
'Symfony\\Component\\HttpKernel\\ClassCollectionLoader',
'Symfony\\Component\\HttpKernel\\HttpKernelInterface',
'Symfony\\Component\\HttpKernel\\HttpKernel',
'Symfony\\Component\\HttpKernel\\KernelInterface',
@ -46,6 +45,7 @@ ClassCollectionLoader::load(array(
'Symfony\\Component\\HttpFoundation\\HeaderBag',
'Symfony\\Component\\HttpFoundation\\Request',
'Symfony\\Component\\ClassLoader\\ClassCollectionLoader',
'Symfony\\Component\\ClassLoader\\UniversalClassLoader',
), __DIR__.'/../..', 'bootstrap', false);

View File

@ -427,120 +427,6 @@ class ErrorHandler
}
namespace Symfony\Component\HttpKernel
{
class ClassCollectionLoader
{
static protected $loaded;
static public function load($classes, $cacheDir, $name, $autoReload, $adaptive = false)
{
if (isset(self::$loaded[$name])) {
return;
}
self::$loaded[$name] = true;
$classes = array_unique($classes);
$cache = $cacheDir.'/'.$name.'.php';
$reload = false;
if ($autoReload) {
if ($adaptive) {
$classes = array_diff($classes, get_declared_classes(), get_declared_interfaces());
}
$metadata = $cacheDir.'/'.$name.'.meta';
if (!file_exists($metadata) || !file_exists($cache)) {
$reload = true;
} else {
$time = filemtime($cache);
$meta = unserialize(file_get_contents($metadata));
if ($meta[1] != $classes) {
$reload = true;
} else {
foreach ($meta[0] as $resource) {
if (!file_exists($resource) || filemtime($resource) > $time) {
$reload = true;
break;
}
}
}
}
}
if (!$reload && file_exists($cache)) {
require_once $cache;
return;
}
if ($adaptive) {
$classes = array_diff($classes, get_declared_classes(), get_declared_interfaces());
}
$files = array();
$content = '';
foreach ($classes as $class) {
if (!class_exists($class) && !interface_exists($class)) {
throw new \InvalidArgumentException(sprintf('Unable to load class "%s"', $class));
}
$r = new \ReflectionClass($class);
$files[] = $r->getFileName();
$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($r->getFileName()));
if (!$r->inNamespace()) {
$c = "\nnamespace\n{\n$c\n}\n";
} else {
$c = self::fixNamespaceDeclarations('<?php '.$c);
$c = preg_replace('/^\s*<\?php/', '', $c);
}
$content .= $c;
}
if (!is_dir(dirname($cache))) {
mkdir(dirname($cache), 0777, true);
}
self::writeCacheFile($cache, Kernel::stripComments('<?php '.$content));
if ($autoReload) {
self::writeCacheFile($metadata, serialize(array($files, $classes)));
}
}
static public function fixNamespaceDeclarations($source)
{
if (!function_exists('token_get_all')) {
return $source;
}
$output = '';
$inNamespace = false;
$tokens = token_get_all($source);
while ($token = array_shift($tokens)) {
if (is_string($token)) {
$output .= $token;
} elseif (T_NAMESPACE === $token[0]) {
if ($inNamespace) {
$output .= "}\n";
}
$output .= $token[1];
while (($t = array_shift($tokens)) && is_array($t) && in_array($t[0], array(T_WHITESPACE, T_NS_SEPARATOR, T_STRING))) {
$output .= $t[1];
}
if (is_string($t) && '{' === $t) {
$inNamespace = false;
array_unshift($tokens, $t);
} else {
$output .= "\n{";
$inNamespace = true;
}
} else {
$output .= $token[1];
}
}
if ($inNamespace) {
$output .= "}\n";
}
return $output;
}
static protected function writeCacheFile($file, $content)
{
$tmpFile = tempnam(dirname($file), basename($file));
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
chmod($file, 0644);
return;
}
throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
}
}
}
namespace Symfony\Component\HttpKernel
{
use Symfony\Component\HttpFoundation\Request;
interface HttpKernelInterface
{
@ -1839,6 +1725,136 @@ class Request
}
namespace Symfony\Component\ClassLoader
{
class ClassCollectionLoader
{
static protected $loaded;
static public function load($classes, $cacheDir, $name, $autoReload, $adaptive = false)
{
if (isset(self::$loaded[$name])) {
return;
}
self::$loaded[$name] = true;
$classes = array_unique($classes);
$cache = $cacheDir.'/'.$name.'.php';
$reload = false;
if ($autoReload) {
if ($adaptive) {
$classes = array_diff($classes, get_declared_classes(), get_declared_interfaces());
}
$metadata = $cacheDir.'/'.$name.'.meta';
if (!file_exists($metadata) || !file_exists($cache)) {
$reload = true;
} else {
$time = filemtime($cache);
$meta = unserialize(file_get_contents($metadata));
if ($meta[1] != $classes) {
$reload = true;
} else {
foreach ($meta[0] as $resource) {
if (!file_exists($resource) || filemtime($resource) > $time) {
$reload = true;
break;
}
}
}
}
}
if (!$reload && file_exists($cache)) {
require_once $cache;
return;
}
if ($adaptive) {
$classes = array_diff($classes, get_declared_classes(), get_declared_interfaces());
}
$files = array();
$content = '';
foreach ($classes as $class) {
if (!class_exists($class) && !interface_exists($class)) {
throw new \InvalidArgumentException(sprintf('Unable to load class "%s"', $class));
}
$r = new \ReflectionClass($class);
$files[] = $r->getFileName();
$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($r->getFileName()));
if (!$r->inNamespace()) {
$c = "\nnamespace\n{\n$c\n}\n";
} else {
$c = self::fixNamespaceDeclarations('<?php '.$c);
$c = preg_replace('/^\s*<\?php/', '', $c);
}
$content .= $c;
}
if (!is_dir(dirname($cache))) {
mkdir(dirname($cache), 0777, true);
}
self::writeCacheFile($cache, self::stripComments('<?php '.$content));
if ($autoReload) {
self::writeCacheFile($metadata, serialize(array($files, $classes)));
}
}
static public function fixNamespaceDeclarations($source)
{
if (!function_exists('token_get_all')) {
return $source;
}
$output = '';
$inNamespace = false;
$tokens = token_get_all($source);
while ($token = array_shift($tokens)) {
if (is_string($token)) {
$output .= $token;
} elseif (T_NAMESPACE === $token[0]) {
if ($inNamespace) {
$output .= "}\n";
}
$output .= $token[1];
while (($t = array_shift($tokens)) && is_array($t) && in_array($t[0], array(T_WHITESPACE, T_NS_SEPARATOR, T_STRING))) {
$output .= $t[1];
}
if (is_string($t) && '{' === $t) {
$inNamespace = false;
array_unshift($tokens, $t);
} else {
$output .= "\n{";
$inNamespace = true;
}
} else {
$output .= $token[1];
}
}
if ($inNamespace) {
$output .= "}\n";
}
return $output;
}
static protected function writeCacheFile($file, $content)
{
$tmpFile = tempnam(dirname($file), basename($file));
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
chmod($file, 0644);
return;
}
throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
}
static protected function stripComments($source)
{
if (!function_exists('token_get_all')) {
return $source;
}
$output = '';
foreach (token_get_all($source) as $token) {
if (is_string($token)) {
$output .= $token;
} elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
$output .= $token[1];
}
}
$output = preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $output);
return $output;
}
}
}
namespace Symfony\Component\ClassLoader
{
class UniversalClassLoader
{
protected $namespaces = array();

View File

@ -9,9 +9,9 @@
* file that was distributed with this source code.
*/
namespace Symfony\Tests\Component\HttpKernel;
namespace Symfony\Tests\Component\ClassLoader;
use Symfony\Component\HttpKernel\ClassCollectionLoader;
use Symfony\Component\ClassLoader\ClassCollectionLoader;
class ClassCollectionLoaderTest extends \PHPUnit_Framework_TestCase
{