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

Fix evaluation order of covariant template params before invariant ones

This commit is contained in:
Matthew Brown 2019-11-30 01:02:23 -05:00
parent 21f36c3dbd
commit baef67e0d8
3 changed files with 16 additions and 39 deletions

View File

@ -575,38 +575,6 @@ class CommentAnalyzer
} }
} }
if (isset($parsed_docblock['specials']['template-covariant'])
|| isset($parsed_docblock['specials']['psalm-template-covariant'])
) {
$all_templates =
(isset($parsed_docblock['specials']['template-covariant'])
? $parsed_docblock['specials']['template-covariant']
: [])
+ (isset($parsed_docblock['specials']['psalm-template-covariant'])
? $parsed_docblock['specials']['psalm-template-covariant']
: []);
foreach ($all_templates as $template_line) {
$template_type = preg_split('/[\s]+/', preg_replace('@^[ \t]*\*@m', '', $template_line));
$template_name = array_shift($template_type);
if (count($template_type) > 1
&& in_array(strtolower($template_type[0]), ['as', 'super', 'of'], true)
) {
$template_modifier = strtolower(array_shift($template_type));
$info->templates[] = [
$template_name,
$template_modifier,
implode(' ', $template_type),
true
];
} else {
$info->templates[] = [$template_name, null, null, true];
}
}
}
if (isset($parsed_docblock['specials']['template-typeof'])) { if (isset($parsed_docblock['specials']['template-typeof'])) {
foreach ($parsed_docblock['specials']['template-typeof'] as $template_typeof) { foreach ($parsed_docblock['specials']['template-typeof'] as $template_typeof) {
$typeof_parts = preg_split('/[\s]+/', preg_replace('@^[ \t]*\*@m', '', $template_typeof)); $typeof_parts = preg_split('/[\s]+/', preg_replace('@^[ \t]*\*@m', '', $template_typeof));
@ -758,7 +726,7 @@ class CommentAnalyzer
? $parsed_docblock['specials']['psalm-template'] ? $parsed_docblock['specials']['psalm-template']
: []); : []);
foreach ($all_templates as $template_line) { foreach ($all_templates as $offset => $template_line) {
$template_type = preg_split('/[\s]+/', preg_replace('@^[ \t]*\*@m', '', $template_line)); $template_type = preg_split('/[\s]+/', preg_replace('@^[ \t]*\*@m', '', $template_line));
$template_name = array_shift($template_type); $template_name = array_shift($template_type);
@ -771,10 +739,11 @@ class CommentAnalyzer
$template_name, $template_name,
$template_modifier, $template_modifier,
implode(' ', $template_type), implode(' ', $template_type),
false false,
$offset
]; ];
} else { } else {
$info->templates[] = [$template_name, null, null, false]; $info->templates[] = [$template_name, null, null, false, $offset];
} }
} }
} }
@ -790,7 +759,7 @@ class CommentAnalyzer
? $parsed_docblock['specials']['psalm-template-covariant'] ? $parsed_docblock['specials']['psalm-template-covariant']
: []); : []);
foreach ($all_templates as $template_line) { foreach ($all_templates as $offset => $template_line) {
$template_type = preg_split('/[\s]+/', preg_replace('@^[ \t]*\*@m', '', $template_line)); $template_type = preg_split('/[\s]+/', preg_replace('@^[ \t]*\*@m', '', $template_line));
$template_name = array_shift($template_type); $template_name = array_shift($template_type);
@ -803,10 +772,11 @@ class CommentAnalyzer
$template_name, $template_name,
$template_modifier, $template_modifier,
implode(' ', $template_type), implode(' ', $template_type),
true true,
$offset
]; ];
} else { } else {
$info->templates[] = [$template_name, null, null, true]; $info->templates[] = [$template_name, null, null, true, $offset];
} }
} }
} }

View File

@ -28,7 +28,7 @@ class ClassLikeDocblockComment
public $psalm_internal = null; public $psalm_internal = null;
/** /**
* @var array<int, array{string, ?string, ?string, bool}> * @var array<int, array{string, ?string, ?string, bool, int}>
*/ */
public $templates = []; public $templates = [];

View File

@ -1127,6 +1127,13 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
if ($docblock_info->templates) { if ($docblock_info->templates) {
$storage->template_types = []; $storage->template_types = [];
usort(
$docblock_info->templates,
function(array $l, array $r) : int {
return $l[4] > $r[4] ? 1 : -1;
}
);
foreach ($docblock_info->templates as $i => $template_map) { foreach ($docblock_info->templates as $i => $template_map) {
$template_name = $template_map[0]; $template_name = $template_map[0];