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

Fix #1198 - add support for template param extends checks

This commit is contained in:
Brown 2019-01-11 10:55:31 -05:00
parent d891c068b4
commit 4ec8d1a8dd
2 changed files with 55 additions and 3 deletions

View File

@ -838,6 +838,8 @@ class CallAnalyzer
$cased_method_id = $function_storage->cased_name; $cased_method_id = $function_storage->cased_name;
} }
$calling_class_storage = $class_storage;
if ($method_id && strpos($method_id, '::')) { if ($method_id && strpos($method_id, '::')) {
$declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id); $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
@ -871,9 +873,24 @@ class CallAnalyzer
if ($function_storage->template_types) { if ($function_storage->template_types) {
$template_types = $function_storage->template_types; $template_types = $function_storage->template_types;
} }
if ($class_storage && $class_storage->template_types) { if ($class_storage) {
foreach ($class_storage->template_types as $template_name => $type) { if ($calling_class_storage
$template_types[$template_name] = $type; && $class_storage !== $calling_class_storage
&& $calling_class_storage->template_type_extends
) {
foreach ($calling_class_storage->template_type_extends as $class_name_lc => $type_map) {
foreach ($type_map as $template_name => $type) {
if (is_string($template_name)
&& $class_name_lc === strtolower($class_storage->name)
) {
$template_types[$template_name] = [new Type\Union([$type]), null];
}
}
}
} elseif ($class_storage->template_types) {
foreach ($class_storage->template_types as $template_name => $type) {
$template_types[$template_name] = $type;
}
} }
} }

View File

@ -1991,6 +1991,41 @@ class TemplateTest extends TestCase
}', }',
'error_message' => 'ImplementedReturnTypeMismatch - src/somefile.php:29 - The return type \'A\Bar\' for', 'error_message' => 'ImplementedReturnTypeMismatch - src/somefile.php:29 - The return type \'A\Bar\' for',
], ],
'extendTemplateAndDoesNotOverrideWithWrongArg' => [
'<?php
/**
* @template T as array-key
*/
abstract class User
{
/**
* @var T
*/
private $id;
/**
* @param T $id
*/
public function __construct($id)
{
$this->id = $id;
}
/**
* @return T
*/
public function getID()
{
return $this->id;
}
}
/**
* @template-extends User<int>
*/
class AppUser extends User {}
$au = new AppUser("string");',
'error_message' => 'InvalidScalarArgument',
],
]; ];
} }
} }