88use PHPStan \BetterReflection \Reflection \Reflection ;
99use PHPStan \BetterReflection \Reflector \Reflector ;
1010use PHPStan \BetterReflection \SourceLocator \Type \SourceLocator ;
11+ use Throwable ;
1112use function class_exists ;
1213use function interface_exists ;
1314use function PHPStan \autoloadFunctions ;
@@ -19,6 +20,7 @@ final class AutoloadFunctionsSourceLocator implements SourceLocator
1920 public function __construct (
2021 private AutoloadSourceLocator $ autoloadSourceLocator ,
2122 private ReflectionClassSourceLocator $ reflectionClassSourceLocator ,
23+ private BootstrapAutoloaderExceptionReporter $ exceptionReporter ,
2224 )
2325 {
2426 }
@@ -37,7 +39,22 @@ public function locateIdentifier(Reflector $reflector, Identifier $identifier):
3739
3840 $ autoloadFunctions = autoloadFunctions ();
3941 foreach ($ autoloadFunctions as $ autoloadFunction ) {
40- $ autoloadFunction ($ className );
42+ try {
43+ $ autoloadFunction ($ className );
44+ } catch (Throwable $ e ) {
45+ // This locator asks every bootstrap-registered autoloader for the class, which is not
46+ // the order PHP uses: at runtime the class loader that resolves the class first is
47+ // often another one, so an autoloader that throws for names outside its own scope is
48+ // never invoked for them and its exception cannot happen. Letting it propagate here
49+ // aborts the analysis of the file with an internal error instead, so it is swallowed
50+ // and the remaining autoloaders and source locators get their turn. The class may
51+ // still have been defined before the throw, so the locators below run either way.
52+ // The autoloader ran for real, so its message is its real reason - with --debug,
53+ // the reporter prints it.
54+ // See https://github.com/phpstan/phpstan/issues/14976
55+ $ this ->exceptionReporter ->report ($ className , $ e );
56+ }
57+
4158 $ reflection = $ this ->autoloadSourceLocator ->locateIdentifier ($ reflector , $ identifier );
4259 if ($ reflection !== null ) {
4360 return $ reflection ;
0 commit comments