93 lines
2.6 KiB
PHP
93 lines
2.6 KiB
PHP
|
<?php
|
||
|
declare(strict_types = 1);
|
||
|
|
||
|
namespace LanguageServer;
|
||
|
|
||
|
use Microsoft\PhpParser\Node\DelimitedList\ArgumentExpressionList;
|
||
|
use Microsoft\PhpParser\Node\Expression\CallExpression;
|
||
|
use LanguageServer\Index\ReadableIndex;
|
||
|
use LanguageServer\Protocol\{
|
||
|
Range,
|
||
|
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);
|
||
|
while ($node &&
|
||
|
!($node instanceof ArgumentExpressionList) &&
|
||
|
!($node instanceof CallExpression) &&
|
||
|
$node->parent
|
||
|
) {
|
||
|
$node = $node->parent;
|
||
|
}
|
||
|
if (!($node instanceof ArgumentExpressionList) &&
|
||
|
!($node instanceof CallExpression)
|
||
|
) {
|
||
|
return new SignatureHelp;
|
||
|
}
|
||
|
$count = 0;
|
||
|
if ($node instanceof ArgumentExpressionList) {
|
||
|
foreach ($node->getElements() as $param) {
|
||
|
$count ++;
|
||
|
}
|
||
|
while ($node && !($node instanceof CallExpression) && $node->parent) {
|
||
|
$node = $node->parent;
|
||
|
}
|
||
|
if (!($node instanceof CallExpression)) {
|
||
|
return new SignatureHelp;
|
||
|
}
|
||
|
}
|
||
|
$def = $this->definitionResolver->resolveReferenceNodeToDefinition($node->callableExpression);
|
||
|
if (!$def) {
|
||
|
return new SignatureHelp;
|
||
|
}
|
||
|
$params = array_map(function ($v) {
|
||
|
return $v->label;
|
||
|
}, $def->parameters);
|
||
|
return new SignatureHelp(
|
||
|
[
|
||
|
new SignatureInformation(
|
||
|
trim(str_replace(['public', 'protected', 'private', 'function', 'static'], '', $def->declarationLine)),
|
||
|
$def->documentation,
|
||
|
$def->parameters
|
||
|
)
|
||
|
],
|
||
|
0,
|
||
|
$count < count($def->parameters) ? $count : null
|
||
|
);
|
||
|
}
|
||
|
}
|