= 0 ) { die(\Psalm\Internal\Fork\Pool::MAC_PCRE_MESSAGE . PHP_EOL . PHP_EOL); } if (isset($options['root'])) { $options['r'] = $options['root']; } $current_dir = (string)getcwd() . DIRECTORY_SEPARATOR; if (isset($options['r']) && is_string($options['r'])) { $root_path = realpath($options['r']); if (!$root_path) { fwrite( STDERR, 'Could not locate root directory ' . $current_dir . DIRECTORY_SEPARATOR . $options['r'] . PHP_EOL ); exit(1); } $current_dir = $root_path . DIRECTORY_SEPARATOR; } $vendor_dir = getVendorDir($current_dir); $first_autoloader = requireAutoloaders($current_dir, isset($options['r']), $vendor_dir); if (array_key_exists('v', $options)) { echo 'Psalm ' . PSALM_VERSION . PHP_EOL; exit; } $ini_handler = new \Psalm\Internal\Fork\PsalmRestarter('PSALM'); $ini_handler->disableExtension('grpc'); // If XDebug is enabled, restart without it $ini_handler->check(); setlocale(LC_CTYPE, 'C'); $path_to_config = isset($options['c']) && is_string($options['c']) ? realpath($options['c']) : null; if ($path_to_config === false) { /** @psalm-suppress InvalidCast */ fwrite(STDERR, 'Could not resolve path to config ' . (string)$options['c'] . PHP_EOL); exit(1); } if (isset($options['tcp'])) { if (!is_string($options['tcp'])) { fwrite(STDERR, 'tcp url should be a string' . PHP_EOL); exit(1); } } $find_dead_code = isset($options['find-dead-code']); // initialise custom config, if passed try { if ($path_to_config) { $config = Config::loadFromXMLFile($path_to_config, $current_dir); } else { $config = Config::getConfigForPath($current_dir, $current_dir, \Psalm\Report::TYPE_CONSOLE); } } catch (Psalm\Exception\ConfigException $e) { fwrite(STDERR, $e->getMessage()); exit(1); } $config->setServerMode(); $config->setComposerClassLoader($first_autoloader); if (isset($options['clear-cache'])) { $cache_directory = $config->getCacheDirectory(); Config::removeCacheDirectory($cache_directory); echo 'Cache directory deleted' . PHP_EOL; exit; } $providers = new Psalm\Internal\Provider\Providers( new Psalm\Internal\Provider\FileProvider, new Psalm\Internal\Provider\ParserCacheProvider($config), new Psalm\Internal\Provider\FileStorageCacheProvider($config), new Psalm\Internal\Provider\ClassLikeStorageCacheProvider($config), new Psalm\Internal\Provider\FileReferenceCacheProvider($config) ); $project_analyzer = new ProjectAnalyzer( $config, $providers ); if (isset($options['disable-on-change'])) { $project_analyzer->onchange_line_limit = (int) $options['disable-on-change']; } $project_analyzer->provide_completion = !isset($options['enable-autocomplete']) || !is_string($options['enable-autocomplete']) || strtolower($options['enable-autocomplete']) !== 'false'; $config->visitComposerAutoloadFiles($project_analyzer); if ($find_dead_code) { $project_analyzer->getCodebase()->reportUnusedCode(); } $project_analyzer->server($options['tcp'] ?? null, isset($options['tcp-server']) ? true : false);