1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Implement better progress

This commit is contained in:
Ilija Tovilo 2019-05-16 23:12:31 +02:00 committed by Matthew Brown
parent fafe73de0a
commit 042070d0fd
37 changed files with 390 additions and 299 deletions

View File

@ -6,6 +6,7 @@ use Psalm;
use Psalm\Checker\CommentChecker;
use Psalm\Codebase;
use Psalm\DocComment;
use Psalm\Progress\Progress;
use Psalm\Storage\FileStorage;
class TemplateScanner extends Psalm\Internal\Scanner\FileScanner
@ -14,7 +15,6 @@ class TemplateScanner extends Psalm\Internal\Scanner\FileScanner
/**
* @param bool $storage_from_cache
* @param bool $debug_output
*
* @return void
*/
@ -22,11 +22,11 @@ class TemplateScanner extends Psalm\Internal\Scanner\FileScanner
Codebase $codebase,
FileStorage $file_storage,
$storage_from_cache = false,
$debug_output = false
Progress $progress = null
) {
$stmts = $codebase->statements_provider->getStatementsForFile(
$file_storage->file_path,
$debug_output
$progress
);
if (empty($stmts)) {
@ -62,6 +62,6 @@ class TemplateScanner extends Psalm\Internal\Scanner\FileScanner
$codebase->scanner->queueClassLikeForScanning(self::VIEW_CLASS, $this->file_path);
parent::scan($codebase, $file_storage, $storage_from_cache, $debug_output);
parent::scan($codebase, $file_storage, $storage_from_cache, $progress);
}
}

View File

@ -12,6 +12,8 @@ use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Internal\Provider\Providers;
use Psalm\Internal\Provider\StatementsProvider;
use Psalm\Progress\Progress;
use Psalm\Progress\DefaultProgress;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FileStorage;
use Psalm\Storage\FunctionLikeStorage;
@ -80,9 +82,9 @@ class Codebase
public $statements_provider;
/**
* @var bool
* @var Progress
*/
private $debug_output = false;
private $progress;
/**
* @var array<string, Type\Union>
@ -190,22 +192,22 @@ class Codebase
*/
public $php_minor_version = PHP_MINOR_VERSION;
/**
* @param bool $debug_output
*/
public function __construct(
Config $config,
Providers $providers,
$debug_output = false
Progress $progress = null
) {
if ($progress === null) {
$progress = new DefaultProgress();
}
$this->config = $config;
$this->file_storage_provider = $providers->file_storage_provider;
$this->classlike_storage_provider = $providers->classlike_storage_provider;
$this->debug_output = $debug_output;
$this->progress = $progress;
$this->file_provider = $providers->file_provider;
$this->file_reference_provider = $providers->file_reference_provider;
$this->statements_provider = $providers->statements_provider;
$this->debug_output = $debug_output;
self::$stubbed_constants = [];
@ -218,7 +220,7 @@ class Codebase
$providers->file_provider,
$this->reflection,
$providers->file_reference_provider,
$debug_output
$progress
);
$this->loadAnalyzer();
@ -250,7 +252,7 @@ class Codebase
$providers->file_storage_provider,
$this->classlikes,
$providers->file_reference_provider,
$debug_output
$progress
);
$this->loadAnalyzer();
@ -265,7 +267,7 @@ class Codebase
$this->config,
$this->file_provider,
$this->file_storage_provider,
$this->debug_output
$this->progress
);
}
@ -413,7 +415,7 @@ class Codebase
{
return $this->statements_provider->getStatementsForFile(
$file_path,
$this->debug_output
$this->progress
);
}

View File

@ -17,6 +17,8 @@ use Psalm\Internal\Analyzer\FileAnalyzer;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Plugin\Hook;
use Psalm\PluginRegistrationSocket;
use Psalm\Progress\Progress;
use Psalm\Progress\DefaultProgress;
use SimpleXMLElement;
class Config
@ -1434,12 +1436,14 @@ class Config
}
/**
* @param bool $debug
*
* @return void
*/
public function visitStubFiles(Codebase $codebase, $debug = false)
public function visitStubFiles(Codebase $codebase, Progress $progress = null)
{
if ($progress === null) {
$progress = new DefaultProgress();
}
$codebase->register_stub_files = true;
// note: don't realpath $generic_stubs_path, or phar version will fail
@ -1468,15 +1472,11 @@ class Config
$codebase->scanner->addFileToShallowScan($file_path);
}
if ($debug) {
echo 'Registering stub files' . "\n";
}
$progress->debug('Registering stub files' . "\n");
$codebase->scanFiles();
if ($debug) {
echo 'Finished registering stub files' . "\n";
}
$progress->debug('Finished registering stub files' . "\n");
$codebase->register_stub_files = false;
}
@ -1546,15 +1546,17 @@ class Config
}
/**
* @param bool $debug
*
* @return void
*
* @psalm-suppress MixedAssignment
* @psalm-suppress MixedArrayAccess
*/
public function visitComposerAutoloadFiles(ProjectAnalyzer $project_analyzer, $debug = false)
public function visitComposerAutoloadFiles(ProjectAnalyzer $project_analyzer, Progress $progress = null)
{
if ($progress === null) {
$progress = new DefaultProgress();
}
$this->collectPredefinedConstants();
$this->collectPredefinedFunctions();
@ -1610,15 +1612,11 @@ class Config
$codebase->scanner->addFileToDeepScan($file_path);
}
if ($debug) {
echo 'Registering autoloaded files' . "\n";
}
$progress->debug('Registering autoloaded files' . "\n");
$codebase->scanner->scanFiles($codebase->classlikes);
if ($debug) {
echo 'Finished registering autoloaded files' . "\n";
}
$progress->debug('Finished registering autoloaded files' . "\n");
$codebase->register_autoload_files = false;
}

View File

