1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Resolve docblock self refs as soon as possible

Fixes #1827
This commit is contained in:
Matthew Brown 2019-06-20 23:38:10 -04:00
parent 7b4dbb1c85
commit 2a4072b1be
3 changed files with 53 additions and 19 deletions

View File

@ -2156,7 +2156,8 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
$storage,
$docblock_info->params,
$stmt,
$fake_method
$fake_method,
$class_storage ? $class_storage->name : null
);
}
@ -2286,7 +2287,8 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
$docblock_return_type,
$this->aliases,
$this->function_template_types + $this->class_template_types,
$this->type_aliases
$this->type_aliases,
$class_storage ? $class_storage->name : null
);
$storage->return_type = Type::parseTokens(
@ -2463,7 +2465,8 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
FunctionLikeStorage $storage,
array $docblock_params,
PhpParser\Node\FunctionLike $function,
bool $fake_method
bool $fake_method,
?string $fq_classlike_name
) {
$base = $this->fq_classlike_names
? $this->fq_classlike_names[count($this->fq_classlike_names) - 1] . '::'
@ -2548,7 +2551,8 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
$docblock_param['type'],
$this->aliases,
$this->function_template_types + $this->class_template_types,
$this->type_aliases
$this->type_aliases,
$fq_classlike_name
),
null,
$this->function_template_types + $this->class_template_types

View File

@ -146,8 +146,10 @@ abstract class Type
*
* @return string
*/
private static function fixScalarTerms($type_string, array $php_version = null)
{
private static function fixScalarTerms(
string $type_string,
?array $php_version = null
) : string {
$type_string_lc = strtolower($type_string);
switch ($type_string_lc) {
@ -878,18 +880,18 @@ abstract class Type
}
/**
* @param string $string_type
* @param Aliases $aliases
* @param array<string, mixed>|null $template_type_map
* @param array<string, array<int, string>>|null $type_aliases
*
* @return array<int, string>
*/
public static function fixUpLocalType(
$string_type,
string $string_type,
Aliases $aliases,
array $template_type_map = null,
array $type_aliases = null
array $type_aliases = null,
?string $self_fqcln = null,
?string $parent_fqcln = null
) {
$type_tokens = self::tokenize($string_type);
@ -926,7 +928,19 @@ abstract class Type
$string_type_token = preg_replace('/(.+)\$.*/', '$1', $string_type_token);
}
$type_tokens[$i] = $string_type_token = self::fixScalarTerms($string_type_token);
$type_tokens[$i]
= $string_type_token
= self::fixScalarTerms($string_type_token);
if ($string_type_token === 'self' && $self_fqcln) {
$type_tokens[$i] = $self_fqcln;
continue;
}
if ($string_type_token === 'parent' && $parent_fqcln) {
$type_tokens[$i] = $parent_fqcln;
continue;
}
if (isset(self::PSALM_RESERVED_WORDS[$string_type_token])) {
continue;
@ -974,14 +988,10 @@ abstract class Type
return $type_tokens;
}
/**
* @param string $class
* @param Aliases $aliases
*
* @return string
*/
public static function getFQCLNFromString($class, Aliases $aliases)
{
public static function getFQCLNFromString(
string $class,
Aliases $aliases
) : string {
if ($class === '') {
throw new \InvalidArgumentException('$class cannot be empty');
}

View File

@ -1038,6 +1038,26 @@ class AnnotationTest extends TestCase
*/
$foo = ["foo" => "", "bar" => "", "baz" => ""];'
],
'inheritedSelfAnnotation' => [
'<?php
interface I {
/**
* @param self $i
* @return self
*/
function foo(self $i) : self;
}
class C implements I {
public function foo(I $i) : I {
return $i;
}
}
function takeI(I $i) : I {
return (new C)->foo($i);
}',
],
];
}