1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-15 10:57:08 +01:00
psalm/src/Psalm/Internal/LanguageServer/ClientHandler.php

112 lines
3.2 KiB
PHP
Raw Normal View History

<?php
2021-12-15 04:42:37 +01:00
declare(strict_types=1);
2018-11-06 03:57:36 +01:00
namespace Psalm\Internal\LanguageServer;
2021-12-13 18:24:02 +01:00
use AdvancedJsonRpc\Notification;
use AdvancedJsonRpc\Request;
use AdvancedJsonRpc\Response;
use AdvancedJsonRpc\SuccessResponse;
use Amp\Deferred;
use Amp\Promise;
2021-12-03 21:40:18 +01:00
use Generator;
2021-06-08 04:55:21 +02:00
use function Amp\call;
use function error_log;
/**
* @internal
*/
class ClientHandler
{
/**
* @var ProtocolReader
*/
public $protocolReader;
/**
* @var ProtocolWriter
*/
public $protocolWriter;
/**
* @var IdGenerator
*/
public $idGenerator;
public function __construct(ProtocolReader $protocolReader, ProtocolWriter $protocolWriter)
{
$this->protocolReader = $protocolReader;
$this->protocolWriter = $protocolWriter;
$this->idGenerator = new IdGenerator;
}
/**
* Sends a request to the client and returns a promise that is resolved with the result or rejected with the error
*
* @param string $method The method to call
* @param array|object $params The method parameters
2019-07-05 22:24:00 +02:00
*
* @return Promise<mixed> Resolved with the result of the request or rejected with an error
*/
public function request(string $method, $params): Promise
{
$id = $this->idGenerator->generate();
return call(
/**
2021-12-04 03:37:19 +01:00
* @return Generator<int, Promise, mixed, Promise<mixed>>
*/
2021-12-03 21:40:18 +01:00
function () use ($id, $method, $params): Generator {
yield $this->protocolWriter->write(
new Message(
2021-12-13 18:24:02 +01:00
new Request($id, $method, (object) $params)
)
);
$deferred = new Deferred();
$listener =
function (Message $msg) use ($id, $deferred, &$listener): void {
error_log('request handler');
/**
* @psalm-suppress UndefinedPropertyFetch
* @psalm-suppress MixedArgument
*/
if ($msg->body
2021-12-13 18:24:02 +01:00
&& Response::isResponse($msg->body)
&& $msg->body->id === $id
) {
// Received a response
$this->protocolReader->removeListener('message', $listener);
2021-12-13 18:24:02 +01:00
if (SuccessResponse::isSuccessResponse($msg->body)) {
$deferred->resolve($msg->body->result);
} else {
$deferred->fail($msg->body->error);
}
}
};
$this->protocolReader->on('message', $listener);
2019-07-05 22:24:00 +02:00
return $deferred->promise();
}
);
}
/**
* Sends a notification to the client
*
* @param string $method The method to call
* @param array|object $params The method parameters
*/
2021-06-10 18:23:53 +02:00
public function notify(string $method, $params): void
{
2021-06-10 18:23:53 +02:00
$this->protocolWriter->write(
new Message(
2021-12-13 18:24:02 +01:00
new Notification($method, (object)$params)
)
);
}
}