diff --git a/src/Psalm/Config.php b/src/Psalm/Config.php index fb8f7ea4c..add21f4fe 100644 --- a/src/Psalm/Config.php +++ b/src/Psalm/Config.php @@ -428,7 +428,7 @@ class Config $config_path = self::locateConfigFile($path); if (!$config_path) { - if ($output_format === ProjectAnalyzer::TYPE_CONSOLE) { + if ($output_format === \Psalm\Report::TYPE_CONSOLE) { exit( 'Could not locate a config XML file in path ' . $path . '. Have you run \'psalm --init\' ?' . PHP_EOL diff --git a/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php b/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php index bd277bad0..9bd4931f9 100644 --- a/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php @@ -29,6 +29,8 @@ use Psalm\Issue\UnusedMethod; use Psalm\Issue\UnusedProperty; use Psalm\Progress\Progress; use Psalm\Progress\VoidProgress; +use Psalm\Report; +use Psalm\Report\ReportOptions; use Psalm\Type; use Psalm\Issue\CodeIssue; @@ -68,32 +70,6 @@ class ProjectAnalyzer /** @var FileReferenceProvider */ private $file_reference_provider; - /** - * Whether or not to use colors in error output - * - * @var bool - */ - public $use_color; - - /** - * Whether or not to show snippets in error output - * - * @var bool - */ - public $show_snippet; - - /** - * Whether or not to show informational messages - * - * @var bool - */ - public $show_info; - - /** - * @var string - */ - public $output_format; - /** * @var Progress */ @@ -157,27 +133,15 @@ class ProjectAnalyzer */ private $to_refactor = []; - const TYPE_COMPACT = 'compact'; - const TYPE_CONSOLE = 'console'; - const TYPE_PYLINT = 'pylint'; - const TYPE_JSON = 'json'; - const TYPE_JSON_SUMMARY = 'json-summary'; - const TYPE_EMACS = 'emacs'; - const TYPE_XML = 'xml'; - const TYPE_CHECKSTYLE = 'checkstyle'; - const TYPE_TEXT = 'text'; + /** + * @var ?ReportOptions + */ + public $stdout_report_options; - const SUPPORTED_OUTPUT_TYPES = [ - self::TYPE_COMPACT, - self::TYPE_CONSOLE, - self::TYPE_PYLINT, - self::TYPE_JSON, - self::TYPE_JSON_SUMMARY, - self::TYPE_EMACS, - self::TYPE_XML, - self::TYPE_CHECKSTYLE, - self::TYPE_TEXT, - ]; + /** + * @var array + */ + public $generated_report_options; /** * @var array> @@ -201,23 +165,18 @@ class ProjectAnalyzer ]; /** - * @param bool $use_color - * @param bool $show_info - * @param string $output_format + * @param array $generated_report_options * @param int $threads * @param string $reports - * @param bool $show_snippet */ public function __construct( Config $config, Providers $providers, - $use_color = true, - $show_info = true, - $output_format = self::TYPE_CONSOLE, - $threads = 1, + ?ReportOptions $stdout_report_options = null, + array $generated_report_options = [], + int $threads = 1, Progress $progress = null, - $reports = null, - $show_snippet = true + $reports = null ) { if ($progress === null) { $progress = new VoidProgress(); @@ -228,12 +187,9 @@ class ProjectAnalyzer $this->classlike_storage_provider = $providers->classlike_storage_provider; $this->file_reference_provider = $providers->file_reference_provider; - $this->use_color = $use_color; - $this->show_info = $show_info; $this->progress = $progress; $this->threads = $threads; $this->config = $config; - $this->show_snippet = $show_snippet; $this->codebase = new Codebase( $config, @@ -241,30 +197,14 @@ class ProjectAnalyzer $progress ); - if (!in_array($output_format, self::SUPPORTED_OUTPUT_TYPES, true)) { - throw new \UnexpectedValueException('Unrecognised output format ' . $output_format); + if ($stdout_report_options + && !in_array($stdout_report_options->format, Report::SUPPORTED_OUTPUT_TYPES, true) + ) { + throw new \UnexpectedValueException('Unrecognised output format ' . $stdout_report_options->format); } - if ($reports) { - $mapping = [ - 'checkstyle.xml' => self::TYPE_CHECKSTYLE, - 'summary.json' => self::TYPE_JSON_SUMMARY, - '.xml' => self::TYPE_XML, - '.json' => self::TYPE_JSON, - '.txt' => self::TYPE_TEXT, - '.emacs' => self::TYPE_EMACS, - '.pylint' => self::TYPE_PYLINT, - ]; - foreach ($mapping as $extension => $type) { - if (substr($reports, -strlen($extension)) === $extension) { - $this->reports[$type] = $reports; - break; - } - } - if (empty($this->reports)) { - throw new \UnexpectedValueException('Unrecognised report format ' . $reports); - } - } + $this->stdout_report_options = $stdout_report_options; + $this->generated_report_options = $generated_report_options; $project_files = []; @@ -286,10 +226,47 @@ class ProjectAnalyzer $this->project_files = $project_files; - $this->output_format = $output_format; self::$instance = $this; } + /** + * @param array $report_file_paths + * @param bool $show_info + * @return array + */ + public static function getFileReportOptions(array $report_file_paths, bool $show_info = true) + { + $report_options = []; + + $mapping = [ + 'checkstyle.xml' => Report::TYPE_CHECKSTYLE, + 'summary.json' => Report::TYPE_JSON_SUMMARY, + '.xml' => Report::TYPE_XML, + '.json' => Report::TYPE_JSON, + '.txt' => Report::TYPE_TEXT, + '.emacs' => Report::TYPE_EMACS, + '.pylint' => Report::TYPE_PYLINT, + ]; + + foreach ($report_file_paths as $report_file_path) { + foreach ($mapping as $extension => $type) { + if (substr($report_file_path, -strlen($extension)) === $extension) { + $o = new ReportOptions(); + + $o->format = $type; + $o->show_info = $show_info; + $o->output_path = $report_file_path; + $report_options[] = $o; + continue 2; + } + } + + throw new \UnexpectedValueException('Unknown report format ' . $report_file_path); + } + + return $report_options; + } + /** * @param string|null $address * @return void @@ -315,8 +292,6 @@ class ProjectAnalyzer $this->checkDirWithConfig($dir_name, $this->config); } - $this->output_format = self::TYPE_JSON; - @cli_set_process_title('Psalm PHP Language Server'); if (!$socket_server_mode && $address) { @@ -786,6 +761,10 @@ class ProjectAnalyzer */ public function findReferencesTo($symbol) { + if (!$this->stdout_report_options) { + throw new \UnexpectedValueException('Not expecting to emit output'); + } + $locations = $this->codebase->findReferencesToSymbol($symbol); foreach ($locations as $location) { @@ -799,7 +778,7 @@ class ProjectAnalyzer echo $location->file_name . ':' . $location->getLineNumber() . "\n" . ( - $this->use_color + $this->stdout_report_options->use_color ? substr($snippet, 0, $selection_start) . "\e[97;42m" . substr($snippet, $selection_start, $selection_length) . "\e[0m" . substr($snippet, $selection_length + $selection_start) @@ -993,7 +972,10 @@ class ProjectAnalyzer $this->codebase->analyzer->analyzeFiles($this, $this->threads, $this->codebase->alter_code); - if ($this->output_format === ProjectAnalyzer::TYPE_CONSOLE && $this->codebase->collect_references) { + if ($this->stdout_report_options + && $this->stdout_report_options->format === Report::TYPE_CONSOLE + && $this->codebase->collect_references + ) { fwrite( STDERR, PHP_EOL . 'To whom it may concern: Psalm cannot detect unused classes, methods and properties' diff --git a/src/Psalm/IssueBuffer.php b/src/Psalm/IssueBuffer.php index 42551e693..9bd2cadfa 100644 --- a/src/Psalm/IssueBuffer.php +++ b/src/Psalm/IssueBuffer.php @@ -3,15 +3,16 @@ namespace Psalm; use Psalm\Internal\Analyzer\ProjectAnalyzer; use Psalm\Issue\CodeIssue; -use Psalm\Output\Checkstyle; -use Psalm\Output\Compact; -use Psalm\Output\Console; -use Psalm\Output\Emacs; -use Psalm\Output\Json; -use Psalm\Output\JsonSummary; -use Psalm\Output\Pylint; -use Psalm\Output\Text; -use Psalm\Output\Xml; +use Psalm\Report; +use Psalm\Report\CheckstyleReport; +use Psalm\Report\CompactReport; +use Psalm\Report\ConsoleReport; +use Psalm\Report\EmacsReport; +use Psalm\Report\JsonReport; +use Psalm\Report\JsonSummaryReport; +use Psalm\Report\PylintReport; +use Psalm\Report\TextReport; +use Psalm\Report\XmlReport; class IssueBuffer { @@ -204,7 +205,11 @@ class IssueBuffer bool $add_stats = false, array $issue_baseline = [] ) { - if ($project_analyzer->output_format === ProjectAnalyzer::TYPE_CONSOLE) { + if (!$project_analyzer->stdout_report_options) { + throw new \UnexpectedValueException('Cannot finish without stdout report options'); + } + + if ($project_analyzer->stdout_report_options->format === Report::TYPE_CONSOLE) { echo "\n"; } @@ -270,10 +275,7 @@ class IssueBuffer } echo self::getOutput( - $project_analyzer->output_format, - $project_analyzer->use_color, - $project_analyzer->show_snippet, - $project_analyzer->show_info, + $project_analyzer->stdout_report_options, $codebase->analyzer->getTotalTypeCoverage($codebase) ); } @@ -300,24 +302,25 @@ class IssueBuffer } } - foreach ($project_analyzer->reports as $format => $path) { + foreach ($project_analyzer->generated_report_options as $report_options) { + if (!$report_options->output_path) { + throw new \UnexpectedValueException('Output path should not be null here'); + } + file_put_contents( - $path, + $report_options->output_path, self::getOutput( - $format, - $project_analyzer->use_color, - true, - true, + $report_options, $codebase->analyzer->getTotalTypeCoverage($codebase) ) ); } - if ($project_analyzer->output_format === ProjectAnalyzer::TYPE_CONSOLE) { + if ($project_analyzer->stdout_report_options->format === Report::TYPE_CONSOLE) { echo str_repeat('-', 30) . "\n"; if ($error_count) { - echo ($project_analyzer->use_color + echo ($project_analyzer->stdout_report_options->use_color ? "\e[0;31m" . $error_count . " errors\e[0m" : $error_count . ' errors' ) . ' found' . "\n"; @@ -325,12 +328,12 @@ class IssueBuffer echo 'No errors found!' . "\n"; } - if ($info_count && $project_analyzer->show_info) { + if ($info_count && $project_analyzer->stdout_report_options->show_info) { echo str_repeat('-', 30) . "\n"; echo $info_count . ' other issues found.' . "\n" . 'You can hide them with ' . - ($project_analyzer->use_color + ($project_analyzer->stdout_report_options->use_color ? "\e[30;48;5;195m--show-info=false\e[0m" : '--show-info=false') . "\n"; } @@ -366,67 +369,57 @@ class IssueBuffer } /** - * @param string $format - * @param bool $use_color - * @param bool $show_snippet - * @param bool $show_info * @param array{int, int} $mixed_counts * * @return string */ public static function getOutput( - string $format, - bool $use_color, - bool $show_snippet = true, - bool $show_info = true, + \Psalm\Report\ReportOptions $report_options, array $mixed_counts = [0, 0] ) { $total_expression_count = $mixed_counts[0] + $mixed_counts[1]; $mixed_expression_count = $mixed_counts[0]; - switch ($format) { - case ProjectAnalyzer::TYPE_COMPACT: - $output = new Compact(self::$issues_data, $use_color, $show_snippet, $show_info); + switch ($report_options->format) { + case Report::TYPE_COMPACT: + $output = new CompactReport(self::$issues_data, $report_options); break; - case ProjectAnalyzer::TYPE_EMACS: - $output = new Emacs(self::$issues_data, $use_color, $show_snippet, $show_info); + case Report::TYPE_EMACS: + $output = new EmacsReport(self::$issues_data, $report_options); break; - case ProjectAnalyzer::TYPE_TEXT: - $output = new Text(self::$issues_data, $use_color, $show_snippet, $show_info); + case Report::TYPE_TEXT: + $output = new TextReport(self::$issues_data, $report_options); break; - case ProjectAnalyzer::TYPE_JSON: - $output = new Json(self::$issues_data, $use_color, $show_snippet, $show_info); + case Report::TYPE_JSON: + $output = new JsonReport(self::$issues_data, $report_options); break; - case ProjectAnalyzer::TYPE_JSON_SUMMARY: - $output = new JsonSummary( + case Report::TYPE_JSON_SUMMARY: + $output = new JsonSummaryReport( self::$issues_data, - $use_color, - $show_snippet, - $show_info, + $report_options, $mixed_expression_count, $total_expression_count ); break; - case ProjectAnalyzer::TYPE_PYLINT: - $output = new Pylint(self::$issues_data, $use_color, $show_snippet, $show_info); + case Report::TYPE_PYLINT: + $output = new PylintReport(self::$issues_data, $report_options); break; - case ProjectAnalyzer::TYPE_CHECKSTYLE: - $output = new Checkstyle(self::$issues_data, $use_color, $show_snippet, $show_info); + case Report::TYPE_CHECKSTYLE: + $output = new CheckstyleReport(self::$issues_data, $report_options); break; - case ProjectAnalyzer::TYPE_XML: - $output = new Xml(self::$issues_data, $use_color, $show_snippet, $show_info); + case Report::TYPE_XML: + $output = new XmlReport(self::$issues_data, $report_options); break; - case ProjectAnalyzer::TYPE_CONSOLE: - default: - $output = new Console(self::$issues_data, $use_color, $show_snippet, $show_info); + case Report::TYPE_CONSOLE: + $output = new ConsoleReport(self::$issues_data, $report_options); break; } diff --git a/src/Psalm/Output.php b/src/Psalm/Report.php similarity index 63% rename from src/Psalm/Output.php rename to src/Psalm/Report.php index 08a7d7495..62496576f 100644 --- a/src/Psalm/Output.php +++ b/src/Psalm/Report.php @@ -1,8 +1,30 @@ issues_data = $issues_data; - $this->use_color = $use_color; - $this->show_snippet = $show_snippet; - $this->show_info = $show_info; + $this->use_color = $report_options->use_color; + $this->show_snippet = $report_options->show_snippet; + $this->show_info = $report_options->show_info; $this->mixed_expression_count = $mixed_expression_count; $this->total_expression_count = $total_expression_count; } diff --git a/src/Psalm/Output/Checkstyle.php b/src/Psalm/Report/CheckstyleReport.php similarity index 92% rename from src/Psalm/Output/Checkstyle.php rename to src/Psalm/Report/CheckstyleReport.php index 6e8bab43b..88605a4c4 100644 --- a/src/Psalm/Output/Checkstyle.php +++ b/src/Psalm/Report/CheckstyleReport.php @@ -1,10 +1,10 @@ + */ + public $format = REPORT::TYPE_CONSOLE; + + /** + * @var ?string + */ + public $output_path; +} diff --git a/src/Psalm/Output/Text.php b/src/Psalm/Report/TextReport.php similarity index 89% rename from src/Psalm/Output/Text.php rename to src/Psalm/Report/TextReport.php index 6a097671d..e22df49b3 100644 --- a/src/Psalm/Output/Text.php +++ b/src/Psalm/Report/TextReport.php @@ -1,10 +1,10 @@ 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) { @@ -216,7 +212,7 @@ try { if ($path_to_config) { $config = Config::loadFromXMLFile($path_to_config, $current_dir); } else { - $config = Config::getConfigForPath($current_dir, $current_dir, $output_format); + $config = Config::getConfigForPath($current_dir, $current_dir, \Psalm\Report::TYPE_CONSOLE); } } catch (Psalm\Exception\ConfigException $e) { fwrite(STDERR, $e->getMessage()); diff --git a/src/psalm-refactor.php b/src/psalm-refactor.php index 3df8fafa7..b2fb3bd69 100644 --- a/src/psalm-refactor.php +++ b/src/psalm-refactor.php @@ -235,7 +235,7 @@ if (!$to_refactor) { if ($path_to_config) { $config = Config::loadFromXMLFile($path_to_config, $current_dir); } else { - $config = Config::getConfigForPath($current_dir, $current_dir, ProjectAnalyzer::TYPE_CONSOLE); + $config = Config::getConfigForPath($current_dir, $current_dir, \Psalm\Report::TYPE_CONSOLE); } $config->setComposerClassLoader($first_autoloader); @@ -259,9 +259,8 @@ $progress = $debug $project_analyzer = new ProjectAnalyzer( $config, $providers, - !array_key_exists('m', $options), - false, - ProjectAnalyzer::TYPE_CONSOLE, + new \Psalm\Report\ReportOptions(), + [], $threads, $progress ); diff --git a/src/psalm.php b/src/psalm.php index 50c7d34ff..d5c9569f5 100644 --- a/src/psalm.php +++ b/src/psalm.php @@ -44,6 +44,7 @@ $valid_long_options = [ 'output-format:', 'plugin:', 'report:', + 'report-show-info:', 'root:', 'set-baseline:', 'show-info:', @@ -214,6 +215,9 @@ Options: The path where to output report file. The output format is based on the file extension. (Currently supported format: ".json", ".xml", ".txt", ".emacs") + --report-show-info[=BOOLEAN] + Whether the report should include non-errors in its output (defaults to true) + --clear-cache Clears all cache files that Psalm uses for this specific project @@ -403,7 +407,7 @@ if (isset($options['i'])) { $output_format = isset($options['output-format']) && is_string($options['output-format']) ? $options['output-format'] - : ProjectAnalyzer::TYPE_CONSOLE; + : \Psalm\Report::TYPE_CONSOLE; $paths_to_check = getPathsToCheck(isset($options['f']) ? $options['f'] : null); @@ -534,16 +538,27 @@ if (isset($options['no-cache'])) { ); } +$stdout_report_options = new \Psalm\Report\ReportOptions(); +$stdout_report_options->use_color = !array_key_exists('m', $options); +$stdout_report_options->show_info = $show_info; +/** + * @psalm-suppress PropertyTypeCoercion + */ +$stdout_report_options->format = $output_format; +$stdout_report_options->show_snippet = !isset($options['show-snippet']) || $options['show-snippet'] !== "false"; + $project_analyzer = new ProjectAnalyzer( $config, $providers, - !array_key_exists('m', $options), - $show_info, - $output_format, + $stdout_report_options, + ProjectAnalyzer::getFileReportOptions( + isset($options['report']) && is_string($options['report']) ? [$options['report']] : [], + isset($options['report-show-info']) + ? $options['report-show-info'] !== 'false' && $options['report-show-info'] !== '0' + : true + ), $threads, - $progress, - isset($options['report']) && is_string($options['report']) ? $options['report'] : null, - !isset($options['show-snippet']) || $options['show-snippet'] !== "false" + $progress ); if (isset($options['php-version'])) { diff --git a/src/psalter.php b/src/psalter.php index 660026aba..69230246a 100644 --- a/src/psalter.php +++ b/src/psalter.php @@ -189,7 +189,7 @@ if ($path_to_config === false) { if ($path_to_config) { $config = Config::loadFromXMLFile($path_to_config, $current_dir); } else { - $config = Config::getConfigForPath($current_dir, $current_dir, ProjectAnalyzer::TYPE_CONSOLE); + $config = Config::getConfigForPath($current_dir, $current_dir, \Psalm\Report::TYPE_CONSOLE); } $config->setComposerClassLoader($first_autoloader); @@ -213,12 +213,14 @@ $progress = $debug ? new DebugProgress() : new DefaultProgress(); +$stdout_report_options = new \Psalm\Report\ReportOptions(); +$stdout_report_options->use_color = !array_key_exists('m', $options); + $project_analyzer = new ProjectAnalyzer( $config, $providers, - !array_key_exists('m', $options), - false, - ProjectAnalyzer::TYPE_CONSOLE, + $stdout_report_options, + [], $threads, $progress ); diff --git a/tests/Config/PluginTest.php b/tests/Config/PluginTest.php index a632fb694..2b65e8cbb 100644 --- a/tests/Config/PluginTest.php +++ b/tests/Config/PluginTest.php @@ -57,11 +57,7 @@ class PluginTest extends \Psalm\Tests\TestCase $this->file_provider, new Provider\FakeParserCacheProvider() ), - true, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null + new \Psalm\Report\ReportOptions() ); } @@ -812,7 +808,9 @@ class PluginTest extends \Psalm\Tests\TestCase $this->project_analyzer->getCodebase()->config->initializePlugins($this->project_analyzer); - $this->project_analyzer->output_format = \Psalm\Internal\Analyzer\ProjectAnalyzer::TYPE_JSON; + $this->assertNotNull($this->project_analyzer->stdout_report_options); + + $this->project_analyzer->stdout_report_options->format = \Psalm\Report::TYPE_JSON; $this->project_analyzer->check('tests/fixtures/DummyProject', true); \Psalm\IssueBuffer::finish($this->project_analyzer, true, microtime(true)); diff --git a/tests/FileUpdates/AnalyzedMethodTest.php b/tests/FileUpdates/AnalyzedMethodTest.php index 2bc60743e..44a48e2c2 100644 --- a/tests/FileUpdates/AnalyzedMethodTest.php +++ b/tests/FileUpdates/AnalyzedMethodTest.php @@ -32,12 +32,7 @@ class AnalyzedMethodTest extends \Psalm\Tests\TestCase $this->project_analyzer = new ProjectAnalyzer( $config, - $providers, - false, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null + $providers ); $this->project_analyzer->setPhpVersion('7.3'); } diff --git a/tests/FileUpdates/CachedStorageTest.php b/tests/FileUpdates/CachedStorageTest.php index 14f3763bf..9ef94a457 100644 --- a/tests/FileUpdates/CachedStorageTest.php +++ b/tests/FileUpdates/CachedStorageTest.php @@ -32,12 +32,7 @@ class CachedStorageTest extends \Psalm\Tests\TestCase $this->project_analyzer = new ProjectAnalyzer( $config, - $providers, - false, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null + $providers ); $this->project_analyzer->setPhpVersion('7.3'); } diff --git a/tests/FileUpdates/ErrorAfterUpdateTest.php b/tests/FileUpdates/ErrorAfterUpdateTest.php index 398788a05..edb77681e 100644 --- a/tests/FileUpdates/ErrorAfterUpdateTest.php +++ b/tests/FileUpdates/ErrorAfterUpdateTest.php @@ -32,12 +32,7 @@ class ErrorAfterUpdateTest extends \Psalm\Tests\TestCase $this->project_analyzer = new ProjectAnalyzer( $config, - $providers, - false, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null + $providers ); $this->project_analyzer->setPhpVersion('7.3'); } diff --git a/tests/FileUpdates/ErrorFixTest.php b/tests/FileUpdates/ErrorFixTest.php index 473ad16b5..89cb22c13 100644 --- a/tests/FileUpdates/ErrorFixTest.php +++ b/tests/FileUpdates/ErrorFixTest.php @@ -33,12 +33,7 @@ class ErrorFixTest extends \Psalm\Tests\TestCase $this->project_analyzer = new ProjectAnalyzer( $config, - $providers, - false, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null + $providers ); $this->project_analyzer->setPhpVersion('7.3'); } diff --git a/tests/FileUpdates/TemporaryUpdateTest.php b/tests/FileUpdates/TemporaryUpdateTest.php index 764c68e90..19e659bca 100644 --- a/tests/FileUpdates/TemporaryUpdateTest.php +++ b/tests/FileUpdates/TemporaryUpdateTest.php @@ -33,12 +33,7 @@ class TemporaryUpdateTest extends \Psalm\Tests\TestCase $this->project_analyzer = new ProjectAnalyzer( $config, - $providers, - false, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null + $providers ); $this->project_analyzer->setPhpVersion('7.3'); } diff --git a/tests/JsonOutputTest.php b/tests/JsonOutputTest.php index c4efa89b4..54ee1881f 100644 --- a/tests/JsonOutputTest.php +++ b/tests/JsonOutputTest.php @@ -22,15 +22,16 @@ class JsonOutputTest extends TestCase $config = new TestConfig(); $config->throw_exception = false; + $stdout_report_options = new \Psalm\Report\ReportOptions(); + $stdout_report_options->format = \Psalm\Report::TYPE_JSON; + $this->project_analyzer = new ProjectAnalyzer( $config, new \Psalm\Internal\Provider\Providers( $this->file_provider, new Provider\FakeParserCacheProvider() ), - false, - true, - ProjectAnalyzer::TYPE_JSON + $stdout_report_options ); $this->project_analyzer->getCodebase()->reportUnusedCode(); diff --git a/tests/LanguageServer/CompletionTest.php b/tests/LanguageServer/CompletionTest.php index a1d346fb3..48f8f319a 100644 --- a/tests/LanguageServer/CompletionTest.php +++ b/tests/LanguageServer/CompletionTest.php @@ -34,12 +34,7 @@ class CompletionTest extends \Psalm\Tests\TestCase $this->project_analyzer = new ProjectAnalyzer( $config, - $providers, - false, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null + $providers ); $this->project_analyzer->setPhpVersion('7.3'); $this->project_analyzer->getCodebase()->store_node_types = true; diff --git a/tests/LanguageServer/SymbolLookupTest.php b/tests/LanguageServer/SymbolLookupTest.php index 0ff50f4d4..5b6c3e6c4 100644 --- a/tests/LanguageServer/SymbolLookupTest.php +++ b/tests/LanguageServer/SymbolLookupTest.php @@ -34,12 +34,7 @@ class SymbolLookupTest extends \Psalm\Tests\TestCase $this->project_analyzer = new ProjectAnalyzer( $config, - $providers, - false, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null + $providers ); $this->project_analyzer->setPhpVersion('7.3'); diff --git a/tests/ProjectCheckerTest.php b/tests/ProjectCheckerTest.php index 19bc2ea52..a66674597 100644 --- a/tests/ProjectCheckerTest.php +++ b/tests/ProjectCheckerTest.php @@ -58,11 +58,7 @@ class ProjectCheckerTest extends TestCase new Provider\ClassLikeStorageInstanceCacheProvider(), new Provider\FakeFileReferenceCacheProvider() ), - true, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null + new \Psalm\Report\ReportOptions() ); } @@ -162,7 +158,9 @@ class ProjectCheckerTest extends TestCase ) ); - $this->project_analyzer->output_format = \Psalm\Internal\Analyzer\ProjectAnalyzer::TYPE_JSON; + $this->assertNotNull($this->project_analyzer->stdout_report_options); + + $this->project_analyzer->stdout_report_options->format = \Psalm\Report::TYPE_JSON; $this->project_analyzer->check('tests/fixtures/DummyProject', true); \Psalm\IssueBuffer::finish($this->project_analyzer, true, microtime(true)); @@ -205,7 +203,9 @@ class ProjectCheckerTest extends TestCase ) ); - $this->project_analyzer->output_format = \Psalm\Internal\Analyzer\ProjectAnalyzer::TYPE_JSON; + $this->assertNotNull($this->project_analyzer->stdout_report_options); + + $this->project_analyzer->stdout_report_options->format = \Psalm\Report::TYPE_JSON; $this->project_analyzer->check('tests/fixtures/DummyProject', true); \Psalm\IssueBuffer::finish($this->project_analyzer, true, microtime(true)); diff --git a/tests/ReportOutputTest.php b/tests/ReportOutputTest.php index 8ae2a6b26..2a81ca572 100644 --- a/tests/ReportOutputTest.php +++ b/tests/ReportOutputTest.php @@ -6,6 +6,7 @@ use Psalm\Internal\Analyzer\FileAnalyzer; use Psalm\Internal\Analyzer\ProjectAnalyzer; use Psalm\IssueBuffer; use Psalm\Tests\Internal\Provider; +use Psalm\Report; class ReportOutputTest extends TestCase { @@ -22,15 +23,17 @@ class ReportOutputTest extends TestCase $config = new TestConfig(); $config->throw_exception = false; + $json_report_options = ProjectAnalyzer::getFileReportOptions([__DIR__ . '/test-report.json']); + $this->project_analyzer = new ProjectAnalyzer( $config, new \Psalm\Internal\Provider\Providers( $this->file_provider, new Provider\FakeParserCacheProvider() ), - false + new Report\ReportOptions(), + $json_report_options ); - $this->project_analyzer->reports['json'] = __DIR__ . '/test-report.json'; } /** @@ -43,19 +46,7 @@ class ReportOutputTest extends TestCase // No exception foreach (['.xml', '.txt', '.json', '.emacs'] as $extension) { - new ProjectAnalyzer( - $config, - new \Psalm\Internal\Provider\Providers( - $this->file_provider, - new Provider\FakeParserCacheProvider() - ), - false, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null, - '/tmp/report' . $extension - ); + ProjectAnalyzer::getFileReportOptions(['/tmp/report' . $extension]); } } @@ -69,19 +60,7 @@ class ReportOutputTest extends TestCase $config = new TestConfig(); $config->throw_exception = false; - new ProjectAnalyzer( - $config, - new \Psalm\Internal\Provider\Providers( - $this->file_provider, - new Provider\FakeParserCacheProvider() - ), - false, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null, - '/tmp/report.log' - ); + ProjectAnalyzer::getFileReportOptions(['/tmp/report.log']); } /** @@ -183,29 +162,38 @@ echo $a;'; ], ]; + $json_report_options = ProjectAnalyzer::getFileReportOptions([__DIR__ . '/test-report.json'])[0]; + $this->assertSame( $issue_data, - json_decode(IssueBuffer::getOutput(ProjectAnalyzer::TYPE_JSON, false), true) + json_decode(IssueBuffer::getOutput($json_report_options), true) ); + $emacs_report_options = ProjectAnalyzer::getFileReportOptions([__DIR__ . '/test-report.emacs'])[0]; + $this->assertSame( 'somefile.php:3:10:error - Cannot find referenced variable $as_you somefile.php:2:42:error - Could not verify return type \'string|null\' for psalmCanVerify somefile.php:7:6:error - Const CHANGE_ME is not defined somefile.php:15:6:error - Possibly undefined global variable $a, first seen on line 10 ', - IssueBuffer::getOutput(ProjectAnalyzer::TYPE_EMACS, false) + IssueBuffer::getOutput($emacs_report_options) ); + $pylint_report_options = ProjectAnalyzer::getFileReportOptions([__DIR__ . '/test-report.pylint'])[0]; + $this->assertSame( 'somefile.php:3: [E0001] UndefinedVariable: Cannot find referenced variable $as_you (column 10) somefile.php:2: [E0001] MixedInferredReturnType: Could not verify return type \'string|null\' for psalmCanVerify (column 42) somefile.php:7: [E0001] UndefinedConstant: Const CHANGE_ME is not defined (column 6) somefile.php:15: [E0001] PossiblyUndefinedGlobalVariable: Possibly undefined global variable $a, first seen on line 10 (column 6) ', - IssueBuffer::getOutput(ProjectAnalyzer::TYPE_PYLINT, false) + IssueBuffer::getOutput($pylint_report_options) ); + $console_report_options = new Report\ReportOptions(); + $console_report_options->use_color = false; + $this->assertSame( 'ERROR: UndefinedVariable - somefile.php:3:10 - Cannot find referenced variable $as_you return $as_you . "type"; @@ -220,9 +208,13 @@ ERROR: PossiblyUndefinedGlobalVariable - somefile.php:15:6 - Possibly undefined echo $a ', - IssueBuffer::getOutput(ProjectAnalyzer::TYPE_CONSOLE, false) + IssueBuffer::getOutput($console_report_options) ); + $console_report_options = new Report\ReportOptions(); + $console_report_options->show_snippet = false; + $console_report_options->use_color = false; + $this->assertSame( 'ERROR: UndefinedVariable - somefile.php:3:10 - Cannot find referenced variable $as_you @@ -237,9 +229,13 @@ ERROR: PossiblyUndefinedGlobalVariable - somefile.php:15:6 - Possibly undefined ', - IssueBuffer::getOutput(ProjectAnalyzer::TYPE_CONSOLE, false, false) + IssueBuffer::getOutput($console_report_options) ); + $compact_report_options = new Report\ReportOptions(); + $compact_report_options->format = Report::TYPE_COMPACT; + $compact_report_options->use_color = false; + $this->assertSame( 'FILE: somefile.php' . PHP_EOL . PHP_EOL . @@ -251,9 +247,11 @@ ERROR: PossiblyUndefinedGlobalVariable - somefile.php:15:6 - Possibly undefined '| ERROR | 7 | UndefinedConstant | Const CHANGE_ME is not defined |' . PHP_EOL . '| ERROR | 15 | PossiblyUndefinedGlobalVariable | Possibly undefined global variable $a, first seen on line 10 |' . PHP_EOL . '+----------+------+---------------------------------+---------------------------------------------------------------+' . PHP_EOL, - IssueBuffer::getOutput(ProjectAnalyzer::TYPE_COMPACT, false) + IssueBuffer::getOutput($compact_report_options) ); + $checkstyle_report_options = ProjectAnalyzer::getFileReportOptions([__DIR__ . '/test-report.checkstyle.xml'])[0]; + $this->assertSame( ' @@ -271,7 +269,7 @@ ERROR: PossiblyUndefinedGlobalVariable - somefile.php:15:6 - Possibly undefined ', - IssueBuffer::getOutput(ProjectAnalyzer::TYPE_CHECKSTYLE, false) + IssueBuffer::getOutput($checkstyle_report_options) ); // FIXME: The XML parser only return strings, all int value are casted, so the assertSame failed @@ -295,11 +293,11 @@ ERROR: PossiblyUndefinedGlobalVariable - somefile.php:15:6 - Possibly undefined $this->assertSame( '[] ', - IssueBuffer::getOutput(ProjectAnalyzer::TYPE_JSON, false) + IssueBuffer::getOutput(ProjectAnalyzer::getFileReportOptions([__DIR__ . '/test-report.json'])[0]) ); $this->assertSame( '', - IssueBuffer::getOutput(ProjectAnalyzer::TYPE_EMACS, false) + IssueBuffer::getOutput(ProjectAnalyzer::getFileReportOptions([__DIR__ . '/test-report.emacs'])[0]) ); $this->assertSame( ' @@ -307,7 +305,7 @@ ERROR: PossiblyUndefinedGlobalVariable - somefile.php:15:6 - Possibly undefined ', - IssueBuffer::getOutput(ProjectAnalyzer::TYPE_XML, false) + IssueBuffer::getOutput(ProjectAnalyzer::getFileReportOptions([__DIR__ . '/test-report.xml'])[0]) ); $this->assertSame( @@ -315,7 +313,7 @@ ERROR: PossiblyUndefinedGlobalVariable - somefile.php:15:6 - Possibly undefined ', - IssueBuffer::getOutput(ProjectAnalyzer::TYPE_CHECKSTYLE, false) + IssueBuffer::getOutput(ProjectAnalyzer::getFileReportOptions([__DIR__ . '/test-report.checkstyle.xml'])[0]) ); ob_start(); diff --git a/tests/TestCase.php b/tests/TestCase.php index 25e5ae09b..7b6261ce2 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -58,12 +58,7 @@ class TestCase extends BaseTestCase $this->project_analyzer = new ProjectAnalyzer( $config, - $providers, - false, - true, - ProjectAnalyzer::TYPE_CONSOLE, - 1, - null + $providers ); $this->project_analyzer->setPhpVersion('7.3'); diff --git a/tests/TypeParseTest.php b/tests/TypeParseTest.php index 289058d18..291a63296 100644 --- a/tests/TypeParseTest.php +++ b/tests/TypeParseTest.php @@ -21,12 +21,7 @@ class TypeParseTest extends TestCase $this->project_analyzer = new \Psalm\Internal\Analyzer\ProjectAnalyzer( $config, - $providers, - false, - true, - \Psalm\Internal\Analyzer\ProjectAnalyzer::TYPE_CONSOLE, - 1, - null + $providers ); }