Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/LanguageServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ public function initialize(ClientCapabilities $capabilities, string $rootPath =
}
if ($this->workspace === null) {
$this->workspace = new Server\Workspace(
$this->client,
$this->projectIndex,
$dependenciesIndex,
$sourceIndex,
Expand Down
33 changes: 31 additions & 2 deletions src/Server/Workspace.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@

use LanguageServer\{LanguageClient, Project, PhpDocumentLoader};
use LanguageServer\Index\{ProjectIndex, DependenciesIndex, Index};
use LanguageServer\Protocol\{SymbolInformation, SymbolDescriptor, ReferenceInformation, DependencyReference, Location};
use LanguageServer\Protocol\{
FileChangeType,
FileEvent,
SymbolInformation,
SymbolDescriptor,
ReferenceInformation,
DependencyReference,
Location
};
use Sabre\Event\Promise;
use function Sabre\Event\coroutine;
use function LanguageServer\{waitForEvent, getPackageName};
Expand All @@ -15,6 +23,11 @@
*/
class Workspace
{
/**
* @var LanguageClient
*/
public $client;

/**
* The symbol index for the workspace
*
Expand Down Expand Up @@ -43,14 +56,16 @@ class Workspace
public $documentLoader;

/**
* @param LanguageClient $client LanguageClient instance used to signal updated results
* @param ProjectIndex $index Index that is searched on a workspace/symbol request
* @param DependenciesIndex $dependenciesIndex Index that is used on a workspace/xreferences request
* @param DependenciesIndex $sourceIndex Index that is used on a workspace/xreferences request
* @param \stdClass $composerLock The parsed composer.lock of the project, if any
* @param PhpDocumentLoader $documentLoader PhpDocumentLoader instance to load documents
*/
public function __construct(ProjectIndex $index, DependenciesIndex $dependenciesIndex, Index $sourceIndex, \stdClass $composerLock = null, PhpDocumentLoader $documentLoader, \stdClass $composerJson = null)
public function __construct(LanguageClient $client, ProjectIndex $index, DependenciesIndex $dependenciesIndex, Index $sourceIndex, \stdClass $composerLock = null, PhpDocumentLoader $documentLoader, \stdClass $composerJson = null)
{
$this->client = $client;
$this->sourceIndex = $sourceIndex;
$this->index = $index;
$this->dependenciesIndex = $dependenciesIndex;
Expand Down Expand Up @@ -82,6 +97,20 @@ public function symbol(string $query): Promise
});
}

/**
* The watched files notification is sent from the client to the server when the client detects changes to files watched by the language client.
*
* @param FileEvent[] $changes
* @return void
*/
public function didChangeWatchedFiles(array $changes) : void {
foreach ($changes as $change) {
if ($change->type === FileChangeType::DELETED) {
$this->client->textDocument->publishDiagnostics($change->uri, []);
}
}
}

/**
* The workspace references request is sent from the client to the server to locate project-wide references to a symbol given its description / metadata.
*
Expand Down
2 changes: 1 addition & 1 deletion tests/Server/ServerTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function setUp()
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
$this->documentLoader = new PhpDocumentLoader(new FileSystemContentRetriever, $projectIndex, $definitionResolver);
$this->textDocument = new Server\TextDocument($this->documentLoader, $definitionResolver, $client, $projectIndex);
$this->workspace = new Server\Workspace($projectIndex, $dependenciesIndex, $sourceIndex, null, $this->documentLoader);
$this->workspace = new Server\Workspace($client, $projectIndex, $dependenciesIndex, $sourceIndex, null, $this->documentLoader);

$globalSymbolsUri = pathToUri(realpath(__DIR__ . '/../../fixtures/global_symbols.php'));
$globalReferencesUri = pathToUri(realpath(__DIR__ . '/../../fixtures/global_references.php'));
Expand Down
43 changes: 43 additions & 0 deletions tests/Server/Workspace/DidChangeWatchedFilesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
declare(strict_types = 1);

namespace LanguageServer\Tests\Server\Workspace;

use LanguageServer\ContentRetriever\FileSystemContentRetriever;
use LanguageServer\{DefinitionResolver, LanguageClient, PhpDocumentLoader, Server};
use LanguageServer\Index\{DependenciesIndex, Index, ProjectIndex};
use LanguageServer\Protocol\{FileChangeType, FileEvent, Message};
use LanguageServer\Tests\MockProtocolStream;
use LanguageServer\Tests\Server\ServerTestCase;
use LanguageServer\Server\Workspace;
use Sabre\Event\Loop;

class DidChangeWatchedFilesTest extends ServerTestCase
{
public function testDeletingFileClearsAllDiagnostics()
{
$client = new LanguageClient(new MockProtocolStream(), $writer = new MockProtocolStream());
$projectIndex = new ProjectIndex($sourceIndex = new Index(), $dependenciesIndex = new DependenciesIndex());
$definitionResolver = new DefinitionResolver($projectIndex);
$loader = new PhpDocumentLoader(new FileSystemContentRetriever(), $projectIndex, $definitionResolver);
$workspace = new Server\Workspace($client, $projectIndex, $dependenciesIndex, $sourceIndex, null, $loader, null);

$fileEvent = new FileEvent();
$fileEvent->uri = 'my uri';
$fileEvent->type = FileChangeType::DELETED;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to add a constructor to FileEvent to make this easier to construct


$isDiagnosticsCleared = false;
$writer->on('message', function (Message $message) use ($fileEvent, & $isDiagnosticsCleared) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No space after &

if ($message->body->method === "textDocument/publishDiagnostics") {
$this->assertEquals($message->body->params->uri, $fileEvent->uri);
$this->assertEquals($message->body->params->diagnostics, []);
$isDiagnosticsCleared = true;
}
});

$workspace->didChangeWatchedFiles([$fileEvent]);
Loop\tick(true);

$this->assertTrue($isDiagnosticsCleared, "Deleting file should clear all diagnostics.");
}
}