@@ -37,7 +37,9 @@ class ClassExistenceResource implements SelfCheckingResourceInterface
3737 public function __construct (string $ resource , bool $ exists = null )
3838 {
3939 $ this ->resource = $ resource ;
40- $ this ->exists = $ exists ;
40+ if (null !== $ exists ) {
41+ $ this ->exists = [(bool ) $ exists , null ];
42+ }
4143 }
4244
4345 /**
@@ -65,26 +67,33 @@ public function isFresh($timestamp)
6567 {
6668 $ loaded = class_exists ($ this ->resource , false ) || interface_exists ($ this ->resource , false ) || trait_exists ($ this ->resource , false );
6769
68- if (null !== $ exists = &self ::$ existsCache [(int ) (0 >= $ timestamp )][$ this ->resource ]) {
69- $ exists = $ exists || $ loaded ;
70- } elseif (!$ exists = $ loaded ) {
70+ if (null !== $ exists = &self ::$ existsCache [$ this ->resource ]) {
71+ if ($ loaded ) {
72+ $ exists = [true , null ];
73+ } elseif (0 >= $ timestamp && !$ exists [0 ] && null !== $ exists [1 ]) {
74+ throw new \ReflectionException ($ exists [1 ]);
75+ }
76+ } elseif ([false , null ] === $ exists = [$ loaded , null ]) {
7177 if (!self ::$ autoloadLevel ++) {
7278 spl_autoload_register (__CLASS__ .'::throwOnRequiredClass ' );
7379 }
7480 $ autoloadedClass = self ::$ autoloadedClass ;
7581 self ::$ autoloadedClass = ltrim ($ this ->resource , '\\' );
7682
7783 try {
78- $ exists = class_exists ($ this ->resource ) || interface_exists ($ this ->resource , false ) || trait_exists ($ this ->resource , false );
84+ $ exists[ 0 ] = class_exists ($ this ->resource ) || interface_exists ($ this ->resource , false ) || trait_exists ($ this ->resource , false );
7985 } catch (\Exception $ e ) {
86+ $ exists [1 ] = $ e ->getMessage ();
87+
8088 try {
8189 self ::throwOnRequiredClass ($ this ->resource , $ e );
8290 } catch (\ReflectionException $ e ) {
8391 if (0 >= $ timestamp ) {
84- unset(self ::$ existsCache [1 ][$ this ->resource ]);
8592 throw $ e ;
8693 }
8794 }
95+ } catch (\Throwable $ e ) {
96+ $ exists [1 ] = $ e ->getMessage ();
8897 } finally {
8998 self ::$ autoloadedClass = $ autoloadedClass ;
9099 if (!--self ::$ autoloadLevel ) {
@@ -97,7 +106,7 @@ public function isFresh($timestamp)
97106 $ this ->exists = $ exists ;
98107 }
99108
100- return $ this ->exists xor !$ exists ;
109+ return $ this ->exists [ 0 ] xor !$ exists[ 0 ] ;
101110 }
102111
103112 /**
@@ -112,6 +121,16 @@ public function __sleep(): array
112121 return ['resource ' , 'exists ' ];
113122 }
114123
124+ /**
125+ * @internal
126+ */
127+ public function __wakeup ()
128+ {
129+ if (\is_bool ($ this ->exists )) {
130+ $ this ->exists = [$ this ->exists , null ];
131+ }
132+ }
133+
115134 /**
116135 * Throws a reflection exception when the passed class does not exist but is required.
117136 *
@@ -147,7 +166,17 @@ public static function throwOnRequiredClass($class, \Exception $previous = null)
147166 throw $ previous ;
148167 }
149168
150- $ e = new \ReflectionException (sprintf ('Class "%s" not found while loading "%s". ' , $ class , self ::$ autoloadedClass ), 0 , $ previous );
169+ $ message = sprintf ('Class "%s" not found. ' , $ class );
170+
171+ if (self ::$ autoloadedClass !== $ class ) {
172+ $ message = substr_replace ($ message , sprintf (' while loading "%s" ' , self ::$ autoloadedClass ), -1 , 0 );
173+ }
174+
175+ if (null !== $ previous ) {
176+ $ message = $ previous ->getMessage ();
177+ }
178+
179+ $ e = new \ReflectionException ($ message , 0 , $ previous );
151180
152181 if (null !== $ previous ) {
153182 throw $ e ;
0 commit comments