Handle Client responses (#128)
parent
ff0a35d833
commit
04ef6c8adf
|
@ -3,9 +3,9 @@ declare(strict_types = 1);
|
||||||
|
|
||||||
namespace LanguageServer\Client;
|
namespace LanguageServer\Client;
|
||||||
|
|
||||||
use AdvancedJsonRpc\Notification as NotificationBody;
|
use LanguageServer\ClientHandler;
|
||||||
use LanguageServer\ProtocolWriter;
|
|
||||||
use LanguageServer\Protocol\Message;
|
use LanguageServer\Protocol\Message;
|
||||||
|
use Sabre\Event\Promise;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides method handlers for all textDocument/* methods
|
* Provides method handlers for all textDocument/* methods
|
||||||
|
@ -13,13 +13,13 @@ use LanguageServer\Protocol\Message;
|
||||||
class TextDocument
|
class TextDocument
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var ProtocolWriter
|
* @var ClientHandler
|
||||||
*/
|
*/
|
||||||
private $protocolWriter;
|
private $handler;
|
||||||
|
|
||||||
public function __construct(ProtocolWriter $protocolWriter)
|
public function __construct(ClientHandler $handler)
|
||||||
{
|
{
|
||||||
$this->protocolWriter = $protocolWriter;
|
$this->handler = $handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,15 +27,13 @@ class TextDocument
|
||||||
*
|
*
|
||||||
* @param string $uri
|
* @param string $uri
|
||||||
* @param Diagnostic[] $diagnostics
|
* @param Diagnostic[] $diagnostics
|
||||||
|
* @return Promise <void>
|
||||||
*/
|
*/
|
||||||
public function publishDiagnostics(string $uri, array $diagnostics)
|
public function publishDiagnostics(string $uri, array $diagnostics): Promise
|
||||||
{
|
{
|
||||||
$this->protocolWriter->write(new Message(new NotificationBody(
|
return $this->handler->notify('textDocument/publishDiagnostics', [
|
||||||
'textDocument/publishDiagnostics',
|
'uri' => $uri,
|
||||||
(object)[
|
'diagnostics' => $diagnostics
|
||||||
'uri' => $uri,
|
]);
|
||||||
'diagnostics' => $diagnostics
|
|
||||||
]
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@ declare(strict_types = 1);
|
||||||
|
|
||||||
namespace LanguageServer\Client;
|
namespace LanguageServer\Client;
|
||||||
|
|
||||||
use AdvancedJsonRpc\Notification as NotificationBody;
|
use LanguageServer\ClientHandler;
|
||||||
use LanguageServer\ProtocolWriter;
|
|
||||||
use LanguageServer\Protocol\Message;
|
use LanguageServer\Protocol\Message;
|
||||||
|
use Sabre\Event\Promise;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides method handlers for all window/* methods
|
* Provides method handlers for all window/* methods
|
||||||
|
@ -13,30 +13,26 @@ use LanguageServer\Protocol\Message;
|
||||||
class Window
|
class Window
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var ProtocolWriter
|
* @var ClientHandler
|
||||||
*/
|
*/
|
||||||
private $protocolWriter;
|
private $handler;
|
||||||
|
|
||||||
public function __construct(ProtocolWriter $protocolWriter)
|
public function __construct(ClientHandler $handler)
|
||||||
{
|
{
|
||||||
$this->protocolWriter = $protocolWriter;
|
$this->handler = $handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface.
|
* The show message notification is sent from a server to a client
|
||||||
|
* to ask the client to display a particular message in the user interface.
|
||||||
*
|
*
|
||||||
* @param int $type
|
* @param int $type
|
||||||
* @param string $message
|
* @param string $message
|
||||||
|
* @return Promise <void>
|
||||||
*/
|
*/
|
||||||
public function showMessage(int $type, string $message)
|
public function showMessage(int $type, string $message): Promise
|
||||||
{
|
{
|
||||||
$this->protocolWriter->write(new Message(new NotificationBody(
|
return $this->handler->notify('window/showMessage', ['type' => $type, 'message' => $message]);
|
||||||
'window/showMessage',
|
|
||||||
(object)[
|
|
||||||
'type' => $type,
|
|
||||||
'message' => $message
|
|
||||||
]
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,15 +40,10 @@ class Window
|
||||||
*
|
*
|
||||||
* @param int $type
|
* @param int $type
|
||||||
* @param string $message
|
* @param string $message
|
||||||
|
* @return Promise <void>
|
||||||
*/
|
*/
|
||||||
public function logMessage(int $type, string $message)
|
public function logMessage(int $type, string $message): Promise
|
||||||
{
|
{
|
||||||
$this->protocolWriter->write(new Message(new NotificationBody(
|
return $this->handler->notify('window/logMessage', ['type' => $type, 'message' => $message]);
|
||||||
'window/logMessage',
|
|
||||||
(object)[
|
|
||||||
'type' => $type,
|
|
||||||
'message' => $message
|
|
||||||
]
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace LanguageServer;
|
||||||
|
|
||||||
|
use AdvancedJsonRpc;
|
||||||
|
use Sabre\Event\Promise;
|
||||||
|
|
||||||
|
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
|
||||||
|
* @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 $this->protocolWriter->write(
|
||||||
|
new Protocol\Message(
|
||||||
|
new AdvancedJsonRpc\Request($id, $method, (object)$params)
|
||||||
|
)
|
||||||
|
)->then(function () use ($id) {
|
||||||
|
$promise = new Promise;
|
||||||
|
$listener = function (Protocol\Message $msg) use ($id, $promise, &$listener) {
|
||||||
|
if (AdvancedJsonRpc\Response::isResponse($msg->body) && $msg->body->id === $id) {
|
||||||
|
// Received a response
|
||||||
|
$this->protocolReader->removeListener('message', $listener);
|
||||||
|
if (AdvancedJsonRpc\SuccessResponse::isSuccessResponse($msg->body)) {
|
||||||
|
$promise->fulfill($msg->body->result);
|
||||||
|
} else {
|
||||||
|
$promise->reject($msg->body->error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$this->protocolReader->on('message', $listener);
|
||||||
|
return $promise;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a notification to the client
|
||||||
|
*
|
||||||
|
* @param string $method The method to call
|
||||||
|
* @param array|object $params The method parameters
|
||||||
|
* @return Promise <null> Will be resolved as soon as the notification has been sent
|
||||||
|
*/
|
||||||
|
public function notify(string $method, $params): Promise
|
||||||
|
{
|
||||||
|
$id = $this->idGenerator->generate();
|
||||||
|
return $this->protocolWriter->write(
|
||||||
|
new Protocol\Message(
|
||||||
|
new AdvancedJsonRpc\Notification($method, (object)$params)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace LanguageServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates unique, incremental IDs for use as request IDs
|
||||||
|
*/
|
||||||
|
class IdGenerator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $counter = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a unique ID
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function generate()
|
||||||
|
{
|
||||||
|
return $this->counter++;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,9 +3,6 @@ declare(strict_types = 1);
|
||||||
|
|
||||||
namespace LanguageServer;
|
namespace LanguageServer;
|
||||||
|
|
||||||
use LanguageServer\Client\TextDocument;
|
|
||||||
use LanguageServer\Client\Window;
|
|
||||||
|
|
||||||
class LanguageClient
|
class LanguageClient
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -22,12 +19,11 @@ class LanguageClient
|
||||||
*/
|
*/
|
||||||
public $window;
|
public $window;
|
||||||
|
|
||||||
private $protocolWriter;
|
public function __construct(ProtocolReader $reader, ProtocolWriter $writer)
|
||||||
|
|
||||||
public function __construct(ProtocolWriter $writer)
|
|
||||||
{
|
{
|
||||||
$this->protocolWriter = $writer;
|
$handler = new ClientHandler($reader, $writer);
|
||||||
$this->textDocument = new TextDocument($writer);
|
|
||||||
$this->window = new Window($writer);
|
$this->textDocument = new Client\TextDocument($handler);
|
||||||
|
$this->window = new Client\Window($handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ declare(strict_types = 1);
|
||||||
|
|
||||||
namespace LanguageServer;
|
namespace LanguageServer;
|
||||||
|
|
||||||
use LanguageServer\Server\TextDocument;
|
|
||||||
use LanguageServer\Protocol\{
|
use LanguageServer\Protocol\{
|
||||||
ServerCapabilities,
|
ServerCapabilities,
|
||||||
ClientCapabilities,
|
ClientCapabilities,
|
||||||
|
@ -15,7 +14,6 @@ use LanguageServer\Protocol\{
|
||||||
};
|
};
|
||||||
use AdvancedJsonRpc;
|
use AdvancedJsonRpc;
|
||||||
use Sabre\Event\Loop;
|
use Sabre\Event\Loop;
|
||||||
use JsonMapper;
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
|
@ -56,7 +54,11 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
{
|
{
|
||||||
parent::__construct($this, '/');
|
parent::__construct($this, '/');
|
||||||
$this->protocolReader = $reader;
|
$this->protocolReader = $reader;
|
||||||
$this->protocolReader->onMessage(function (Message $msg) {
|
$this->protocolReader->on('message', function (Message $msg) {
|
||||||
|
// Ignore responses, this is the handler for requests and notifications
|
||||||
|
if (AdvancedJsonRpc\Response::isResponse($msg->body)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$result = null;
|
$result = null;
|
||||||
$error = null;
|
$error = null;
|
||||||
try {
|
try {
|
||||||
|
@ -81,7 +83,7 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$this->protocolWriter = $writer;
|
$this->protocolWriter = $writer;
|
||||||
$this->client = new LanguageClient($writer);
|
$this->client = new LanguageClient($reader, $writer);
|
||||||
|
|
||||||
$this->project = new Project($this->client);
|
$this->project = new Project($this->client);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,13 @@ declare(strict_types = 1);
|
||||||
|
|
||||||
namespace LanguageServer;
|
namespace LanguageServer;
|
||||||
|
|
||||||
interface ProtocolReader
|
use Sabre\Event\EmitterInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Must emit a "message" event with a Protocol\Message object as parameter
|
||||||
|
* when a message comes in
|
||||||
|
*/
|
||||||
|
interface ProtocolReader extends EmitterInterface
|
||||||
{
|
{
|
||||||
public function onMessage(callable $listener);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ namespace LanguageServer;
|
||||||
|
|
||||||
use LanguageServer\Protocol\Message;
|
use LanguageServer\Protocol\Message;
|
||||||
use AdvancedJsonRpc\Message as MessageBody;
|
use AdvancedJsonRpc\Message as MessageBody;
|
||||||
use Sabre\Event\Loop;
|
use Sabre\Event\{Loop, Emitter};
|
||||||
|
|
||||||
class ProtocolStreamReader implements ProtocolReader
|
class ProtocolStreamReader extends Emitter implements ProtocolReader
|
||||||
{
|
{
|
||||||
const PARSE_HEADERS = 1;
|
const PARSE_HEADERS = 1;
|
||||||
const PARSE_BODY = 2;
|
const PARSE_BODY = 2;
|
||||||
|
@ -17,7 +17,6 @@ class ProtocolStreamReader implements ProtocolReader
|
||||||
private $buffer = '';
|
private $buffer = '';
|
||||||
private $headers = [];
|
private $headers = [];
|
||||||
private $contentLength;
|
private $contentLength;
|
||||||
private $listener;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resource $input
|
* @param resource $input
|
||||||
|
@ -43,11 +42,8 @@ class ProtocolStreamReader implements ProtocolReader
|
||||||
break;
|
break;
|
||||||
case self::PARSE_BODY:
|
case self::PARSE_BODY:
|
||||||
if (strlen($this->buffer) === $this->contentLength) {
|
if (strlen($this->buffer) === $this->contentLength) {
|
||||||
if (isset($this->listener)) {
|
$msg = new Message(MessageBody::parse($this->buffer), $this->headers);
|
||||||
$msg = new Message(MessageBody::parse($this->buffer), $this->headers);
|
$this->emit('message', [$msg]);
|
||||||
$listener = $this->listener;
|
|
||||||
$listener($msg);
|
|
||||||
}
|
|
||||||
$this->parsingMode = self::PARSE_HEADERS;
|
$this->parsingMode = self::PARSE_HEADERS;
|
||||||
$this->headers = [];
|
$this->headers = [];
|
||||||
$this->buffer = '';
|
$this->buffer = '';
|
||||||
|
@ -57,13 +53,4 @@ class ProtocolStreamReader implements ProtocolReader
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param callable $listener Is called with a Message object
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function onMessage(callable $listener)
|
|
||||||
{
|
|
||||||
$this->listener = $listener;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,9 @@ class ProtocolStreamWriter implements ProtocolWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a Message to the client
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param Message $msg
|
|
||||||
* @return Promise Resolved when the message has been fully written out to the output stream
|
|
||||||
*/
|
*/
|
||||||
public function write(Message $msg)
|
public function write(Message $msg): Promise
|
||||||
{
|
{
|
||||||
// if the message queue is currently empty, register a write handler.
|
// if the message queue is currently empty, register a write handler.
|
||||||
if (empty($this->messages)) {
|
if (empty($this->messages)) {
|
||||||
|
|
|
@ -4,8 +4,15 @@ declare(strict_types = 1);
|
||||||
namespace LanguageServer;
|
namespace LanguageServer;
|
||||||
|
|
||||||
use LanguageServer\Protocol\Message;
|
use LanguageServer\Protocol\Message;
|
||||||
|
use Sabre\Event\Promise;
|
||||||
|
|
||||||
interface ProtocolWriter
|
interface ProtocolWriter
|
||||||
{
|
{
|
||||||
public function write(Message $msg);
|
/**
|
||||||
|
* Sends a Message to the client
|
||||||
|
*
|
||||||
|
* @param Message $msg
|
||||||
|
* @return Promise Resolved when the message has been fully written out to the output stream
|
||||||
|
*/
|
||||||
|
public function write(Message $msg): Promise;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace LanguageServer\Tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use LanguageServer\ClientHandler;
|
||||||
|
use LanguageServer\Protocol\Message;
|
||||||
|
use AdvancedJsonRpc;
|
||||||
|
use Sabre\Event\Loop;
|
||||||
|
|
||||||
|
class ClientHandlerTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testRequest()
|
||||||
|
{
|
||||||
|
$reader = new MockProtocolStream;
|
||||||
|
$writer = new MockProtocolStream;
|
||||||
|
$handler = new ClientHandler($reader, $writer);
|
||||||
|
$writer->once('message', function (Message $msg) use ($reader) {
|
||||||
|
// Respond to request
|
||||||
|
Loop\setTimeout(function () use ($reader, $msg) {
|
||||||
|
$reader->write(new Message(new AdvancedJsonRpc\SuccessResponse($msg->body->id, 'pong')));
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
$handler->request('testMethod', ['ping'])->then(function ($result) {
|
||||||
|
$this->assertEquals('pong', $result);
|
||||||
|
})->wait();
|
||||||
|
// No event listeners
|
||||||
|
$this->assertEquals([], $reader->listeners('message'));
|
||||||
|
$this->assertEquals([], $writer->listeners('message'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNotify()
|
||||||
|
{
|
||||||
|
$reader = new MockProtocolStream;
|
||||||
|
$writer = new MockProtocolStream;
|
||||||
|
$handler = new ClientHandler($reader, $writer);
|
||||||
|
$handler->notify('testMethod', ['ping'])->wait();
|
||||||
|
// No event listeners
|
||||||
|
$this->assertEquals([], $reader->listeners('message'));
|
||||||
|
$this->assertEquals([], $writer->listeners('message'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ class LanguageServerTest extends TestCase
|
||||||
$writer = new MockProtocolStream();
|
$writer = new MockProtocolStream();
|
||||||
$server = new LanguageServer($reader, $writer);
|
$server = new LanguageServer($reader, $writer);
|
||||||
$msg = null;
|
$msg = null;
|
||||||
$writer->onMessage(function (Message $message) use (&$msg) {
|
$writer->on('message', function (Message $message) use (&$msg) {
|
||||||
$msg = $message;
|
$msg = $message;
|
||||||
});
|
});
|
||||||
$reader->write(new Message(new AdvancedJsonRpc\Request(1, 'initialize', [
|
$reader->write(new Message(new AdvancedJsonRpc\Request(1, 'initialize', [
|
||||||
|
@ -24,7 +24,7 @@ class LanguageServerTest extends TestCase
|
||||||
'processId' => getmypid(),
|
'processId' => getmypid(),
|
||||||
'capabilities' => new ClientCapabilities()
|
'capabilities' => new ClientCapabilities()
|
||||||
])));
|
])));
|
||||||
$this->assertNotNull($msg, 'onMessage callback should be called');
|
$this->assertNotNull($msg, 'message event should be emitted');
|
||||||
$this->assertInstanceOf(AdvancedJsonRpc\SuccessResponse::class, $msg->body);
|
$this->assertInstanceOf(AdvancedJsonRpc\SuccessResponse::class, $msg->body);
|
||||||
$this->assertEquals((object)[
|
$this->assertEquals((object)[
|
||||||
'capabilities' => (object)[
|
'capabilities' => (object)[
|
||||||
|
|
|
@ -5,34 +5,22 @@ namespace LanguageServer\Tests;
|
||||||
|
|
||||||
use LanguageServer\{ProtocolReader, ProtocolWriter};
|
use LanguageServer\{ProtocolReader, ProtocolWriter};
|
||||||
use LanguageServer\Protocol\Message;
|
use LanguageServer\Protocol\Message;
|
||||||
|
use Sabre\Event\{Emitter, Promise};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A fake duplex protocol stream
|
* A fake duplex protocol stream
|
||||||
*/
|
*/
|
||||||
class MockProtocolStream implements ProtocolReader, ProtocolWriter
|
class MockProtocolStream extends Emitter implements ProtocolReader, ProtocolWriter
|
||||||
{
|
{
|
||||||
private $listener;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a Message to the client
|
* Sends a Message to the client
|
||||||
*
|
*
|
||||||
* @param Message $msg
|
* @param Message $msg
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function write(Message $msg)
|
public function write(Message $msg): Promise
|
||||||
{
|
{
|
||||||
if (isset($this->listener)) {
|
$this->emit('message', [Message::parse((string)$msg)]);
|
||||||
$listener = $this->listener;
|
return Promise\resolve(null);
|
||||||
$listener(Message::parse((string)$msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param callable $listener Is called with a Message object
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function onMessage(callable $listener)
|
|
||||||
{
|
|
||||||
$this->listener = $listener;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ class DefinitionCollectorTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testCollectsSymbols()
|
public function testCollectsSymbols()
|
||||||
{
|
{
|
||||||
$client = new LanguageClient(new MockProtocolStream());
|
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
|
||||||
$project = new Project($client);
|
$project = new Project($client);
|
||||||
$parser = new Parser;
|
$parser = new Parser;
|
||||||
$uri = pathToUri(realpath(__DIR__ . '/../../fixtures/symbols.php'));
|
$uri = pathToUri(realpath(__DIR__ . '/../../fixtures/symbols.php'));
|
||||||
|
@ -54,7 +54,7 @@ class DefinitionCollectorTest extends TestCase
|
||||||
|
|
||||||
public function testDoesNotCollectReferences()
|
public function testDoesNotCollectReferences()
|
||||||
{
|
{
|
||||||
$client = new LanguageClient(new MockProtocolStream());
|
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
|
||||||
$project = new Project($client);
|
$project = new Project($client);
|
||||||
$parser = new Parser;
|
$parser = new Parser;
|
||||||
$uri = pathToUri(realpath(__DIR__ . '/../../fixtures/references.php'));
|
$uri = pathToUri(realpath(__DIR__ . '/../../fixtures/references.php'));
|
||||||
|
|
|
@ -19,7 +19,7 @@ class PhpDocumentTest extends TestCase
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
$this->project = new Project(new LanguageClient(new MockProtocolStream()));
|
$this->project = new Project(new LanguageClient(new MockProtocolStream, new MockProtocolStream));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testParsesVariableVariables()
|
public function testParsesVariableVariables()
|
||||||
|
|
|
@ -19,7 +19,7 @@ class ProjectTest extends TestCase
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
$this->project = new Project(new LanguageClient(new MockProtocolStream()));
|
$this->project = new Project(new LanguageClient(new MockProtocolStream, new MockProtocolStream));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetDocumentLoadsDocument()
|
public function testGetDocumentLoadsDocument()
|
||||||
|
|
|
@ -18,7 +18,7 @@ class ProtocolStreamReaderTest extends TestCase
|
||||||
$writeHandle = fopen($tmpfile, 'w');
|
$writeHandle = fopen($tmpfile, 'w');
|
||||||
$reader = new ProtocolStreamReader(fopen($tmpfile, 'r'));
|
$reader = new ProtocolStreamReader(fopen($tmpfile, 'r'));
|
||||||
$msg = null;
|
$msg = null;
|
||||||
$reader->onMessage(function (Message $message) use (&$msg) {
|
$reader->on('message', function (Message $message) use (&$msg) {
|
||||||
$msg = $message;
|
$msg = $message;
|
||||||
});
|
});
|
||||||
$ret = fwrite($writeHandle, (string)new Message(new RequestBody(1, 'aMethod', ['arg' => 'Hello World'])));
|
$ret = fwrite($writeHandle, (string)new Message(new RequestBody(1, 'aMethod', ['arg' => 'Hello World'])));
|
||||||
|
|
|
@ -42,7 +42,7 @@ abstract class ServerTestCase extends TestCase
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
$client = new LanguageClient(new MockProtocolStream());
|
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
|
||||||
$this->project = new Project($client);
|
$this->project = new Project($client);
|
||||||
$this->textDocument = new Server\TextDocument($this->project, $client);
|
$this->textDocument = new Server\TextDocument($this->project, $client);
|
||||||
$this->workspace = new Server\Workspace($this->project, $client);
|
$this->workspace = new Server\Workspace($this->project, $client);
|
||||||
|
|
|
@ -12,7 +12,7 @@ class GlobalFallbackTest extends ServerTestCase
|
||||||
{
|
{
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
$client = new LanguageClient(new MockProtocolStream());
|
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
|
||||||
$project = new Project($client);
|
$project = new Project($client);
|
||||||
$this->textDocument = new Server\TextDocument($project, $client);
|
$this->textDocument = new Server\TextDocument($project, $client);
|
||||||
$project->openDocument('global_fallback', file_get_contents(__DIR__ . '/../../../../fixtures/global_fallback.php'));
|
$project->openDocument('global_fallback', file_get_contents(__DIR__ . '/../../../../fixtures/global_fallback.php'));
|
||||||
|
|
|
@ -19,7 +19,7 @@ class DidChangeTest extends TestCase
|
||||||
{
|
{
|
||||||
public function test()
|
public function test()
|
||||||
{
|
{
|
||||||
$client = new LanguageClient(new MockProtocolStream());
|
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
|
||||||
$project = new Project($client);
|
$project = new Project($client);
|
||||||
$textDocument = new Server\TextDocument($project, $client);
|
$textDocument = new Server\TextDocument($project, $client);
|
||||||
$phpDocument = $project->openDocument('whatever', "<?php\necho 'Hello, World'\n");
|
$phpDocument = $project->openDocument('whatever', "<?php\necho 'Hello, World'\n");
|
||||||
|
|
|
@ -13,7 +13,7 @@ class DidCloseTest extends TestCase
|
||||||
{
|
{
|
||||||
public function test()
|
public function test()
|
||||||
{
|
{
|
||||||
$client = new LanguageClient(new MockProtocolStream());
|
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
|
||||||
$project = new Project($client);
|
$project = new Project($client);
|
||||||
$textDocument = new Server\TextDocument($project, $client);
|
$textDocument = new Server\TextDocument($project, $client);
|
||||||
$phpDocument = $project->openDocument('whatever', 'hello world');
|
$phpDocument = $project->openDocument('whatever', 'hello world');
|
||||||
|
|
|
@ -18,14 +18,14 @@ class FormattingTest extends TestCase
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
$client = new LanguageClient(new MockProtocolStream());
|
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
|
||||||
$project = new Project($client);
|
$project = new Project($client);
|
||||||
$this->textDocument = new Server\TextDocument($project, $client);
|
$this->textDocument = new Server\TextDocument($project, $client);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFormatting()
|
public function testFormatting()
|
||||||
{
|
{
|
||||||
$client = new LanguageClient(new MockProtocolStream());
|
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
|
||||||
$project = new Project($client);
|
$project = new Project($client);
|
||||||
$textDocument = new Server\TextDocument($project, $client);
|
$textDocument = new Server\TextDocument($project, $client);
|
||||||
$path = realpath(__DIR__ . '/../../../fixtures/format.php');
|
$path = realpath(__DIR__ . '/../../../fixtures/format.php');
|
||||||
|
|
|
@ -5,8 +5,9 @@ namespace LanguageServer\Tests\Server\TextDocument;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use LanguageServer\Tests\MockProtocolStream;
|
use LanguageServer\Tests\MockProtocolStream;
|
||||||
use LanguageServer\{Server, Client, LanguageClient, Project};
|
use LanguageServer\{Server, Client, LanguageClient, Project, ClientHandler};
|
||||||
use LanguageServer\Protocol\{TextDocumentIdentifier, TextDocumentItem, DiagnosticSeverity};
|
use LanguageServer\Protocol\{TextDocumentIdentifier, TextDocumentItem, DiagnosticSeverity};
|
||||||
|
use Sabre\Event\Promise;
|
||||||
|
|
||||||
class ParseErrorsTest extends TestCase
|
class ParseErrorsTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -19,17 +20,18 @@ class ParseErrorsTest extends TestCase
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
$client = new LanguageClient(new MockProtocolStream());
|
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
|
||||||
$client->textDocument = new class($this->args) extends Client\TextDocument {
|
$client->textDocument = new class($this->args) extends Client\TextDocument {
|
||||||
private $args;
|
private $args;
|
||||||
public function __construct(&$args)
|
public function __construct(&$args)
|
||||||
{
|
{
|
||||||
parent::__construct(new MockProtocolStream());
|
parent::__construct(new ClientHandler(new MockProtocolStream, new MockProtocolStream));
|
||||||
$this->args = &$args;
|
$this->args = &$args;
|
||||||
}
|
}
|
||||||
public function publishDiagnostics(string $uri, array $diagnostics)
|
public function publishDiagnostics(string $uri, array $diagnostics): Promise
|
||||||
{
|
{
|
||||||
$this->args = func_get_args();
|
$this->args = func_get_args();
|
||||||
|
return Promise\resolve(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
$project = new Project($client);
|
$project = new Project($client);
|
||||||
|
|
|
@ -13,7 +13,7 @@ class GlobalFallbackTest extends ServerTestCase
|
||||||
{
|
{
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
$client = new LanguageClient(new MockProtocolStream());
|
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
|
||||||
$project = new Project($client);
|
$project = new Project($client);
|
||||||
$this->textDocument = new Server\TextDocument($project, $client);
|
$this->textDocument = new Server\TextDocument($project, $client);
|
||||||
$project->openDocument('global_fallback', file_get_contents(__DIR__ . '/../../../../fixtures/global_fallback.php'));
|
$project->openDocument('global_fallback', file_get_contents(__DIR__ . '/../../../../fixtures/global_fallback.php'));
|
||||||
|
|
Loading…
Reference in New Issue