From 647b3d2f54f6ae2ac7f61d3597e9661755937413 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 5 Sep 2016 14:06:16 +0200 Subject: [PATCH] [ClassLoader] Fix ClassCollectionLoader inlining with declare(strict_types=1) --- .../ClassLoader/ClassCollectionLoader.php | 52 ++++++++++++++----- .../Tests/ClassCollectionLoaderTest.php | 14 +++-- .../Tests/ClassMapGeneratorTest.php | 1 + .../Fixtures/Namespaced/WithStrictTypes.php | 13 +++++ 4 files changed, 61 insertions(+), 19 deletions(-) create mode 100644 src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/WithStrictTypes.php diff --git a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php index b695b9272f..18e22a5bca 100644 --- a/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php +++ b/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php @@ -58,7 +58,12 @@ class ClassCollectionLoader $classes = array_unique($classes); - $cache = $cacheDir.'/'.$name.$extension; + // cache the core classes + if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) { + throw new \RuntimeException(sprintf('Class Collection Loader was not able to create directory "%s"', $cacheDir)); + } + $cacheDir = rtrim(realpath($cacheDir), '/'.DIRECTORY_SEPARATOR); + $cache = $cacheDir.DIRECTORY_SEPARATOR.$name.$extension; // auto-reload $reload = false; @@ -99,6 +104,10 @@ class ClassCollectionLoader } } + $c = '(?:\s*+(?:(?:#|//)[^\n]*+\n|/\*(?:(?getFileName(); + $files[] = $file = $class->getFileName(); + $c = file_get_contents($file); - $c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($class->getFileName())); + if (preg_match($strictTypesRegex, $c)) { + $file = explode(DIRECTORY_SEPARATOR, $file); - // fakes namespace declaration for global code - if (!$class->inNamespace()) { - $c = "\nnamespace\n{\n".$c."\n}\n"; + for ($i = 0; isset($file[$i], $cacheDir[$i]); ++$i) { + if ($file[$i] !== $cacheDir[$i]) { + break; + } + } + if (1 >= $i) { + $file = var_export(implode(DIRECTORY_SEPARATOR, $file), true); + } else { + $file = array_slice($file, $i); + $file = str_repeat('..'.DIRECTORY_SEPARATOR, count($cacheDir) - $i).implode(DIRECTORY_SEPARATOR, $file); + $file = '__DIR__.'.var_export(DIRECTORY_SEPARATOR.$file, true); + } + + $c = "\nnamespace {require $file;}"; + } else { + $c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', $c); + + // fakes namespace declaration for global code + if (!$class->inNamespace()) { + $c = "\nnamespace\n{\n".$c."\n}\n"; + } + + $c = self::fixNamespaceDeclarations(' realpath(__DIR__).'/Fixtures/Namespaced/Foo.php', 'Namespaced\\Baz' => realpath(__DIR__).'/Fixtures/Namespaced/Baz.php', 'Namespaced\\WithComments' => realpath(__DIR__).'/Fixtures/Namespaced/WithComments.php', + 'Namespaced\WithStrictTypes' => realpath(__DIR__).'/Fixtures/Namespaced/WithStrictTypes.php', ), ), array(__DIR__.'/Fixtures/beta/NamespaceCollision', array( diff --git a/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/WithStrictTypes.php b/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/WithStrictTypes.php new file mode 100644 index 0000000000..3c7870592b --- /dev/null +++ b/src/Symfony/Component/ClassLoader/Tests/Fixtures/Namespaced/WithStrictTypes.php @@ -0,0 +1,13 @@ +