|
| 1 | +<?php declare(strict_types = 1); |
| 2 | + |
| 3 | +namespace PHPStan; |
| 4 | + |
| 5 | +use Composer\Autoload\ClassLoader; |
| 6 | +use function class_exists; |
| 7 | +use function file_exists; |
| 8 | +use const PHP_VERSION_ID; |
| 9 | + |
| 10 | +final class PharAutoloader |
| 11 | +{ |
| 12 | + /** @var ClassLoader */ |
| 13 | + private static $composerAutoloader; |
| 14 | + |
| 15 | + /** @var bool */ |
| 16 | + private static $polyfillsLoaded = false; |
| 17 | + |
| 18 | + final public static function loadClass(string $class): void { |
| 19 | + $downloadedPharPath = 'phar://' . __DIR__ . '/phpstan.phar'; |
| 20 | + if (!file_exists($downloadedPharPath)) { |
| 21 | + return; |
| 22 | + } |
| 23 | + if (!extension_loaded('phar') || defined('__PHPSTAN_RUNNING__')) { |
| 24 | + return; |
| 25 | + } |
| 26 | + |
| 27 | + if (strpos($class, '_PHPStan_') === 0) { |
| 28 | + if (!in_array('phar', stream_get_wrappers(), true)) { |
| 29 | + throw new \Exception('Phar wrapper is not registered. Please review your php.ini settings.'); |
| 30 | + } |
| 31 | + |
| 32 | + if (self::$composerAutoloader === null) { |
| 33 | + self::$composerAutoloader = require $downloadedPharPath . '/vendor/autoload.php'; |
| 34 | + require_once $downloadedPharPath . '/vendor/jetbrains/phpstorm-stubs/PhpStormStubsMap.php'; |
| 35 | + require_once $downloadedPharPath . '/vendor/react/async/src/functions_include.php'; |
| 36 | + require_once $downloadedPharPath . '/vendor/react/promise/src/functions_include.php'; |
| 37 | + } |
| 38 | + self::$composerAutoloader->loadClass($class); |
| 39 | + |
| 40 | + return; |
| 41 | + } |
| 42 | + if (strpos($class, 'PHPStan\\') !== 0 || strpos($class, 'PHPStan\\PhpDocParser\\') === 0) { |
| 43 | + return; |
| 44 | + } |
| 45 | + |
| 46 | + if (!in_array('phar', stream_get_wrappers(), true)) { |
| 47 | + throw new \Exception('Phar wrapper is not registered. Please review your php.ini settings.'); |
| 48 | + } |
| 49 | + |
| 50 | + if (!self::$polyfillsLoaded) { |
| 51 | + self::$polyfillsLoaded = true; |
| 52 | + |
| 53 | + if ( |
| 54 | + PHP_VERSION_ID < 80000 |
| 55 | + && empty($GLOBALS['__composer_autoload_files']['a4a119a56e50fbb293281d9a48007e0e']) |
| 56 | + && !class_exists(\Symfony\Polyfill\Php80\Php80::class, false) |
| 57 | + ) { |
| 58 | + $GLOBALS['__composer_autoload_files']['a4a119a56e50fbb293281d9a48007e0e'] = true; |
| 59 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-php80/Php80.php'; |
| 60 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-php80/bootstrap.php'; |
| 61 | + } |
| 62 | + |
| 63 | + if ( |
| 64 | + empty($GLOBALS['__composer_autoload_files']['0e6d7bf4a5811bfa5cf40c5ccd6fae6a']) |
| 65 | + && !class_exists(\Symfony\Polyfill\Mbstring\Mbstring::class, false) |
| 66 | + ) { |
| 67 | + $GLOBALS['__composer_autoload_files']['0e6d7bf4a5811bfa5cf40c5ccd6fae6a'] = true; |
| 68 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-mbstring/Mbstring.php'; |
| 69 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-mbstring/bootstrap.php'; |
| 70 | + } |
| 71 | + |
| 72 | + if ( |
| 73 | + empty($GLOBALS['__composer_autoload_files']['e69f7f6ee287b969198c3c9d6777bd38']) |
| 74 | + && !class_exists(\Symfony\Polyfill\Intl\Normalizer\Normalizer::class, false) |
| 75 | + ) { |
| 76 | + $GLOBALS['__composer_autoload_files']['e69f7f6ee287b969198c3c9d6777bd38'] = true; |
| 77 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-intl-normalizer/Normalizer.php'; |
| 78 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-intl-normalizer/bootstrap.php'; |
| 79 | + } |
| 80 | + |
| 81 | + if ( |
| 82 | + !extension_loaded('intl') |
| 83 | + && empty($GLOBALS['__composer_autoload_files']['8825ede83f2f289127722d4e842cf7e8']) |
| 84 | + && !class_exists(\Symfony\Polyfill\Intl\Grapheme\Grapheme::class, false) |
| 85 | + ) { |
| 86 | + $GLOBALS['__composer_autoload_files']['8825ede83f2f289127722d4e842cf7e8'] = true; |
| 87 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-intl-grapheme/Grapheme.php'; |
| 88 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-intl-grapheme/bootstrap.php'; |
| 89 | + } |
| 90 | + |
| 91 | + if ( |
| 92 | + PHP_VERSION_ID < 80100 |
| 93 | + && empty ($GLOBALS['__composer_autoload_files']['23c18046f52bef3eea034657bafda50f']) |
| 94 | + && !class_exists(\Symfony\Polyfill\Php81\Php81::class, false) |
| 95 | + ) { |
| 96 | + $GLOBALS['__composer_autoload_files']['23c18046f52bef3eea034657bafda50f'] = true; |
| 97 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-php81/Php81.php'; |
| 98 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-php81/bootstrap.php'; |
| 99 | + } |
| 100 | + |
| 101 | + if ( |
| 102 | + PHP_VERSION_ID < 80300 |
| 103 | + && empty ($GLOBALS['__composer_autoload_files']['662a729f963d39afe703c9d9b7ab4a8c']) |
| 104 | + && !class_exists(\Symfony\Polyfill\Php83\Php83::class, false) |
| 105 | + ) { |
| 106 | + $GLOBALS['__composer_autoload_files']['662a729f963d39afe703c9d9b7ab4a8c'] = true; |
| 107 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-php83/Php83.php'; |
| 108 | + require_once $downloadedPharPath . '/vendor/symfony/polyfill-php83/bootstrap.php'; |
| 109 | + } |
| 110 | + } |
| 111 | + |
| 112 | + $filename = str_replace('\\', DIRECTORY_SEPARATOR, $class); |
| 113 | + if (strpos($class, 'PHPStan\\BetterReflection\\') === 0) { |
| 114 | + $filename = substr($filename, strlen('PHPStan\\BetterReflection\\')); |
| 115 | + $filepath = $downloadedPharPath . '/vendor/ondrejmirtes/better-reflection/src/' . $filename . '.php'; |
| 116 | + } else { |
| 117 | + $filename = substr($filename, strlen('PHPStan\\')); |
| 118 | + $filepath = $downloadedPharPath . '/src/' . $filename . '.php'; |
| 119 | + } |
| 120 | + |
| 121 | + if (!file_exists($filepath)) { |
| 122 | + return; |
| 123 | + } |
| 124 | + |
| 125 | + require $filepath; |
| 126 | + } |
| 127 | +} |
| 128 | + |
| 129 | +spl_autoload_register([PharAutoloader::class, 'loadClass']); |
0 commit comments