@ -1370,9 +1370,9 @@ class ClassAnalyzer extends ClassLikeAnalyzer
&& !$class_context->collect_mutations
&& !$is_fake
) {
if ($project_analyzer->debug_output) {
echo 'Skipping analysis of pre-analyzed method ' . $analyzed_method_id . "\n";
}
$project_analyzer->progress->debug(
'Skipping analysis of pre-analyzed method ' . $analyzed_method_id . "\n"
);
$existing_issues = $codebase->analyzer->getExistingIssuesForFile(
$source->getFilePath(),

View File

@ -10,6 +10,8 @@ use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\ParserCacheProvider;
use Psalm\Internal\Provider\Providers;
use Psalm\Progress\Progress;
use Psalm\Progress\DefaultProgress;
use Psalm\Type;
/**
@ -75,9 +77,9 @@ class ProjectAnalyzer
public $output_format;
/**
* @var bool
* @var Progress
*/
public $debug_output = false;
public $progress;
/**
* @var bool
@ -159,7 +161,6 @@ class ProjectAnalyzer
* @param bool $show_info
* @param string $output_format
* @param int $threads
* @param bool $debug_output
* @param string $reports
* @param bool $show_snippet
*/
@ -170,10 +171,14 @@ class ProjectAnalyzer
$show_info = true,
$output_format = self::TYPE_CONSOLE,
$threads = 1,
$debug_output = false,
Progress $progress = null,
$reports = null,
$show_snippet = true
) {
if ($progress === null) {
$progress = new DefaultProgress();
}
$this->parser_cache_provider = $providers->parser_cache_provider;
$this->file_provider = $providers->file_provider;
$this->classlike_storage_provider = $providers->classlike_storage_provider;
@ -181,7 +186,7 @@ class ProjectAnalyzer
$this->use_color = $use_color;
$this->show_info = $show_info;
$this->debug_output = $debug_output;
$this->progress = $progress;
$this->threads = $threads;
$this->config = $config;
$this->show_snippet = $show_snippet;
@ -189,7 +194,7 @@ class ProjectAnalyzer
$this->codebase = new Codebase(
$config,
$providers,
$debug_output
$progress
);
if (!in_array($output_format, self::SUPPORTED_OUTPUT_TYPES, true)) {
@ -400,9 +405,7 @@ class ProjectAnalyzer
}
}
if ($this->output_format === self::TYPE_CONSOLE) {
echo 'Scanning files...' . "\n";
}
$this->progress->startScanningFiles();
if ($diff_files === null
|| $deleted_files === null
@ -421,10 +424,8 @@ class ProjectAnalyzer
$this->codebase->scanFiles($this->threads);
} else {
if ($this->debug_output) {
echo count($diff_files) . ' changed files: ' . "\n";
echo ' ' . implode("\n ", $diff_files) . "\n";
}
$this->progress->debug(count($diff_files) . ' changed files: ' . "\n");
$this->progress->debug(' ' . implode("\n ", $diff_files) . "\n");
if ($diff_files || $this->codebase->find_unused_code) {
$file_list = $this->getReferencedFilesFromDiff($diff_files);
@ -440,11 +441,9 @@ class ProjectAnalyzer
}
}
if ($this->output_format === self::TYPE_CONSOLE) {
echo 'Analyzing files...' . "\n";
}
$this->progress->startAnalyzingFiles();
$this->config->visitStubFiles($this->codebase, $this->debug_output);
$this->config->visitStubFiles($this->codebase, $this->progress);
$plugin_classes = $this->config->after_codebase_populated;
@ -461,8 +460,8 @@ class ProjectAnalyzer
$is_diff ? $this->parser_cache_provider->getLastGoodRun() : $start_checks
);
if ($this->debug_output && $removed_parser_files) {
echo 'Removed ' . $removed_parser_files . ' old parser caches' . "\n";
if ($removed_parser_files) {
$this->progress->debug('Removed ' . $removed_parser_files . ' old parser caches' . "\n");
}
if ($is_diff) {
@ -482,7 +481,7 @@ class ProjectAnalyzer
$this->codebase->classlikes->checkClassReferences(
$this->codebase->methods,
$this->debug_output
$this->progress
);
}
@ -526,19 +525,15 @@ class ProjectAnalyzer
$this->checkDirWithConfig($dir_name, $this->config, true);
if ($this->output_format === self::TYPE_CONSOLE) {
echo 'Scanning files...' . "\n";
}
$this->progress->startScanningFiles();
$this->config->initializePlugins($this);
$this->codebase->scanFiles($this->threads);
$this->config->visitStubFiles($this->codebase, $this->debug_output);
$this->config->visitStubFiles($this->codebase, $this->progress);
if ($this->output_format === self::TYPE_CONSOLE) {
echo 'Analyzing files...' . "\n";
}
$this->progress->startAnalyzingFiles();
$this->codebase->analyzer->analyzeFiles($this, $this->threads, $this->codebase->alter_code);
}
@ -634,9 +629,7 @@ class ProjectAnalyzer
}
if (!$config->isInProjectDirs($file_path)) {
if ($this->debug_output) {
echo 'skipping ' . $file_path . "\n";
}
$this->progress->debug('skipping ' . $file_path . "\n");
continue;
}
@ -654,9 +647,7 @@ class ProjectAnalyzer
*/
public function checkFile($file_path)
{
if ($this->debug_output) {
echo 'Checking ' . $file_path . "\n";
}
$this->progress->debug('Checking ' . $file_path . "\n");
$this->config->hide_external_errors = $this->config->isInProjectDirs($file_path);
@ -664,19 +655,15 @@ class ProjectAnalyzer
$this->file_reference_provider->loadReferenceCache();
if ($this->output_format === self::TYPE_CONSOLE) {
echo 'Scanning files...' . "\n";
}
$this->progress->startScanningFiles();
$this->config->initializePlugins($this);
$this->codebase->scanFiles($this->threads);
$this->config->visitStubFiles($this->codebase, $this->debug_output);
$this->config->visitStubFiles($this->codebase, $this->progress);
if ($this->output_format === self::TYPE_CONSOLE) {
echo 'Analyzing files...' . "\n";
}
$this->progress->startAnalyzingFiles();
$this->codebase->analyzer->analyzeFiles($this, $this->threads, $this->codebase->alter_code);
}
@ -688,9 +675,7 @@ class ProjectAnalyzer
public function checkPaths(array $paths_to_check)
{
foreach ($paths_to_check as $path) {
if ($this->debug_output) {
echo 'Checking ' . $path . "\n";
}
$this->progress->debug('Checking ' . $path . "\n");
if (is_dir($path)) {
$this->checkDirWithConfig($path, $this->config, true);
@ -702,26 +687,25 @@ class ProjectAnalyzer
$this->file_reference_provider->loadReferenceCache();
if ($this->output_format === self::TYPE_CONSOLE) {
echo 'Scanning files...' . "\n";
}
$this->progress->startScanningFiles();
$this->config->initializePlugins($this);
$this->codebase->scanFiles($this->threads);
$this->config->visitStubFiles($this->codebase, $this->debug_output);
$this->config->visitStubFiles($this->codebase, $this->progress);
if ($this->output_format === self::TYPE_CONSOLE) {
echo 'Analyzing files...' . "\n";
}
$this->progress->startAnalyzingFiles();
$this->codebase->analyzer->analyzeFiles($this, $this->threads, $this->codebase->alter_code);
if ($this->output_format === ProjectAnalyzer::TYPE_CONSOLE && $this->codebase->collect_references) {
echo PHP_EOL . 'To whom it may concern: Psalm cannot detect unused classes, methods and properties'
fwrite(
STDERR,
PHP_EOL . 'To whom it may concern: Psalm cannot detect unused classes, methods and properties'
. PHP_EOL . 'when analyzing individual files and folders. Run on the full project to enable'
. PHP_EOL . 'complete unused code detection.' . PHP_EOL;
. PHP_EOL . 'complete unused code detection.' . PHP_EOL
);
}
}

View File

@ -90,10 +90,10 @@ class IncludeAnalyzer
$file_name = $config->shortenFileName($path_to_file);
if ($current_file_analyzer->project_analyzer->debug_output) {
$nesting = $statements_analyzer->getRequireNesting() + 1;
echo (str_repeat(' ', $nesting) . 'checking ' . $file_name . PHP_EOL);
}
$nesting = $statements_analyzer->getRequireNesting() + 1;
$current_file_analyzer->project_analyzer->progress->debug(
str_repeat(' ', $nesting) . 'checking ' . $file_name . PHP_EOL
);
$include_file_analyzer = new \Psalm\Internal\Analyzer\FileAnalyzer(
$current_file_analyzer->project_analyzer,

View File

@ -193,7 +193,7 @@ class StatementsAnalyzer extends SourceAnalyzer implements StatementsSource
}
if ($project_analyzer->debug_lines) {
echo $this->getFilePath() . ':' . $stmt->getLine() . "\n";
fwrite(STDERR, $this->getFilePath() . ':' . $stmt->getLine() . "\n");
}
/*

View File

@ -11,6 +11,7 @@ use Psalm\Internal\FileManipulation\FunctionDocblockManipulator;
use Psalm\IssueBuffer;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Progress\Progress;
/**
* @psalm-type IssueData = array{
@ -77,9 +78,9 @@ class Analyzer
private $file_storage_provider;
/**
* @var bool
* @var Progress
*/
private $debug_output;
private $progress;
/**
* Used to store counts of mixed vs non-mixed variables
@ -134,19 +135,16 @@ class Analyzer
*/
private $type_map = [];
/**
* @param bool $debug_output
*/
public function __construct(
Config $config,
FileProvider $file_provider,
FileStorageProvider $file_storage_provider,
$debug_output
Progress $progress
) {
$this->config = $config;
$this->file_provider = $file_provider;
$this->file_storage_provider = $file_storage_provider;
$this->debug_output = $debug_output;
$this->progress = $progress;
}
/**
@ -199,9 +197,7 @@ class Analyzer
$file_analyzer = new FileAnalyzer($project_analyzer, $file_path, $file_name);
}
if ($this->debug_output) {
echo 'Getting ' . $file_path . "\n";
}
$this->progress->debug('Getting ' . $file_path . "\n");
return $file_analyzer;
}
@ -230,9 +226,7 @@ class Analyzer
function ($_, $file_path) use ($project_analyzer, $filetype_analyzers) {
$file_analyzer = $this->getFileAnalyzer($project_analyzer, $file_path, $filetype_analyzers);
if ($this->debug_output) {
echo 'Analyzing ' . $file_analyzer->getFilePath() . "\n";
}
$this->progress->debug('Analyzing ' . $file_analyzer->getFilePath() . "\n");
$file_analyzer->analyze(null);
};
@ -274,9 +268,7 @@ class Analyzer
$analyzer = $codebase->analyzer;
$file_reference_provider = $codebase->file_reference_provider;
if ($this->debug_output) {
echo 'Gathering data for forked process' . "\n";
}
$this->progress->debug('Gathering data for forked process' . "\n");
return [
'issues' => IssueBuffer::getIssuesData(),
@ -303,9 +295,7 @@ class Analyzer
}
);
if ($this->debug_output) {
echo 'Forking analysis' . "\n";
}
$this->progress->debug('Forking analysis' . "\n");
// Wait for all tasks to complete and collect the results.
/**
@ -313,9 +303,7 @@ class Analyzer
*/
$forked_pool_data = $pool->wait();
if ($this->debug_output) {
echo 'Collecting forked analysis results' . "\n";
}
$this->progress->debug('Collecting forked analysis results' . "\n");
foreach ($forked_pool_data as $pool_data) {
IssueBuffer::addIssues($pool_data['issues']);

View File

@ -17,6 +17,8 @@ use Psalm\Issue\UnusedProperty;
use Psalm\IssueBuffer;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Progress\Progress;
use Psalm\Progress\DefaultProgress;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Type;
use ReflectionProperty;
@ -665,12 +667,14 @@ class ClassLikes
/**
* @return void
*/
public function checkClassReferences(Methods $methods, bool $debug_output = false)
public function checkClassReferences(Methods $methods, Progress $progress = null)
{
if ($debug_output) {
echo 'Checking class references' . PHP_EOL;
if ($progress === null) {
$progress = new DefaultProgress();
}
$progress->debug('Checking class references' . PHP_EOL);
foreach ($this->existing_classlikes_lc as $fq_class_name_lc => $_) {
try {
$classlike_storage = $this->classlike_storage_provider->get($fq_class_name_lc);

View File

@ -9,6 +9,7 @@ use Psalm\IssueBuffer;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Progress\Progress;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FileStorage;
use Psalm\Type;
@ -31,9 +32,9 @@ class Populator
private $file_storage_provider;
/**
* @var bool
* @var Progress
*/
private $debug_output;
private $progress;
/**
* @var ClassLikes
@ -50,21 +51,18 @@ class Populator
*/
private $file_reference_provider;
/**
* @param bool $debug_output
*/
public function __construct(
Config $config,
ClassLikeStorageProvider $classlike_storage_provider,
FileStorageProvider $file_storage_provider,
ClassLikes $classlikes,
FileReferenceProvider $file_reference_provider,
$debug_output
Progress $progress
) {
$this->classlike_storage_provider = $classlike_storage_provider;
$this->file_storage_provider = $file_storage_provider;
$this->classlikes = $classlikes;
$this->debug_output = $debug_output;
$this->progress = $progress;
$this->config = $config;
$this->file_reference_provider = $file_reference_provider;
}
@ -74,21 +72,15 @@ class Populator
*/
public function populateCodebase(\Psalm\Codebase $codebase)
{
if ($this->debug_output) {
echo 'ClassLikeStorage is populating' . "\n";
}
$this->progress->debug('ClassLikeStorage is populating' . "\n");
foreach ($this->classlike_storage_provider->getNew() as $class_storage) {
$this->populateClassLikeStorage($class_storage);
}
if ($this->debug_output) {
echo 'ClassLikeStorage is populated' . "\n";
}
$this->progress->debug('ClassLikeStorage is populated' . "\n");
if ($this->debug_output) {
echo 'FileStorage is populating' . "\n";
}
$this->progress->debug('FileStorage is populating' . "\n");
$all_file_storage = $this->file_storage_provider->getNew();
@ -175,9 +167,7 @@ class Populator
}
}
if ($this->debug_output) {
echo 'FileStorage is populated' . "\n";
}
$this->progress->debug('FileStorage is populated' . "\n");
$this->classlike_storage_provider->populated();
$this->file_storage_provider->populated();
@ -271,9 +261,7 @@ class Populator
$this->populateOverriddenMethods($storage);
if ($this->debug_output) {
echo 'Have populated ' . $storage->name . "\n";
}
$this->progress->debug('Have populated ' . $storage->name . "\n");
$storage->populated = true;
}
@ -457,9 +445,7 @@ class Populator
);
$parent_storage = $storage_provider->get($parent_storage_class);
} catch (\InvalidArgumentException $e) {
if ($this->debug_output) {
echo 'Populator could not find dependency (' . __LINE__ . ")\n";
}
$this->progress->debug('Populator could not find dependency (' . __LINE__ . ")\n");
$storage->invalid_dependencies[] = $parent_storage_class;
$parent_storage = null;
@ -571,9 +557,7 @@ class Populator
);
$parent_interface_storage = $storage_provider->get($parent_interface_lc);
} catch (\InvalidArgumentException $e) {
if ($this->debug_output) {
echo 'Populator could not find dependency (' . __LINE__ . ")\n";
}
$this->progress->debug('Populator could not find dependency (' . __LINE__ . ")\n");
$storage->invalid_dependencies[] = $parent_interface_lc;
continue;
@ -661,9 +645,7 @@ class Populator
);
$implemented_interface_storage = $storage_provider->get($implemented_interface_lc);
} catch (\InvalidArgumentException $e) {
if ($this->debug_output) {
echo 'Populator could not find dependency (' . __LINE__ . ")\n";
}
$this->progress->debug('Populator could not find dependency (' . __LINE__ . ")\n");
$storage->invalid_dependencies[] = $implemented_interface_lc;
continue;

View File

@ -7,6 +7,7 @@ use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Progress\Progress;
/**
* @psalm-type IssueData = array{
@ -127,9 +128,9 @@ class Scanner
private $config;
/**
* @var bool
* @var Progress
*/
private $debug_output;
private $progress;
/**
* @var FileStorageProvider
@ -151,9 +152,6 @@ class Scanner
*/
private $is_forked = false;
/**
* @param bool $debug_output
*/
public function __construct(
Codebase $codebase,
Config $config,
@ -161,12 +159,12 @@ class Scanner
FileProvider $file_provider,
Reflection $reflection,
FileReferenceProvider $file_reference_provider,
$debug_output
Progress $progress
) {
$this->codebase = $codebase;
$this->reflection = $reflection;
$this->file_provider = $file_provider;
$this->debug_output = $debug_output;
$this->progress = $progress;
$this->file_storage_provider = $file_storage_provider;
$this->config = $config;
$this->file_reference_provider = $file_reference_provider;
@ -386,18 +384,14 @@ class Scanner
++$i;
}
if ($this->debug_output) {
echo 'Forking process for scanning' . PHP_EOL;
}
$this->progress->debug('Forking process for scanning' . PHP_EOL);
// Run scanning one file at a time, splitting the set of
// files up among a given number of child processes.
$pool = new \Psalm\Internal\Fork\Pool(
$process_file_paths,
function () {
if ($this->debug_output) {
echo 'Initialising forked process for scanning' . PHP_EOL;
}
$this->progress->debug('Initialising forked process for scanning' . PHP_EOL);
$project_analyzer = \Psalm\Internal\Analyzer\ProjectAnalyzer::getInstance();
$codebase = $project_analyzer->getCodebase();
@ -409,18 +403,14 @@ class Scanner
$statements_provider->resetDiffs();
if ($this->debug_output) {
echo 'Have initialised forked process for scanning' . PHP_EOL;
}
$this->progress->debug('Have initialised forked process for scanning' . PHP_EOL);
},
$scanner_worker,
/**
* @return PoolData
*/
function () {
if ($this->debug_output) {
echo 'Collecting data from forked scanner process' . PHP_EOL;
}
$this->progress->debug('Collecting data from forked scanner process' . PHP_EOL);
$project_analyzer = \Psalm\Internal\Analyzer\ProjectAnalyzer::getInstance();
$codebase = $project_analyzer->getCodebase();
@ -520,9 +510,7 @@ class Scanner
continue;
}
if ($this->debug_output) {
echo 'Using reflection to get metadata for ' . $fq_classlike_name . "\n";
}
$this->progress->debug('Using reflection to get metadata for ' . $fq_classlike_name . "\n");
/** @psalm-suppress TypeCoercion */
$reflected_class = new \ReflectionClass($fq_classlike_name);
@ -596,7 +584,7 @@ class Scanner
$this->codebase,
$file_storage,
$from_cache,
$this->debug_output
$this->progress
);
if (!$from_cache) {
@ -710,9 +698,7 @@ class Scanner
$composer_file_path = $this->config->getComposerFilePathForClassLike($fq_class_name);
if ($composer_file_path && file_exists($composer_file_path)) {
if ($this->debug_output) {
echo 'Using composer to locate file for ' . $fq_class_name . "\n";
}
$this->progress->debug('Using composer to locate file for ' . $fq_class_name . "\n");
$classlikes->addFullyQualifiedClassLikeName(
$fq_class_name_lc,
@ -724,14 +710,10 @@ class Scanner
$old_level = error_reporting();
if (!$this->debug_output) {
error_reporting(E_ERROR);
}
$this->progress->setErrorReporting();
try {
if ($this->debug_output) {
echo 'Using reflection to locate file for ' . $fq_class_name . "\n";
}
$this->progress->debug('Using reflection to locate file for ' . $fq_class_name . "\n");
/** @psalm-suppress TypeCoercion */
$reflected_class = new \ReflectionClass($fq_class_name);

View File

@ -184,7 +184,7 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
$codebase->scanFiles($this->project_analyzer->threads);
$codebase->config->visitStubFiles($codebase, false);
$codebase->config->visitStubFiles($codebase, null);
if ($this->textDocument === null) {
$this->textDocument = new TextDocument(

View File

@ -2,6 +2,8 @@
namespace Psalm\Internal\Provider;
use PhpParser;
use Psalm\Progress\Progress;
use Psalm\Progress\DefaultProgress;
/**
* @internal
@ -65,13 +67,16 @@ class StatementsProvider
}
/**
* @param string $file_path
* @param bool $debug_output
* @param string $file_path
*
* @return array<int, \PhpParser\Node\Stmt>
*/
public function getStatementsForFile($file_path, $debug_output = false)
public function getStatementsForFile($file_path, Progress $progress = null)
{
if ($progress === null) {
$progress = new DefaultProgress();
}
$from_cache = false;
$version = (string) PHP_PARSER_VERSION . $this->this_modified_time;
@ -80,9 +85,7 @@ class StatementsProvider
$modified_time = $this->file_provider->getModifiedTime($file_path);
if (!$this->parser_cache_provider) {
if ($debug_output) {
echo 'Parsing ' . $file_path . "\n";
}
$progress->debug('Parsing ' . $file_path . "\n");
$stmts = self::parseStatements($file_contents, $file_path);
@ -98,9 +101,7 @@ class StatementsProvider
);
if ($stmts === null) {
if ($debug_output) {
echo 'Parsing ' . $file_path . "\n";
}
$progress->debug('Parsing ' . $file_path . "\n");
$existing_statements = $this->parser_cache_provider->loadExistingStatementsFromCache($file_path);

View File

@ -5,6 +5,8 @@ use PhpParser;
use PhpParser\NodeTraverser;
use Psalm\Codebase;
use Psalm\FileSource;
use Psalm\Progress\Progress;
use Psalm\Progress\DefaultProgress;
use Psalm\Storage\FileStorage;
use Psalm\Internal\Visitor\ReflectorVisitor;
@ -42,7 +44,6 @@ class FileScanner implements FileSource
/**
* @param bool $storage_from_cache
* @param bool $debug_output
*
* @return void
*/
@ -50,8 +51,12 @@ class FileScanner implements FileSource
Codebase $codebase,
FileStorage $file_storage,
$storage_from_cache = false,
$debug_output = false
Progress $progress = null
) {
if ($progress === null) {
$progress = new DefaultProgress();
}
if ((!$this->will_analyze || $file_storage->deep_scan)
&& $storage_from_cache
&& !$file_storage->has_trait
@ -63,7 +68,7 @@ class FileScanner implements FileSource
$stmts = $codebase->statements_provider->getStatementsForFile(
$file_storage->file_path,
$debug_output
$progress
);
foreach ($stmts as $stmt) {
@ -77,12 +82,10 @@ class FileScanner implements FileSource
}
}
if ($debug_output) {
if ($this->will_analyze) {
echo 'Deep scanning ' . $file_storage->file_path . "\n";
} else {
echo 'Scanning ' . $file_storage->file_path . "\n";
}
if ($this->will_analyze) {
$progress->debug('Deep scanning ' . $file_storage->file_path . "\n");
} else {
$progress->debug('Scanning ' . $file_storage->file_path . "\n");
}
$traverser = new NodeTraverser();

View File

@ -21,7 +21,7 @@ class Shepherd implements \Psalm\Plugin\Hook\AfterAnalysisInterface
SourceControlInfo $source_control_info = null
) {
if (!function_exists('curl_init')) {
echo 'No curl found, cannot send data to ' . $codebase->config->shepherd_host . PHP_EOL;
fwrite(STDERR, 'No curl found, cannot send data to ' . $codebase->config->shepherd_host . PHP_EOL);
return;
}
@ -67,115 +67,115 @@ class Shepherd implements \Psalm\Plugin\Hook\AfterAnalysisInterface
$return = curl_exec($ch);
if ($return !== '') {
echo 'Error with Psalm Shepherd:' . PHP_EOL;
fwrite(STDERR, 'Error with Psalm Shepherd:' . PHP_EOL);
if ($return === false) {
/** @var array */
$curl_info = curl_getinfo($ch);
if (($curl_info['ssl_verify_result'] ?? 0) !== 0) {
echo 'Curl SSL error: ';
fwrite(STDERR, 'Curl SSL error: ');
switch ($curl_info['ssl_verify_result']) {
case 2:
echo 'unable to get issuer certificate';
fwrite(STDERR, 'unable to get issuer certificate');
break;
case 3:
echo 'unable to get certificate CRL';
fwrite(STDERR, 'unable to get certificate CRL');
break;
case 4:
echo 'unable to decrypt certificates signature';
fwrite(STDERR, 'unable to decrypt certificates signature');
break;
case 5:
echo 'unable to decrypt CRLs signature';
fwrite(STDERR, 'unable to decrypt CRLs signature');
break;
case 6:
echo 'unable to decode issuer public key';
fwrite(STDERR, 'unable to decode issuer public key');
break;
case 7:
echo 'certificate signature failure';
fwrite(STDERR, 'certificate signature failure');
break;
case 8:
echo 'CRL signature failure';
fwrite(STDERR, 'CRL signature failure');
break;
case 9:
echo 'certificate is not yet valid';
fwrite(STDERR, 'certificate is not yet valid');
break;
case 10:
echo 'certificate has expired';
fwrite(STDERR, 'certificate has expired');
break;
case 11:
echo 'CRL is not yet valid';
fwrite(STDERR, 'CRL is not yet valid');
break;
case 12:
echo 'CRL has expired';
fwrite(STDERR, 'CRL has expired');
break;
case 13:
echo 'format error in certificates notBefore field';
fwrite(STDERR, 'format error in certificates notBefore field');
break;
case 14:
echo 'format error in certificates notAfter field';
fwrite(STDERR, 'format error in certificates notAfter field');
break;
case 15:
echo 'format error in CRLs lastUpdate field';
fwrite(STDERR, 'format error in CRLs lastUpdate field');
break;
case 16:
echo 'format error in CRLs nextUpdate field';
fwrite(STDERR, 'format error in CRLs nextUpdate field');
break;
case 17:
echo 'out of memory';
fwrite(STDERR, 'out of memory');
break;
case 18:
echo 'self signed certificate';
fwrite(STDERR, 'self signed certificate');
break;
case 19:
echo 'self signed certificate in certificate chain';
fwrite(STDERR, 'self signed certificate in certificate chain');
break;
case 20:
echo 'unable to get local issuer certificate';
fwrite(STDERR, 'unable to get local issuer certificate');
break;
case 21:
echo 'unable to verify the first certificate';
fwrite(STDERR, 'unable to verify the first certificate');
break;
case 22:
echo 'certificate chain too long';
fwrite(STDERR, 'certificate chain too long');
break;
case 23:
echo 'certificate revoked';
fwrite(STDERR, 'certificate revoked');
break;
case 24:
echo 'invalid CA certificate';
fwrite(STDERR, 'invalid CA certificate');
break;
case 25:
echo 'path length constraint exceeded';
fwrite(STDERR, 'path length constraint exceeded');
break;
case 26:
echo 'unsupported certificate purpose';
fwrite(STDERR, 'unsupported certificate purpose');
break;
case 27:
echo 'certificate not trusted';
fwrite(STDERR, 'certificate not trusted');
break;
case 28:
echo 'certificate rejected';
fwrite(STDERR, 'certificate rejected');
break;
case 29:
echo 'subject issuer mismatch';
fwrite(STDERR, 'subject issuer mismatch');
break;
case 30:
echo 'authority and subject key identifier mismatch';
fwrite(STDERR, 'authority and subject key identifier mismatch');
break;
case 31:
echo 'authority and issuer serial number mismatch';
fwrite(STDERR, 'authority and issuer serial number mismatch');
break;
case 32:
echo 'key usage does not include certificate signing';
fwrite(STDERR, 'key usage does not include certificate signing');
break;
case 50:
echo 'application verification failure';
fwrite(STDERR, 'application verification failure');
break;
}
echo PHP_EOL;
fwrite(STDERR, PHP_EOL);
} else {
echo var_export(curl_getinfo($ch), true) . PHP_EOL;
}

View File

@ -0,0 +1,26 @@
<?php
namespace Psalm\Progress;
class DebugProgress extends Progress
{
public function setErrorReporting(): void
{
error_reporting(E_ALL);
}
public function debug(string $message): void
{
fwrite(STDERR, $message);
}
public function startScanningFiles(): void
{
fwrite(STDERR, 'Scanning files...' . "\n");
}
public function startAnalyzingFiles(): void
{
fwrite(STDERR, 'Analyzing files...' . "\n");
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace Psalm\Progress;
class DefaultProgress extends Progress
{
public function startScanningFiles(): void
{
fwrite(STDERR, 'Scanning files...' . "\n");
}
public function startAnalyzingFiles(): void
{
fwrite(STDERR, 'Analyzing files...' . "\n");
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Psalm\Progress;
abstract class Progress
{
public function setErrorReporting(): void
{
error_reporting(E_ERROR);
}
public function debug(string $message): void
{
}
public function startScanningFiles(): void
{
}
public function startAnalyzingFiles(): void
{
}
}

View File

@ -64,7 +64,7 @@ function requireAutoloaders($current_dir, $has_explicit_root, $vendor_dir)
. 'to specify a particular project to run Psalm on.';
}
echo $error_message . PHP_EOL;
fwrite(STDERR, $error_message . PHP_EOL);
exit(1);
}
}
@ -88,13 +88,15 @@ function requireAutoloaders($current_dir, $has_explicit_root, $vendor_dir)
if ($first_autoloader === null && !$in_phar) {
if (!$autoload_files) {
echo 'Failed to find a valid Composer autoloader' . "\n";
fwrite(STDERR, 'Failed to find a valid Composer autoloader' . "\n");
} else {
echo 'Failed to find a valid Composer autoloader in ' . implode(', ', $autoload_files) . "\n";
fwrite(STDERR, 'Failed to find a valid Composer autoloader in ' . implode(', ', $autoload_files) . "\n");
}
echo 'Please make sure youve run `composer install` in the current directory before using Psalm.' . "\n";
fwrite(
STDERR,
'Please make sure youve run `composer install` in the current directory before using Psalm.' . "\n"
);
exit(1);
}
@ -194,19 +196,19 @@ function getPathsToCheck($f_paths)
foreach ($filtered_input_paths as $path_to_check) {
if ($path_to_check[0] === '-') {
echo 'Invalid usage, expecting psalm [options] [file...]' . PHP_EOL;
fwrite(STDERR, 'Invalid usage, expecting psalm [options] [file...]' . PHP_EOL);
exit(1);
}
if (!file_exists($path_to_check)) {
echo 'Cannot locate ' . $path_to_check . PHP_EOL;
fwrite(STDERR, 'Cannot locate ' . $path_to_check . PHP_EOL);
exit(1);
}
$path_to_check = realpath($path_to_check);
if (!$path_to_check) {
echo 'Error getting realpath for file' . PHP_EOL;
fwrite(STDERR, 'Error getting realpath for file' . PHP_EOL);
exit(1);
}

View File

@ -52,8 +52,11 @@ array_map(
&& !in_array($arg_name . ':', $valid_long_options)
&& !in_array($arg_name . '::', $valid_long_options)
) {
echo 'Unrecognised argument "--' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL;
fwrite(
STDERR,
'Unrecognised argument "--' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL
);
error_log('Bad argument');
exit(1);
}
@ -61,8 +64,11 @@ array_map(
$arg_name = preg_replace('/=.*$/', '', substr($arg, 1));
if (!in_array($arg_name, $valid_short_options) && !in_array($arg_name . ':', $valid_short_options)) {
echo 'Unrecognised argument "-' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL;
fwrite(
STDERR,
'Unrecognised argument "-' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL
);
error_log('Bad argument');
exit(1);
}
@ -93,7 +99,7 @@ if (isset($options['config'])) {
}
if (isset($options['c']) && is_array($options['c'])) {
echo 'Too many config files provided' . PHP_EOL;
fwrite(STDERR, 'Too many config files provided' . PHP_EOL);
exit(1);
}
@ -142,7 +148,7 @@ HELP;
}
if (getcwd() === false) {
echo 'Cannot get current working directory' . PHP_EOL;
fwrite(STDERR, 'Cannot get current working directory' . PHP_EOL);
exit(1);
}
@ -156,7 +162,10 @@ if (isset($options['r']) && is_string($options['r'])) {
$root_path = realpath($options['r']);
if (!$root_path) {
echo 'Could not locate root directory ' . $current_dir . DIRECTORY_SEPARATOR . $options['r'] . PHP_EOL;
fwrite(
STDERR,
'Could not locate root directory ' . $current_dir . DIRECTORY_SEPARATOR . $options['r'] . PHP_EOL
);
exit(1);
}
@ -189,13 +198,13 @@ $path_to_config = isset($options['c']) && is_string($options['c']) ? realpath($o
if ($path_to_config === false) {
/** @psalm-suppress InvalidCast */
echo 'Could not resolve path to config ' . (string)$options['c'] . PHP_EOL;
fwrite(STDERR, '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;
fwrite(STDERR, 'tcp url should be a string' . PHP_EOL);
exit(1);
}
}
@ -210,7 +219,7 @@ try {
$config = Config::getConfigForPath($current_dir, $current_dir, $output_format);
}
} catch (Psalm\Exception\ConfigException $e) {
echo $e->getMessage();
fwrite(STDERR, $e->getMessage());
exit(1);
}

View File

@ -6,6 +6,8 @@ use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Provider;
use Psalm\Config;
use Psalm\IssueBuffer;
use Psalm\Progress\DebugProgress;
use Psalm\Progress\DefaultProgress;
// show all errors
error_reporting(-1);
@ -89,16 +91,22 @@ array_map(
&& !in_array($arg_name . ':', $valid_long_options)
&& !in_array($arg_name . '::', $valid_long_options)
) {
echo 'Unrecognised argument "--' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL;
fwrite(
STDERR,
'Unrecognised argument "--' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL
);
exit(1);
}
} elseif (substr($arg, 0, 2) === '-' && $arg !== '-' && $arg !== '--') {
$arg_name = preg_replace('/=.*$/', '', substr($arg, 1));
if (!in_array($arg_name, $valid_short_options) && !in_array($arg_name . ':', $valid_short_options)) {
echo 'Unrecognised argument "-' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL;
fwrite(
STDERR,
'Unrecognised argument "-' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL
);
exit(1);
}
}
@ -133,7 +141,7 @@ if (isset($options['config'])) {
}
if (isset($options['c']) && is_array($options['c'])) {
echo 'Too many config files provided' . PHP_EOL;
fwrite(STDERR, 'Too many config files provided' . PHP_EOL);
exit(1);
}
@ -254,7 +262,7 @@ HELP;
}
if (getcwd() === false) {
echo 'Cannot get current working directory' . PHP_EOL;
fwrite(STDERR, 'Cannot get current working directory' . PHP_EOL);
exit(1);
}
@ -268,7 +276,10 @@ if (isset($options['r']) && is_string($options['r'])) {
$root_path = realpath($options['r']);
if (!$root_path) {
echo 'Could not locate root directory ' . $current_dir . DIRECTORY_SEPARATOR . $options['r'] . PHP_EOL;
fwrite(
STDERR,
'Could not locate root directory ' . $current_dir . DIRECTORY_SEPARATOR . $options['r'] . PHP_EOL
);
exit(1);
}
@ -396,7 +407,7 @@ $path_to_config = isset($options['c']) && is_string($options['c']) ? realpath($o
if ($path_to_config === false) {
/** @psalm-suppress InvalidCast */
echo 'Could not resolve path to config ' . (string)$options['c'] . PHP_EOL;
fwrite(STDERR, 'Could not resolve path to config ' . (string)$options['c'] . PHP_EOL);
exit(1);
}
@ -432,7 +443,7 @@ try {
$config = Config::getConfigForPath($current_dir, $current_dir, $output_format);
}
} catch (Psalm\Exception\ConfigException $e) {
echo $e->getMessage() . PHP_EOL;
fwrite(STDERR, $e->getMessage() . PHP_EOL);
exit(1);
}
@ -471,6 +482,9 @@ if (isset($options['clear-global-cache'])) {
}
$debug = array_key_exists('debug', $options) || array_key_exists('debug-by-line', $options);
$progress = $debug
? new DebugProgress()
: new DefaultProgress();
if (isset($options['no-cache'])) {
$providers = new Provider\Providers(
@ -503,7 +517,7 @@ $project_analyzer = new ProjectAnalyzer(
$show_info,
$output_format,
$threads,
$debug,
$progress,
isset($options['report']) && is_string($options['report']) ? $options['report'] : null,
!isset($options['show-snippet']) || $options['show-snippet'] !== "false"
);
@ -525,13 +539,11 @@ if ($type_map_location) {
$start_time = microtime(true);
$config->visitComposerAutoloadFiles($project_analyzer, $debug);
$config->visitComposerAutoloadFiles($project_analyzer, $progress);
$now_time = microtime(true);
if ($debug) {
echo 'Visiting autoload files took ' . number_format($now_time - $start_time, 3) . 's' . "\n";
}
$progress->debug('Visiting autoload files took ' . number_format($now_time - $start_time, 3) . 's' . "\n");
if (array_key_exists('debug-by-line', $options)) {
$project_analyzer->debug_lines = true;
@ -571,11 +583,9 @@ if ($find_references_to) {
if (isset($options['set-baseline']) && is_string($options['set-baseline'])) {
if ($is_diff) {
if ($output_format === ProjectAnalyzer::TYPE_CONSOLE) {
echo 'Cannot set baseline in --diff mode' . PHP_EOL;
}
fwrite(STDERR, 'Cannot set baseline in --diff mode' . PHP_EOL);
} else {
echo 'Writing error baseline to file...', PHP_EOL;
fwrite(STDERR, 'Writing error baseline to file...' . PHP_EOL);
ErrorBaseline::create(
new \Psalm\Internal\Provider\FileProvider,
@ -583,7 +593,7 @@ if (isset($options['set-baseline']) && is_string($options['set-baseline'])) {
IssueBuffer::getIssuesData()
);
echo "Baseline saved to {$options['set-baseline']}.";
fwrite(STDERR, "Baseline saved to {$options['set-baseline']}.");
/** @var string $configFile */
$configFile = Config::locateConfigFile($path_to_config ?? $current_dir);
@ -599,7 +609,7 @@ if (isset($options['set-baseline']) && is_string($options['set-baseline'])) {
$endPsalmOpenTag = strpos($configFileContents, '>', (int)strpos($configFileContents, '<psalm'));
if (!$endPsalmOpenTag) {
echo " Don't forget to set errorBaseline=\"{$options['set-baseline']}\" in your config.";
fwrite(STDERR, " Don't forget to set errorBaseline=\"{$options['set-baseline']}\" in your config.");
} elseif ($configFileContents[$endPsalmOpenTag - 1] === "\n") {
$amendedConfigFileContents = substr_replace(
$configFileContents,
@ -619,7 +629,7 @@ if (isset($options['set-baseline']) && is_string($options['set-baseline'])) {
file_put_contents($configFile, $amendedConfigFileContents);
echo PHP_EOL;
fwrite(STDERR, PHP_EOL);
}
}
@ -627,9 +637,7 @@ $issue_baseline = [];
if (isset($options['update-baseline'])) {
if ($is_diff) {
if ($output_format === ProjectAnalyzer::TYPE_CONSOLE) {
echo 'Cannot update baseline in --diff mode' . PHP_EOL;
}
fwrite(STDERR, 'Cannot update baseline in --diff mode' . PHP_EOL);
} else {
$baselineFile = Config::getInstance()->error_baseline;
@ -658,7 +666,8 @@ if (isset($options['update-baseline'])) {
echo $total_fixed_issues . ' errors fixed' . "\n";
}
} catch (\Psalm\Exception\ConfigException $exception) {
die('Could not update baseline file: ' . $exception->getMessage());
fwrite(STDERR, 'Could not update baseline file: ' . $exception->getMessage() . PHP_EOL);
exit(1);
}
}
}

View File

@ -4,6 +4,8 @@ require_once('command_functions.php');
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Config;
use Psalm\IssueBuffer;
use Psalm\Progress\DebugProgress;
use Psalm\Progress\DefaultProgress;
// show all errors
error_reporting(-1);
@ -41,16 +43,22 @@ array_map(
&& !in_array($arg_name . ':', $valid_long_options)
&& !in_array($arg_name . '::', $valid_long_options)
) {
echo 'Unrecognised argument "--' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL;
fwrite(
STDERR,
'Unrecognised argument "--' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL
);
exit(1);
}
} elseif (substr($arg, 0, 2) === '-' && $arg !== '-' && $arg !== '--') {
$arg_name = preg_replace('/=.*$/', '', substr($arg, 1));
if (!in_array($arg_name, $valid_short_options) && !in_array($arg_name . ':', $valid_short_options)) {
echo 'Unrecognised argument "-' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL;
fwrite(
STDERR,
'Unrecognised argument "-' . $arg_name . '"' . PHP_EOL
. 'Type --help to see a list of supported arguments'. PHP_EOL
);
exit(1);
}
}
@ -181,6 +189,11 @@ $providers = new Psalm\Internal\Provider\Providers(
new Psalm\Internal\Provider\ClassLikeStorageCacheProvider($config)
);
$debug = array_key_exists('debug', $options);
$progress = $debug
? new DebugProgress()
: new DefaultProgress();
$project_analyzer = new ProjectAnalyzer(
$config,
$providers,
@ -188,7 +201,7 @@ $project_analyzer = new ProjectAnalyzer(
false,
ProjectAnalyzer::TYPE_CONSOLE,
$threads,
array_key_exists('debug', $options)
$progress
);
if (array_key_exists('debug-by-line', $options)) {

View File

@ -5,9 +5,11 @@ use Psalm\Codebase;
use Psalm\Config;
use Psalm\Context;
use Psalm\Internal\Analyzer\FileAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Plugin\Hook\AfterCodebasePopulatedInterface;
use Psalm\PluginRegistrationSocket;
use Psalm\Tests\Internal\Provider;
use Psalm\Tests\Progress\VoidProgress;
use Psalm\Tests\TestConfig;
class PluginTest extends \Psalm\Tests\TestCase
@ -55,7 +57,12 @@ class PluginTest extends \Psalm\Tests\TestCase
new \Psalm\Internal\Provider\Providers(
$this->file_provider,
new Provider\FakeParserCacheProvider()
)
),
true,
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
new VoidProgress()
);
}

View File

@ -5,6 +5,7 @@ use Psalm\Internal\Analyzer\FileAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Provider\Providers;
use Psalm\Tests\Internal\Provider;
use Psalm\Tests\Progress\VoidProgress;
use Psalm\Tests\TestConfig;
class AnalyzedMethodTest extends \Psalm\Tests\TestCase
@ -37,7 +38,7 @@ class AnalyzedMethodTest extends \Psalm\Tests\TestCase
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
false
new VoidProgress()
);
$this->project_analyzer->setPhpVersion('7.3');
}

View File

@ -37,7 +37,7 @@ class CachedStorageTest extends \Psalm\Tests\TestCase
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
false
null
);
$this->project_analyzer->setPhpVersion('7.3');
}

View File

@ -37,7 +37,7 @@ class ErrorAfterUpdateTest extends \Psalm\Tests\TestCase
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
false
null
);
$this->project_analyzer->setPhpVersion('7.3');
}

View File

@ -38,7 +38,7 @@ class ErrorFixTest extends \Psalm\Tests\TestCase
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
false
null
);
$this->project_analyzer->setPhpVersion('7.3');
}

View File

@ -38,7 +38,7 @@ class TemporaryUpdateTest extends \Psalm\Tests\TestCase
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
false
null
);
$this->project_analyzer->setPhpVersion('7.3');
}

View File

@ -39,7 +39,7 @@ class CompletionTest extends \Psalm\Tests\TestCase
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
false
null
);
$this->project_analyzer->setPhpVersion('7.3');
$this->project_analyzer->getCodebase()->store_node_types = true;

View File

@ -39,7 +39,7 @@ class SymbolLookupTest extends \Psalm\Tests\TestCase
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
false
null
);
$this->project_analyzer->setPhpVersion('7.3');

View File

@ -0,0 +1,17 @@
<?php
namespace Psalm\Tests\Progress;
use Psalm\Progress\Progress;
class EchoProgress extends Progress
{
public function startScanningFiles(): void
{
echo 'Scanning files...' . "\n";
}
public function startAnalyzingFiles(): void
{
echo 'Analyzing files...' . "\n";
}
}

View File

@ -0,0 +1,8 @@
<?php
namespace Psalm\Tests\Progress;
use Psalm\Progress\Progress;
class VoidProgress extends Progress
{
}

View File

@ -4,8 +4,11 @@ namespace Psalm\Tests;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Internal\Analyzer\FileAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Plugin\Hook\AfterCodebasePopulatedInterface;
use Psalm\Tests\Internal\Provider;
use Psalm\Tests\Progress\EchoProgress;
use Psalm\Tests\Progress\VoidProgress;
class ProjectCheckerTest extends TestCase
{
@ -55,7 +58,12 @@ class ProjectCheckerTest extends TestCase
new Provider\FileStorageInstanceCacheProvider(),
new Provider\ClassLikeStorageInstanceCacheProvider(),
new Provider\FakeFileReferenceCacheProvider()
)
),
true,
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
new VoidProgress()
);
}
@ -76,6 +84,8 @@ class ProjectCheckerTest extends TestCase
)
);
$this->project_analyzer->progress = new EchoProgress();
ob_start();
$this->project_analyzer->check('tests/fixtures/DummyProject');
$output = ob_get_clean();
@ -260,6 +270,8 @@ class Bat
)
);
$this->project_analyzer->progress = new EchoProgress();
ob_start();
$this->project_analyzer->checkDir('tests/fixtures/DummyProject');
$output = ob_get_clean();
@ -293,6 +305,8 @@ class Bat
)
);
$this->project_analyzer->progress = new EchoProgress();
ob_start();
$this->project_analyzer->checkPaths(['tests/fixtures/DummyProject/Bar.php']);
$output = ob_get_clean();
@ -326,6 +340,8 @@ class Bat
)
);
$this->project_analyzer->progress = new EchoProgress();
ob_start();
$this->project_analyzer->checkFile('tests/fixtures/DummyProject/Bar.php');
$output = ob_get_clean();

View File

@ -53,7 +53,7 @@ class ReportOutputTest extends TestCase
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
false,
null,
'/tmp/report' . $extension
);
}
@ -79,7 +79,7 @@ class ReportOutputTest extends TestCase
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
false,
null,
'/tmp/report.log'
);
}

View File

@ -52,7 +52,7 @@ class StubTest extends TestCase
);
$project_analyzer->setPhpVersion('7.3');
$config->visitComposerAutoloadFiles($project_analyzer, false);
$config->visitComposerAutoloadFiles($project_analyzer, null);
return $project_analyzer;
}

View File

@ -63,7 +63,7 @@ class TestCase extends BaseTestCase
true,
ProjectAnalyzer::TYPE_CONSOLE,
1,
false
null
);
$this->project_analyzer->setPhpVersion('7.3');

View File

@ -26,7 +26,7 @@ class TypeParseTest extends TestCase
true,
\Psalm\Internal\Analyzer\ProjectAnalyzer::TYPE_CONSOLE,
1,
false
null
);
}