mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Enable LS completion when whitespace follows known type
This change enables completion when there is whitespace following a known type and an object access operator, e.g.: $foo ->bar() ->baz();
This commit is contained in:
parent
53506fb879
commit
3db32f2274
@ -1150,11 +1150,16 @@ class Codebase
|
|||||||
|
|
||||||
$gap = null;
|
$gap = null;
|
||||||
|
|
||||||
foreach ($type_map as $start_pos => list($end_pos, $possible_type)) {
|
foreach ($type_map as $start_pos => list($end_pos_excluding_whitespace, $possible_type)) {
|
||||||
if ($offset < $start_pos) {
|
if ($offset < $start_pos) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$num_whitespace_bytes = preg_match('/\G\s+/', $file_contents, $matches, 0, $end_pos_excluding_whitespace)
|
||||||
|
? strlen($matches[0])
|
||||||
|
: 0;
|
||||||
|
$end_pos = $end_pos_excluding_whitespace + $num_whitespace_bytes;
|
||||||
|
|
||||||
if ($offset - $end_pos === 2 || $offset - $end_pos === 3) {
|
if ($offset - $end_pos === 2 || $offset - $end_pos === 3) {
|
||||||
$candidate_gap = substr($file_contents, $end_pos, 2);
|
$candidate_gap = substr($file_contents, $end_pos, 2);
|
||||||
|
|
||||||
|
@ -434,4 +434,78 @@ class CompletionTest extends \Psalm\Tests\TestCase
|
|||||||
$this->analyzeFile('somefile.php', new Context());
|
$this->analyzeFile('somefile.php', new Context());
|
||||||
$this->assertSame(['B\A', '->'], $codebase->getCompletionDataAtPosition('somefile.php', new Position(11, 33)));
|
$this->assertSame(['B\A', '->'], $codebase->getCompletionDataAtPosition('somefile.php', new Position(11, 33)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testCompletionOnVariableWithWhitespace()
|
||||||
|
{
|
||||||
|
$codebase = $this->project_analyzer->getCodebase();
|
||||||
|
$config = $codebase->config;
|
||||||
|
$config->throw_exception = false;
|
||||||
|
|
||||||
|
$this->addFile(
|
||||||
|
'somefile.php',
|
||||||
|
'<?php
|
||||||
|
namespace B;
|
||||||
|
|
||||||
|
class A {}
|
||||||
|
|
||||||
|
function (A $a) {
|
||||||
|
$a ->
|
||||||
|
}
|
||||||
|
|
||||||
|
function (A $a) {
|
||||||
|
$a
|
||||||
|
->
|
||||||
|
}
|
||||||
|
'
|
||||||
|
);
|
||||||
|
|
||||||
|
$codebase->file_provider->openFile('somefile.php');
|
||||||
|
$codebase->scanFiles();
|
||||||
|
|
||||||
|
$this->analyzeFile('somefile.php', new Context());
|
||||||
|
$this->assertSame(['B\A', '->'], $codebase->getCompletionDataAtPosition('somefile.php', new Position(6, 25)));
|
||||||
|
$this->assertSame(['B\A', '->'], $codebase->getCompletionDataAtPosition('somefile.php', new Position(11, 26)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testCompletionOnMethodReturnValueWithWhitespace()
|
||||||
|
{
|
||||||
|
$codebase = $this->project_analyzer->getCodebase();
|
||||||
|
$config = $codebase->config;
|
||||||
|
$config->throw_exception = false;
|
||||||
|
|
||||||
|
$this->addFile(
|
||||||
|
'somefile.php',
|
||||||
|
'<?php
|
||||||
|
namespace B;
|
||||||
|
|
||||||
|
class A {
|
||||||
|
public function foo() : self {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function (A $a) {
|
||||||
|
$a->foo() ->
|
||||||
|
}
|
||||||
|
|
||||||
|
function (A $a) {
|
||||||
|
$a->foo()
|
||||||
|
->
|
||||||
|
}
|
||||||
|
'
|
||||||
|
);
|
||||||
|
|
||||||
|
$codebase->file_provider->openFile('somefile.php');
|
||||||
|
$codebase->scanFiles();
|
||||||
|
|
||||||
|
$this->analyzeFile('somefile.php', new Context());
|
||||||
|
$this->assertSame(['B\A', '->'], $codebase->getCompletionDataAtPosition('somefile.php', new Position(10, 32)));
|
||||||
|
$this->assertSame(['B\A', '->'], $codebase->getCompletionDataAtPosition('somefile.php', new Position(15, 26)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user