disableExtension('grpc'); // If XDebug is enabled, restart without it $ini_handler->check(); setlocale(LC_CTYPE, 'C'); $output_format = isset($options['output-format']) && is_string($options['output-format']) ? $options['output-format'] : ProjectAnalyzer::TYPE_CONSOLE; $path_to_config = isset($options['c']) && is_string($options['c']) ? realpath($options['c']) : null; if ($path_to_config === false) { /** @psalm-suppress InvalidCast */ echo 'Could not resolve path to config ' . (string)$options['c'] . PHP_EOL; exit(1); } if (isset($options['tcp'])) { if (!is_string($options['tcp'])) { echo '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, $output_format); } } catch (Psalm\Exception\ConfigException $e) { echo $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']; } $config->visitComposerAutoloadFiles($project_analyzer); if ($find_dead_code) { $project_analyzer->getCodebase()->reportUnusedCode(); } $project_analyzer->server($options['tcp'] ?? null, isset($options['tcp-server']) ? true : false);