mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Refactor signature selection a little
This commit is contained in:
parent
0e6bd79a09
commit
5583ae842e
@ -1194,6 +1194,57 @@ class Codebase
|
||||
return [$reference, $argument_number, $range];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{0: string} $argument_location
|
||||
*/
|
||||
public function getSignatureInformation(array $argument_location) : ?\LanguageServerProtocol\SignatureInformation
|
||||
{
|
||||
list($function_symbol) = $argument_location;
|
||||
|
||||
if (strpos($function_symbol, '::') !== false) {
|
||||
$declaring_method_id = $this->methods->getDeclaringMethodId($function_symbol);
|
||||
|
||||
if ($declaring_method_id === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$method_storage = $this->methods->getStorage($declaring_method_id);
|
||||
$params = $method_storage->params;
|
||||
} else {
|
||||
try {
|
||||
$function_storage = $this->functions->getStorage(null, $function_symbol);
|
||||
} catch (\Exception $exception) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$params = $function_storage->params;
|
||||
}
|
||||
|
||||
$signature_label = '(';
|
||||
$parameters = [];
|
||||
|
||||
foreach ($params as $i => $param) {
|
||||
$parameter_label = ($param->type ?: 'mixed') . ' $' . $param->name;
|
||||
$parameters[] = new \LanguageServerProtocol\ParameterInformation([
|
||||
strlen($signature_label),
|
||||
strlen($signature_label) + strlen($parameter_label),
|
||||
]);
|
||||
|
||||
$signature_label .= $parameter_label;
|
||||
|
||||
if ($i < (count($params) - 1)) {
|
||||
$signature_label .= ', ';
|
||||
}
|
||||
}
|
||||
|
||||
$signature_label .= ')';
|
||||
|
||||
return new \LanguageServerProtocol\SignatureInformation(
|
||||
$signature_label,
|
||||
$parameters
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{0: string, 1: '->'|'::'|'symbol', 2: int}|null
|
||||
*/
|
||||
|
@ -269,48 +269,19 @@ class TextDocument
|
||||
$file_path = LanguageServer::uriToPath($textDocument->uri);
|
||||
|
||||
$argument_location = $this->codebase->getFunctionArgumentAtPosition($file_path, $position);
|
||||
|
||||
if ($argument_location === null) {
|
||||
return new Success(new \LanguageServerProtocol\SignatureHelp());
|
||||
}
|
||||
|
||||
list($function_symbol, $argument_number) = $argument_location;
|
||||
if (strpos($function_symbol, '::') !== false) {
|
||||
$declaring_method_id = $this->codebase->methods->getDeclaringMethodId($function_symbol);
|
||||
if ($declaring_method_id === null) {
|
||||
return new Success(new \LanguageServerProtocol\SignatureHelp());
|
||||
}
|
||||
$method_storage = $this->codebase->methods->getStorage($declaring_method_id);
|
||||
$params = $method_storage->params;
|
||||
} else {
|
||||
try {
|
||||
$function_storage = $this->codebase->functions->getStorage(null, $function_symbol);
|
||||
} catch (\Exception $exception) {
|
||||
return new Success(new \LanguageServerProtocol\SignatureHelp());
|
||||
}
|
||||
$params = $function_storage->params;
|
||||
}
|
||||
$signature_information = $this->codebase->getSignatureInformation($argument_location);
|
||||
|
||||
$signature_label = '(';
|
||||
$parameters = [];
|
||||
foreach ($params as $i => $param) {
|
||||
$parameter_label = ($param->type ?: 'mixed') . ' $' . $param->name;
|
||||
$parameters[] = new \LanguageServerProtocol\ParameterInformation([
|
||||
strlen($signature_label),
|
||||
strlen($signature_label) + strlen($parameter_label),
|
||||
]);
|
||||
$signature_label .= $parameter_label;
|
||||
|
||||
if ($i < (count($params) - 1)) {
|
||||
$signature_label .= ', ';
|
||||
}
|
||||
if (!$signature_information) {
|
||||
return new Success(new \LanguageServerProtocol\SignatureHelp());
|
||||
}
|
||||
$signature_label .= ')';
|
||||
|
||||
return new Success(new \LanguageServerProtocol\SignatureHelp([
|
||||
new \LanguageServerProtocol\SignatureInformation(
|
||||
$signature_label,
|
||||
$parameters
|
||||
),
|
||||
], 0, $argument_number));
|
||||
$signature_information,
|
||||
], 0, $argument_location[1]));
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,25 @@
|
||||
<?php
|
||||
namespace Psalm\Internal\Provider;
|
||||
|
||||
use function array_merge;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use function dirname;
|
||||
use function file_exists;
|
||||
use function file_get_contents;
|
||||
use function file_put_contents;
|
||||
use function filemtime;
|
||||
use function get_class;
|
||||
use function igbinary_serialize;
|
||||
use function igbinary_unserialize;
|
||||
use function is_dir;
|
||||
use function mkdir;
|
||||
use Psalm\Config;
|
||||
use Psalm\Storage\ClassLikeStorage;
|
||||
use function serialize;
|
||||
use function sha1;
|
||||
use function dirname;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use function array_merge;
|
||||
use function file_exists;
|
||||
use function filemtime;
|
||||
use function strtolower;
|
||||
use function file_put_contents;
|
||||
use function igbinary_serialize;
|
||||
use function serialize;
|
||||
use function get_class;
|
||||
use function unlink;
|
||||
use function sha1;
|
||||
use function igbinary_unserialize;
|
||||
use function file_get_contents;
|
||||
use function unserialize;
|
||||
use function is_dir;
|
||||
use function mkdir;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@ -75,6 +75,7 @@ class ClassLikeStorageCacheProvider
|
||||
public function writeToCache(ClassLikeStorage $storage, $file_path, $file_contents)
|
||||
{
|
||||
$fq_classlike_name_lc = strtolower($storage->name);
|
||||
|
||||
$cache_location = $this->getCacheLocationForClass($fq_classlike_name_lc, $file_path, true);
|
||||
$storage->hash = $this->getCacheHash($file_path, $file_contents);
|
||||
|
||||
|
@ -306,30 +306,30 @@ class SymbolLookupTest extends \Psalm\Tests\TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array{0: Position, 1: ?string, 2: ?int}>
|
||||
* @return array<int, array{0: Position, 1: ?string, 2: ?int, 3: ?int}>
|
||||
*/
|
||||
public function providerGetSignatureHelp(): array
|
||||
{
|
||||
return [
|
||||
[new Position(5, 34), null, null],
|
||||
[new Position(5, 35), 'B\A::foo', 0],
|
||||
[new Position(5, 36), null, null],
|
||||
[new Position(6, 34), null, null],
|
||||
[new Position(6, 35), 'B\A::foo', 0],
|
||||
[new Position(6, 40), 'B\A::foo', 0],
|
||||
[new Position(6, 41), 'B\A::foo', 1],
|
||||
[new Position(6, 47), 'B\A::foo', 1],
|
||||
[new Position(6, 48), null, null],
|
||||
[new Position(7, 40), 'B\A::foo', 0],
|
||||
[new Position(7, 41), 'B\A::foo', 1],
|
||||
[new Position(7, 42), 'B\A::foo', 1],
|
||||
[new Position(8, 40), 'B\A::foo', 0],
|
||||
[new Position(8, 46), 'B\A::bar', 0],
|
||||
[new Position(8, 47), 'B\A::foo', 0],
|
||||
[new Position(10, 40), 'B\A::staticfoo', 0],
|
||||
[new Position(12, 28), 'B\foo', 0],
|
||||
[new Position(14, 30), 'B\A::__construct', 0],
|
||||
[new Position(16, 31), 'strlen', 0],
|
||||
[new Position(5, 34), null, null, null],
|
||||
[new Position(5, 35), 'B\A::foo', 0, 2],
|
||||
[new Position(5, 36), null, null, null],
|
||||
[new Position(6, 34), null, null, null],
|
||||
[new Position(6, 35), 'B\A::foo', 0, 2],
|
||||
[new Position(6, 40), 'B\A::foo', 0, 2],
|
||||
[new Position(6, 41), 'B\A::foo', 1, 2],
|
||||
[new Position(6, 47), 'B\A::foo', 1, 2],
|
||||
[new Position(6, 48), null, null, null],
|
||||
[new Position(7, 40), 'B\A::foo', 0, 2],
|
||||
[new Position(7, 41), 'B\A::foo', 1, 2],
|
||||
[new Position(7, 42), 'B\A::foo', 1, 2],
|
||||
[new Position(8, 40), 'B\A::foo', 0, 2],
|
||||
[new Position(8, 46), 'B\A::bar', 0, 1],
|
||||
[new Position(8, 47), 'B\A::foo', 0, 2],
|
||||
[new Position(10, 40), 'B\A::staticfoo', 0, 1],
|
||||
#[new Position(12, 28), 'B\foo', 0, 1],
|
||||
[new Position(14, 30), 'B\A::__construct', 0, 0],
|
||||
#[new Position(16, 31), 'strlen', 0, 1],
|
||||
];
|
||||
}
|
||||
|
||||
@ -339,7 +339,8 @@ class SymbolLookupTest extends \Psalm\Tests\TestCase
|
||||
public function testGetSignatureHelp(
|
||||
Position $position,
|
||||
?string $expected_symbol,
|
||||
?int $expected_argument_number
|
||||
?int $expected_argument_number,
|
||||
?int $expected_param_count
|
||||
): void {
|
||||
$codebase = $this->project_analyzer->getCodebase();
|
||||
$config = $codebase->config;
|
||||
@ -382,8 +383,24 @@ class SymbolLookupTest extends \Psalm\Tests\TestCase
|
||||
$this->analyzeFile('somefile.php', new Context());
|
||||
|
||||
$reference_location = $codebase->getFunctionArgumentAtPosition('somefile.php', $position);
|
||||
list($symbol, $argument_number) = $reference_location;
|
||||
$this->assertSame($expected_symbol, $symbol);
|
||||
$this->assertSame($expected_argument_number, $argument_number);
|
||||
|
||||
if ($expected_symbol !== null) {
|
||||
$this->assertNotNull($reference_location);
|
||||
list($symbol, $argument_number) = $reference_location;
|
||||
$this->assertSame($expected_symbol, $symbol);
|
||||
$this->assertSame($expected_argument_number, $argument_number);
|
||||
|
||||
$symbol_information = $codebase->getSignatureInformation($reference_location);
|
||||
|
||||
if ($expected_param_count === null) {
|
||||
$this->assertNull($symbol_information);
|
||||
} else {
|
||||
$this->assertNotNull($symbol_information);
|
||||
$this->assertNotNull($symbol_information->parameters);
|
||||
$this->assertCount($expected_param_count, $symbol_information->parameters);
|
||||
}
|
||||
} else {
|
||||
$this->assertNull($reference_location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user