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

Alter docblock params too

This commit is contained in:
Brown 2020-08-14 16:26:55 -04:00
parent dbcf154036
commit cdef4ec351
6 changed files with 96 additions and 12 deletions

View File

@ -1841,7 +1841,7 @@ class ClassAnalyzer extends ClassLikeAnalyzer
MethodComparator::compare(
$codebase,
$stmt,
null,
$class_storage,
$declaring_storage,
$implementer_method_storage,

View File

@ -387,15 +387,20 @@ class MethodComparator
}
}
$config = \Psalm\Config::getInstance();
if ($guide_param->name !== $implementer_param->name
&& $guide_method_storage->allow_named_arg_calls
&& count($implementer_method_storage->params) > 1
&& $guide_classlike_storage->user_defined
&& $implementer_classlike_storage->user_defined
&& $implementer_classlike_storage->location
&& $implementer_param->location
&& $guide_method_storage->cased_name
&& substr($guide_method_storage->cased_name, 0, 2) !== '__'
&& $config->isInProjectDirs(
$implementer_param->location->file_path
)
) {
$config = \Psalm\Config::getInstance();
if ($config->allow_named_arg_calls
|| ($guide_classlike_storage->location
&& !$config->isInProjectDirs($guide_classlike_storage->location->file_path)
@ -416,7 +421,7 @@ class MethodComparator
if ($replacements = $param_replacer->getReplacements()) {
\Psalm\Internal\FileManipulation\FileManipulationBuffer::add(
$implementer_classlike_storage->location->file_path,
$implementer_param->location->file_path,
$replacements
);
}
@ -429,11 +434,6 @@ class MethodComparator
. $guide_param->name . ' as defined by '
. $cased_guide_method_id,
$implementer_param->location
&& $config->isInProjectDirs(
$implementer_param->location->file_path
)
? $implementer_param->location
: $code_location
)
)) {
// fall through

View File

@ -65,6 +65,43 @@ class ParamReplacementVisitor extends PhpParser\NodeVisitorAbstract implements P
$this->new_new_name_used = true;
}
} elseif ($node instanceof PhpParser\Node\Stmt\ClassMethod
&& ($docblock = $node->getDocComment())
) {
$parsed_docblock = \Psalm\Internal\Scanner\DocblockParser::parse($docblock->getText());
$replaced = false;
foreach ($parsed_docblock->tags as $tag_name => $tags) {
foreach ($tags as $i => $tag) {
if ($tag_name === 'param'
|| $tag_name === 'psalm-param'
|| $tag_name === 'phpstan-param'
|| $tag_name === 'phan-param'
) {
$parts = \Psalm\Internal\Analyzer\CommentAnalyzer::splitDocLine($tag);
if (($parts[1] ?? '') === '$' . $this->old_name) {
$parsed_docblock->tags[$tag_name][$i] = \str_replace(
'$' . $this->old_name,
'$' . $this->new_name,
$tag
);
$replaced = true;
}
}
}
}
if ($replaced) {
$this->replacements[] = new FileManipulation(
$docblock->getStartFilePos(),
$docblock->getEndFilePos() + 1,
\rtrim($parsed_docblock->render($parsed_docblock->first_line_padding)),
false,
false
);
}
}
}

View File

@ -31,6 +31,8 @@ class DocblockParser
$special = [];
$first_line_padding = null;
$last = false;
foreach ($lines as $k => $line) {
if (preg_match('/^[ \t]*\*?\s*@\w/i', $line)) {
@ -52,6 +54,14 @@ class DocblockParser
$line = str_replace("\r", '', $line);
if ($first_line_padding === null) {
$asterisk_pos = strpos($line, '*');
if ($asterisk_pos) {
$first_line_padding = substr($line, 0, $asterisk_pos - 1);
}
}
if (preg_match('/^[ \t]*\*?\s*@([\w\-:]+)[\t ]*(.*)$/sm', $line, $matches, PREG_OFFSET_CAPTURE)) {
/** @var array<int, array{string, int}> $matches */
list($_, $type_info, $data_info) = $matches;
@ -107,7 +117,7 @@ class DocblockParser
// is one.
$docblock = preg_replace('/^\s*\n/', '', $docblock);
$parsed = new ParsedDocblock($docblock, $special);
$parsed = new ParsedDocblock($docblock, $special, $first_line_padding ?: '');
self::resolveTags($parsed);

View File

@ -10,6 +10,9 @@ class ParsedDocblock
/** @var string */
public $description;
/** @var string */
public $first_line_padding;
/** @var array<string, array<int, string>> */
public $tags = [];
@ -22,10 +25,11 @@ class ParsedDocblock
private static $shouldAddNewLineBetweenAnnotations = true;
/** @param array<string, array<int, string>> $tags */
public function __construct(string $description, array $tags)
public function __construct(string $description, array $tags, string $first_line_padding = '')
{
$this->description = $description;
$this->tags = $tags;
$this->first_line_padding = $first_line_padding;
}
public function render(string $left_padding) : string

View File

@ -92,6 +92,39 @@ class ParamNameMismatchTest extends FileManipulationTest
['ParamNameMismatch'],
true,
],
'fixMismatchingParamNameWithDocblockType74' => [
'<?php
class A {
/**
* @param string $str
*/
public function foo($str, bool $b = false) : void {}
}
class AChild extends A {
/**
* @param string $string
*/
public function foo($string, bool $b = false) : void {}
}',
'<?php
class A {
/**
* @param string $str
*/
public function foo($str, bool $b = false) : void {}
}
class AChild extends A {
/**
* @param string $str
*/
public function foo($str, bool $b = false) : void {}
}',
'7.1',
['ParamNameMismatch'],
true,
],
];
}
}