1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Find properties and methods annotated by mixin

This commit is contained in:
Ivan Sidorov 2023-11-16 20:54:44 +00:00
parent 0c4b8a3c49
commit 8bb68e9b3f
2 changed files with 42 additions and 2 deletions

View File

@ -18,6 +18,7 @@ use PhpParser\Node\Arg;
use Psalm\CodeLocation\Raw;
use Psalm\Exception\UnanalyzedFileException;
use Psalm\Exception\UnpopulatedClasslikeException;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
@ -1867,13 +1868,24 @@ final class Codebase
}
/**
* @param list<int> $allow_visibilities
* @return list<CompletionItem>
*/
public function getCompletionItemsForClassishThing(
string $type_string,
string $gap,
bool $snippets_supported = false
bool $snippets_supported = false,
array $allow_visibilities = null
): array {
if ($allow_visibilities === null) {
$allow_visibilities = [
ClassLikeAnalyzer::VISIBILITY_PUBLIC,
ClassLikeAnalyzer::VISIBILITY_PROTECTED,
ClassLikeAnalyzer::VISIBILITY_PRIVATE,
];
}
$allow_visibilities[] = null;
$completion_items = [];
$type = Type::parseString($type_string);
@ -1895,6 +1907,9 @@ final class Codebase
}
foreach ($method_storages as $method_storage) {
if (!in_array($method_storage->visibility, $allow_visibilities)) {
continue;
}
if ($method_storage->is_static || $gap === '->') {
$completion_item = new CompletionItem(
$method_storage->cased_name,
@ -1957,6 +1972,9 @@ final class Codebase
$declaring_class . '::$' . $property_name,
);
if (!in_array($property_storage->visibility, $allow_visibilities)) {
continue;
}
if ($property_storage->is_static === ($gap === '::')) {
$completion_items[] = new CompletionItem(
$property_name,
@ -1981,6 +1999,18 @@ final class Codebase
$const_name,
);
}
if ($gap === '->') {
foreach ($class_storage->namedMixins as $mixin) {
$mixin_completion_items = $this->getCompletionItemsForClassishThing(
$mixin->value,
$gap,
$snippets_supported,
[ClassLikeAnalyzer::VISIBILITY_PUBLIC],
);
$completion_items = [...$completion_items, ...$mixin_completion_items];
}
}
} catch (Exception $e) {
error_log($e->getMessage());
continue;

View File

@ -538,7 +538,17 @@ final class MethodGetCompletionItemsForClassishThingTest extends TestCase
$actual_labels = $this->getCompletionLabels($content, 'B\A', $gap);
$expected_labels = [
'->' => [],
'->' => [
'magicObjProp1',
'magicObjProp2',
'magicObjMethod',
'publicObjProp',
'publicObjMethod',
'publicStaticMethod',
],
'::' => [],
];