Add globWorkspace helper
parent
0060045a1e
commit
b9aeea2523
|
@ -18,6 +18,8 @@ use function Sabre\Event\coroutine;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use Generator;
|
use Generator;
|
||||||
|
use Webmozart\Glob\Iterator\GlobIterator;
|
||||||
|
use Webmozart\PathUril\Path;
|
||||||
|
|
||||||
class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
{
|
{
|
||||||
|
@ -182,32 +184,15 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
private function indexProject()
|
private function indexProject()
|
||||||
{
|
{
|
||||||
return coroutine(function () {
|
return coroutine(function () {
|
||||||
if ($this->clientCapabilities->xglobProvider) {
|
$textDocuments = yield $this->globWorkspace('**/*.php');
|
||||||
$textDocuments = yield $this->client->workspace->xglob('**/*.php');
|
|
||||||
$uris = array_map(function ($textDocument) {
|
|
||||||
return $textDocument->uri;
|
|
||||||
}, $textDocuments);
|
|
||||||
} else {
|
|
||||||
$uris = array_map(function ($path) {
|
|
||||||
return pathToUri($path);
|
|
||||||
}, findFilesRecursive($this->rootPath, '/^.+\.php$/i'));
|
|
||||||
}
|
|
||||||
$count = count($uris);
|
$count = count($uris);
|
||||||
|
|
||||||
$startTime = microtime(true);
|
$startTime = microtime(true);
|
||||||
|
|
||||||
foreach ($uris as $i => $uri) {
|
foreach ($textDocuments as $i => $textDocument) {
|
||||||
// Give LS to the chance to handle requests while indexing
|
// Give LS to the chance to handle requests while indexing
|
||||||
Loop\tick();
|
Loop\tick();
|
||||||
|
$this->client->window->logMessage(MessageType::INFO, "Parsing file $i/$count: {$textDocument->uri}");
|
||||||
try {
|
|
||||||
$shortName = substr(uriToPath($uri), strlen($this->rootPath) + 1);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$shortName = $uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$this->client->window->logMessage(MessageType::INFO, "Parsing file $i/$count: $shortName.");
|
|
||||||
try {
|
try {
|
||||||
$this->project->loadDocument($uri);
|
$this->project->loadDocument($uri);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
@ -220,4 +205,36 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
$this->client->window->logMessage(MessageType::INFO, "All PHP files parsed in $duration seconds. $mem MiB allocated.");
|
$this->client->window->logMessage(MessageType::INFO, "All PHP files parsed in $duration seconds. $mem MiB allocated.");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all files matching a glob pattern.
|
||||||
|
* If the client does not support workspace/xglob, it falls back to globbing the file system directly.
|
||||||
|
*
|
||||||
|
* @param string $pattern
|
||||||
|
* @return Promise <TextDocumentIdentifier[]>
|
||||||
|
*/
|
||||||
|
private function globWorkspace(string $pattern): Promise
|
||||||
|
{
|
||||||
|
if ($this->clientCapabilities->xglobProvider) {
|
||||||
|
// Use xglob request
|
||||||
|
return $this->client->workspace->xglob($pattern);
|
||||||
|
} else {
|
||||||
|
// Use the file system
|
||||||
|
$promise = new Promise;
|
||||||
|
$textDocuments = [];
|
||||||
|
$pattern = Path::makeAbsolute($pattern, $this->rootPath);
|
||||||
|
$iterator = new GlobIterator($pattern);
|
||||||
|
$next = function () use ($iterator, &$textDocuments, $promise, &$next) {
|
||||||
|
if (!$iterator->valid()) {
|
||||||
|
$promise->resolve($textDocuments);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$textDocuments[] = new TextDocumentIdentifier(pathToUri($iterator->current()));
|
||||||
|
$iterator->next();
|
||||||
|
Loop\setTimeout($next, 0);
|
||||||
|
};
|
||||||
|
Loop\setTimeout($next, 0);
|
||||||
|
return $promise;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,25 +5,6 @@ namespace LanguageServer;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively Searches files with matching filename, starting at $path.
|
|
||||||
*
|
|
||||||
* @param string $path
|
|
||||||
* @param string $pattern
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function findFilesRecursive(string $path, string $pattern): array
|
|
||||||
{
|
|
||||||
$dir = new \RecursiveDirectoryIterator($path);
|
|
||||||
$ite = new \RecursiveIteratorIterator($dir);
|
|
||||||
$files = new \RegexIterator($ite, $pattern, \RegexIterator::GET_MATCH);
|
|
||||||
$fileList = [];
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$fileList = array_merge($fileList, $file);
|
|
||||||
}
|
|
||||||
return $fileList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms an absolute file path into a URI as used by the language server protocol.
|
* Transforms an absolute file path into a URI as used by the language server protocol.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types = 1);
|
|
||||||
|
|
||||||
namespace LanguageServer\Tests\Utils;
|
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
class RecursiveFileSearchTest extends TestCase
|
|
||||||
{
|
|
||||||
public function testFilesAreFound()
|
|
||||||
{
|
|
||||||
$path = realpath(__DIR__ . '/../../fixtures/recursive');
|
|
||||||
$files = \LanguageServer\findFilesRecursive($path, '/.+\.txt/');
|
|
||||||
sort($files);
|
|
||||||
$this->assertEquals([
|
|
||||||
$path . DIRECTORY_SEPARATOR . 'a.txt',
|
|
||||||
$path . DIRECTORY_SEPARATOR . 'search' . DIRECTORY_SEPARATOR . 'b.txt',
|
|
||||||
$path . DIRECTORY_SEPARATOR . 'search' . DIRECTORY_SEPARATOR . 'here' . DIRECTORY_SEPARATOR . 'c.txt',
|
|
||||||
], $files);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue