Add FilesFinder
parent
ebd1cc6133
commit
164c4589e4
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace LanguageServer\ContentRetriever;
|
||||||
|
|
||||||
|
use LanguageServer\LanguageClient;
|
||||||
|
use Sabre\Event\Promise;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves file content from the client through a textDocument/xcontent request
|
||||||
|
*/
|
||||||
|
class ClientFilesFinder implements FilesFinder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var LanguageClient
|
||||||
|
*/
|
||||||
|
private $client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param LanguageClient $client
|
||||||
|
*/
|
||||||
|
public function __construct(LanguageClient $client)
|
||||||
|
{
|
||||||
|
$this->client = $client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all files in the workspace that match a glob.
|
||||||
|
* If the client does not support workspace/files, it falls back to searching the file system directly.
|
||||||
|
*
|
||||||
|
* @param string $glob
|
||||||
|
* @return Promise <string[]> The URIs
|
||||||
|
*/
|
||||||
|
private function find(string $glob): Promise
|
||||||
|
{
|
||||||
|
return $this->client->workspace->xfiles()->then(function (array $textDocuments) {
|
||||||
|
$uris = [];
|
||||||
|
foreach ($textDocuments as $textDocument) {
|
||||||
|
$path = Uri\parse($textDocument->uri)['path'];
|
||||||
|
if (Glob::match($path, $pattern)) {
|
||||||
|
$uris[] = $textDocument->uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $uris;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace LanguageServer\FilesFinder;
|
||||||
|
|
||||||
|
use Sabre\Event\Promise;
|
||||||
|
use function LanguageServer\{uriToPath, timeout};
|
||||||
|
use Webmozart\Glob\Iterator\GlobIterator;
|
||||||
|
|
||||||
|
class FileSystemFindFinder implements FilesFinder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns all files in the workspace that match a glob.
|
||||||
|
* If the client does not support workspace/files, it falls back to searching the file system directly.
|
||||||
|
*
|
||||||
|
* @param string $glob
|
||||||
|
* @return Promise <string[]>
|
||||||
|
*/
|
||||||
|
public function find(string $glob): Promise
|
||||||
|
{
|
||||||
|
return coroutine(function () use ($glob) {
|
||||||
|
$uris = [];
|
||||||
|
foreach (new GlobIterator($pattern) as $path) {
|
||||||
|
$uris[] = pathToUri($path);
|
||||||
|
yield timeout();
|
||||||
|
}
|
||||||
|
return $uris;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace LanguageServer\ContentRetriever;
|
||||||
|
|
||||||
|
use Sabre\Event\Promise;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for retrieving the content of a text document
|
||||||
|
*/
|
||||||
|
interface FilesFinder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns all files in the workspace that match a glob.
|
||||||
|
* If the client does not support workspace/files, it falls back to searching the file system directly.
|
||||||
|
*
|
||||||
|
* @param string $glob
|
||||||
|
* @return Promise <string[]>
|
||||||
|
*/
|
||||||
|
public function find(string $glob): Promise;
|
||||||
|
}
|
|
@ -14,13 +14,12 @@ use LanguageServer\Protocol\{
|
||||||
TextDocumentIdentifier,
|
TextDocumentIdentifier,
|
||||||
CompletionOptions
|
CompletionOptions
|
||||||
};
|
};
|
||||||
|
use LanguageServer\FilesFinder\{FilesFinder, ClientFilesFinder, FileSystemFilesFinder};
|
||||||
use AdvancedJsonRpc;
|
use AdvancedJsonRpc;
|
||||||
use Sabre\Event\{Loop, Promise};
|
use Sabre\Event\{Loop, Promise};
|
||||||
use function Sabre\Event\coroutine;
|
use function Sabre\Event\coroutine;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use Webmozart\Glob\Iterator\GlobIterator;
|
|
||||||
use Webmozart\Glob\Glob;
|
|
||||||
use Webmozart\PathUtil\Path;
|
use Webmozart\PathUtil\Path;
|
||||||
use Sabre\Uri;
|
use Sabre\Uri;
|
||||||
|
|
||||||
|
@ -62,6 +61,11 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
private $rootPath;
|
private $rootPath;
|
||||||
private $project;
|
private $project;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FilesFinder
|
||||||
|
*/
|
||||||
|
private $filesFinder;
|
||||||
|
|
||||||
public function __construct(ProtocolReader $reader, ProtocolWriter $writer)
|
public function __construct(ProtocolReader $reader, ProtocolWriter $writer)
|
||||||
{
|
{
|
||||||
parent::__construct($this, '/');
|
parent::__construct($this, '/');
|
||||||
|
@ -107,6 +111,11 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
});
|
});
|
||||||
$this->protocolWriter = $writer;
|
$this->protocolWriter = $writer;
|
||||||
$this->client = new LanguageClient($reader, $writer);
|
$this->client = new LanguageClient($reader, $writer);
|
||||||
|
if ($this->clientCapabilities->xfilesProvider) {
|
||||||
|
$this->filesFinder = new ClientFilesFinder($this->client);
|
||||||
|
} else {
|
||||||
|
$this->filesFinder = new FileSystemFilesFinder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -183,7 +192,8 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
private function indexProject(): Promise
|
private function indexProject(): Promise
|
||||||
{
|
{
|
||||||
return coroutine(function () {
|
return coroutine(function () {
|
||||||
$textDocuments = yield $this->findPhpFiles();
|
$pattern = Path::makeAbsolute('**/*.php', $this->rootPath);
|
||||||
|
$textDocuments = yield $this->filesFinder->find($pattern);
|
||||||
$count = count($textDocuments);
|
$count = count($textDocuments);
|
||||||
|
|
||||||
$startTime = microtime(true);
|
$startTime = microtime(true);
|
||||||
|
@ -219,33 +229,4 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all PHP files in the workspace.
|
|
||||||
* If the client does not support workspace/files, it falls back to searching the file system directly.
|
|
||||||
*
|
|
||||||
* @return Promise <TextDocumentIdentifier[]>
|
|
||||||
*/
|
|
||||||
private function findPhpFiles(): Promise
|
|
||||||
{
|
|
||||||
return coroutine(function () {
|
|
||||||
$textDocuments = [];
|
|
||||||
$pattern = Path::makeAbsolute('**/*.php', $this->rootPath);
|
|
||||||
if ($this->clientCapabilities->xfilesProvider) {
|
|
||||||
// Use xfiles request
|
|
||||||
foreach (yield $this->client->workspace->xfiles() as $textDocument) {
|
|
||||||
$path = Uri\parse($textDocument->uri)['path'];
|
|
||||||
if (Glob::match($path, $pattern)) {
|
|
||||||
$textDocuments[] = $textDocument;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Use the file system
|
|
||||||
foreach (new GlobIterator($pattern) as $path) {
|
|
||||||
$textDocuments[] = new TextDocumentIdentifier(pathToUri($path));
|
|
||||||
yield timeout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $textDocuments;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue