1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix #1822 - update use statements with classes

This commit is contained in:
Matthew Brown 2019-06-30 11:12:50 -04:00
parent 8f1ed61ccb
commit 36e2ea6881
4 changed files with 68 additions and 17 deletions

View File

@ -5,12 +5,6 @@ use PhpParser;
class DocblockTypeLocation extends \Psalm\CodeLocation
{
/** @var int */
public $raw_file_start;
/** @var int */
public $raw_file_end;
/** @var int */
public $raw_line_number;

View File

@ -1353,6 +1353,47 @@ class Codebase
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_,
@ -1360,12 +1401,9 @@ class Codebase
null,
null,
$storage->name,
Type::getStringFromFQCLN(
$storage->name,
$aliases && $aliases->namespace ? $aliases->namespace : null,
$aliases ? $aliases->uses_flipped : [],
null
)
$insertion_text,
null,
$extra_edits
);
}
@ -1375,9 +1413,12 @@ class Codebase
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
);
}

View File

@ -240,7 +240,7 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
$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);
@ -270,7 +270,7 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
$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;

View File

@ -688,7 +688,7 @@ class CompletionTest extends \Psalm\Tests\TestCase
/**
* @return void
*/
public function testCompletionOnNewExceptionWithNamespace()
public function testCompletionOnNewExceptionWithNamespaceNoUse()
{
$codebase = $this->project_analyzer->getCodebase();
$config = $codebase->config;
@ -724,7 +724,15 @@ class CompletionTest extends \Psalm\Tests\TestCase
$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);
}
/**
@ -769,6 +777,14 @@ class CompletionTest extends \Psalm\Tests\TestCase
$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);
}
/**