Skip to content
Permalink
Browse files

Add support for completing builtin class names

Fixes #1863
  • Loading branch information...
muglug committed Jul 18, 2019
1 parent ab50c6c commit 74e1b521a5570cd05ae09cace8fa6fc99cf954b6
Showing with 34 additions and 27 deletions.
  1. +8 −14 src/Psalm/Codebase.php
  2. +15 −3 src/Psalm/Internal/Codebase/ClassLikes.php
  3. +11 −10 tests/LanguageServer/CompletionTest.php
@@ -1399,30 +1399,24 @@ public function getCompletionItemsForPartialSymbol(
}
}
foreach ($matching_classlike_names as $fq_class_name_lc) {
try {
$storage = $this->classlike_storage_provider->get($fq_class_name_lc);
} catch (\Exception $e) {
continue;
}
foreach ($matching_classlike_names as $fq_class_name) {
$extra_edits = [];
$insertion_text = Type::getStringFromFQCLN(
$storage->name,
$fq_class_name,
$aliases && $aliases->namespace ? $aliases->namespace : null,
$aliases ? $aliases->uses_flipped : [],
null
);
if ($aliases
&& $aliases->namespace
&& $insertion_text === '\\' . $storage->name
&& $insertion_text === '\\' . $fq_class_name
&& $aliases->namespace_first_stmt_start
) {
$file_contents = $this->getFileContents($file_path);
$class_name = \preg_replace('/^.*\\\/', '', $storage->name);
$class_name = \preg_replace('/^.*\\\/', '', $fq_class_name);
if ($aliases->uses_end) {
$position = self::getPositionFromOffset($aliases->uses_end, $file_contents);
@@ -1431,7 +1425,7 @@ public function getCompletionItemsForPartialSymbol(
$position,
$position
),
"\n" . 'use ' . $storage->name . ';'
"\n" . 'use ' . $fq_class_name . ';'
);
} else {
$position = self::getPositionFromOffset($aliases->namespace_first_stmt_start, $file_contents);
@@ -1440,20 +1434,20 @@ public function getCompletionItemsForPartialSymbol(
$position,
$position
),
'use ' . $storage->name . ';' . "\n" . "\n"
'use ' . $fq_class_name . ';' . "\n" . "\n"
);
}
$insertion_text = $class_name;
}
$completion_items[] = new \LanguageServerProtocol\CompletionItem(
$storage->name,
$fq_class_name,
\LanguageServerProtocol\CompletionItemKind::CLASS_,
null,
null,
null,
$storage->name,
$fq_class_name,
$insertion_text,
null,
$extra_edits
@@ -155,6 +155,7 @@ private function collectPredefinedClassLikes()
$predefined_class_lc = strtolower($predefined_class);
$this->existing_classlikes_lc[$predefined_class_lc] = true;
$this->existing_classes_lc[$predefined_class_lc] = true;
$this->existing_classes[$predefined_class] = true;
}
}
@@ -170,6 +171,7 @@ private function collectPredefinedClassLikes()
$predefined_interface_lc = strtolower($predefined_interface);
$this->existing_classlikes_lc[$predefined_interface_lc] = true;
$this->existing_interfaces_lc[$predefined_interface_lc] = true;
$this->existing_interfaces[$predefined_interface] = true;
}
}
}
@@ -262,13 +264,23 @@ public function getMatchingClassLikeNames(string $stub) : array
$stub = strtolower($stub);
foreach ($this->existing_classlikes_lc as $fq_classlike_name_lc => $found) {
foreach ($this->existing_classes as $fq_classlike_name => $found) {
if (!$found) {
continue;
}
if (preg_match('@(^|\\\)' . $stub . '.*@', $fq_classlike_name_lc)) {
$matching_classes[] = $fq_classlike_name_lc;
if (preg_match('@(^|\\\)' . $stub . '.*@i', $fq_classlike_name)) {
$matching_classes[] = $fq_classlike_name;
}
}
foreach ($this->existing_interfaces as $fq_classlike_name => $found) {
if (!$found) {
continue;
}
if (preg_match('@(^|\\\)' . $stub . '.*@i', $fq_classlike_name)) {
$matching_classes[] = $fq_classlike_name;
}
}
@@ -755,28 +755,28 @@ class Alpha {}
class Antelope {}
function foo() : void {
new A
new ArrayO
}'
);
$codebase->file_provider->openFile('somefile.php');
$codebase->scanFiles();
$this->analyzeFile('somefile.php', new Context());
$completion_data = $codebase->getCompletionDataAtPosition('somefile.php', new Position(9, 25));
$completion_data = $codebase->getCompletionDataAtPosition('somefile.php', new Position(9, 30));
$this->assertSame(
[
'*A',
'*ArrayO',
'symbol',
215,
220,
],
$completion_data
);
$completion_items = $codebase->getCompletionItemsForPartialSymbol($completion_data[0], $completion_data[2], 'somefile.php');
$this->assertCount(5, $completion_items);
$this->assertCount(1, $completion_items);
$this->assertNotNull($completion_items[0]->additionalTextEdits);
$this->assertCount(1, $completion_items[0]->additionalTextEdits);
@@ -805,29 +805,30 @@ public function testCompletionOnInstanceofWithNamespaceAndUse()
class Alpha {}
class Antelope {}
class Anteater {}
function foo($a) : void {
if ($a instanceof A) {}
if ($a instanceof Ant) {}
}'
);
$codebase->file_provider->openFile('somefile.php');
$codebase->scanFiles();
$this->analyzeFile('somefile.php', new Context());
$completion_data = $codebase->getCompletionDataAtPosition('somefile.php', new Position(9, 39));
$completion_data = $codebase->getCompletionDataAtPosition('somefile.php', new Position(10, 41));
$this->assertSame(
[
'*A',
'*Ant',
'symbol',
231,
267,
],
$completion_data
);
$completion_items = $codebase->getCompletionItemsForPartialSymbol($completion_data[0], $completion_data[2], 'somefile.php');
$this->assertCount(5, $completion_items);
$this->assertCount(2, $completion_items);
}
}

0 comments on commit 74e1b52

Please sign in to comment.
You can’t perform that action at this time.