1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

Add support for phpstan import-type and type annotations (#5648)

* Add support for phpstan import-type and type annotations

* Add test

* Fix cs
This commit is contained in:
Vincent Langlet 2021-04-20 04:56:08 +02:00 committed by GitHub
parent d773007f29
commit 39e61ae942
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 11 deletions

View File

@ -23,6 +23,7 @@ use function preg_match;
use function count;
use function reset;
use function preg_split;
use function array_merge;
use function array_shift;
use function implode;
use function substr;
@ -239,15 +240,18 @@ class ClassLikeDocblockParser
}
}
if (isset($parsed_docblock->tags['psalm-import-type'])) {
foreach ($parsed_docblock->tags['psalm-import-type'] as $offset => $imported_type_entry) {
$info->imported_types[] = [
'line_number' => $comment->getStartLine() + substr_count($comment->getText(), "\n", 0, $offset),
'start_offset' => $comment->getStartFilePos() + $offset,
'end_offset' => $comment->getStartFilePos() + $offset + strlen($imported_type_entry),
'parts' => CommentAnalyzer::splitDocLine($imported_type_entry) ?: []
];
}
$imported_types = array_merge(
$parsed_docblock->tags['phpstan-import-type'] ?? [],
$parsed_docblock->tags['psalm-import-type'] ?? []
);
foreach ($imported_types as $offset => $imported_type_entry) {
$info->imported_types[] = [
'line_number' => $comment->getStartLine() + substr_count($comment->getText(), "\n", 0, $offset),
'start_offset' => $comment->getStartFilePos() + $offset,
'end_offset' => $comment->getStartFilePos() + $offset + strlen($imported_type_entry),
'parts' => CommentAnalyzer::splitDocLine($imported_type_entry) ?: []
];
}
if (isset($parsed_docblock->combined_tags['method'])) {

View File

@ -3,6 +3,7 @@ namespace Psalm\Internal\PhpVisitor\Reflector;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Scanner\ClassLikeDocblockComment;
use function array_merge;
use function array_pop;
use function count;
use function explode;
@ -1538,12 +1539,17 @@ class ClassLikeNodeScanner
): array {
$parsed_docblock = DocComment::parsePreservingLength($comment);
if (!isset($parsed_docblock->tags['psalm-type'])) {
if (!isset($parsed_docblock->tags['psalm-type']) && !isset($parsed_docblock->tags['phpstan-type'])) {
return [];
}
$type_alias_comment_lines = array_merge(
$parsed_docblock->tags['phpstan-type'] ?? [],
$parsed_docblock->tags['psalm-type'] ?? []
);
return self::getTypeAliasesFromCommentLines(
$parsed_docblock->tags['psalm-type'],
$type_alias_comment_lines,
$aliases,
$type_aliases,
$self_fqcln

View File

@ -532,6 +532,38 @@ class TypeAnnotationTest extends TestCase
*/
class C extends A {}
$instance = new C("hello");
$output = $instance->value;',
[
'$output' => 'string',
],
],
'importedTypeWithPhpstanAnnotation' => [
'<?php
/** @template T */
abstract class A {
/** @var T */
public $value;
/** @param T $value */
public function __construct($value) {
$this->value = $value;
}
}
/**
* @phpstan-type Foo=string
*/
class B {}
/**
* @phpstan-import-type Foo from B
* @phpstan-type Baz=Foo
*
* @extends A<Baz>
*/
class C extends A {}
$instance = new C("hello");
$output = $instance->value;',
[