1
0
Fork 0

added signature help

pull/250/head
Ivan Bozhanov 2017-01-19 20:33:31 +02:00
parent ddf8274879
commit f9240cd2be
6 changed files with 127 additions and 2 deletions

View File

@ -55,9 +55,13 @@ class TestClass implements TestInterface
* @param TestClass $testParameter Lorem sunt velit incididunt mollit
* @return TestClass
*/
public function testMethod($testParameter): TestInterface
public function testMethod(
string $testParameter = '()',
string $asdf = ","
) : TestInterface
{
$this->testProperty = $testParameter;
$this->testMethod();
}
}

View File

@ -89,4 +89,11 @@ class Definition
* @var string
*/
public $documentation;
/**
* Parameters array (for methods and functions), for use in textDocument/signatureHelp
*
* @var string[]
*/
public $parameters;
}

View File

@ -131,6 +131,12 @@ class DefinitionResolver
$def->type = $this->getTypeFromNode($node);
$def->declarationLine = $this->getDeclarationLineFromNode($node);
$def->documentation = $this->getDocumentationFromNode($node);
$def->parameters = [];
if ($node instanceof Node\FunctionLike) {
foreach ($node->getParams() as $param) {
$def->parameters[] = $this->prettyPrinter->prettyPrint([$param]);
}
}
return $def;
}

View File

@ -247,6 +247,9 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
$serverCapabilities->completionProvider = new CompletionOptions;
$serverCapabilities->completionProvider->resolveProvider = false;
$serverCapabilities->completionProvider->triggerCharacters = ['$', '>'];
// Support "Signature Help"
$serverCapabilities->signatureHelpProvider = new SignatureHelpOptions;
$serverCapabilities->signatureHelpProvider->triggerCharacters = ['('];
// Support global references
$serverCapabilities->xworkspaceReferencesProvider = true;
$serverCapabilities->xdefinitionProvider = true;

View File

@ -5,7 +5,7 @@ namespace LanguageServer\Server;
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
use PhpParser\{Node, NodeTraverser};
use LanguageServer\{LanguageClient, PhpDocumentLoader, PhpDocument, DefinitionResolver, CompletionProvider};
use LanguageServer\{LanguageClient, PhpDocumentLoader, PhpDocument, DefinitionResolver, CompletionProvider, SignatureHelpProvider};
use LanguageServer\NodeVisitor\VariableReferencesCollector;
use LanguageServer\Protocol\{
SymbolLocationInformation,
@ -63,6 +63,11 @@ class TextDocument
*/
protected $completionProvider;
/**
* @var SignatureHelpProvider
*/
protected $signatureHelpProvider;
/**
* @var ReadableIndex
*/
@ -99,6 +104,7 @@ class TextDocument
$this->prettyPrinter = new PrettyPrinter();
$this->definitionResolver = $definitionResolver;
$this->completionProvider = new CompletionProvider($this->definitionResolver, $index);
$this->signatureHelpProvider = new SignatureHelpProvider($this->definitionResolver, $index);
$this->index = $index;
$this->composerJson = $composerJson;
$this->composerLock = $composerLock;
@ -343,6 +349,14 @@ class TextDocument
});
}
public function signatureHelp(TextDocumentIdentifier $textDocument, Position $position): Promise
{
return coroutine(function () use ($textDocument, $position) {
$document = yield $this->documentLoader->getOrLoad($textDocument->uri);
return $this->signatureHelpProvider->provideSignature($document, $position);
});
}
/**
* This method is the same as textDocument/definition, except that
*

View File

@ -0,0 +1,91 @@
<?php
declare(strict_types = 1);
namespace LanguageServer;
use PhpParser\Node;
use LanguageServer\Index\ReadableIndex;
use LanguageServer\Protocol\{
Position,
SignatureHelp,
SignatureInformation,
ParameterInformation
};
class SignatureHelpProvider
{
/**
* @var DefinitionResolver
*/
private $definitionResolver;
/**
* @var ReadableIndex
*/
private $index;
/**
* @param DefinitionResolver $definitionResolver
* @param ReadableIndex $index
*/
public function __construct(DefinitionResolver $definitionResolver, ReadableIndex $index)
{
$this->definitionResolver = $definitionResolver;
$this->index = $index;
}
/**
* Returns signature help for a specific cursor position in a document
*
* @param PhpDocument $doc The opened document
* @param Position $pos The cursor position
* @return SignatureHelp
*/
public function provideSignature(PhpDocument $doc, Position $pos): SignatureHelp
{
$node = $doc->getNodeAtPosition($pos);
$help = new SignatureHelp;
$help->signatures = [];
if ($node instanceof Node\Expr\FuncCall) {
if ($def = $this->definitionResolver->resolveReferenceNodeToDefinition($node)) {
$signature = new SignatureInformation;
$signature->label = str_replace('()', '', $def->fqn);
$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) {
if ($def = $this->definitionResolver->resolveReferenceNodeToDefinition($node)) {
$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) {
$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;
}
}