Skip to content

Commit 5924bb4

Browse files
committed
Fix diagnostics engine
1 parent 43058bc commit 5924bb4

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

lib/Core/Diagnostics/DiagnosticsEngine.php

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Phpactor\LanguageServer\Core\Diagnostics;
44

55
use Amp\CancelledException;
6+
use Amp\Success;
67
use Phpactor\LanguageServerProtocol\Diagnostic;
78
use Phpactor\LanguageServerProtocol\TextDocument;
89
use Phpactor\LanguageServer\Core\Server\ClientApi;
@@ -43,6 +44,16 @@ class DiagnosticsEngine
4344
*/
4445
private array $versions = [];
4546

47+
/**
48+
* @var array<string,Deferred>
49+
*/
50+
private array $locks = [];
51+
52+
/**
53+
* @var array<string,int>
54+
*/
55+
private array $concurrencies = [];
56+
4657
/**
4758
* @param DiagnosticsProvider[] $providers
4859
*/
@@ -99,12 +110,27 @@ public function run(CancellationToken $token): Promise
99110
$this->next = null;
100111
}
101112

102-
foreach ($this->providers as $i => $provider) {
103-
asyncCall(function () use ($provider, $token, $textDocument) {
113+
foreach ($this->providers as $providerId => $provider) {
114+
asyncCall(function () use ($providerId, $provider, $token, $textDocument) {
104115
$start = microtime(true);
105116

117+
yield $this->await($providerId);
118+
119+
if (!$this->isDocumentCurrent($textDocument)) {
120+
return;
121+
}
122+
123+
$this->locks[$providerId] = new Deferred();
124+
106125
/** @var Diagnostic[] $diagnostics */
107126
$diagnostics = yield $provider->provideDiagnostics($textDocument, $token) ;
127+
128+
if (isset($this->locks[$providerId])) {
129+
$lock = $this->locks[$providerId];
130+
unset($this->locks[$providerId]);
131+
$lock->resolve(true);
132+
}
133+
108134
$elapsed = (int)round((microtime(true) - $start) / 1000);
109135

110136
$this->diagnostics[$textDocument->uri] = array_merge(
@@ -118,7 +144,7 @@ public function run(CancellationToken $token): Promise
118144
yield delay($timeToSleep);
119145
}
120146

121-
if ($textDocument->version !== ($this->versions[$textDocument->uri] ?? -1)) {
147+
if (!$this->isDocumentCurrent($textDocument)) {
122148
return;
123149
}
124150

@@ -147,4 +173,19 @@ public function enqueue(TextDocumentItem $textDocument): void
147173
$this->running = true;
148174
$this->deferred->resolve($textDocument);
149175
}
176+
177+
private function isDocumentCurrent(?TextDocumentItem $textDocument): bool
178+
{
179+
return $textDocument->version === ($this->versions[$textDocument->uri] ?? -1);
180+
}
181+
182+
private function await($providerId): Promise
183+
{
184+
if (!array_key_exists($providerId, $this->locks)) {
185+
return new Success(true);
186+
}
187+
188+
return $this->locks[$providerId]->promise();
189+
190+
}
150191
}

0 commit comments

Comments
 (0)