Skip to content

Commit

Permalink
Fix #1822 - update use statements with classes
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Jun 30, 2019
1 parent 8f1ed61 commit 36e2ea6
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 17 deletions.
6 changes: 0 additions & 6 deletions src/Psalm/CodeLocation/DocblockTypeLocation.php
Expand Up @@ -5,12 +5,6 @@

class DocblockTypeLocation extends \Psalm\CodeLocation
{
/** @var int */
public $raw_file_start;

/** @var int */
public $raw_file_end;

/** @var int */
public $raw_line_number;

Expand Down
55 changes: 48 additions & 7 deletions src/Psalm/Codebase.php
Expand Up @@ -1353,19 +1353,57 @@ public function getCompletionItemsForPartialSymbol(
continue;
}

$extra_edits = [];

$insertion_text = Type::getStringFromFQCLN(
$storage->name,
$aliases && $aliases->namespace ? $aliases->namespace : null,
$aliases ? $aliases->uses_flipped : [],
null
);

if ($aliases
&& $aliases->namespace
&& $insertion_text === '\\' . $storage->name
&& $aliases->namespace_first_stmt_start
) {
$file_contents = $this->getFileContents($file_path);

$class_name = \preg_replace('/^.*\\\/', '', $storage->name);

if ($aliases->uses_end) {
$position = self::getPositionFromOffset($aliases->uses_end, $file_contents);
$extra_edits[] = new \LanguageServerProtocol\TextEdit(
new Range(
$position,
$position
),
\PHP_EOL . 'use ' . $storage->name . ';'
);
} else {
$position = self::getPositionFromOffset($aliases->namespace_first_stmt_start, $file_contents);
$extra_edits[] = new \LanguageServerProtocol\TextEdit(
new Range(
$position,
$position
),
'use ' . $storage->name . ';' . \PHP_EOL . \PHP_EOL
);
}

$insertion_text = $class_name;
}

$completion_items[] = new \LanguageServerProtocol\CompletionItem(
$storage->name,
\LanguageServerProtocol\CompletionItemKind::CLASS_,
null,
null,
null,
$storage->name,
Type::getStringFromFQCLN(
$storage->name,
$aliases && $aliases->namespace ? $aliases->namespace : null,
$aliases ? $aliases->uses_flipped : [],
null
)
$insertion_text,
null,
$extra_edits
);
}

Expand All @@ -1375,9 +1413,12 @@ public function getCompletionItemsForPartialSymbol(
private static function getPositionFromOffset(int $offset, string $file_contents) : Position
{
$file_contents = substr($file_contents, 0, $offset);

$before_newline_count = strrpos($file_contents, "\n", $offset - strlen($file_contents));

return new Position(
substr_count($file_contents, "\n"),
$offset - (int)strrpos($file_contents, "\n", strlen($file_contents))
$offset - (int)$before_newline_count - 1
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Psalm/Internal/Visitor/ReflectorVisitor.php
Expand Up @@ -240,7 +240,7 @@ public function enterNode(PhpParser\Node $node)
$this->aliases->uses_start = (int) $node->getAttribute('startFilePos');
}

$this->aliases->uses_end = (int) $node->getAttribute('endFilePos');
$this->aliases->uses_end = (int) $node->getAttribute('endFilePos') + 1;
} elseif ($node instanceof PhpParser\Node\Stmt\GroupUse) {
$use_prefix = implode('\\', $node->prefix->parts);

Expand Down Expand Up @@ -270,7 +270,7 @@ public function enterNode(PhpParser\Node $node)
$this->aliases->uses_start = (int) $node->getAttribute('startFilePos');
}

$this->aliases->uses_end = (int) $node->getAttribute('endFilePos');
$this->aliases->uses_end = (int) $node->getAttribute('endFilePos') + 1;
} elseif ($node instanceof PhpParser\Node\Stmt\ClassLike) {
if ($this->skip_if_descendants) {
return;
Expand Down
20 changes: 18 additions & 2 deletions tests/LanguageServer/CompletionTest.php
Expand Up @@ -688,7 +688,7 @@ function foo() : void {
/**
* @return void
*/
public function testCompletionOnNewExceptionWithNamespace()
public function testCompletionOnNewExceptionWithNamespaceNoUse()
{
$codebase = $this->project_analyzer->getCodebase();
$config = $codebase->config;
Expand Down Expand Up @@ -724,7 +724,15 @@ function foo() : void {
$this->assertCount(1, $completion_items);

$this->assertSame('Exception', $completion_items[0]->label);
$this->assertSame('\Exception', $completion_items[0]->insertText);
$this->assertSame('Exception', $completion_items[0]->insertText);

$this->assertNotNull($completion_items[0]->additionalTextEdits);
$this->assertCount(1, $completion_items[0]->additionalTextEdits);
$this->assertSame('use Exception;' . \PHP_EOL . \PHP_EOL, $completion_items[0]->additionalTextEdits[0]->newText);
$this->assertSame(3, $completion_items[0]->additionalTextEdits[0]->range->start->line);
$this->assertSame(16, $completion_items[0]->additionalTextEdits[0]->range->start->character);
$this->assertSame(3, $completion_items[0]->additionalTextEdits[0]->range->end->line);
$this->assertSame(16, $completion_items[0]->additionalTextEdits[0]->range->end->character);
}

/**
Expand Down Expand Up @@ -769,6 +777,14 @@ function foo() : void {
$completion_items = $codebase->getCompletionItemsForPartialSymbol($completion_data[0], $completion_data[2], 'somefile.php');

$this->assertCount(5, $completion_items);

$this->assertNotNull($completion_items[0]->additionalTextEdits);
$this->assertCount(1, $completion_items[0]->additionalTextEdits);
$this->assertSame(\PHP_EOL . 'use ArrayObject;', $completion_items[0]->additionalTextEdits[0]->newText);
$this->assertSame(3, $completion_items[0]->additionalTextEdits[0]->range->start->line);
$this->assertSame(44, $completion_items[0]->additionalTextEdits[0]->range->start->character);
$this->assertSame(3, $completion_items[0]->additionalTextEdits[0]->range->end->line);
$this->assertSame(44, $completion_items[0]->additionalTextEdits[0]->range->end->character);
}

/**
Expand Down

0 comments on commit 36e2ea6

Please sign in to comment.