Skip to content

Commit

Permalink
feat: Signature help (#547)
Browse files Browse the repository at this point in the history
closes #18
  • Loading branch information
phil-nelson authored and felixfbecker committed Dec 10, 2017
1 parent 7831654 commit a40cf73
Show file tree
Hide file tree
Showing 70 changed files with 1,183 additions and 161 deletions.
66 changes: 66 additions & 0 deletions fixtures/signature_help/calls.php
@@ -0,0 +1,66 @@
<?php

namespace Foo;

class Test
{
/**
* Constructor comment goes here
*
* @param string $first First param
* @param int $second Second param
* @param Test $third Third param with a longer description
*/
public function __construct(string $first, int $second, Test $third)
{
}

/**
* Function doc
*
* @param SomethingElse $a A param with a different doc type
* @param int|null $b Param with default value
*/
public function foo(\DateTime $a, int $b = null)
{
}

public static function bar($a)
{
}

/**
* Method with no params
*/
public function baz()
{
}
}

/**
* @param int $i Global function param one
* @param bool $b Default false param
* @param Test|null ...$things Test things
*/
function foo(int $i, bool $b = false, Test ...$things = null)
{
}

$t = new Test();
$t = new Test(1, );
$t->foo();
$t->foo(1,
$t->foo(1,);
$t->baz();

foo(
1,
foo(1, 2,
);

Test::bar();

new $foo();
new $foo(1, );

new NotExist();
7 changes: 7 additions & 0 deletions src/Definition.php
Expand Up @@ -99,6 +99,13 @@ class Definition
*/
public $documentation;

/**
* Signature information if this definition is for a FunctionLike, for use in textDocument/signatureHelp
*
* @var SignatureInformation
*/
public $signatureInformation;

/**
* Yields the definitons of all ancestor classes (the Definition fqn is yielded as key)
*
Expand Down
13 changes: 13 additions & 0 deletions src/DefinitionResolver.php
Expand Up @@ -7,6 +7,7 @@
use LanguageServer\Protocol\SymbolInformation;
use Microsoft\PhpParser;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\FunctionLike;
use phpDocumentor\Reflection\{
DocBlock, DocBlockFactory, Fqsen, Type, TypeResolver, Types
};
Expand Down Expand Up @@ -34,6 +35,13 @@ class DefinitionResolver
*/
private $docBlockFactory;

/**
* Creates SignatureInformation
*
* @var SignatureInformationFactory
*/
private $signatureInformationFactory;

/**
* @param ReadableIndex $index
*/
Expand All @@ -42,6 +50,7 @@ public function __construct(ReadableIndex $index)
$this->index = $index;
$this->typeResolver = new TypeResolver;
$this->docBlockFactory = DocBlockFactory::createInstance();
$this->signatureInformationFactory = new SignatureInformationFactory($this);
}

/**
Expand Down Expand Up @@ -232,6 +241,10 @@ public function createDefinitionFromNode(Node $node, string $fqn = null): Defini
$def->documentation = $this->getDocumentationFromNode($node);
}

if ($node instanceof FunctionLike) {
$def->signatureInformation = $this->signatureInformationFactory->create($node);
}

return $def;
}

Expand Down
7 changes: 6 additions & 1 deletion src/LanguageServer.php
Expand Up @@ -9,7 +9,8 @@
TextDocumentSyncKind,
Message,
InitializeResult,
CompletionOptions
CompletionOptions,
SignatureHelpOptions
};
use LanguageServer\FilesFinder\{FilesFinder, ClientFilesFinder, FileSystemFilesFinder};
use LanguageServer\ContentRetriever\{ContentRetriever, ClientContentRetriever, FileSystemContentRetriever};
Expand Down Expand Up @@ -275,6 +276,10 @@ public function initialize(ClientCapabilities $capabilities, string $rootPath =
$serverCapabilities->completionProvider = new CompletionOptions;
$serverCapabilities->completionProvider->resolveProvider = false;
$serverCapabilities->completionProvider->triggerCharacters = ['$', '>'];

$serverCapabilities->signatureHelpProvider = new SignatureHelpOptions();
$serverCapabilities->signatureHelpProvider->triggerCharacters = ['(', ','];

// Support global references
$serverCapabilities->xworkspaceReferencesProvider = true;
$serverCapabilities->xdefinitionProvider = true;
Expand Down
13 changes: 13 additions & 0 deletions src/Protocol/ParameterInformation.php
Expand Up @@ -23,4 +23,17 @@ class ParameterInformation
* @var string|null
*/
public $documentation;

/**
* Create ParameterInformation
*
* @param string $label The label of this signature. Will be shown in the UI.
* @param string $documentation The human-readable doc-comment of this signature. Will be shown in the UI but can
* be omitted.
*/
public function __construct(string $label, string $documentation = null)
{
$this->label = $label;
$this->documentation = $documentation;
}
}
14 changes: 14 additions & 0 deletions src/Protocol/SignatureHelp.php
Expand Up @@ -29,4 +29,18 @@ class SignatureHelp
* @var int|null
*/
public $activeParameter;

/**
* Create a SignatureHelp
*
* @param SignatureInformation[] $signatures List of signature information
* @param int|null $activeSignature The active signature, zero based
* @param int|null $activeParameter The active parameter, zero based
*/
public function __construct(array $signatures = [], $activeSignature = null, int $activeParameter = null)
{
$this->signatures = $signatures;
$this->activeSignature = $activeSignature;
$this->activeParameter = $activeParameter;
}
}
15 changes: 15 additions & 0 deletions src/Protocol/SignatureInformation.php
Expand Up @@ -31,4 +31,19 @@ class SignatureInformation
* @var ParameterInformation[]|null
*/
public $parameters;

