Skip to content
Permalink
Browse files

Fix #1656 - allow chained call completion

  • Loading branch information...
muglug committed May 17, 2019
1 parent a1c9ad5 commit 963d5bb901e64f3c20bbdd0edc130e64f55218c8
@@ -1091,15 +1091,22 @@ public function getCompletionDataAtPosition(string $file_path, Position $positio
krsort($type_map);
$gap = null;
foreach ($type_map as $start_pos => list($end_pos, $possible_type)) {
if ($offset < $start_pos) {
continue;
}
if ($offset - $end_pos === 2 || $offset - $end_pos === 3) {
$recent_type = $possible_type;
$candidate_gap = substr($file_contents, $end_pos, 2);
break;
if ($candidate_gap === '->' || $candidate_gap === '::') {
$gap = $candidate_gap;
$recent_type = $possible_type;
break;
}
}
if ($offset - $end_pos > 3) {
@@ -1109,12 +1116,11 @@ public function getCompletionDataAtPosition(string $file_path, Position $positio
if (!$recent_type
|| $recent_type === 'mixed'
|| !$gap
) {
return null;
}
$gap = substr($file_contents, $end_pos, 2);
return [$recent_type, $gap];
}
@@ -325,7 +325,8 @@ public static function analyze(
$codebase->analyzer->addNodeType(
$statements_analyzer->getFilePath(),
$stmt->name,
(string) $stmt->inferredType
(string) $stmt->inferredType,
$stmt
);
}
@@ -890,7 +890,8 @@ function (Assertion $assertion) use ($found_generic_params) : Assertion {
$codebase->analyzer->addNodeType(
$statements_analyzer->getFilePath(),
$stmt->name,
(string) $stmt->inferredType
(string) $stmt->inferredType,
$stmt
);
}
}
@@ -902,10 +902,14 @@ public function getMixedCounts()
/**
* @return void
*/
public function addNodeType(string $file_path, PhpParser\Node $node, string $node_type)
{
public function addNodeType(
string $file_path,
PhpParser\Node $node,
string $node_type,
PhpParser\Node $parent_node = null
) {
$this->type_map[$file_path][(int)$node->getAttribute('startFilePos')] = [
(int)$node->getAttribute('endFilePos') + 1,
($parent_node ? (int)$parent_node->getAttribute('endFilePos') : (int)$node->getAttribute('endFilePos')) + 1,
$node_type
];
}
@@ -202,6 +202,88 @@ public function foo() : void {
$this->assertSame(['B\C', '->'], $codebase->getCompletionDataAtPosition('somefile.php', new Position(16, 39)));
}
/**
* @return void
*/
public function testCompletionOnThisPropertyWithCharacter()
{
$codebase = $this->project_analyzer->getCodebase();
$config = $codebase->config;
$config->throw_exception = false;
$this->addFile(
'somefile.php',
'<?php
namespace B;
class C {
public function otherFunction() : void
}
class A {
/** @var C */
protected $cee_me;
public function __construct() {
$this->cee_me = new C();
}
public function foo() : void {
$this->cee_me->o
}
}'
);
$codebase = $this->project_analyzer->getCodebase();
$codebase->file_provider->openFile('somefile.php');
$codebase->scanFiles();
$this->analyzeFile('somefile.php', new Context());
$this->assertSame(['B\C', '->'], $codebase->getCompletionDataAtPosition('somefile.php', new Position(16, 40)));
}
/**
* @return void
*/
public function testCompletionOnThisPropertyWithAnotherCharacter()
{
$codebase = $this->project_analyzer->getCodebase();
$config = $codebase->config;
$config->throw_exception = false;
$this->addFile(
'somefile.php',
'<?php
namespace B;
class C {
public function otherFunction() : void
}
class A {
/** @var C */
protected $cee_me;
public function __construct() {
$this->cee_me = new C();
}
public function foo() : void {
$this->cee_me->ot
}
}'
);
$codebase = $this->project_analyzer->getCodebase();
$codebase->file_provider->openFile('somefile.php');
$codebase->scanFiles();
$this->analyzeFile('somefile.php', new Context());
$this->assertSame(null, $codebase->getCompletionDataAtPosition('somefile.php', new Position(16, 41)));
}
/**
* @return void
*/
@@ -257,4 +339,104 @@ public function foo() : void {
$this->assertCount(3, $completion_items);
}
/**
* @return void
*/
public function testCompletionOnMethodReturnValue()
{
$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()->
}
'
);
$codebase->file_provider->openFile('somefile.php');
$codebase->scanFiles();
$this->analyzeFile('somefile.php', new Context());
$this->assertSame(['B\A', '->'], $codebase->getCompletionDataAtPosition('somefile.php', new Position(9, 31)));
}
/**
* @return void
*/
public function testCompletionOnMethodArgument()
{
$codebase = $this->project_analyzer->getCodebase();
$config = $codebase->config;
$config->throw_exception = false;
$this->addFile(
'somefile.php',
'<?php
namespace B;
class A {
public function foo(A $a) : self {
return $this;
}
}
class C {}
function (A $a, C $c) {
$a->foo($c->)
}
'
);
$codebase->file_provider->openFile('somefile.php');
$codebase->scanFiles();
$this->analyzeFile('somefile.php', new Context());
$this->assertSame(['B\C', '->'], $codebase->getCompletionDataAtPosition('somefile.php', new Position(11, 32)));
}
/**
* @return void
*/
public function testCompletionOnMethodReturnValueWithArgument()
{
$codebase = $this->project_analyzer->getCodebase();
$config = $codebase->config;
$config->throw_exception = false;
$this->addFile(
'somefile.php',
'<?php
namespace B;
class A {
public function foo(A $a) : self {
return $this;
}
}
class C {}
function (A $a, C $c) {
$a->foo($c)->
}
'
);
$codebase->file_provider->openFile('somefile.php');
$codebase->scanFiles();
$this->analyzeFile('somefile.php', new Context());
$this->assertSame(['B\A', '->'], $codebase->getCompletionDataAtPosition('somefile.php', new Position(11, 33)));
}
}

0 comments on commit 963d5bb

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