Make it work
parent
8116305966
commit
0060045a1e
|
@ -35,7 +35,7 @@ class Workspace
|
||||||
* @param string $pattern A glob pattern
|
* @param string $pattern A glob pattern
|
||||||
* @return Promise <TextDocumentIdentifier[]> Array of documents that match the glob pattern
|
* @return Promise <TextDocumentIdentifier[]> Array of documents that match the glob pattern
|
||||||
*/
|
*/
|
||||||
public function _glob(string $pattern): Promise
|
public function xglob(string $pattern): Promise
|
||||||
{
|
{
|
||||||
return $this->handler->request('workspace/_glob', ['pattern' => $pattern])->then(function ($textDocuments) {
|
return $this->handler->request('workspace/_glob', ['pattern' => $pattern])->then(function ($textDocuments) {
|
||||||
return $this->mapper->mapArray($textDocuments, [], TextDocumentIdentifier::class);
|
return $this->mapper->mapArray($textDocuments, [], TextDocumentIdentifier::class);
|
||||||
|
|
|
@ -17,6 +17,7 @@ use Sabre\Event\Loop;
|
||||||
use function Sabre\Event\coroutine;
|
use function Sabre\Event\coroutine;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
use Generator;
|
||||||
|
|
||||||
class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
{
|
{
|
||||||
|
@ -61,6 +62,7 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
parent::__construct($this, '/');
|
parent::__construct($this, '/');
|
||||||
$this->protocolReader = $reader;
|
$this->protocolReader = $reader;
|
||||||
$this->protocolReader->on('message', function (Message $msg) {
|
$this->protocolReader->on('message', function (Message $msg) {
|
||||||
|
coroutine(function () use ($msg) {
|
||||||
// Ignore responses, this is the handler for requests and notifications
|
// Ignore responses, this is the handler for requests and notifications
|
||||||
if (AdvancedJsonRpc\Response::isResponse($msg->body)) {
|
if (AdvancedJsonRpc\Response::isResponse($msg->body)) {
|
||||||
return;
|
return;
|
||||||
|
@ -70,12 +72,17 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
try {
|
try {
|
||||||
// Invoke the method handler to get a result
|
// Invoke the method handler to get a result
|
||||||
$result = $this->dispatch($msg->body);
|
$result = $this->dispatch($msg->body);
|
||||||
|
if ($result instanceof Generator) {
|
||||||
|
$result = yield from $result;
|
||||||
|
} else if ($result instanceof Promise) {
|
||||||
|
$result = yield $result;
|
||||||
|
}
|
||||||
} catch (AdvancedJsonRpc\Error $e) {
|
} catch (AdvancedJsonRpc\Error $e) {
|
||||||
// If a ResponseError is thrown, send it back in the Response
|
// If a ResponseError is thrown, send it back in the Response
|
||||||
$error = $e;
|
$error = $e;
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
// If an unexpected error occured, send back an INTERNAL_ERROR error response
|
// If an unexpected error occured, send back an INTERNAL_ERROR error response
|
||||||
$error = new AdvancedJsonRpc\Error($e->getMessage(), AdvancedJsonRpc\ErrorCode::INTERNAL_ERROR, null, $e);
|
$error = new AdvancedJsonRpc\Error((string)$e, AdvancedJsonRpc\ErrorCode::INTERNAL_ERROR, null, $e);
|
||||||
}
|
}
|
||||||
// Only send a Response for a Request
|
// Only send a Response for a Request
|
||||||
// Notifications do not send Responses
|
// Notifications do not send Responses
|
||||||
|
@ -87,6 +94,12 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
}
|
}
|
||||||
$this->protocolWriter->write(new Message($responseBody));
|
$this->protocolWriter->write(new Message($responseBody));
|
||||||
}
|
}
|
||||||
|
})->otherwise(function ($err) {
|
||||||
|
// Crash process
|
||||||
|
Loop\nextTick(function () use ($err) {
|
||||||
|
throw $err;
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
$this->protocolWriter = $writer;
|
$this->protocolWriter = $writer;
|
||||||
$this->client = new LanguageClient($reader, $writer);
|
$this->client = new LanguageClient($reader, $writer);
|
||||||
|
@ -107,11 +120,18 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
*/
|
*/
|
||||||
public function initialize(int $processId, ClientCapabilities $capabilities, string $rootPath = null): InitializeResult
|
public function initialize(int $processId, ClientCapabilities $capabilities, string $rootPath = null): InitializeResult
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->rootPath = $rootPath;
|
$this->rootPath = $rootPath;
|
||||||
|
$this->clientCapabilities = $capabilities;
|
||||||
|
|
||||||
// start building project index
|
// start building project index
|
||||||
if ($rootPath !== null) {
|
if ($rootPath !== null) {
|
||||||
$this->indexProject();
|
$this->indexProject()->otherwise(function ($err) {
|
||||||
|
// Crash process
|
||||||
|
Loop\nextTick(function () use ($err) {
|
||||||
|
throw $err;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$serverCapabilities = new ServerCapabilities();
|
$serverCapabilities = new ServerCapabilities();
|
||||||
|
@ -157,37 +177,43 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
/**
|
/**
|
||||||
* Parses workspace files, one at a time.
|
* Parses workspace files, one at a time.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return Promise <void>
|
||||||
*/
|
*/
|
||||||
private function indexProject()
|
private function indexProject()
|
||||||
{
|
{
|
||||||
coroutine(function () {
|
return coroutine(function () {
|
||||||
$textDocuments = yield $this->client->workspace->xGlob('**/*.php');
|
if ($this->clientCapabilities->xglobProvider) {
|
||||||
$count = count($textDocuments);
|
$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);
|
||||||
|
|
||||||
$startTime = microtime(true);
|
$startTime = microtime(true);
|
||||||
|
|
||||||
foreach ($textDocuments as $i => $textDocument) {
|
foreach ($uris as $i => $uri) {
|
||||||
// Give LS to the chance to handle requests while indexing
|
// Give LS to the chance to handle requests while indexing
|
||||||
Loop\tick();
|
Loop\tick();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$shortName = substr(uriToPath($textDocument->uri), strlen($this->rootPath) + 1);
|
$shortName = substr(uriToPath($uri), strlen($this->rootPath) + 1);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$shortName = $textDocument->uri;
|
$shortName = $uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filesize($file) > 500000) {
|
|
||||||
$this->client->window->logMessage(MessageType::INFO, "Not parsing $shortName because it exceeds size limit of 0.5MB");
|
|
||||||
} else {
|
|
||||||
$this->client->window->logMessage(MessageType::INFO, "Parsing file $i/$count: $shortName.");
|
$this->client->window->logMessage(MessageType::INFO, "Parsing file $i/$count: $shortName.");
|
||||||
try {
|
try {
|
||||||
$this->project->loadDocument($textDocument->uri);
|
$this->project->loadDocument($uri);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->client->window->logMessage(MessageType::ERROR, "Error parsing file $shortName: " . (string)$e);
|
$this->client->window->logMessage(MessageType::ERROR, "Error parsing file $shortName: " . (string)$e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$duration = (int)(microtime(true) - $startTime);
|
$duration = (int)(microtime(true) - $startTime);
|
||||||
$mem = (int)(memory_get_usage(true) / (1024 * 1024));
|
$mem = (int)(memory_get_usage(true) / (1024 * 1024));
|
||||||
|
|
|
@ -4,5 +4,8 @@ namespace LanguageServer\Protocol;
|
||||||
|
|
||||||
class ClientCapabilities
|
class ClientCapabilities
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var bool|null
|
||||||
|
*/
|
||||||
|
public $xglobProvider;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue