runAndCollect( function () use ($current_dir, $options, $vendor_dir): ?\Composer\Autoload\ClassLoader { return \Psalm\requireAutoloaders($current_dir, isset($options['r']), $vendor_dir); } ); $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 = \Psalm\get_path_to_config($options); if (isset($options['tcp'])) { if (!is_string($options['tcp'])) { fwrite(STDERR, 'tcp url should be a string' . PHP_EOL); exit(1); } } $find_unused_code = isset($options['find-dead-code']) ? 'auto' : null; $config = \Psalm\initialiseConfig($path_to_config, $current_dir, \Psalm\Report::TYPE_CONSOLE, $first_autoloader); $config->setIncludeCollector($include_collector); if ($config->resolve_from_config_file) { $current_dir = $config->base_dir; chdir($current_dir); } $config->setServerMode(); if (isset($options['clear-cache'])) { $cache_directory = $config->getCacheDirectory(); if ($cache_directory !== null) { 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), new \Psalm\Internal\Provider\ProjectCacheProvider(Composer::getLockFilePath($current_dir)) ); $project_analyzer = new ProjectAnalyzer( $config, $providers ); if ($config->find_unused_variables) { $project_analyzer->getCodebase()->reportUnusedVariables(); } if ($config->find_unused_code) { $find_unused_code = 'auto'; } 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_unused_code) { $project_analyzer->getCodebase()->reportUnusedCode($find_unused_code); } if (isset($options['use-extended-diagnostic-codes'])) { $project_analyzer->language_server_use_extended_diagnostic_codes = true; } if (isset($options['verbose'])) { $project_analyzer->language_server_verbose = true; } $project_analyzer->server($options['tcp'] ?? null, isset($options['tcp-server']) ? true : false);