From 27c0caf2fbeb5e35fe181d578a89db16a9b70c59 Mon Sep 17 00:00:00 2001 From: Andrew Nagy Date: Wed, 25 Jan 2023 18:13:27 +0000 Subject: [PATCH] Fixes #9180 allow baseline file --- src/Psalm/Internal/Cli/LanguageServer.php | 8 +++ .../LanguageServer/ClientConfiguration.php | 9 +++- .../LanguageServer/LanguageServer.php | 54 ++++++++++++++++++- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/Psalm/Internal/Cli/LanguageServer.php b/src/Psalm/Internal/Cli/LanguageServer.php index fdd2bc9b7..88f36b41d 100644 --- a/src/Psalm/Internal/Cli/LanguageServer.php +++ b/src/Psalm/Internal/Cli/LanguageServer.php @@ -82,6 +82,7 @@ final class LanguageServer 'tcp:', 'tcp-server', 'disable-on-change::', + 'use-baseline:', 'enable-autocomplete::', 'enable-code-actions::', 'enable-provide-diagnostics::', @@ -181,6 +182,9 @@ final class LanguageServer --use-ini-defaults Use PHP-provided ini defaults for memory and error display + --use-baseline=PATH + Allows you to use a baseline other than the default baseline provided in your config + --tcp=url Use TCP mode (by default Psalm uses STDIO) @@ -312,6 +316,10 @@ final class LanguageServer } } + if (isset($options['use-baseline']) && is_string($options['use-baseline'])) { + $clientConfiguration->baseline = $options['use-baseline']; + } + if (isset($options['disable-on-change']) && is_numeric($options['disable-on-change'])) { $clientConfiguration->onchangeLineLimit = (int) $options['disable-on-change']; } diff --git a/src/Psalm/Internal/LanguageServer/ClientConfiguration.php b/src/Psalm/Internal/LanguageServer/ClientConfiguration.php index 973439cf9..1684287ec 100644 --- a/src/Psalm/Internal/LanguageServer/ClientConfiguration.php +++ b/src/Psalm/Internal/LanguageServer/ClientConfiguration.php @@ -12,6 +12,11 @@ use LanguageServerProtocol\MessageType; class ClientConfiguration { + /** + * Location of Baseline file + */ + public ?string $baseline = null; + /** * TCP Server Address */ @@ -106,7 +111,8 @@ class ClientConfiguration ?bool $findUnusedVariables = null, ?string $findUnusedCode = null, ?int $logLevel = null, - ?int $onchangeLineLimit = null + ?int $onchangeLineLimit = null, + ?string $baseline = null ) { $this->hideWarnings = $hideWarnings; $this->provideCompletion = $provideCompletion; @@ -119,5 +125,6 @@ class ClientConfiguration $this->findUnusedCode = $findUnusedCode; $this->logLevel = $logLevel; $this->onchangeLineLimit = $onchangeLineLimit; + $this->baseline = $baseline; } } diff --git a/src/Psalm/Internal/LanguageServer/LanguageServer.php b/src/Psalm/Internal/LanguageServer/LanguageServer.php index b41dff23d..8c318c79a 100644 --- a/src/Psalm/Internal/LanguageServer/LanguageServer.php +++ b/src/Psalm/Internal/LanguageServer/LanguageServer.php @@ -37,6 +37,7 @@ use LanguageServerProtocol\TextDocumentSyncKind; use LanguageServerProtocol\TextDocumentSyncOptions; use Psalm\Codebase; use Psalm\Config; +use Psalm\ErrorBaseline; use Psalm\Internal\Analyzer\IssueData; use Psalm\Internal\Analyzer\ProjectAnalyzer; use Psalm\Internal\Composer; @@ -59,10 +60,13 @@ use function array_filter; use function array_keys; use function array_map; use function array_reduce; +use function array_search; use function array_shift; +use function array_splice; use function array_unshift; use function array_values; use function cli_set_process_title; +use function count; use function explode; use function extension_loaded; use function fwrite; @@ -125,6 +129,9 @@ class LanguageServer extends Dispatcher */ protected string $versionedAnalysisDelayToken = ''; + /** @var array}>> */ + protected array $issue_baseline = []; + /** * This should actually be a private property on `parent` * @@ -578,6 +585,14 @@ class LanguageServer extends Dispatcher */ $serverCapabilities->signatureHelpProvider = new SignatureHelpOptions(['(', ',']); + if ($this->client->clientConfiguration->baseline !== null) { + $this->logInfo('Utilizing Baseline: '.$this->client->clientConfiguration->baseline); + $this->issue_baseline= ErrorBaseline::read( + new FileProvider, + $this->client->clientConfiguration->baseline, + ); + } + $this->logInfo("Initializing: Complete."); $this->clientStatus('initialized'); @@ -724,6 +739,9 @@ class LanguageServer extends Dispatcher 'version' => $version, ]); + //Copy variable here to be able to process it + $issue_baseline = $this->issue_baseline; + $data = IssueBuffer::clear(); foreach ($files as $file_path => $uri) { //Dont report errors in files we are not watching @@ -787,7 +805,41 @@ class LanguageServer extends Dispatcher return $diagnostic; }, array_filter( - $data[$file_path] ?? [], + array_map(function (IssueData $issue_data) use (&$issue_baseline) { + if (empty($issue_baseline)) { + return $issue_data; + } + //Process Baseline + $file = $issue_data->file_name; + $type = $issue_data->type; + /** @psalm-suppress MixedArrayAccess */ + if (isset($issue_baseline[$file][$type]) && $issue_baseline[$file][$type]['o'] > 0) { + /** @psalm-suppress MixedArrayAccess, MixedArgument */ + if ($issue_baseline[$file][$type]['o'] === count($issue_baseline[$file][$type]['s'])) { + /** @psalm-suppress MixedArrayAccess, MixedAssignment */ + $position = array_search( + trim($issue_data->selected_text), + $issue_baseline[$file][$type]['s'], + true, + ); + + if ($position !== false) { + $issue_data->severity = Config::REPORT_INFO; + /** @psalm-suppress MixedArgument */ + array_splice($issue_baseline[$file][$type]['s'], $position, 1); + /** @psalm-suppress MixedArrayAssignment, MixedOperand, MixedAssignment */ + $issue_baseline[$file][$type]['o']--; + } + } else { + /** @psalm-suppress MixedArrayAssignment, MixedOperand, MixedAssignment */ + $issue_baseline[$file][$type]['s'] = []; + $issue_data->severity = Config::REPORT_INFO; + /** @psalm-suppress MixedArrayAssignment, MixedOperand, MixedAssignment */ + $issue_baseline[$file][$type]['o']--; + } + } + return $issue_data; + }, $data[$file_path] ?? []), function (IssueData $issue_data) { //Hide Warnings if ($issue_data->severity === Config::REPORT_INFO &&