diff --git a/src/Symfony/Component/Config/Resource/ClassExistenceResource.php b/src/Symfony/Component/Config/Resource/ClassExistenceResource.php index 4e0d0d834e..685da72850 100644 --- a/src/Symfony/Component/Config/Resource/ClassExistenceResource.php +++ b/src/Symfony/Component/Config/Resource/ClassExistenceResource.php @@ -36,7 +36,7 @@ class ClassExistenceResource implements SelfCheckingResourceInterface, \Serializ { $this->resource = $resource; if (null !== $exists) { - $this->exists = (bool) $exists; + $this->exists = [(bool) $exists, null]; } } @@ -65,9 +65,13 @@ class ClassExistenceResource implements SelfCheckingResourceInterface, \Serializ { $loaded = class_exists($this->resource, false) || interface_exists($this->resource, false) || trait_exists($this->resource, false); - if (null !== $exists = &self::$existsCache[(int) (0 >= $timestamp)][$this->resource]) { - $exists = $exists || $loaded; - } elseif (!$exists = $loaded) { + if (null !== $exists = &self::$existsCache[$this->resource]) { + if ($loaded) { + $exists = [true, null]; + } elseif (0 >= $timestamp && !$exists[0] && null !== $exists[1]) { + throw new \ReflectionException($exists[1]); + } + } elseif ([false, null] === $exists = [$loaded, null]) { if (!self::$autoloadLevel++) { spl_autoload_register(__CLASS__.'::throwOnRequiredClass'); } @@ -75,16 +79,19 @@ class ClassExistenceResource implements SelfCheckingResourceInterface, \Serializ self::$autoloadedClass = ltrim($this->resource, '\\'); try { - $exists = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false); + $exists[0] = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false); } catch (\Exception $e) { + $exists[1] = $e->getMessage(); + try { self::throwOnRequiredClass($this->resource, $e); } catch (\ReflectionException $e) { if (0 >= $timestamp) { - unset(self::$existsCache[1][$this->resource]); throw $e; } } + } catch (\Throwable $e) { + $exists[1] = $e->getMessage(); } finally { self::$autoloadedClass = $autoloadedClass; if (!--self::$autoloadLevel) { @@ -97,7 +104,7 @@ class ClassExistenceResource implements SelfCheckingResourceInterface, \Serializ $this->exists = $exists; } - return $this->exists xor !$exists; + return $this->exists[0] xor !$exists[0]; } /** @@ -118,6 +125,10 @@ class ClassExistenceResource implements SelfCheckingResourceInterface, \Serializ public function unserialize($serialized) { list($this->resource, $this->exists) = unserialize($serialized); + + if (\is_bool($this->exists)) { + $this->exists = [$this->exists, null]; + } } /** @@ -155,7 +166,17 @@ class ClassExistenceResource implements SelfCheckingResourceInterface, \Serializ throw $previous; } - $e = new \ReflectionException(sprintf('Class "%s" not found while loading "%s".', $class, self::$autoloadedClass), 0, $previous); + $message = sprintf('Class "%s" not found.', $class); + + if (self::$autoloadedClass !== $class) { + $message = substr_replace($message, sprintf(' while loading "%s"', self::$autoloadedClass), -1, 0); + } + + if (null !== $previous) { + $message = $previous->getMessage(); + } + + $e = new \ReflectionException($message, 0, $previous); if (null !== $previous) { throw $e; diff --git a/src/Symfony/Component/Config/Tests/Fixtures/BadFileName.php b/src/Symfony/Component/Config/Tests/Fixtures/BadFileName.php new file mode 100644 index 0000000000..0f79bdd523 --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Fixtures/BadFileName.php @@ -0,0 +1,9 @@ +isFresh(0); } + public function testBadFileName() + { + $this->expectException('ReflectionException'); + $this->expectExceptionMessage('Mismatch between file name and class name.'); + + $res = new ClassExistenceResource(BadFileName::class, false); + $res->isFresh(0); + } + + public function testBadFileNameBis() + { + $this->expectException('ReflectionException'); + $this->expectExceptionMessage('Mismatch between file name and class name.'); + + $res = new ClassExistenceResource(BadFileName::class, false); + $res->isFresh(0); + } + public function testConditionalClass() { $res = new ClassExistenceResource(ConditionalClass::class, false);