/**
* Create a SignatureInformation
*
* @param string $label The label of this signature. Will be shown in the UI.
* @param ParameterInformation[]|null The parameters of this signature
* @param string|null The human-readable doc-comment of this signature. Will be shown in the UI
* but can be omitted.
*/
public function __construct(string $label, array $parameters = null, string $documentation = null)
{
$this->label = $label;
$this->parameters = $parameters;
$this->documentation = $documentation;
}
}
25 changes: 24 additions & 1 deletion src/Server/TextDocument.php
Expand Up @@ -4,7 +4,7 @@
namespace LanguageServer\Server;

use LanguageServer\{
CompletionProvider, LanguageClient, PhpDocument, PhpDocumentLoader, DefinitionResolver
CompletionProvider, SignatureHelpProvider, LanguageClient, PhpDocument, PhpDocumentLoader, DefinitionResolver
};
use LanguageServer\Index\ReadableIndex;
use LanguageServer\Protocol\{
Expand Down Expand Up @@ -59,6 +59,11 @@ class TextDocument
*/
protected $completionProvider;

/**
* @var SignatureHelpProvider
*/
protected $signatureHelpProvider;

/**
* @var ReadableIndex
*/
Expand Down Expand Up @@ -94,6 +99,7 @@ public function __construct(
$this->client = $client;
$this->definitionResolver = $definitionResolver;
$this->completionProvider = new CompletionProvider($this->definitionResolver, $index);
$this->signatureHelpProvider = new SignatureHelpProvider($this->definitionResolver, $index, $documentLoader);
$this->index = $index;
$this->composerJson = $composerJson;
$this->composerLock = $composerLock;
Expand Down Expand Up @@ -237,6 +243,23 @@ public function references(
});
}

/**
* The signature help request is sent from the client to the server to request signature information at a given
* cursor position.
*
* @param TextDocumentIdentifier $textDocument The text document
* @param Position $position The position inside the text document
*
* @return Promise <SignatureHelp>
*/
public function signatureHelp(TextDocumentIdentifier $textDocument, Position $position): Promise
{
return coroutine(function () use ($textDocument, $position) {
$document = yield $this->documentLoader->getOrLoad($textDocument->uri);
return $this->signatureHelpProvider->getSignatureHelp($document, $position);
});
}

/**
* The goto definition request is sent from the client to the server to resolve the definition location of a symbol
* at a given text document position.
Expand Down

0 comments on commit a40cf73

Please sign in to comment.