added tests
parent
67be71a847
commit
1e109a32d6
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function helpFunc1(int $count = 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
helpFunc1()
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function helpFunc2(int $count = 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
helpFunc2(
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class HelpClass1
|
||||||
|
{
|
||||||
|
protected function method(string $param = "")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public function test()
|
||||||
|
{
|
||||||
|
$this->method();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class HelpClass2
|
||||||
|
{
|
||||||
|
protected function method(string $param = "")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public function test()
|
||||||
|
{
|
||||||
|
$this->method(
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class HelpClass3
|
||||||
|
{
|
||||||
|
public static function method(string $param = "")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelpClass3::method()
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class HelpClass4
|
||||||
|
{
|
||||||
|
public static function method(string $param = "")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelpClass4::method(
|
|
@ -43,10 +43,44 @@ class SignatureHelpProvider
|
||||||
*/
|
*/
|
||||||
public function provideSignature(PhpDocument $doc, Position $pos): SignatureHelp
|
public function provideSignature(PhpDocument $doc, Position $pos): SignatureHelp
|
||||||
{
|
{
|
||||||
$node = $doc->getNodeAtPosition($pos);
|
|
||||||
$help = new SignatureHelp;
|
$help = new SignatureHelp;
|
||||||
$help->signatures = [];
|
$help->signatures = [];
|
||||||
|
|
||||||
|
$newPos = clone $pos;
|
||||||
|
$line = explode("\n", $doc->getContent())[$newPos->line];
|
||||||
|
do {
|
||||||
|
$newPos->character --;
|
||||||
|
} while ($newPos->character > 0 && $line[$newPos->character] !== "(");
|
||||||
|
|
||||||
|
if (!$newPos->character) {
|
||||||
|
return $help;
|
||||||
|
}
|
||||||
|
$line = substr($line, 0, $newPos->character);
|
||||||
|
|
||||||
|
//echo $line . "\n";
|
||||||
|
//die();
|
||||||
|
$newPos->character --;
|
||||||
|
|
||||||
|
$node = $doc->getNodeAtPosition($newPos);
|
||||||
|
|
||||||
|
if ($node instanceof Node\Expr\Error) {
|
||||||
|
$node = $node->getAttribute('parentNode');
|
||||||
|
}
|
||||||
|
|
||||||
|
//echo get_class($node);
|
||||||
|
//die();
|
||||||
|
//$def = $this->definitionResolver->resolveReferenceNodeToDefinition($node->var);
|
||||||
|
//var_dump($def);
|
||||||
|
//echo $def->fqn;
|
||||||
|
|
||||||
|
//echo $node->name;
|
||||||
|
|
||||||
|
|
||||||
|
//die();
|
||||||
|
|
||||||
|
if ($node instanceof Node\Expr\Error) {
|
||||||
|
$node = $node->getAttribute('parentNode');
|
||||||
|
}
|
||||||
if ($node instanceof Node\Expr\FuncCall) {
|
if ($node instanceof Node\Expr\FuncCall) {
|
||||||
if ($def = $this->definitionResolver->resolveReferenceNodeToDefinition($node)) {
|
if ($def = $this->definitionResolver->resolveReferenceNodeToDefinition($node)) {
|
||||||
$signature = new SignatureInformation;
|
$signature = new SignatureInformation;
|
||||||
|
@ -60,6 +94,22 @@ class SignatureHelpProvider
|
||||||
}
|
}
|
||||||
$help->signatures[] = $signature;
|
$help->signatures[] = $signature;
|
||||||
}
|
}
|
||||||
|
} else if ($node instanceof Node\Name\FullyQualified || $node === null) {
|
||||||
|
if (preg_match('([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$)', $line, $method)) {
|
||||||
|
$fqn = $method[0] . '()';
|
||||||
|
if ($def = $this->index->getDefinition($fqn)) {
|
||||||
|
$signature = new SignatureInformation;
|
||||||
|
$signature->label = $method[0];
|
||||||
|
$signature->documentation = $def->documentation;
|
||||||
|
$signature->parameters = [];
|
||||||
|
foreach ($def->parameters as $param) {
|
||||||
|
$p = new ParameterInformation;
|
||||||
|
$p->label = $param;
|
||||||
|
$signature->parameters[] = $p;
|
||||||
|
}
|
||||||
|
$help->signatures[] = $signature;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if ($node instanceof Node\Expr\MethodCall) {
|
} else if ($node instanceof Node\Expr\MethodCall) {
|
||||||
if ($def = $this->definitionResolver->resolveReferenceNodeToDefinition($node)) {
|
if ($def = $this->definitionResolver->resolveReferenceNodeToDefinition($node)) {
|
||||||
$signature = new SignatureInformation;
|
$signature = new SignatureInformation;
|
||||||
|
@ -73,7 +123,27 @@ class SignatureHelpProvider
|
||||||
}
|
}
|
||||||
$help->signatures[] = $signature;
|
$help->signatures[] = $signature;
|
||||||
}
|
}
|
||||||
|
} else if ($node instanceof Node\Expr\PropertyFetch) {
|
||||||
|
if ($def = $this->definitionResolver->resolveReferenceNodeToDefinition($node->var)) {
|
||||||
|
$method = trim(substr($line, strrpos($line, ">") + 1));
|
||||||
|
if ($method) {
|
||||||
|
$fqn = $def->fqn . '->' . $method . '()';
|
||||||
|
if ($def = $this->index->getDefinition($fqn)) {
|
||||||
|
$signature = new SignatureInformation;
|
||||||
|
$signature->label = str_replace('()', '', explode('->', $def->fqn)[1]);
|
||||||
|
$signature->documentation = $def->documentation;
|
||||||
|
$signature->parameters = [];
|
||||||
|
foreach ($def->parameters as $param) {
|
||||||
|
$p = new ParameterInformation;
|
||||||
|
$p->label = $param;
|
||||||
|
$signature->parameters[] = $p;
|
||||||
|
}
|
||||||
|
$help->signatures[] = $signature;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if ($node instanceof Node\Expr\StaticCall) {
|
} else if ($node instanceof Node\Expr\StaticCall) {
|
||||||
|
if ($def = $this->definitionResolver->resolveReferenceNodeToDefinition($node)) {
|
||||||
$signature = new SignatureInformation;
|
$signature = new SignatureInformation;
|
||||||
$signature->label = str_replace('()', '', explode('::', $def->fqn)[1]);
|
$signature->label = str_replace('()', '', explode('::', $def->fqn)[1]);
|
||||||
$signature->documentation = $def->documentation;
|
$signature->documentation = $def->documentation;
|
||||||
|
@ -85,6 +155,26 @@ class SignatureHelpProvider
|
||||||
}
|
}
|
||||||
$help->signatures[] = $signature;
|
$help->signatures[] = $signature;
|
||||||
}
|
}
|
||||||
|
} else if ($node instanceof Node\Expr\ClassConstFetch) {
|
||||||
|
if ($def = $this->definitionResolver->resolveReferenceNodeToDefinition($node->class)) {
|
||||||
|
$method = trim(substr($line, strrpos($line, ":") + 1));
|
||||||
|
if ($method) {
|
||||||
|
$fqn = $def->fqn . '::' . $method . '()';
|
||||||
|
if ($def = $this->index->getDefinition($fqn)) {
|
||||||
|
$signature = new SignatureInformation;
|
||||||
|
$signature->label = str_replace('()', '', explode('::', $def->fqn)[1]);
|
||||||
|
$signature->documentation = $def->documentation;
|
||||||
|
$signature->parameters = [];
|
||||||
|
foreach ($def->parameters as $param) {
|
||||||
|
$p = new ParameterInformation;
|
||||||
|
$p->label = $param;
|
||||||
|
$signature->parameters[] = $p;
|
||||||
|
}
|
||||||
|
$help->signatures[] = $signature;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $help;
|
return $help;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,8 @@ use LanguageServer\Protocol\{
|
||||||
TextDocumentIdentifier,
|
TextDocumentIdentifier,
|
||||||
InitializeResult,
|
InitializeResult,
|
||||||
ServerCapabilities,
|
ServerCapabilities,
|
||||||
CompletionOptions
|
CompletionOptions,
|
||||||
|
SignatureHelpOptions
|
||||||
};
|
};
|
||||||
use AdvancedJsonRpc;
|
use AdvancedJsonRpc;
|
||||||
use Webmozart\Glob\Glob;
|
use Webmozart\Glob\Glob;
|
||||||
|
@ -41,6 +42,8 @@ class LanguageServerTest extends TestCase
|
||||||
$serverCapabilities->completionProvider = new CompletionOptions;
|
$serverCapabilities->completionProvider = new CompletionOptions;
|
||||||
$serverCapabilities->completionProvider->resolveProvider = false;
|
$serverCapabilities->completionProvider->resolveProvider = false;
|
||||||
$serverCapabilities->completionProvider->triggerCharacters = ['$', '>'];
|
$serverCapabilities->completionProvider->triggerCharacters = ['$', '>'];
|
||||||
|
$serverCapabilities->signatureHelpProvider = new SignatureHelpOptions;
|
||||||
|
$serverCapabilities->signatureHelpProvider->triggerCharacters = ['('];
|
||||||
$serverCapabilities->xworkspaceReferencesProvider = true;
|
$serverCapabilities->xworkspaceReferencesProvider = true;
|
||||||
$serverCapabilities->xdefinitionProvider = true;
|
$serverCapabilities->xdefinitionProvider = true;
|
||||||
$serverCapabilities->xdependenciesProvider = true;
|
$serverCapabilities->xdependenciesProvider = true;
|
||||||
|
@ -57,7 +60,7 @@ class LanguageServerTest extends TestCase
|
||||||
if ($msg->body->method === 'window/logMessage' && $promise->state === Promise::PENDING) {
|
if ($msg->body->method === 'window/logMessage' && $promise->state === Promise::PENDING) {
|
||||||
if ($msg->body->params->type === MessageType::ERROR) {
|
if ($msg->body->params->type === MessageType::ERROR) {
|
||||||
$promise->reject(new Exception($msg->body->params->message));
|
$promise->reject(new Exception($msg->body->params->message));
|
||||||
} else if (strpos($msg->body->params->message, 'All 25 PHP files parsed') !== false) {
|
} else if (strpos($msg->body->params->message, 'All 33 PHP files parsed') !== false) {
|
||||||
$promise->fulfill();
|
$promise->fulfill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +106,7 @@ class LanguageServerTest extends TestCase
|
||||||
if ($promise->state === Promise::PENDING) {
|
if ($promise->state === Promise::PENDING) {
|
||||||
$promise->reject(new Exception($msg->body->params->message));
|
$promise->reject(new Exception($msg->body->params->message));
|
||||||
}
|
}
|
||||||
} else if (strpos($msg->body->params->message, 'All 25 PHP files parsed') !== false) {
|
} else if (strpos($msg->body->params->message, 'All 33 PHP files parsed') !== false) {
|
||||||
if ($run === 1) {
|
if ($run === 1) {
|
||||||
$run++;
|
$run++;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace LanguageServer\Tests\Server\TextDocument;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use LanguageServer\Tests\MockProtocolStream;
|
||||||
|
use LanguageServer\{Server, LanguageClient, PhpDocumentLoader, CompletionProvider, DefinitionResolver};
|
||||||
|
use LanguageServer\Index\{Index, ProjectIndex, DependenciesIndex, GlobalIndex, StubsIndex};
|
||||||
|
use LanguageServer\ContentRetriever\FileSystemContentRetriever;
|
||||||
|
use LanguageServer\Protocol\{
|
||||||
|
TextDocumentIdentifier,
|
||||||
|
TextEdit,
|
||||||
|
Range,
|
||||||
|
Position,
|
||||||
|
ClientCapabilities,
|
||||||
|
SignatureHelp,
|
||||||
|
SignatureInformation,
|
||||||
|
ParameterInformation
|
||||||
|
};
|
||||||
|
use function LanguageServer\pathToUri;
|
||||||
|
|
||||||
|
class SignatureHelpTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Server\TextDocument
|
||||||
|
*/
|
||||||
|
private $textDocument;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var PhpDocumentLoader
|
||||||
|
*/
|
||||||
|
private $loader;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$client = new LanguageClient(new MockProtocolStream, new MockProtocolStream);
|
||||||
|
$projectIndex = new ProjectIndex(new Index, new DependenciesIndex);
|
||||||
|
$definitionResolver = new DefinitionResolver($projectIndex);
|
||||||
|
$contentRetriever = new FileSystemContentRetriever;
|
||||||
|
$this->loader = new PhpDocumentLoader($contentRetriever, $projectIndex, $definitionResolver);
|
||||||
|
$this->loader->load(pathToUri(__DIR__ . '/../../../fixtures/global_symbols.php'))->wait();
|
||||||
|
$this->loader->load(pathToUri(__DIR__ . '/../../../fixtures/symbols.php'))->wait();
|
||||||
|
$this->textDocument = new Server\TextDocument($this->loader, $definitionResolver, $client, $projectIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMethodClosed()
|
||||||
|
{
|
||||||
|
$completionUri = pathToUri(__DIR__ . '/../../../fixtures/signatureHelp/methodClosed.php');
|
||||||
|
$this->loader->open($completionUri, file_get_contents($completionUri));
|
||||||
|
$result = $this->textDocument->signatureHelp(
|
||||||
|
new TextDocumentIdentifier($completionUri),
|
||||||
|
new Position(9, 22)
|
||||||
|
)->wait();
|
||||||
|
|
||||||
|
$help = new SignatureHelp;
|
||||||
|
$help->signatures = [];
|
||||||
|
$info = new SignatureInformation;
|
||||||
|
$help->signatures[] = $info;
|
||||||
|
$info->label = 'method';
|
||||||
|
$info->parameters = [];
|
||||||
|
$param = new ParameterInformation;
|
||||||
|
$info->parameters[] = $param;
|
||||||
|
$param->label = 'string $param = ""';
|
||||||
|
|
||||||
|
$this->assertEquals($help, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMethodNotClosed()
|
||||||
|
{
|
||||||
|
$completionUri = pathToUri(__DIR__ . '/../../../fixtures/signatureHelp/methodNotClosed.php');
|
||||||
|
$this->loader->open($completionUri, file_get_contents($completionUri));
|
||||||
|
$result = $this->textDocument->signatureHelp(
|
||||||
|
new TextDocumentIdentifier($completionUri),
|
||||||
|
new Position(9, 22)
|
||||||
|
)->wait();
|
||||||
|
|
||||||
|
$help = new SignatureHelp;
|
||||||
|
$help->signatures = [];
|
||||||
|
$info = new SignatureInformation;
|
||||||
|
$help->signatures[] = $info;
|
||||||
|
$info->label = 'method';
|
||||||
|
$info->parameters = [];
|
||||||
|
$param = new ParameterInformation;
|
||||||
|
$info->parameters[] = $param;
|
||||||
|
$param->label = 'string $param = ""';
|
||||||
|
|
||||||
|
$this->assertEquals($help, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function funcClosed()
|
||||||
|
{
|
||||||
|
$completionUri = pathToUri(__DIR__ . '/../../../fixtures/signatureHelp/funcClosed.php');
|
||||||
|
$this->loader->open($completionUri, file_get_contents($completionUri));
|
||||||
|
$result = $this->textDocument->signatureHelp(
|
||||||
|
new TextDocumentIdentifier($completionUri),
|
||||||
|
new Position(5, 10)
|
||||||
|
)->wait();
|
||||||
|
|
||||||
|
$help = new SignatureHelp;
|
||||||
|
$help->signatures = [];
|
||||||
|
$info = new SignatureInformation;
|
||||||
|
$help->signatures[] = $info;
|
||||||
|
$info->label = 'helpFunc1';
|
||||||
|
$info->parameters = [];
|
||||||
|
$param = new ParameterInformation;
|
||||||
|
$info->parameters[] = $param;
|
||||||
|
$param->label = 'int $count = 0';
|
||||||
|
|
||||||
|
$this->assertEquals($help, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function funcNotClosed()
|
||||||
|
{
|
||||||
|
$completionUri = pathToUri(__DIR__ . '/../../../fixtures/signatureHelp/funcNotClosed.php');
|
||||||
|
$this->loader->open($completionUri, file_get_contents($completionUri));
|
||||||
|
$result = $this->textDocument->signatureHelp(
|
||||||
|
new TextDocumentIdentifier($completionUri),
|
||||||
|
new Position(5, 10)
|
||||||
|
)->wait();
|
||||||
|
|
||||||
|
$help = new SignatureHelp;
|
||||||
|
$help->signatures = [];
|
||||||
|
$info = new SignatureInformation;
|
||||||
|
$help->signatures[] = $info;
|
||||||
|
$info->label = 'helpFunc2';
|
||||||
|
$info->parameters = [];
|
||||||
|
$param = new ParameterInformation;
|
||||||
|
$info->parameters[] = $param;
|
||||||
|
$param->label = 'int $count = 0';
|
||||||
|
|
||||||
|
$this->assertEquals($help, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function staticClosed()
|
||||||
|
{
|
||||||
|
$completionUri = pathToUri(__DIR__ . '/../../../fixtures/signatureHelp/staticClosed.php');
|
||||||
|
$this->loader->open($completionUri, file_get_contents($completionUri));
|
||||||
|
$result = $this->textDocument->signatureHelp(
|
||||||
|
new TextDocumentIdentifier($completionUri),
|
||||||
|
new Position(9, 19)
|
||||||
|
)->wait();
|
||||||
|
|
||||||
|
$help = new SignatureHelp;
|
||||||
|
$help->signatures = [];
|
||||||
|
$info = new SignatureInformation;
|
||||||
|
$help->signatures[] = $info;
|
||||||
|
$info->label = 'method';
|
||||||
|
$info->parameters = [];
|
||||||
|
$param = new ParameterInformation;
|
||||||
|
$info->parameters[] = $param;
|
||||||
|
$param->label = 'string $param = ""';
|
||||||
|
|
||||||
|
$this->assertEquals($help, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function staticNotClosed()
|
||||||
|
{
|
||||||
|
$completionUri = pathToUri(__DIR__ . '/../../../fixtures/signatureHelp/staticNotClosed.php');
|
||||||
|
$this->loader->open($completionUri, file_get_contents($completionUri));
|
||||||
|
$result = $this->textDocument->signatureHelp(
|
||||||
|
new TextDocumentIdentifier($completionUri),
|
||||||
|
new Position(9, 19)
|
||||||
|
)->wait();
|
||||||
|
|
||||||
|
$help = new SignatureHelp;
|
||||||
|
$help->signatures = [];
|
||||||
|
$info = new SignatureInformation;
|
||||||
|
$help->signatures[] = $info;
|
||||||
|
$info->label = 'method';
|
||||||
|
$info->parameters = [];
|
||||||
|
$param = new ParameterInformation;
|
||||||
|
$info->parameters[] = $param;
|
||||||
|
$param->label = 'string $param = ""';
|
||||||
|
|
||||||
|
$this->assertEquals($help, $result);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue